feat: align M3 slices and strings with v0.1.7

This commit is contained in:
2026-08-16 18:23:30 +09:00
parent cba2c86fbc
commit 42abc0d7e7
32 changed files with 183 additions and 60 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ FeNode *fe_node(FeAst *a, FeNodeKind k, FeLoc loc, const char *text, unsigned lo
FeNode *n=(FeNode *)fe_arena_alloc(&a->arena,sizeof(FeNode)); FeNode *n=(FeNode *)fe_arena_alloc(&a->arena,sizeof(FeNode));
if (!n) return 0; if (!n) return 0;
n->kind=k; n->loc=loc; n->text=text?fe_arena_strdup(&a->arena,text,len):0; n->kind=k; n->loc=loc; n->text=text?fe_arena_strdup(&a->arena,text,len):0;
n->a=n->b=n->c=n->children=n->next=0; n->cname=0; n->aux_text=0; n->aux_cname=0; n->sem_type=0; n->flags=0; return n; n->a=n->b=n->c=n->children=n->next=0; n->cname=0; n->aux_text=0; n->aux_cname=0; n->sem_type=0; n->sem_decl=0; n->flags=0; return n;
} }
void fe_node_add(FeNode *parent, FeNode *child) void fe_node_add(FeNode *parent, FeNode *child)
{ {
+1
View File
@@ -30,6 +30,7 @@ struct FeNode {
char *aux_text; char *aux_text;
char *aux_cname; char *aux_cname;
FeType *sem_type; FeType *sem_type;
FeNode *sem_decl;
unsigned flags; unsigned flags;
}; };
+37 -16
View File
@@ -54,7 +54,7 @@ static int is_copy_type(FeType *t)
unsigned i; unsigned i;
if (!t) return 1; if (!t) return 1;
if (t->kind==FE_TYPE_OWNED) return 0; if (t->kind==FE_TYPE_OWNED) return 0;
if (t->kind==FE_TYPE_REF) return !t->ref_mut; if (t->kind==FE_TYPE_REF || t->kind==FE_TYPE_SLICE) return !t->ref_mut;
if (t->kind==FE_TYPE_ARRAY) return is_copy_type(t->elem); if (t->kind==FE_TYPE_ARRAY) return is_copy_type(t->elem);
if (t->kind==FE_TYPE_STRUCT) { if (t->kind==FE_TYPE_STRUCT) {
if (t->has_drop) return 0; if (t->has_drop) return 0;
@@ -311,6 +311,8 @@ static FeNode *find_const_node(FeCheck *c, const char *name)
return 0; return 0;
} }
static int format_is_slice_u8(FeType *t);
static const char *builtin_format(FeCheckerState *s, FeNode *fmt) static const char *builtin_format(FeCheckerState *s, FeNode *fmt)
{ {
FeNode *decl; FeNode *decl;
@@ -323,7 +325,7 @@ static const char *builtin_format(FeCheckerState *s, FeNode *fmt)
sym->decl : find_const_node(s->c,fmt->text); sym->decl : find_const_node(s->c,fmt->text);
if (decl && decl->b && decl->b->kind==FE_N_LITERAL && if (decl && decl->b && decl->b->kind==FE_N_LITERAL &&
decl->b->text && decl->b->text[0]=='"') { decl->b->text && decl->b->text[0]=='"') {
if (!decl->a || fe_type_from_ast(&s->c->types,decl->a)->kind==FE_TYPE_STR) if (!decl->a || format_is_slice_u8(fe_type_from_ast(&s->c->types,decl->a)))
return decl->b->text; return decl->b->text;
} }
} }
@@ -347,10 +349,10 @@ static int format_arg_ok(FeType *t, int verb)
if (!t) return 0; if (!t) return 0;
if (verb=='x') return fe_type_is_integer(t); if (verb=='x') return fe_type_is_integer(t);
if (verb=='c') return t->kind==FE_TYPE_CHAR; if (verb=='c') return t->kind==FE_TYPE_CHAR;
if (verb=='s') return t->kind==FE_TYPE_STR || format_is_slice_u8(t); if (verb=='s') return format_is_slice_u8(t);
if (verb=='b') return t->kind==FE_TYPE_BOOL; if (verb=='b') return t->kind==FE_TYPE_BOOL;
if (t->kind==FE_TYPE_INT || t->kind==FE_TYPE_BOOL || if (t->kind==FE_TYPE_INT || t->kind==FE_TYPE_BOOL ||
t->kind==FE_TYPE_CHAR || t->kind==FE_TYPE_STR) return 1; t->kind==FE_TYPE_CHAR) return 1;
return format_is_slice_u8(t) || return format_is_slice_u8(t) ||
(t->kind==FE_TYPE_ENUM && t->is_error); (t->kind==FE_TYPE_ENUM && t->is_error);
} }
@@ -381,7 +383,8 @@ static void check_format_call(FeCheckerState *s, FeNode *n)
if (strcmp(n->text,"@sprint")==0) { if (strcmp(n->text,"@sprint")==0) {
if (!fmt_node) { err(s->c,n->loc,"@sprint requires a buffer"); return; } if (!fmt_node) { err(s->c,n->loc,"@sprint requires a buffer"); return; }
t=check_expr(s,fmt_node); t=check_expr(s,fmt_node);
if (!format_is_slice_u8(t)) err(s->c,fmt_node->loc,"@sprint requires []u8 buffer"); if (!format_is_slice_u8(t) || !t->ref_mut)
err(s->c,fmt_node->loc,"@sprint requires []mut u8 buffer");
fmt_node=fmt_node->next; fmt_node=fmt_node->next;
} }
fmt=builtin_format(s,fmt_node); fmt=builtin_format(s,fmt_node);
@@ -517,7 +520,18 @@ static FeType *check_index(FeCheckerState *s, FeNode *n)
if(n->c || !n->b) { if(n->c || !n->b) {
if (base->kind==FE_TYPE_ARRAY && !array_slice_lvalue(n->a)) if (base->kind==FE_TYPE_ARRAY && !array_slice_lvalue(n->a))
err(s->c,n->loc,"array slicing requires a stable lvalue"); err(s->c,n->loc,"array slicing requires a stable lvalue");
if(n->c) { idx=check_expr(s,n->c); if(known(idx)&&!fe_type_is_integer(idx)) err(s->c,n->loc,"slice bound must be an integer"); } elem=base->elem; n->sem_type=fe_type_slice(&s->c->types,elem); if(base->kind==FE_TYPE_STR) n->flags|=2U; return n->sem_type; } if(n->c) {
idx=check_expr(s,n->c);
if(known(idx)&&!fe_type_is_integer(idx))
err(s->c,n->loc,"slice bound must be an integer");
}
elem=base->elem;
n->sem_type=(base->kind==FE_TYPE_SLICE ? base->ref_mut :
lvalue_writable(s,n->a)) ?
fe_type_mut_slice(&s->c->types,elem) :
fe_type_slice(&s->c->types,elem);
return n->sem_type;
}
n->sem_type=base->elem; return n->sem_type; n->sem_type=base->elem; return n->sem_type;
} }
@@ -715,6 +729,7 @@ static FeType *check_expr(FeCheckerState *s, FeNode *n)
return unknown(c); return unknown(c);
} }
n->a->cname = sym->cname; n->a->cname = sym->cname;
n->sem_decl = sym->fn;
if (!sym->fn) { if (!sym->fn) {
err(c, n->loc, "name is not a function"); err(c, n->loc, "name is not a function");
return unknown(c); return unknown(c);
@@ -725,7 +740,10 @@ static FeType *check_expr(FeCheckerState *s, FeNode *n)
a = check_expr(s, arg); a = check_expr(s, arg);
mark_moved(s,arg,a); mark_moved(s,arg,a);
b = node_type(c, param->a); b = node_type(c, param->a);
if (!compatible(b, a, arg) && a->kind != FE_TYPE_UNKNOWN) if (!compatible(b, a, arg) &&
!(b && a && b->kind==FE_TYPE_SLICE && a->kind==FE_TYPE_SLICE &&
!b->ref_mut && a->ref_mut && fe_type_equal(b->elem,a->elem)) &&
a->kind != FE_TYPE_UNKNOWN)
err(c, arg->loc, "argument type mismatch"); err(c, arg->loc, "argument type mismatch");
param = param->next; param = param->next;
arg = arg->next; arg = arg->next;
@@ -819,14 +837,15 @@ static FeType *check_lvalue(FeCheckerState *s, FeNode *n, int read)
n->sem_type=field->type; return field->type; n->sem_type=field->type; return field->type;
} }
if (n && n->kind == FE_N_INDEX) { if (n && n->kind == FE_N_INDEX) {
if (n->a && n->a->sem_type && n->a->sem_type->kind == FE_TYPE_STR) {
err(s->c, n->loc, "str is immutable");
}
if (n->a && n->a->kind == FE_N_INDEX && (n->a->flags & 2U))
err(s->c, n->loc, "str slice is immutable");
if (!lvalue_writable(s,n->a))
err(s->c,n->loc,"cannot assign through immutable value");
base=check_index(s,n); base=check_index(s,n);
if (n->a && n->a->sem_type &&
n->a->sem_type->kind == FE_TYPE_SLICE &&
!n->a->sem_type->ref_mut)
err(s->c,n->loc,"cannot write through shared slice");
else if (n->a && n->a->sem_type &&
n->a->sem_type->kind != FE_TYPE_SLICE &&
!lvalue_writable(s,n->a))
err(s->c,n->loc,"cannot assign through immutable value");
return base; return base;
} }
if (n) err(s->c, n->loc, "assignment requires a variable"); if (n) err(s->c, n->loc, "assignment requires a variable");
@@ -903,8 +922,8 @@ static void check_for(FeCheckerState *s, FeNode *n)
else if (n->a && n->a->kind==FE_N_INDEX && n->a->a && else if (n->a && n->a->kind==FE_N_INDEX && n->a->a &&
n->a->a->kind==FE_N_IDENT) n->a->a->kind==FE_N_IDENT)
iter_sym=find_symbol(s->scope,n->a->a->text ? n->a->a->text : ""); iter_sym=find_symbol(s->scope,n->a->a->text ? n->a->a->text : "");
iter_mut=iter_sym && iter_sym->mutable; iter_mut=start->kind==FE_TYPE_SLICE ? start->ref_mut :
if (start->kind==FE_TYPE_STR) iter_mut=0; (iter_sym && iter_sym->mutable);
ref_type=fe_type_ref(&s->c->types,elem,iter_mut); ref_type=fe_type_ref(&s->c->types,elem,iter_mut);
if (iter_mut) n->flags |= 4U; if (iter_mut) n->flags |= 4U;
s->scope=scope_new(s,old); s->scope=scope_new(s,old);
@@ -1017,6 +1036,8 @@ static void check_stmt(FeCheckerState *s, FeNode *n)
err(c, n->loc, "initializer type mismatch"); err(c, n->loc, "initializer type mismatch");
if (b->kind == FE_TYPE_VOID) if (b->kind == FE_TYPE_VOID)
err(c, n->loc, "void expression cannot initialize a variable"); err(c, n->loc, "void expression cannot initialize a variable");
if (n->kind==FE_N_LET && a->kind==FE_TYPE_SLICE && a->ref_mut)
err(c,n->loc,"let cannot bind a mutable slice");
mark_moved(s,n->b,b); mark_moved(s,n->b,b);
add_symbol(s, s->scope, n->text, a, 0, 0, 1, add_symbol(s, s->scope, n->text, a, 0, 0, 1,
local_cname(c, n->text ? n->text : "local"), n); local_cname(c, n->text ? n->text : "local"), n);
+49 -19
View File
@@ -75,8 +75,10 @@ static void emit_one_type(FeEmitter *e, FeType *t)
} else if(t->kind==FE_TYPE_ARRAY) { } else if(t->kind==FE_TYPE_ARRAY) {
fputs(t->cname,e->out); fputs(" { ",e->out); fputs(fe_type_c_name(t->elem,e->pointer_bits),e->out); fputs(" a[",e->out); fprintf(e->out,"%lu",t->length); fputs("]; };\n",e->out); fputs(t->cname,e->out); fputs(" { ",e->out); fputs(fe_type_c_name(t->elem,e->pointer_bits),e->out); fputs(" a[",e->out); fprintf(e->out,"%lu",t->length); fputs("]; };\n",e->out);
} else if(t->kind==FE_TYPE_SLICE && t->cname) { } else if(t->kind==FE_TYPE_SLICE && t->cname) {
fputs("typedef struct { ",e->out); fputs(fe_type_c_name(t->elem,e->pointer_bits),e->out); fputs(" *p; unsigned long n; } ",e->out); fputs(t->cname,e->out); fputs(";\n",e->out); fputs("typedef struct { ",e->out);
fprintf(e->out,"static %s %s(%s *p, unsigned long n) { %s s; s.p=p; s.n=n; return s; }\n",t->cname,t->maker,fe_type_c_name(t->elem,e->pointer_bits),t->cname); if(!t->ref_mut) fputs("const ",e->out);
fputs(fe_type_c_name(t->elem,e->pointer_bits),e->out); fputs(" *p; unsigned long n; } ",e->out); fputs(t->cname,e->out); fputs(";\n",e->out);
fprintf(e->out,"static %s %s(%s%s *p, unsigned long n) { %s s; s.p=p; s.n=n; return s; }\n",t->cname,t->maker,t->ref_mut ? "" : "const ",fe_type_c_name(t->elem,e->pointer_bits),t->cname);
} else if(t->kind==FE_TYPE_ERROR_UNION) { } else if(t->kind==FE_TYPE_ERROR_UNION) {
fputs(t->cname,e->out); fputs(" { unsigned short e; ",e->out); fputs(t->cname,e->out); fputs(" { unsigned short e; ",e->out);
fputs(fe_type_c_name(t->error_value,e->pointer_bits),e->out); fputs(fe_type_c_name(t->error_value,e->pointer_bits),e->out);
@@ -97,8 +99,6 @@ static void emit_one_type(FeEmitter *e, FeType *t)
static void emit_type_defs(FeEmitter *e) static void emit_type_defs(FeEmitter *e)
{ {
FeType *t; FeType *t;
fputs("typedef struct { const unsigned char *p; unsigned long n; } fe_str;\n",e->out);
fputs("static fe_str fe_make_str(const unsigned char *p, unsigned long n) { fe_str s; s.p=p; s.n=n; return s; }\n",e->out);
/* Every fixed array has a slice conversion helper, even if this unit /* Every fixed array has a slice conversion helper, even if this unit
only indexes the array. Intern those result types before emission so only indexes the array. Intern those result types before emission so
their typedefs are present before helper definitions. */ their typedefs are present before helper definitions. */
@@ -246,14 +246,6 @@ static void emit_type_helpers(FeEmitter *e)
fprintf(e->out,"static %s %s(%s x, unsigned long a) { return %s(x,a,x.n); }\n",t->cname,t->tail_slicer,t->cname,t->slicer); fprintf(e->out,"static %s %s(%s x, unsigned long a) { return %s(x,a,x.n); }\n",t->cname,t->tail_slicer,t->cname,t->slicer);
} }
} }
fputs("static unsigned char fe_idx_str(fe_str x, unsigned long i) { ",e->out);
if(!e->no_checks) fputs("if (i >= x.n) fe_trap_bounds(); ",e->out);
fputs("return x.p[i]; }\n",e->out);
fputs("static fe_str fe_slice_str(fe_str x, unsigned long a, unsigned long b) { ",e->out);
if(!e->no_checks) fputs("if (a > b || b > x.n) fe_trap_bounds(); ",e->out);
fputs("return fe_make_str(x.p+a,b-a); }\n",e->out);
fputs("static fe_str fe_full_slice_str(fe_str x) { return fe_slice_str(x,0,x.n); }\n",e->out);
fputs("static fe_str fe_tail_slice_str(fe_str x, unsigned long a) { return fe_slice_str(x,a,x.n); }\n",e->out);
} }
static void emit_m4_runtime(FeEmitter *e) static void emit_m4_runtime(FeEmitter *e)
@@ -276,7 +268,6 @@ static void emit_m4_runtime(FeEmitter *e)
fputs("unsigned long fe_m4_sprint_finish(void) { unsigned long result; if (!fe_m4_sprint_depth) abort(); --fe_m4_sprint_depth; result=fe_m4_sprint_stack[fe_m4_sprint_depth].start_n-fe_m4_sprint_stack[fe_m4_sprint_depth].b.n; return result; }\n",e->out); fputs("unsigned long fe_m4_sprint_finish(void) { unsigned long result; if (!fe_m4_sprint_depth) abort(); --fe_m4_sprint_depth; result=fe_m4_sprint_stack[fe_m4_sprint_depth].start_n-fe_m4_sprint_stack[fe_m4_sprint_depth].b.n; return result; }\n",e->out);
fputs("unsigned short fe_m4_write_bytes(fe_writer w, const unsigned char *p, unsigned long n) { return w.write_fn ? w.write_fn(w.ctx,p,n) : 1; }\n",e->out); fputs("unsigned short fe_m4_write_bytes(fe_writer w, const unsigned char *p, unsigned long n) { return w.write_fn ? w.write_fn(w.ctx,p,n) : 1; }\n",e->out);
fputs("unsigned short fe_m4_write_cstr(fe_writer w, const char *p) { return fe_m4_write_bytes(w,(const unsigned char*)p,(unsigned long)strlen(p)); }\n",e->out); fputs("unsigned short fe_m4_write_cstr(fe_writer w, const char *p) { return fe_m4_write_bytes(w,(const unsigned char*)p,(unsigned long)strlen(p)); }\n",e->out);
fputs("unsigned short fe_m4_write_str(fe_writer w, fe_str s) { return fe_m4_write_bytes(w,s.p,s.n); }\n",e->out);
fputs("#define fe_m4_write_slice(w,s) fe_m4_write_bytes((w),(s).p,(s).n)\n",e->out); fputs("#define fe_m4_write_slice(w,s) fe_m4_write_bytes((w),(s).p,(s).n)\n",e->out);
fputs("unsigned short fe_m4_write_int(fe_writer w, long v) { char b[40]; sprintf(b,\"%ld\",v); return fe_m4_write_cstr(w,b); }\n",e->out); fputs("unsigned short fe_m4_write_int(fe_writer w, long v) { char b[40]; sprintf(b,\"%ld\",v); return fe_m4_write_cstr(w,b); }\n",e->out);
fputs("unsigned short fe_m4_write_hex(fe_writer w, unsigned long v) { char b[40]; sprintf(b,\"%lx\",v); return fe_m4_write_cstr(w,b); }\n",e->out); fputs("unsigned short fe_m4_write_hex(fe_writer w, unsigned long v) { char b[40]; sprintf(b,\"%lx\",v); return fe_m4_write_cstr(w,b); }\n",e->out);
@@ -504,9 +495,8 @@ static void emit_m4_arg(FeEmitter *e, FeNode *arg, int verb,
if (verb=='b') { if (verb=='b') {
fputs("fe_m4_write_bool(",e->out); emit_m4_writer_value(e,writer,buffer); fputs(", ",e->out); emit_expr(e,arg); fputc(')',e->out); return; fputs("fe_m4_write_bool(",e->out); emit_m4_writer_value(e,writer,buffer); fputs(", ",e->out); emit_expr(e,arg); fputc(')',e->out); return;
} }
if (verb=='s' || (verb==' ' && t && (t->kind==FE_TYPE_STR || t->kind==FE_TYPE_SLICE))) { if (verb=='s' || (verb==' ' && t && t->kind==FE_TYPE_SLICE)) {
if (t && t->kind==FE_TYPE_STR) fputs("fe_m4_write_str(",e->out); fputs("fe_m4_write_slice(",e->out);
else fputs("fe_m4_write_slice(",e->out);
emit_m4_writer_value(e,writer,buffer); fputs(", ",e->out); emit_expr(e,arg); fputc(')',e->out); return; emit_m4_writer_value(e,writer,buffer); fputs(", ",e->out); emit_expr(e,arg); fputc(')',e->out); return;
} }
if (error_value) { if (error_value) {
@@ -651,7 +641,29 @@ static FeNode *init_field(FeNode *n, const char *name)
static void emit_slice_call(FeEmitter *e, FeNode *n) static void emit_slice_call(FeEmitter *e, FeNode *n)
{ {
FeType *bt=n->a ? n->a->sem_type : 0; FeType *bt=n->a ? n->a->sem_type : 0;
const char *maker=bt && bt->slicer ? bt->slicer : "fe_slice_str"; const char *maker=n->sem_type && n->sem_type->maker ? n->sem_type->maker :
(bt && bt->slicer ? bt->slicer : "fe_missing_slice");
if (bt && (bt->kind==FE_TYPE_ARRAY || bt->kind==FE_TYPE_SLICE)) {
fputs(n->sem_type && n->sem_type->slicer ?
n->sem_type->slicer : "fe_missing_slicer",e->out);
fputc('(',e->out); fputs(maker,e->out); fputc('(',e->out);
if (bt->kind==FE_TYPE_ARRAY) {
fputs("(&",e->out); emit_lvalue(e,n->a); fputs(")->a",e->out);
} else {
emit_expr(e,n->a); fputs(".p",e->out);
}
fputs(", ",e->out);
if(bt->kind==FE_TYPE_ARRAY) fprintf(e->out,"%lu",bt->length);
else { emit_expr(e,n->a); fputs(".n",e->out); }
fputs("), ",e->out);
if(n->b) emit_expr(e,n->b); else fputs("0",e->out);
fputs(", ",e->out);
if(n->c) emit_expr(e,n->c);
else if(bt->kind==FE_TYPE_ARRAY) fprintf(e->out,"%lu",bt->length);
else { emit_expr(e,n->a); fputs(".n",e->out); }
fputc(')',e->out);
return;
}
if (!n->b && !n->c && bt && bt->full_slicer) { if (!n->b && !n->c && bt && bt->full_slicer) {
fputs(bt->full_slicer,e->out); fputs(bt->full_slicer,e->out);
if (bt->kind==FE_TYPE_ARRAY) { fputs("(&",e->out); emit_lvalue(e,n->a); } if (bt->kind==FE_TYPE_ARRAY) { fputs("(&",e->out); emit_lvalue(e,n->a); }
@@ -698,7 +710,13 @@ static void emit_expr(FeEmitter *e, FeNode *n)
case FE_N_LITERAL: case FE_N_LITERAL:
if (n->text && strcmp(n->text, "true") == 0) fputs("1", e->out); if (n->text && strcmp(n->text, "true") == 0) fputs("1", e->out);
else if (n->text && strcmp(n->text, "false") == 0) fputs("0", e->out); else if (n->text && strcmp(n->text, "false") == 0) fputs("0", e->out);
else if (n->text && n->text[0]=='"') { fputs("fe_make_str((const unsigned char*)",e->out); emit_c_literal(e->out,n->text,1); fputs(", sizeof(",e->out); emit_c_literal(e->out,n->text,1); fputs(")-1)",e->out); } else if (n->text && n->text[0]=='"') {
fputs(n->sem_type && n->sem_type->maker ?
n->sem_type->maker : "fe_missing_str",e->out);
fputs("((const unsigned char*)",e->out);
emit_c_literal(e->out,n->text,1); fputs(", sizeof(",e->out);
emit_c_literal(e->out,n->text,1); fputs(")-1)",e->out);
}
else if (n->text && n->text[0]=='\'') emit_c_literal(e->out,n->text,0); else if (n->text && n->text[0]=='\'') emit_c_literal(e->out,n->text,0);
else fputs(n->text ? n->text : "0", e->out); else fputs(n->text ? n->text : "0", e->out);
break; break;
@@ -775,6 +793,7 @@ static void emit_expr(FeEmitter *e, FeNode *n)
break; break;
case FE_N_CALL: { case FE_N_CALL: {
FeVariantType *v; FeVariantType *v;
FeNode *call_param=0;
int special=0; int special=0;
if(n->text && (strcmp(n->text,"@print")==0 || strcmp(n->text,"@fprint")==0 || strcmp(n->text,"@sprint")==0)) { emit_m4_builtin(e,n); special=1; } if(n->text && (strcmp(n->text,"@print")==0 || strcmp(n->text,"@fprint")==0 || strcmp(n->text,"@sprint")==0)) { emit_m4_builtin(e,n); special=1; }
else if(n->a && n->a->kind==FE_N_MEMBER && n->a->a && else if(n->a && n->a->kind==FE_N_MEMBER && n->a->a &&
@@ -814,14 +833,25 @@ static void emit_expr(FeEmitter *e, FeNode *n)
} else if (n->a) emit_expr(e, n->a); } else if (n->a) emit_expr(e, n->a);
else fputs(n->text ? n->text : "fe_builtin", e->out); else fputs(n->text ? n->text : "fe_builtin", e->out);
if(!special) { if(!special) {
if(n->sem_decl && n->sem_decl->kind==FE_N_FN && n->sem_decl->a)
call_param=n->sem_decl->a->children;
fputc('(', e->out); fputc('(', e->out);
for (x = n->children; x; x = x->next) { for (x = n->children; x; x = x->next) {
FeType *want=call_param && call_param->a ?
fe_type_from_ast(&e->check->types,call_param->a) : 0;
if (x != n->children) fputs(", ", e->out); if (x != n->children) fputs(", ", e->out);
if ((x->flags & 0x100U) && x->kind==FE_N_IDENT && if(want && want->kind==FE_TYPE_SLICE && !want->ref_mut &&
x->sem_type && x->sem_type->kind==FE_TYPE_SLICE &&
x->sem_type->ref_mut) {
fputs(want->maker,e->out); fputc('(',e->out);
emit_expr(e,x); fputs(".p, ",e->out);
emit_expr(e,x); fputs(".n)",e->out);
} else if ((x->flags & 0x100U) && x->kind==FE_N_IDENT &&
x->sem_type && x->sem_type->kind==FE_TYPE_OWNED) { x->sem_type && x->sem_type->kind==FE_TYPE_OWNED) {
fputs("(fe_live_",e->out); fputs(cname(x,"owned"),e->out); fputs("(fe_live_",e->out); fputs(cname(x,"owned"),e->out);
fputs("=0, ",e->out); emit_expr(e,x); fputc(')',e->out); fputs("=0, ",e->out); emit_expr(e,x); fputc(')',e->out);
} else emit_expr(e, x); } else emit_expr(e, x);
if(call_param) call_param=call_param->next;
} }
fputc(')', e->out); fputc(')', e->out);
} }
+1
View File
@@ -49,6 +49,7 @@ static FeNode *type(FeParser *p)
if (is(p,FE_TOK_LBRACKET)) { if (is(p,FE_TOK_LBRACKET)) {
next(p); n=toknode(p,FE_N_TYPE,t); 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"); } if(!eat(p,FE_TOK_RBRACKET)) { n->a=expr(p,0); want(p,FE_TOK_RBRACKET,"expected ']' in array type"); }
else if(eat(p,FE_TOK_MUT)) n->text=fe_arena_strdup(&p->ast->arena,"[]mut",5);
n->b=type(p); return n; n->b=type(p); return n;
} }
if (is(p,FE_TOK_FN)) { if (is(p,FE_TOK_FN)) {
+28 -4
View File
@@ -64,7 +64,8 @@ FeType *fe_type_intern(FeTypeCtx *ctx, const char *name)
if (strcmp(name, "void") == 0) kind = FE_TYPE_VOID; if (strcmp(name, "void") == 0) kind = FE_TYPE_VOID;
else if (strcmp(name, "bool") == 0) kind = FE_TYPE_BOOL; else if (strcmp(name, "bool") == 0) kind = FE_TYPE_BOOL;
else if (strcmp(name, "char") == 0) kind = FE_TYPE_CHAR; else if (strcmp(name, "char") == 0) kind = FE_TYPE_CHAR;
else if (strcmp(name, "str") == 0) kind = FE_TYPE_STR; else if (strcmp(name, "str") == 0)
return fe_type_slice(ctx, fe_type_intern(ctx, "u8"));
else if (strcmp(name, "io.Writer") == 0) { else if (strcmp(name, "io.Writer") == 0) {
kind = FE_TYPE_STRUCT; kind = FE_TYPE_STRUCT;
} }
@@ -156,6 +157,26 @@ FeType *fe_type_slice(FeTypeCtx *ctx, FeType *elem)
return t; return t;
} }
FeType *fe_type_mut_slice(FeTypeCtx *ctx, FeType *elem)
{
char key[96];
FeType *t;
sprintf(key, "[]mut %s", elem ? elem->name : "?");
t = fe_type_intern(ctx, key);
if (t->kind == FE_TYPE_UNKNOWN) {
t->kind = FE_TYPE_SLICE;
t->elem = elem;
t->ref_mut = 1;
t->cname = generated_name(ctx, "fe_mut_slice_", "type");
t->maker = generated_name(ctx, "fe_make_mut_slice_", "type");
t->indexer = generated_name(ctx, "fe_idx_mut_slice_", "type");
t->slicer = generated_name(ctx, "fe_slice_mut_slice_", "type");
t->full_slicer = generated_name(ctx, "fe_full_mut_slice_", "type");
t->tail_slicer = generated_name(ctx, "fe_tail_mut_slice_", "type");
}
return t;
}
FeType *fe_type_ref(FeTypeCtx *ctx, FeType *elem, int mutable) FeType *fe_type_ref(FeTypeCtx *ctx, FeType *elem, int mutable)
{ {
char key[128]; char key[128];
@@ -478,7 +499,7 @@ FeType *fe_type_from_ast(FeTypeCtx *ctx, const FeNode *node)
if (node->text && strcmp(node->text, "as") == 0) if (node->text && strcmp(node->text, "as") == 0)
return fe_type_from_ast(ctx, node->b); return fe_type_from_ast(ctx, node->b);
if (node->text && strcmp(node->text, "str") == 0) if (node->text && strcmp(node->text, "str") == 0)
return fe_type_intern(ctx, "str"); return fe_type_slice(ctx, fe_type_intern(ctx, "u8"));
if (node->a && node->a->kind==FE_N_IDENT && node->text && if (node->a && node->a->kind==FE_N_IDENT && node->text &&
strcmp(node->text,"io")==0 && node->a->text) { strcmp(node->text,"io")==0 && node->a->text) {
sprintf(qualified,"%s.%s",node->text,node->a->text); sprintf(qualified,"%s.%s",node->text,node->a->text);
@@ -490,13 +511,16 @@ FeType *fe_type_from_ast(FeTypeCtx *ctx, const FeNode *node)
strcmp(node->text,"&mut") == 0); strcmp(node->text,"&mut") == 0);
if (node->text && strcmp(node->text,"^")==0) if (node->text && strcmp(node->text,"^")==0)
return fe_type_owned(ctx,fe_type_from_ast(ctx,node->a)); return fe_type_owned(ctx,fe_type_from_ast(ctx,node->a));
if (node->text && strcmp(node->text, "[") == 0) { if (node->text && (strcmp(node->text, "[") == 0 ||
strcmp(node->text, "[]mut") == 0)) {
if (node->a) { if (node->a) {
if (node->a->kind == FE_N_LITERAL && node->a->text) if (node->a->kind == FE_N_LITERAL && node->a->text)
length = strtoul(node->a->text, 0, 0); length = strtoul(node->a->text, 0, 0);
return fe_type_array(ctx, length, fe_type_from_ast(ctx, node->b)); return fe_type_array(ctx, length, fe_type_from_ast(ctx, node->b));
} }
return fe_type_slice(ctx, fe_type_from_ast(ctx, node->b)); return strcmp(node->text,"[]mut")==0 ?
fe_type_mut_slice(ctx, fe_type_from_ast(ctx,node->b)) :
fe_type_slice(ctx, fe_type_from_ast(ctx, node->b));
} }
if (node->text && strcmp(node->text, "!") == 0) if (node->text && strcmp(node->text, "!") == 0)
/* Prefix !T stores T in a; the E!T spelling stores its success /* Prefix !T stores T in a; the E!T spelling stores its success
+1
View File
@@ -73,6 +73,7 @@ FeType *fe_type_intern(FeTypeCtx *ctx, const char *name);
FeType *fe_type_from_ast(FeTypeCtx *ctx, const FeNode *node); FeType *fe_type_from_ast(FeTypeCtx *ctx, const FeNode *node);
FeType *fe_type_array(FeTypeCtx *ctx, unsigned long length, FeType *elem); FeType *fe_type_array(FeTypeCtx *ctx, unsigned long length, FeType *elem);
FeType *fe_type_slice(FeTypeCtx *ctx, FeType *elem); FeType *fe_type_slice(FeTypeCtx *ctx, FeType *elem);
FeType *fe_type_mut_slice(FeTypeCtx *ctx, FeType *elem);
FeType *fe_type_ref(FeTypeCtx *ctx, FeType *elem, int mutable); FeType *fe_type_ref(FeTypeCtx *ctx, FeType *elem, int mutable);
FeType *fe_type_owned(FeTypeCtx *ctx, FeType *elem); FeType *fe_type_owned(FeTypeCtx *ctx, FeType *elem);
FeType *fe_type_error_union(FeTypeCtx *ctx, FeType *value); FeType *fe_type_error_union(FeTypeCtx *ctx, FeType *value);
+36 -20
View File
@@ -15,9 +15,9 @@ fec.exe --dump-ast TESTS\PASS\BASIC.FE > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --dump-ast TESTS\PASS\LITERALS.FE > nul fec.exe --dump-ast TESTS\PASS\LITERALS.FE > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --dump-ast TESTS\PASS\KEYWORDS-AND-BUILTINS.FE > nul fec.exe --dump-ast TESTS\PASS\KEYBUILT.FE > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --dump-ast TESTS\PASS\V012-FORMS.FE > nul fec.exe --dump-ast TESTS\PASS\V012FORM.FE > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --dump-ast STD\CORE.FE > nul fec.exe --dump-ast STD\CORE.FE > nul
@@ -37,11 +37,11 @@ if errorlevel 1 goto test_fail
fec.exe --dump-ast STD\SYS.FE > nul fec.exe --dump-ast STD\SYS.FE > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --dump-ast TESTS\FAIL\MISSING-SEMI.FE > nul fec.exe --dump-ast TESTS\FAIL\MISSSEMI.FE > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --dump-ast TESTS\FAIL\UNCLOSED-COMMENT.FE > nul fec.exe --dump-ast TESTS\FAIL\UNCLCOMM.FE > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --dump-ast TESTS\FAIL\LOGICAL-SYMBOLS.FE > nul fec.exe --dump-ast TESTS\FAIL\LOGICAL.FE > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
if exist TESTS\M2\HELLO.C del TESTS\M2\HELLO.C if exist TESTS\M2\HELLO.C del TESTS\M2\HELLO.C
@@ -67,28 +67,28 @@ TESTS\M2\SCOPES.EXE
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
rem M2 bits16 regression path remains on compiler A (wcl). rem M2 bits16 regression path remains on compiler A (wcl).
fec.exe --target=bits16 --emit-c TESTS\M2\CAST-WHILE.FE -o TESTS\M2\CAST16.C > nul fec.exe --target=bits16 --emit-c TESTS\M2\CASTWHIL.FE -o TESTS\M2\CAST16.C > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
wcl -q -za -bt=dos -fe=TESTS\M2\CAST16.EXE TESTS\M2\CAST16.C wcl -q -za -bt=dos -fe=TESTS\M2\CAST16.EXE TESTS\M2\CAST16.C
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
TESTS\M2\CAST16.EXE TESTS\M2\CAST16.EXE
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-CONDITION.FE -o TESTS\M2\BAD-CO.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-COND.FE -o TESTS\M2\BAD-CO.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-CAST.FE -o TESTS\M2\BAD-CA.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-CAST.FE -o TESTS\M2\BAD-CA.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-ASSIGN.FE -o TESTS\M2\BAD-AS.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-ASGN.FE -o TESTS\M2\BAD-AS.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-UNKNOWN.FE -o TESTS\M2\BAD-UN.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-UNK.FE -o TESTS\M2\BAD-UN.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-ARITY.FE -o TESTS\M2\BAD-AR.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-ARI.FE -o TESTS\M2\BAD-AR.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-TYPES.FE -o TESTS\M2\BAD-TY.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-TYPE.FE -o TESTS\M2\BAD-TY.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-RETURN.FE -o TESTS\M2\BAD-RE.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-RET.FE -o TESTS\M2\BAD-RE.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-UNINIT.FE -o TESTS\M2\BAD-UI.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-UNIT.FE -o TESTS\M2\BAD-UI.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M2\BAD-VOID.FE -o TESTS\M2\BAD-VO.C > nul fec.exe --target=bits32 --emit-c TESTS\M2\BAD-VOID.FE -o TESTS\M2\BAD-VO.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
@@ -132,6 +132,16 @@ wcl386 -q -za -bt=dos -fe=TESTS\M3\ARRAY.EXE TESTS\M3\ARRAY.C
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
TESTS\M3\ARRAY.EXE TESTS\M3\ARRAY.EXE
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M3\MUTABLE.FE -o TESTS\M3\MUTABLE.C > nul
if errorlevel 1 goto test_fail
wcl386 -q -za -bt=dos -fe=TESTS\M3\MUTABLE.EXE TESTS\M3\MUTABLE.C
if errorlevel 1 goto test_fail
TESTS\M3\MUTABLE.EXE
if errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M3\BAD-MLET.FE -o TESTS\M3\BAD-MLET.C > nul
if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M3\BAD-SHWR.FE -o TESTS\M3\BAD-SHWR.C > nul
if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M3\STR.FE -o TESTS\M3\STR.C > nul fec.exe --target=bits32 --emit-c TESTS\M3\STR.FE -o TESTS\M3\STR.C > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
wcl386 -q -za -bt=dos -fe=TESTS\M3\STR.EXE TESTS\M3\STR.C wcl386 -q -za -bt=dos -fe=TESTS\M3\STR.EXE TESTS\M3\STR.C
@@ -168,6 +178,12 @@ wcl386 -q -za -bt=dos -fe=TESTS\M3\BOUNDS.EXE TESTS\M3\BOUNDS.C
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
TESTS\M3\BOUNDS.EXE TESTS\M3\BOUNDS.EXE
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M3\SLCBOUND.FE -o TESTS\M3\SLCBOUND.C > nul
if errorlevel 1 goto test_fail
wcl386 -q -za -bt=dos -fe=TESTS\M3\SLCBOUND.EXE TESTS\M3\SLCBOUND.C
if errorlevel 1 goto test_fail
TESTS\M3\SLCBOUND.EXE
if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --no-checks --emit-c TESTS\M3\BOUNDS.FE -o TESTS\M3\BOUNDS-N.C > nul fec.exe --target=bits32 --no-checks --emit-c TESTS\M3\BOUNDS.FE -o TESTS\M3\BOUNDS-N.C > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
wcl386 -q -za -bt=dos -fe=TESTS\M3\BOUNDS-N.EXE TESTS\M3\BOUNDS-N.C wcl386 -q -za -bt=dos -fe=TESTS\M3\BOUNDS-N.EXE TESTS\M3\BOUNDS-N.C
@@ -197,7 +213,7 @@ wcl386 -q -za -wx -wcd=202 -bt=dos -fe=TESTS\M4\FORMAT.EXE TESTS\M4\FORMAT.C
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
TESTS\M4\FORMAT.EXE > nul TESTS\M4\FORMAT.EXE > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\TRY-FPRINT.FE -o TESTS\M4\TRY-FPR.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\TRY-FPR.FE -o TESTS\M4\TRY-FPR.C > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
wcl386 -q -za -wx -wcd=202 -bt=dos -fe=TESTS\M4\TRY-FPR.EXE TESTS\M4\TRY-FPR.C wcl386 -q -za -wx -wcd=202 -bt=dos -fe=TESTS\M4\TRY-FPR.EXE TESTS\M4\TRY-FPR.C
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
@@ -209,17 +225,17 @@ wcl386 -q -za -wx -wcd=202 -bt=dos -fe=TESTS\M4\PROP.EXE TESTS\M4\PROPTEST.C
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
TESTS\M4\PROP.EXE > nul TESTS\M4\PROP.EXE > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\BAD-ARITY.FE -o TESTS\M4\BAD-ARI.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\BAD-ARI.FE -o TESTS\M4\BAD-ARI.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\BAD-VERB.FE -o TESTS\M4\BAD-VERB.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\BAD-VERB.FE -o TESTS\M4\BAD-VERB.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\BAD-RUNTIME.FE -o TESTS\M4\BAD-RUN.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\BAD-RUN.FE -o TESTS\M4\BAD-RUN.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\BAD-TYPE.FE -o TESTS\M4\BAD-TYP.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\BAD-TYPE.FE -o TESTS\M4\BAD-TYP.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\BAD-TRY.FE -o TESTS\M4\BAD-TRY.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\BAD-TRY.FE -o TESTS\M4\BAD-TRY.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\BAD-WRITER.FE -o TESTS\M4\BAD-WRI.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\BAD-WRIT.FE -o TESTS\M4\BAD-WRI.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M4\BAD-MANY.FE -o TESTS\M4\BAD-MANY.C > nul fec.exe --target=bits32 --emit-c TESTS\M4\BAD-MANY.FE -o TESTS\M4\BAD-MANY.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
@@ -233,13 +249,13 @@ fec.exe --target=bits32 --emit-c TESTS\M5\OWNED.FE -o TESTS\M5\OWNED.C > nul
if errorlevel 1 goto test_fail if errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M5\BAD-MOVE.FE -o TESTS\M5\BAD-MOVE.C > nul fec.exe --target=bits32 --emit-c TESTS\M5\BAD-MOVE.FE -o TESTS\M5\BAD-MOVE.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DESTROY.FE -o TESTS\M5\BAD-DES.C > nul fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DEST.FE -o TESTS\M5\BAD-DES.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DROP.FE -o TESTS\M5\BAD-DROP.C > nul fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DROP.FE -o TESTS\M5\BAD-DROP.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DOUBLE.FE -o TESTS\M5\BAD-DBL.C > nul fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DBL.FE -o TESTS\M5\BAD-DBL.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
fec.exe --target=bits32 --emit-c TESTS\M5\BAD-CONDITIONAL.FE -o TESTS\M5\BAD-COND.C > nul fec.exe --target=bits32 --emit-c TESTS\M5\BAD-COND.FE -o TESTS\M5\BAD-COND.C > nul
if not errorlevel 1 goto test_fail if not errorlevel 1 goto test_fail
if exist TESTS\M5\RUNTIME-G.C del TESTS\M5\RUNTIME-G.C if exist TESTS\M5\RUNTIME-G.C del TESTS\M5\RUNTIME-G.C
if exist TESTS\M5\RUNTIME.O del TESTS\M5\RUNTIME.O if exist TESTS\M5\RUNTIME.O del TESTS\M5\RUNTIME.O
+6
View File
@@ -0,0 +1,6 @@
unit m3_bad_mut_let;
fn bad() -> void {
var raw: [2]u8 = [1, 2];
let s: []mut u8 = raw[..];
}
+5
View File
@@ -0,0 +1,5 @@
unit m3_bad_shared_write;
fn bad(s: []u8) -> void {
s[0] = 1;
}
+11
View File
@@ -0,0 +1,11 @@
unit m3_mutable;
fn takes_shared(s: []u8) -> u8 { return s[0]; }
fn main() -> i32 {
var raw: [3]u8 = [1, 2, 3];
var s: []mut u8 = raw[..];
s[1] = 9;
if takes_shared(s) == 1 and raw[1] == 9 { return 0; }
return 1;
}
+7
View File
@@ -0,0 +1,7 @@
unit m3_slice_bounds;
fn main() -> i32 {
let a: [2]i32 = [1, 2];
let s: []i32 = a[0..3];
return s.n as i32;
}