spec: 타깃을 i386 하나로 정하고 far 를 언어에서 뺀다
세그먼트 주소 지정은 x86 리얼모드에만 있는 개념이고, 평평한 주소 공간을 가진 다른 32비트 프로세서에는 대응물이 없다. 영구 제외다. usize/isize 는 타깃의 포인터 폭이며 특정 비트 수를 약속하지 않는다. 오늘 32비트지만 u32 와 자동 변환되지 않는다. bits16 에서 배울 것은 '32로 정하자'가 아니라 '폭이 언어 의미론으로 새어나가지 않게 하자'이고, 그것이 나중에 다른 폭의 타깃을 여는 유일한 장치다. 타깃이 하나이므로 레이아웃에서 pointer_bits 분기가 전부 사라졌다. 인터럽트 핸들러와 공유 상태는 v0.2 로 내렸다 -- 문법은 아직 파싱되지만 명세의 약속은 아니다.
This commit is contained in:
+2
-4
@@ -16,7 +16,7 @@ static char *read_file(const char *name, unsigned long *size)
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
puts("usage: fec [--dump-tokens|--dump-ast|--check|--emit-c] file.fe [--target=bits16|bits32] [-o output.c]");
|
||||
puts("usage: fec [--dump-tokens|--dump-ast|--check] file.fe [--no-checks]");
|
||||
}
|
||||
|
||||
static void dump_tokens(const char *src, unsigned long n, const char *file,
|
||||
@@ -45,14 +45,12 @@ int main(int argc, char **argv)
|
||||
FeAst ast;
|
||||
FeParser p;
|
||||
FeCheck check;
|
||||
unsigned pointer_bits=32;
|
||||
unsigned pointer_bits=FE_PTR_BITS;
|
||||
if(argc<2){usage();return 2;}
|
||||
for(i=1;i<argc;i++) {
|
||||
if(strcmp(argv[i],"--dump-ast")==0) dump=1;
|
||||
else if(strcmp(argv[i],"--dump-tokens")==0) dump_tok=1;
|
||||
else if(strcmp(argv[i],"--check")==0) check_only=1;
|
||||
else if(strncmp(argv[i],"--target=bits16",15)==0) pointer_bits=16;
|
||||
else if(strncmp(argv[i],"--target=bits32",15)==0) pointer_bits=32;
|
||||
else if(strcmp(argv[i],"--no-checks")==0) no_checks=1;
|
||||
else if(strncmp(argv[i],"--target=",9)==0 || strncmp(argv[i],"--model=",8)==0 || strcmp(argv[i],"--strip-error-names")==0) { }
|
||||
else if(argv[i][0]!='-') file=argv[i];
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ static const FeKw keywords[] = {
|
||||
{"match",FE_TOK_MATCH},{"return",FE_TOK_RETURN},{"break",FE_TOK_BREAK},{"continue",FE_TOK_CONTINUE},
|
||||
{"defer",FE_TOK_DEFER},{"unsafe",FE_TOK_UNSAFE},{"comptime",FE_TOK_COMPTIME},{"asm",FE_TOK_ASM},
|
||||
{"try",FE_TOK_TRY},{"catch",FE_TOK_CATCH},{"as",FE_TOK_AS},{"extern",FE_TOK_EXTERN},
|
||||
{"interrupt",FE_TOK_INTERRUPT},{"interrupt_safe",FE_TOK_INTERRUPT_SAFE},{"far",FE_TOK_FAR},
|
||||
{"interrupt",FE_TOK_INTERRUPT},{"interrupt_safe",FE_TOK_INTERRUPT_SAFE},
|
||||
{"true",FE_TOK_TRUE},{"false",FE_TOK_FALSE},{"null",FE_TOK_NULL},{"undefined",FE_TOK_UNDEFINED},
|
||||
{"shared",FE_TOK_SHARED},{"atomic",FE_TOK_ATOMIC},{"critical",FE_TOK_CRITICAL},
|
||||
{"self",FE_TOK_SELF},{"Self",FE_TOK_SELFTYPE},{"type",FE_TOK_TYPE},
|
||||
|
||||
@@ -43,9 +43,6 @@ static FeNode *type(FeParser *p)
|
||||
if (is(p,FE_TOK_AND)) {
|
||||
next(p); n=toknode(p,FE_N_TYPE,t); if(eat(p,FE_TOK_MUT)) n->text=fe_arena_strdup(&p->ast->arena,"&mut",4); n->a=type(p); return n;
|
||||
}
|
||||
if (is(p,FE_TOK_FAR)) {
|
||||
next(p); n=toknode(p,FE_N_TYPE,t); if(is(p,FE_TOK_STAR)||is(p,FE_TOK_XOR)||is(p,FE_TOK_AND)) next(p); n->a=type(p); return n;
|
||||
}
|
||||
if (is(p,FE_TOK_LBRACKET)) {
|
||||
next(p); n=toknode(p,FE_N_TYPE,t);
|
||||
if(!eat(p,FE_TOK_RBRACKET)) { n->a=expr(p,0); want(p,FE_TOK_RBRACKET,"expected ']' in array type"); }
|
||||
|
||||
+19
-21
@@ -441,12 +441,12 @@ static void layout_type(FeTypeCtx *ctx, FeType *t)
|
||||
if (t->kind == FE_TYPE_ERROR_UNION) {
|
||||
if (t->error_value && t->error_value->kind != FE_TYPE_VOID) {
|
||||
layout_type(ctx,t->error_value);
|
||||
t->align=ctx->pointer_bits==16 ? 1U : fe_type_align(t->error_value);
|
||||
t->align=fe_type_align(t->error_value);
|
||||
t->size=round_up(2UL,t->align)+fe_type_size(t->error_value);
|
||||
t->size=round_up(t->size,t->align);
|
||||
} else {
|
||||
t->size=2;
|
||||
t->align=ctx->pointer_bits==16 ? 1U : 2U;
|
||||
t->align=2U;
|
||||
}
|
||||
t->cycle_state = 2; return;
|
||||
}
|
||||
@@ -456,7 +456,7 @@ static void layout_type(FeTypeCtx *ctx, FeType *t)
|
||||
t->size=fe_type_size(t->elem);
|
||||
t->align=fe_type_align(t->elem);
|
||||
} else {
|
||||
t->align=ctx->pointer_bits==16 ? 1U : fe_type_align(t->elem);
|
||||
t->align=fe_type_align(t->elem);
|
||||
t->size=round_up(1UL,t->align)+fe_type_size(t->elem);
|
||||
t->size=round_up(t->size,t->align);
|
||||
}
|
||||
@@ -467,30 +467,29 @@ static void layout_type(FeTypeCtx *ctx, FeType *t)
|
||||
}
|
||||
if (t->kind == FE_TYPE_INT) {
|
||||
t->size = (t->bits + 7U) / 8U;
|
||||
t->align = ctx->pointer_bits == 16 ? 1U : t->size;
|
||||
if (t->size > 4UL) t->size = ctx->pointer_bits == 16 ? 2UL : 4UL;
|
||||
t->align = t->size;
|
||||
if (t->size > 4UL) t->size = 4UL;
|
||||
t->cycle_state = 2; return;
|
||||
}
|
||||
if (t->kind == FE_TYPE_REF) {
|
||||
t->size = ctx->pointer_bits == 16 ? 2UL : 4UL;
|
||||
t->align = ctx->pointer_bits == 16 ? 1U : 4U;
|
||||
t->size = FE_PTR_SIZE;
|
||||
t->align = FE_PTR_ALIGN;
|
||||
t->cycle_state = 2; return;
|
||||
}
|
||||
if (t->kind == FE_TYPE_OWNED) {
|
||||
t->size = t->elem && t->elem->kind==FE_TYPE_SLICE ?
|
||||
(ctx->pointer_bits == 16 ? 4UL : 8UL) :
|
||||
(ctx->pointer_bits == 16 ? 2UL : 4UL);
|
||||
t->align = ctx->pointer_bits == 16 ? 1U : 4U;
|
||||
2UL * FE_PTR_SIZE : FE_PTR_SIZE;
|
||||
t->align = FE_PTR_ALIGN;
|
||||
t->cycle_state = 2; return;
|
||||
}
|
||||
if (t->kind == FE_TYPE_SLICE || t->kind == FE_TYPE_STR) {
|
||||
t->size = ctx->pointer_bits == 16 ? 4UL : 8UL;
|
||||
t->align = ctx->pointer_bits == 16 ? 1U : 4U;
|
||||
t->size = 2UL * FE_PTR_SIZE;
|
||||
t->align = FE_PTR_ALIGN;
|
||||
t->cycle_state = 2; return;
|
||||
}
|
||||
if (t->kind == FE_TYPE_ARRAY) {
|
||||
layout_type(ctx, t->elem);
|
||||
t->align = t->packed || ctx->pointer_bits == 16 ? 1U : fe_type_align(t->elem);
|
||||
t->align = t->packed ? 1U : fe_type_align(t->elem);
|
||||
t->size = t->length * fe_type_size(t->elem);
|
||||
t->cycle_state = 2; return;
|
||||
}
|
||||
@@ -500,7 +499,7 @@ static void layout_type(FeTypeCtx *ctx, FeType *t)
|
||||
if (!t->fields[i].type && t->fields[i].ast_node)
|
||||
t->fields[i].type = fe_type_from_ast(ctx, t->fields[i].ast_node->a);
|
||||
layout_type(ctx, t->fields[i].type);
|
||||
align = t->packed || ctx->pointer_bits == 16 ? 1U : fe_type_align(t->fields[i].type);
|
||||
align = t->packed ? 1U : fe_type_align(t->fields[i].type);
|
||||
if (align > max_align) max_align = align;
|
||||
off = round_up(off, align);
|
||||
t->fields[i].offset = off;
|
||||
@@ -528,9 +527,9 @@ static void layout_type(FeTypeCtx *ctx, FeType *t)
|
||||
if (off > max_size) max_size = off;
|
||||
}
|
||||
t->bits = t->variant_count > 256U ? 16U : 8U;
|
||||
off = ctx->pointer_bits == 16 ? t->bits / 8U : round_up(t->bits / 8U, max_align);
|
||||
t->size = round_up(off + max_size, ctx->pointer_bits == 16 ? 1U : max_align);
|
||||
t->align = ctx->pointer_bits == 16 ? 1U : max_align;
|
||||
off = round_up(t->bits / 8U, max_align);
|
||||
t->size = round_up(off + max_size, max_align);
|
||||
t->align = max_align;
|
||||
t->cycle_state = 2;
|
||||
}
|
||||
}
|
||||
@@ -599,8 +598,7 @@ FeType *fe_type_from_ast(FeTypeCtx *ctx, const FeNode *node)
|
||||
fe_type_from_ast(ctx,node->b));
|
||||
return fe_type_error_union(ctx,fe_type_from_ast(ctx,node->a));
|
||||
}
|
||||
if (node->text && (strcmp(node->text, "*") == 0 ||
|
||||
strcmp(node->text, "far") == 0))
|
||||
if (node->text && strcmp(node->text, "*") == 0)
|
||||
return fe_type_intern(ctx, "<unknown>");
|
||||
if (node->text && strcmp(node->text, "fn") == 0)
|
||||
return fe_type_intern(ctx, "<unknown>");
|
||||
@@ -665,8 +663,8 @@ const char *fe_type_c_name(const FeType *t, unsigned pointer_bits)
|
||||
return owned_name;
|
||||
}
|
||||
if (t->kind != FE_TYPE_INT) return "long";
|
||||
if (strcmp(t->name, "usize") == 0) return pointer_bits == 16 ? "unsigned short" : "unsigned long";
|
||||
if (strcmp(t->name, "isize") == 0) return pointer_bits == 16 ? "short" : "long";
|
||||
if (strcmp(t->name, "usize") == 0) return "unsigned long";
|
||||
if (strcmp(t->name, "isize") == 0) return "long";
|
||||
if (strcmp(t->name, "i8") == 0) return "signed char";
|
||||
if (strcmp(t->name, "u8") == 0) return "unsigned char";
|
||||
if (strcmp(t->name, "i16") == 0) return "short";
|
||||
|
||||
@@ -10,6 +10,13 @@ typedef enum FeTypeKind {
|
||||
FE_TYPE_REF, FE_TYPE_OWNED, FE_TYPE_UNKNOWN
|
||||
} FeTypeKind;
|
||||
|
||||
/* One target, one pointer width (SPEC 2). usize and isize are that width and
|
||||
are not promised to be any particular number of bits, which is what keeps a
|
||||
different width possible later. */
|
||||
#define FE_PTR_SIZE 4UL
|
||||
#define FE_PTR_ALIGN 4U
|
||||
#define FE_PTR_BITS 32U
|
||||
|
||||
typedef struct FeFieldType FeFieldType;
|
||||
|
||||
/* A type parameter bound to an argument while an instance is checked. */
|
||||
|
||||
@@ -7,7 +7,6 @@ packed struct Packet {
|
||||
}
|
||||
interrupt_safe fn poll() { }
|
||||
interrupt fn timer() { }
|
||||
fn invoke(p: far fn()) { }
|
||||
|
||||
pub fn demo() {
|
||||
var count = undefined;
|
||||
@@ -16,5 +15,4 @@ pub fn demo() {
|
||||
let x = true and not false or false;
|
||||
let y = x orelse true;
|
||||
let e = error.NotFound;
|
||||
@call_far(@as_far_fn(timer));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user