diff --git a/fec/src/driver.c b/fec/src/driver.c index 7a5c55f..93002fa 100644 --- a/fec/src/driver.c +++ b/fec/src/driver.c @@ -1,5 +1,6 @@ #include "parser.h" #include "check.h" +#include "resolve.h" #include #include #include @@ -80,6 +81,15 @@ int main(int argc, char **argv) free(src); return d.errors?1:0; } + /* Unit identity before semantic analysis: a unit that is not named + correctly, or does not sit where its name says, cannot be resolved from + another unit either. */ + fe_resolve_unit_identity(&ast,&d,file); + if(d.errors){ + fe_ast_destroy(&ast); + free(src); + return 1; + } fe_check_init(&check,&ast,&d,pointer_bits,no_checks); if(!fe_check_program(&check)){ fe_ast_destroy(&ast); diff --git a/fec/src/parser.c b/fec/src/parser.c index 37b6f89..7d8a8e6 100644 --- a/fec/src/parser.c +++ b/fec/src/parser.c @@ -302,12 +302,46 @@ static FeNode *statement(FeParser *p) e=expr(p,0); if(is(p,FE_TOK_EQ)||is(p,FE_TOK_PLUS_EQ)||is(p,FE_TOK_MINUS_EQ)||is(p,FE_TOK_STAR_EQ)||is(p,FE_TOK_SLASH_EQ)||is(p,FE_TOK_PERCENT_EQ)||is(p,FE_TOK_AND_EQ)||is(p,FE_TOK_OR_EQ)||is(p,FE_TOK_XOR_EQ)||is(p,FE_TOK_SHL_EQ)||is(p,FE_TOK_SHR_EQ)){n=toknode(p,FE_N_ASSIGN,p->current);n->a=e;next(p);n->b=expr(p,0);}else{n=toknode(p,FE_N_EXPR_STMT,t);n->a=e;}want(p,FE_TOK_SEMI,"expected ';' after statement");return n; } +/* A unit path is dotted: `game.world.map`. It is stored canonically, dots and + all, because that spelling is the unit's identity everywhere else. */ +static char *unit_path(FeParser *p) +{ + char buf[256]; + unsigned long len=0; + if(!is_name(p)) return 0; + for(;;) { + unsigned long n=p->current.length; + if(len && len+1=sizeof buf){error(p,"unit path is too long");return 0;} + memcpy(buf+len,p->current.begin,n); + len+=n; + next(p); + if(!eat(p,FE_TOK_DOT)) break; + if(!is_name(p)){error(p,"expected a name after '.' in unit path");return 0;} + } + return fe_arena_strdup(&p->ast->arena,buf,len); +} + FeNode *fe_parse_unit(FeParser *p) { - FeToken t=p->current, name; FeNode *root; + FeToken t=p->current; FeNode *root; char *path; if(!eat(p,FE_TOK_UNIT)){error(p,"source must start with 'unit'");return fe_node(p->ast,FE_N_ERROR_NODE,t.loc,"unit",4);} - root=toknode(p,FE_N_UNIT,t);if(is_name(p)){name=p->current;root->text=fe_arena_strdup(&p->ast->arena,name.begin,name.length);next(p);}else error(p,"expected unit name");want(p,FE_TOK_SEMI,"expected ';' after unit name"); - while(eat(p,FE_TOK_IMPORT)){FeToken it=p->previous;FeNode *i=toknode(p,FE_N_IMPORT,it);if(is_name(p)){next(p);i->text=fe_arena_strdup(&p->ast->arena,p->previous.begin,p->previous.length);}else error(p,"expected import name");want(p,FE_TOK_SEMI,"expected ';' after import");fe_node_add(root,i);} + root=toknode(p,FE_N_UNIT,t); + path=unit_path(p); + if(path) root->text=path; else error(p,"expected unit name"); + want(p,FE_TOK_SEMI,"expected ';' after unit name"); + while(eat(p,FE_TOK_IMPORT)){ + FeToken it=p->previous;FeNode *i=toknode(p,FE_N_IMPORT,it); + path=unit_path(p); + if(path) i->text=path; else error(p,"expected import name"); + /* `as` renames the binding; without it the binding is the last segment. */ + if(eat(p,FE_TOK_AS)) { + if(is_name(p)){i->aux_text=fe_arena_strdup(&p->ast->arena,p->current.begin,p->current.length);next(p);} + else error(p,"expected an alias name after 'as'"); + } + want(p,FE_TOK_SEMI,"expected ';' after import"); + fe_node_add(root,i); + } while(!is(p,FE_TOK_EOF)){FeNode *d=decl(p);if(d)fe_node_add(root,d);} return root; } diff --git a/fec/src/resolve.c b/fec/src/resolve.c new file mode 100644 index 0000000..2cc2aae --- /dev/null +++ b/fec/src/resolve.c @@ -0,0 +1,86 @@ +#include "resolve.h" + +#include + +static int segment_ok(const char *s, unsigned long n, const char **why) +{ + unsigned long i; + if (!n) { *why = "unit path segment is empty"; return 0; } + if (n > FE_UNIT_SEGMENT_MAX) { + *why = "unit path segment is longer than eight characters"; + return 0; + } + if (s[0] < 'a' || s[0] > 'z') { + *why = "unit path segment must start with a lowercase letter"; + return 0; + } + for (i = 1; i < n; ++i) { + char c = s[i]; + if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_') continue; + *why = "unit path segment may only contain lowercase letters, digits and '_'"; + return 0; + } + return 1; +} + +/* Compare a dotted unit path against the source path it was read from. + `game.world.map` matches `.../game/world/map.fe` and nothing else. Only the + trailing segments are compared, since the leading part is the import root. */ +static int path_matches(const char *unit, const char *source) +{ + unsigned long ulen = strlen(unit), slen = strlen(source); + unsigned long u, s; + if (slen < 3 || strcmp(source + slen - 3, ".fe") != 0) return 0; + slen -= 3; + u = ulen; + s = slen; + while (u > 0) { + char uc, sc; + --u; + if (s == 0) return 0; + --s; + uc = unit[u]; + sc = source[s]; + if (uc == '.') { + if (sc != '/' && sc != '\\') return 0; + continue; + } + /* Host filesystems may be case-insensitive; the unit name is the + authority and is lowercase by 8.1, so fold the path side down. */ + if (sc >= 'A' && sc <= 'Z') sc = (char)(sc - 'A' + 'a'); + if (uc != sc) return 0; + } + /* What remains of the source path is the import root, and must end there. */ + return s == 0 || source[s - 1] == '/' || source[s - 1] == '\\'; +} + +int fe_resolve_unit_identity(FeAst *ast, FeDiags *diags, const char *source_path) +{ + FeNode *root = ast ? ast->root : 0; + const char *name, *why; + const char *seg; + unsigned long i, len; + int ok = 1; + + if (!root || root->kind != FE_N_UNIT || !root->text) return 0; + name = root->text; + len = strlen(name); + + seg = name; + for (i = 0; i <= len; ++i) { + if (i != len && name[i] != '.') continue; + if (!segment_ok(seg, (unsigned long)(name + i - seg), &why)) { + fe_diag_error(diags, root->loc, why); + ok = 0; + } + seg = name + i + 1; + } + + if (ok && source_path && !path_matches(name, source_path)) { + fe_diag_errorf(diags, root->loc, + "unit %s must be declared in a source file matching its path", + name); + ok = 0; + } + return ok; +} diff --git a/fec/src/resolve.h b/fec/src/resolve.h new file mode 100644 index 0000000..6b49e3d --- /dev/null +++ b/fec/src/resolve.h @@ -0,0 +1,24 @@ +#ifndef FE_RESOLVE_H +#define FE_RESOLVE_H + +#include "ast.h" +#include "diag.h" + +/* Unit-level resolution: identity, import bindings, and the unit graph. + This runs between parsing and semantic checking. It answers questions that + need more than one file -- what a unit is called, what it imports, and + whether those imports exist and terminate -- so that check.c can keep + looking at one function at a time. */ + +/* SPEC 8.1: each segment is ASCII lowercase, starts with a letter, continues + with letters, digits or '_', and is at most eight characters. The limit is + what makes a unit path map to a FAT/DOS 8.3 source path unambiguously. */ +#define FE_UNIT_SEGMENT_MAX 8 + +/* Validate the `unit` declaration against SPEC 8.1, and against the file it was + read from: the path must match the dotted name, so `game.world.map` has to + come from `game/world/map.fe`. `source_path` may be null to skip that half. + Returns non-zero when the unit is well formed. */ +int fe_resolve_unit_identity(FeAst *ast, FeDiags *diags, const char *source_path); + +#endif diff --git a/fec/tests/format/bad-ari.fe b/fec/tests/format/bad_ari.fe similarity index 75% rename from fec/tests/format/bad-ari.fe rename to fec/tests/format/bad_ari.fe index 3b29ff8..7dc30b8 100644 --- a/fec/tests/format/bad-ari.fe +++ b/fec/tests/format/bad_ari.fe @@ -1,4 +1,4 @@ -unit m4_bad_arity; +unit bad_ari; fn main() -> i32 { @print("{} {}", 1); diff --git a/fec/tests/format/bad-bufw.fe b/fec/tests/format/bad_bufw.fe similarity index 82% rename from fec/tests/format/bad-bufw.fe rename to fec/tests/format/bad_bufw.fe index 791bd7d..37bf521 100644 --- a/fec/tests/format/bad-bufw.fe +++ b/fec/tests/format/bad_bufw.fe @@ -1,4 +1,4 @@ -unit m4_bad_buffer_writer; +unit bad_bufw; fn main() -> void { var raw: [4]u8 = [0, 0, 0, 0]; diff --git a/fec/tests/format/bad-cls.fe b/fec/tests/format/bad_cls.fe similarity index 76% rename from fec/tests/format/bad-cls.fe rename to fec/tests/format/bad_cls.fe index a321e1c..1f8a720 100644 --- a/fec/tests/format/bad-cls.fe +++ b/fec/tests/format/bad_cls.fe @@ -1,4 +1,4 @@ -unit m4_bad_cls; +unit bad_cls; fn main() -> i32 { @print("}", 1); diff --git a/fec/tests/format/bad-many.fe b/fec/tests/format/bad_many.fe similarity index 76% rename from fec/tests/format/bad-many.fe rename to fec/tests/format/bad_many.fe index 66a7833..ab25401 100644 --- a/fec/tests/format/bad-many.fe +++ b/fec/tests/format/bad_many.fe @@ -1,4 +1,4 @@ -unit m4_bad_many; +unit bad_many; fn main() -> i32 { @print("{}", 1, 2); diff --git a/fec/tests/format/bad-open.fe b/fec/tests/format/bad_open.fe similarity index 75% rename from fec/tests/format/bad-open.fe rename to fec/tests/format/bad_open.fe index 3f1f584..98ee2c8 100644 --- a/fec/tests/format/bad-open.fe +++ b/fec/tests/format/bad_open.fe @@ -1,4 +1,4 @@ -unit m4_bad_open; +unit bad_open; fn main() -> i32 { @print("{", 1); diff --git a/fec/tests/format/bad-run.fe b/fec/tests/format/bad_run.fe similarity index 79% rename from fec/tests/format/bad-run.fe rename to fec/tests/format/bad_run.fe index fa6d7f1..c7945e1 100644 --- a/fec/tests/format/bad-run.fe +++ b/fec/tests/format/bad_run.fe @@ -1,4 +1,4 @@ -unit m4_bad_runtime; +unit bad_run; fn main() -> i32 { var fmt: str = "{}"; diff --git a/fec/tests/format/bad-try.fe b/fec/tests/format/bad_try.fe similarity index 77% rename from fec/tests/format/bad-try.fe rename to fec/tests/format/bad_try.fe index 2bd0e28..0c5da62 100644 --- a/fec/tests/format/bad-try.fe +++ b/fec/tests/format/bad_try.fe @@ -1,4 +1,4 @@ -unit m4_bad_try; +unit bad_try; fn main() -> i32 { try @print("nope"); diff --git a/fec/tests/format/bad-type.fe b/fec/tests/format/bad_type.fe similarity index 86% rename from fec/tests/format/bad-type.fe rename to fec/tests/format/bad_type.fe index e88b48f..9279e47 100644 --- a/fec/tests/format/bad-type.fe +++ b/fec/tests/format/bad_type.fe @@ -1,4 +1,4 @@ -unit m4_bad_type; +unit bad_type; struct Point { x: i32, } diff --git a/fec/tests/format/bad-verb.fe b/fec/tests/format/bad_verb.fe similarity index 76% rename from fec/tests/format/bad-verb.fe rename to fec/tests/format/bad_verb.fe index ea19d9a..9a928ce 100644 --- a/fec/tests/format/bad-verb.fe +++ b/fec/tests/format/bad_verb.fe @@ -1,4 +1,4 @@ -unit m4_bad_verb; +unit bad_verb; fn main() -> i32 { @print("{q}", 1); diff --git a/fec/tests/format/bad-writ.fe b/fec/tests/format/bad_writ.fe similarity index 79% rename from fec/tests/format/bad-writ.fe rename to fec/tests/format/bad_writ.fe index 794ed64..18e33a6 100644 --- a/fec/tests/format/bad-writ.fe +++ b/fec/tests/format/bad_writ.fe @@ -1,4 +1,4 @@ -unit m4_bad_writer; +unit bad_writ; fn main() -> i32 { var x: i32 = 0; diff --git a/fec/tests/format/ok-format.fe b/fec/tests/format/ok_forma.fe similarity index 98% rename from fec/tests/format/ok-format.fe rename to fec/tests/format/ok_forma.fe index 2445625..a830b93 100644 --- a/fec/tests/format/ok-format.fe +++ b/fec/tests/format/ok_forma.fe @@ -1,4 +1,4 @@ -unit m4_format; +unit ok_forma; const FMT: str = "n={} hex={x} c={c} s={s} b={b} {{ok}}\n"; diff --git a/fec/tests/format/ok-prop.fe b/fec/tests/format/ok_prop.fe similarity index 84% rename from fec/tests/format/ok-prop.fe rename to fec/tests/format/ok_prop.fe index 878a77a..49a0051 100644 --- a/fec/tests/format/ok-prop.fe +++ b/fec/tests/format/ok_prop.fe @@ -1,4 +1,4 @@ -unit m4_prop; +unit ok_prop; pub fn propagate(w: io.Writer) -> !void { try @fprint(w, "a{}b", 1); diff --git a/fec/tests/format/ok-try-fpr.fe b/fec/tests/format/ok_try_f.fe similarity index 88% rename from fec/tests/format/ok-try-fpr.fe rename to fec/tests/format/ok_try_f.fe index 94736cc..5429146 100644 --- a/fec/tests/format/ok-try-fpr.fe +++ b/fec/tests/format/ok_try_f.fe @@ -1,4 +1,4 @@ -unit m4_try_fprint; +unit ok_try_f; fn main() -> !void { var raw: [4]u8 = [0, 0, 0, 0]; diff --git a/fec/tests/own/own-bad-clos.fe b/fec/tests/own/bad_clos.fe similarity index 89% rename from fec/tests/own/own-bad-clos.fe rename to fec/tests/own/bad_clos.fe index 530696b..28ff3e4 100644 --- a/fec/tests/own/own-bad-clos.fe +++ b/fec/tests/own/bad_clos.fe @@ -1,4 +1,4 @@ -unit m5_bad_consuming_close; +unit bad_clos; struct FileLike { handle: i32, diff --git a/fec/tests/own/own-bad-cond.fe b/fec/tests/own/bad_cond.fe similarity index 83% rename from fec/tests/own/own-bad-cond.fe rename to fec/tests/own/bad_cond.fe index 90582bc..f46cfe4 100644 --- a/fec/tests/own/own-bad-cond.fe +++ b/fec/tests/own/bad_cond.fe @@ -1,4 +1,4 @@ -unit m5_bad_conditional; +unit bad_cond; fn take(p: ^i32) -> void { mem.destroy(p); } diff --git a/fec/tests/own/own-bad-dbl.fe b/fec/tests/own/bad_dbl.fe similarity index 77% rename from fec/tests/own/own-bad-dbl.fe rename to fec/tests/own/bad_dbl.fe index 32f4b2b..a990673 100644 --- a/fec/tests/own/own-bad-dbl.fe +++ b/fec/tests/own/bad_dbl.fe @@ -1,4 +1,4 @@ -unit m5_bad_double; +unit bad_dbl; fn bad(p: ^i32) -> void { mem.destroy(p); diff --git a/fec/tests/own/own-bad-dest.fe b/fec/tests/own/bad_dest.fe similarity index 69% rename from fec/tests/own/own-bad-dest.fe rename to fec/tests/own/bad_dest.fe index bc60537..8cedd19 100644 --- a/fec/tests/own/own-bad-dest.fe +++ b/fec/tests/own/bad_dest.fe @@ -1,4 +1,4 @@ -unit m5_bad_destroy; +unit bad_dest; fn bad(x: i32) -> void { mem.destroy(x); diff --git a/fec/tests/own/own-bad-drop.fe b/fec/tests/own/bad_drop.fe similarity index 89% rename from fec/tests/own/own-bad-drop.fe rename to fec/tests/own/bad_drop.fe index 7587db6..ad9e9cc 100644 --- a/fec/tests/own/own-bad-drop.fe +++ b/fec/tests/own/bad_drop.fe @@ -1,4 +1,4 @@ -unit m5_bad_drop; +unit bad_drop; struct Box { value: i32, diff --git a/fec/tests/own/own-bad-loop.fe b/fec/tests/own/bad_loop.fe similarity index 83% rename from fec/tests/own/own-bad-loop.fe rename to fec/tests/own/bad_loop.fe index 091d253..c7fd822 100644 --- a/fec/tests/own/own-bad-loop.fe +++ b/fec/tests/own/bad_loop.fe @@ -1,4 +1,4 @@ -unit m5_bad_loop_move; +unit bad_loop; fn take(p: ^i32) -> void { mem.destroy(p); } diff --git a/fec/tests/own/own-bad-move.fe b/fec/tests/own/bad_move.fe similarity index 85% rename from fec/tests/own/own-bad-move.fe rename to fec/tests/own/bad_move.fe index 6614cff..15d25fb 100644 --- a/fec/tests/own/own-bad-move.fe +++ b/fec/tests/own/bad_move.fe @@ -1,4 +1,4 @@ -unit m5_bad_move; +unit bad_move; fn take(p: ^i32) -> void { mem.destroy(p); } diff --git a/fec/tests/own/own-bad-proj.fe b/fec/tests/own/bad_proj.fe similarity index 80% rename from fec/tests/own/own-bad-proj.fe rename to fec/tests/own/bad_proj.fe index bf928ea..0c50987 100644 --- a/fec/tests/own/own-bad-proj.fe +++ b/fec/tests/own/bad_proj.fe @@ -1,4 +1,4 @@ -unit m5_bad_projection_move; +unit bad_proj; struct Holder { p: ^i32 } fn take(p: ^i32) -> void { mem.destroy(p); } diff --git a/fec/tests/own/ok-defer.fe b/fec/tests/own/ok_defer.fe similarity index 81% rename from fec/tests/own/ok-defer.fe rename to fec/tests/own/ok_defer.fe index b21cbe3..e4e2fef 100644 --- a/fec/tests/own/ok-defer.fe +++ b/fec/tests/own/ok_defer.fe @@ -1,4 +1,4 @@ -unit m5_defer; +unit ok_defer; pub fn cleanup(p: ^i32) -> void { defer { mem.destroy(p); } diff --git a/fec/tests/own/ok-owned.fe b/fec/tests/own/ok_owned.fe similarity index 91% rename from fec/tests/own/ok-owned.fe rename to fec/tests/own/ok_owned.fe index 3903ba0..2881628 100644 --- a/fec/tests/own/ok-owned.fe +++ b/fec/tests/own/ok_owned.fe @@ -1,4 +1,4 @@ -unit m5_owned; +unit ok_owned; fn main() -> !void { var p: ^i32 = try mem.create(0); diff --git a/fec/tests/parse/keybuilt.fe b/fec/tests/parse/keybuilt.fe index 21b231d..9f2eba6 100644 --- a/fec/tests/parse/keybuilt.fe +++ b/fec/tests/parse/keybuilt.fe @@ -1,4 +1,4 @@ -unit keywords_and_builtins; +unit keybuilt; pub fn demo() { let a = true and not false; diff --git a/fec/tests/parse/logical.fe b/fec/tests/parse/logical.fe index a38bcc6..8137071 100644 --- a/fec/tests/parse/logical.fe +++ b/fec/tests/parse/logical.fe @@ -1,3 +1,3 @@ // ERROR:logical operator -unit old_logic; +unit logical; fn main() { let x = true && false; } diff --git a/fec/tests/parse/misssemi.fe b/fec/tests/parse/misssemi.fe index c767019..a43b432 100644 --- a/fec/tests/parse/misssemi.fe +++ b/fec/tests/parse/misssemi.fe @@ -1,3 +1,3 @@ // ERROR:expected ';' -unit broken; +unit misssemi; fn main() { let x: i32 = 1 } diff --git a/fec/tests/parse/unclcomm.fe b/fec/tests/parse/unclcomm.fe index fe95c5a..7cab161 100644 --- a/fec/tests/parse/unclcomm.fe +++ b/fec/tests/parse/unclcomm.fe @@ -1,3 +1,3 @@ // ERROR:unterminated block comment -unit broken; +unit unclcomm; /* no ending delimiter diff --git a/fec/tests/parse/v012form.fe b/fec/tests/parse/v012form.fe index db3d4b5..406a63d 100644 --- a/fec/tests/parse/v012form.fe +++ b/fec/tests/parse/v012form.fe @@ -1,4 +1,4 @@ -unit v012_forms; +unit v012form; shared atomic var ticks: u16 = 0; packed struct Packet { diff --git a/fec/tests/pending-backend/bounds-nocheck.fe b/fec/tests/pending-backend/bounds_nocheck.fe similarity index 100% rename from fec/tests/pending-backend/bounds-nocheck.fe rename to fec/tests/pending-backend/bounds_nocheck.fe diff --git a/fec/tests/pending-backend/bounds-trap.fe b/fec/tests/pending-backend/bounds_trap.fe similarity index 100% rename from fec/tests/pending-backend/bounds-trap.fe rename to fec/tests/pending-backend/bounds_trap.fe diff --git a/fec/tests/pending-backend/ownership-drop.fe b/fec/tests/pending-backend/ownership_drop.fe similarity index 100% rename from fec/tests/pending-backend/ownership-drop.fe rename to fec/tests/pending-backend/ownership_drop.fe diff --git a/fec/tests/pending-backend/slice-bounds-trap.fe b/fec/tests/pending-backend/slice_bounds_trap.fe similarity index 100% rename from fec/tests/pending-backend/slice-bounds-trap.fe rename to fec/tests/pending-backend/slice_bounds_trap.fe diff --git a/fec/tests/types/bad-ari.fe b/fec/tests/types/bad_ari.fe similarity index 85% rename from fec/tests/types/bad-ari.fe rename to fec/tests/types/bad_ari.fe index 2ba4b2a..bdf4619 100644 --- a/fec/tests/types/bad-ari.fe +++ b/fec/tests/types/bad_ari.fe @@ -1,4 +1,4 @@ -unit bad_arity; +unit bad_ari; fn add(a: i32, b: i32) -> i32 { return a + b; diff --git a/fec/tests/types/bad-asgn.fe b/fec/tests/types/bad_asgn.fe similarity index 82% rename from fec/tests/types/bad-asgn.fe rename to fec/tests/types/bad_asgn.fe index fac907a..3e921bc 100644 --- a/fec/tests/types/bad-asgn.fe +++ b/fec/tests/types/bad_asgn.fe @@ -1,4 +1,4 @@ -unit bad_assign; +unit bad_asgn; fn main() -> i32 { let value: i32 = 1; diff --git a/fec/tests/types/bad-cast.fe b/fec/tests/types/bad_cast.fe similarity index 100% rename from fec/tests/types/bad-cast.fe rename to fec/tests/types/bad_cast.fe diff --git a/fec/tests/types/bad-cond.fe b/fec/tests/types/bad_cond.fe similarity index 74% rename from fec/tests/types/bad-cond.fe rename to fec/tests/types/bad_cond.fe index 2e706fa..a3968f1 100644 --- a/fec/tests/types/bad-cond.fe +++ b/fec/tests/types/bad_cond.fe @@ -1,4 +1,4 @@ -unit bad_condition; +unit bad_cond; fn main() -> i32 { if 1 { return 0; } diff --git a/fec/tests/types/bad-mlet.fe b/fec/tests/types/bad_mlet.fe similarity index 79% rename from fec/tests/types/bad-mlet.fe rename to fec/tests/types/bad_mlet.fe index af257c1..a3960b0 100644 --- a/fec/tests/types/bad-mlet.fe +++ b/fec/tests/types/bad_mlet.fe @@ -1,4 +1,4 @@ -unit m3_bad_mut_let; +unit bad_mlet; fn bad() -> void { var raw: [2]u8 = [1, 2]; diff --git a/fec/tests/types/bad-ret.fe b/fec/tests/types/bad_ret.fe similarity index 69% rename from fec/tests/types/bad-ret.fe rename to fec/tests/types/bad_ret.fe index 914cd99..a151ab3 100644 --- a/fec/tests/types/bad-ret.fe +++ b/fec/tests/types/bad_ret.fe @@ -1,4 +1,4 @@ -unit bad_return; +unit bad_ret; fn main() -> i32 { return true; diff --git a/fec/tests/types/bad-shwr.fe b/fec/tests/types/bad_shwr.fe similarity index 62% rename from fec/tests/types/bad-shwr.fe rename to fec/tests/types/bad_shwr.fe index aa4f105..7c7881f 100644 --- a/fec/tests/types/bad-shwr.fe +++ b/fec/tests/types/bad_shwr.fe @@ -1,4 +1,4 @@ -unit m3_bad_shared_write; +unit bad_shwr; fn bad(s: []u8) -> void { s[0] = 1; diff --git a/fec/tests/types/bad-type.fe b/fec/tests/types/bad_type.fe similarity index 86% rename from fec/tests/types/bad-type.fe rename to fec/tests/types/bad_type.fe index 1f277fe..15a4aca 100644 --- a/fec/tests/types/bad-type.fe +++ b/fec/tests/types/bad_type.fe @@ -1,4 +1,4 @@ -unit bad_types; +unit bad_type; fn add(a: i32, b: i32) -> i32 { return a + b; diff --git a/fec/tests/types/bad-unit.fe b/fec/tests/types/bad_unit.fe similarity index 77% rename from fec/tests/types/bad-unit.fe rename to fec/tests/types/bad_unit.fe index 51f6092..99d8bbd 100644 --- a/fec/tests/types/bad-unit.fe +++ b/fec/tests/types/bad_unit.fe @@ -1,4 +1,4 @@ -unit bad_uninit; +unit bad_unit; fn main() -> i32 { var value: i32; diff --git a/fec/tests/types/bad-unk.fe b/fec/tests/types/bad_unk.fe similarity index 72% rename from fec/tests/types/bad-unk.fe rename to fec/tests/types/bad_unk.fe index 51d1b01..b868c3b 100644 --- a/fec/tests/types/bad-unk.fe +++ b/fec/tests/types/bad_unk.fe @@ -1,4 +1,4 @@ -unit bad_unknown; +unit bad_unk; fn main() -> i32 { return missing_name; diff --git a/fec/tests/types/bad-void.fe b/fec/tests/types/bad_void.fe similarity index 100% rename from fec/tests/types/bad-void.fe rename to fec/tests/types/bad_void.fe diff --git a/fec/tests/types/badarr.fe b/fec/tests/types/badarr.fe index f419f7a..11007cb 100644 --- a/fec/tests/types/badarr.fe +++ b/fec/tests/types/badarr.fe @@ -1,4 +1,4 @@ -unit fail_m3_array; +unit badarr; fn main() -> i32 { let a: [2]i32 = [1, true, 3]; return a[0]; diff --git a/fec/tests/types/badchar.fe b/fec/tests/types/badchar.fe index aed42d4..9d1a1d4 100644 --- a/fec/tests/types/badchar.fe +++ b/fec/tests/types/badchar.fe @@ -1,4 +1,4 @@ -unit fail_m3_char; +unit badchar; fn main() -> i32 { let u: u8 = 'A'; diff --git a/fec/tests/types/badcycle.fe b/fec/tests/types/badcycle.fe index e96c17e..532ea1e 100644 --- a/fec/tests/types/badcycle.fe +++ b/fec/tests/types/badcycle.fe @@ -1,4 +1,4 @@ -unit fail_m3_cycle; +unit badcycle; struct A { b: B, } struct B { a: A, } diff --git a/fec/tests/types/badfield.fe b/fec/tests/types/badfield.fe index 350edbb..4fa664c 100644 --- a/fec/tests/types/badfield.fe +++ b/fec/tests/types/badfield.fe @@ -1,4 +1,4 @@ -unit fail_m3_let_field; +unit badfield; struct Point { x: i32, y: i32, } fn main() -> i32 { diff --git a/fec/tests/types/badfld.fe b/fec/tests/types/badfld.fe index dd9e0c4..68704be 100644 --- a/fec/tests/types/badfld.fe +++ b/fec/tests/types/badfld.fe @@ -1,4 +1,4 @@ -unit fail_m3_fields; +unit badfld; struct Point { x: i32, y: i32, } fn main() -> i32 { let p: Point = Point{ x: 1 }; diff --git a/fec/tests/types/badindex.fe b/fec/tests/types/badindex.fe index 88e8bca..06b1b10 100644 --- a/fec/tests/types/badindex.fe +++ b/fec/tests/types/badindex.fe @@ -1,4 +1,4 @@ -unit fail_m3_let_index; +unit badindex; fn main() -> i32 { let a: [2]i32 = [1, 2]; diff --git a/fec/tests/types/badmat.fe b/fec/tests/types/badmat.fe index f1c1d54..3c7df6a 100644 --- a/fec/tests/types/badmat.fe +++ b/fec/tests/types/badmat.fe @@ -1,4 +1,4 @@ -unit fail_m3_match; +unit badmat; enum Shape { Empty, Circle(i32), } fn main() -> i32 { match Shape.Empty { Empty => 0; } diff --git a/fec/tests/types/badstr.fe b/fec/tests/types/badstr.fe index 2896f0c..6219d9a 100644 --- a/fec/tests/types/badstr.fe +++ b/fec/tests/types/badstr.fe @@ -1,4 +1,4 @@ -unit fail_m3_str; +unit badstr; fn main() -> i32 { var text: str = "abc"; text[0] = 'z'; diff --git a/fec/tests/types/ok-arrayctx.fe b/fec/tests/types/ok_arra1.fe similarity index 87% rename from fec/tests/types/ok-arrayctx.fe rename to fec/tests/types/ok_arra1.fe index 9e6d047..487b1ec 100644 --- a/fec/tests/types/ok-arrayctx.fe +++ b/fec/tests/types/ok_arra1.fe @@ -1,4 +1,4 @@ -unit m3_arrayctx; +unit ok_arra1; fn main() -> i32 { let bytes: [3]u8 = [1, 2, 3]; diff --git a/fec/tests/types/ok-array.fe b/fec/tests/types/ok_array.fe similarity index 92% rename from fec/tests/types/ok-array.fe rename to fec/tests/types/ok_array.fe index a8ff358..bf748bc 100644 --- a/fec/tests/types/ok-array.fe +++ b/fec/tests/types/ok_array.fe @@ -1,4 +1,4 @@ -unit m3_array; +unit ok_array; fn main() -> i32 { let a: [3]i32 = [1, 2, 3]; diff --git a/fec/tests/types/ok-castwhil.fe b/fec/tests/types/ok_castw.fe similarity index 90% rename from fec/tests/types/ok-castwhil.fe rename to fec/tests/types/ok_castw.fe index c54b114..2e962f5 100644 --- a/fec/tests/types/ok-castwhil.fe +++ b/fec/tests/types/ok_castw.fe @@ -1,4 +1,4 @@ -unit cast_while; +unit ok_castw; pub fn main() -> i32 { var x: i16 = 0; diff --git a/fec/tests/types/ok-char.fe b/fec/tests/types/ok_char.fe similarity index 92% rename from fec/tests/types/ok-char.fe rename to fec/tests/types/ok_char.fe index 253ff85..e6939b7 100644 --- a/fec/tests/types/ok-char.fe +++ b/fec/tests/types/ok_char.fe @@ -1,4 +1,4 @@ -unit m3_char; +unit ok_char; fn main() -> i32 { let c: char = '\u0041'; diff --git a/fec/tests/types/ok-enum.fe b/fec/tests/types/ok_enum.fe similarity index 96% rename from fec/tests/types/ok-enum.fe rename to fec/tests/types/ok_enum.fe index 2e2e934..581cbb3 100644 --- a/fec/tests/types/ok-enum.fe +++ b/fec/tests/types/ok_enum.fe @@ -1,4 +1,4 @@ -unit m3_enum; +unit ok_enum; enum Shape { Empty, Circle(i32), Rect { w: i32, h: i32, }, } diff --git a/fec/tests/types/ok-for.fe b/fec/tests/types/ok_for.fe similarity index 97% rename from fec/tests/types/ok-for.fe rename to fec/tests/types/ok_for.fe index e591000..3aab7bf 100644 --- a/fec/tests/types/ok-for.fe +++ b/fec/tests/types/ok_for.fe @@ -1,4 +1,4 @@ -unit m3_for; +unit ok_for; fn main() -> i32 { var total: i32 = 0; diff --git a/fec/tests/types/ok-hello.fe b/fec/tests/types/ok_hello.fe similarity index 95% rename from fec/tests/types/ok-hello.fe rename to fec/tests/types/ok_hello.fe index aec68c7..e55fedb 100644 --- a/fec/tests/types/ok-hello.fe +++ b/fec/tests/types/ok_hello.fe @@ -1,4 +1,4 @@ -unit hello; +unit ok_hello; fn add(a: i32, b: i32) -> i32 { return a + b; diff --git a/fec/tests/types/ok-mutable.fe b/fec/tests/types/ok_mutab.fe similarity index 92% rename from fec/tests/types/ok-mutable.fe rename to fec/tests/types/ok_mutab.fe index 9c31d51..dc596a2 100644 --- a/fec/tests/types/ok-mutable.fe +++ b/fec/tests/types/ok_mutab.fe @@ -1,4 +1,4 @@ -unit m3_mutable; +unit ok_mutab; fn takes_shared(s: []u8) -> u8 { return s[0]; } diff --git a/fec/tests/types/ok-nested.fe b/fec/tests/types/ok_neste.fe similarity index 92% rename from fec/tests/types/ok-nested.fe rename to fec/tests/types/ok_neste.fe index 3f71cc9..e8c0485 100644 --- a/fec/tests/types/ok-nested.fe +++ b/fec/tests/types/ok_neste.fe @@ -1,4 +1,4 @@ -unit m3_nested; +unit ok_neste; struct Outer { inner: Inner, } struct Inner { value: i32, } diff --git a/fec/tests/types/ok-scopes.fe b/fec/tests/types/ok_scope.fe similarity index 94% rename from fec/tests/types/ok-scopes.fe rename to fec/tests/types/ok_scope.fe index b0d6168..153398f 100644 --- a/fec/tests/types/ok-scopes.fe +++ b/fec/tests/types/ok_scope.fe @@ -1,4 +1,4 @@ -unit scopes; +unit ok_scope; fn register(switch: i32) -> i32 { let auto: i32 = switch; diff --git a/fec/tests/types/ok-str.fe b/fec/tests/types/ok_str.fe similarity index 90% rename from fec/tests/types/ok-str.fe rename to fec/tests/types/ok_str.fe index f0077fd..fec3064 100644 --- a/fec/tests/types/ok-str.fe +++ b/fec/tests/types/ok_str.fe @@ -1,4 +1,4 @@ -unit m3_str; +unit ok_str; fn main() -> i32 { let text: str = "abc"; diff --git a/fec/tests/types/ok-struct.fe b/fec/tests/types/ok_struc.fe similarity index 96% rename from fec/tests/types/ok-struct.fe rename to fec/tests/types/ok_struc.fe index 2d7e2b1..1754eb9 100644 --- a/fec/tests/types/ok-struct.fe +++ b/fec/tests/types/ok_struc.fe @@ -1,4 +1,4 @@ -unit m3_struct; +unit ok_struc; struct Point { x: i32, y: i32, } packed struct PackedPoint { x: u8, y: i32, } diff --git a/tests/run.py b/tests/run.py index 20700dd..ff66496 100644 --- a/tests/run.py +++ b/tests/run.py @@ -34,7 +34,7 @@ ROOT = Path(__file__).resolve().parent.parent FIXTURES = ROOT / "fec" / "tests" WATCOM = ROOT / ".dosboxx" / "watcom" SOURCES = ("arena", "diag", "lexer", "ast", "parser", "types", "m7", "own", - "check", "driver") + "check", "resolve", "driver") # Fixtures live here until there is a code generator to run them against. QUARANTINE = "pending-backend"