X-Git-Url: https://ocean-lang.org/code/?a=blobdiff_plain;f=csrc%2Foceani.mdc;h=ebb69ade3d2a32f40e0e3666ed6416cf8d2cc4e9;hb=217a763da640550da7645c75adc0cd8424f6c452;hp=4689a525233f020dd92362fddbb8712b200ff5d3;hpb=db13a7edae07b9905343b68f568a7d335d176951;p=ocean diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index 4689a52..ebb69ad 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -375,6 +375,12 @@ stored. c->parse_error = 1; } + static void tok_err(struct parse_context *c, char *fmt, struct token *t) + { + fprintf(stderr, "%s:%d:%d: %s\n", c->file_name, t->line, t->col, fmt); + c->parse_error = 1; + } + ## Data Structures One last introductory step before detailing the language elements and @@ -663,6 +669,7 @@ cannot nest, so a declaration while a name is in-scope is an error. struct variable *previous; struct value val; struct binding *name; + struct exec *where_decl;// where name was declared struct exec *where_set; // where type was set ## variable fields }; @@ -895,7 +902,7 @@ all pending-scope variables become conditionally scoped. switch (v ? v->scope : OutScope) { case InScope: - /* Signal error ... once I build error signalling support */ + /* Caller will report the error */ return NULL; case CondScope: for (; @@ -1280,16 +1287,25 @@ an executable. $0->val.vtype = Vnum; if (number_parse($0->val.num, $0->val.tail, $1.txt) == 0) mpq_init($0->val.num); + if ($0->val.tail[0]) + tok_err(config2context(config), "error: unsupported number suffix.", + &$1); }$ | STRING ${ $0 = new_pos(val, $1); $0->val.vtype = Vstr; string_parse(&$1, '\\', &$0->val.str, $0->val.tail); + if ($0->val.tail[0]) + tok_err(config2context(config), "error: unsupported string suffix.", + &$1); }$ | MULTI_STRING ${ $0 = new_pos(val, $1); $0->val.vtype = Vstr; string_parse(&$1, '\\', &$0->val.str, $0->val.tail); + if ($0->val.tail[0]) + tok_err(config2context(config), "error: unsupported string suffix.", + &$1); }$ ###### print exec cases @@ -1378,12 +1394,32 @@ link to find the primary instance. struct variable *v = var_decl(config2context(config), $1.txt); $0 = new_pos(var, $1); $0->var = v; + if (v) + v->where_decl = $0; + else { + v = var_ref(config2context(config), $1.txt); + $0->var = v; + type_err(config2context(config), "error: variable '%v' redeclared", + $0, Vnone, Vnone); + type_err(config2context(config), "info: this is where '%v' was first declared", + v->where_decl, Vnone, Vnone); + } } }$ | IDENTIFIER ::= ${ { struct variable *v = var_decl(config2context(config), $1.txt); - v->constant = 1; $0 = new_pos(var, $1); $0->var = v; + if (v) { + v->where_decl = $0; + v->constant = 1; + } else { + v = var_ref(config2context(config), $1.txt); + $0->var = v; + type_err(config2context(config), "error: variable '%v' redeclared", + $0, Vnone, Vnone); + type_err(config2context(config), "info: this is where '%v' was first declared", + v->where_decl, Vnone, Vnone); + } } }$ Variable -> IDENTIFIER ${ { @@ -1446,9 +1482,9 @@ link to find the primary instance. return type; } if (!vtype_compat(type, v->val.vtype, bool_permitted)) { - type_err(c, "error: expected %1 but variable %v is %2", prog, + type_err(c, "error: expected %1 but variable '%v' is %2", prog, type, v->val.vtype); - type_err(c, "info: this is where %v was set to %1", v->where_set, + type_err(c, "info: this is where '%v' was set to %1", v->where_set, v->val.vtype, Vnone); *ok = 0; } @@ -2195,7 +2231,7 @@ it is declared, and error will be raised as the name is created as if (t > Vunknown) { if (propagate_types(b->right, c, ok, t, 0) != t) if (b->left->type == Xvar) - type_err(c, "info: variable %v was set as %1 here.", + type_err(c, "info: variable '%v' was set as %1 here.", cast(var, b->left)->var->where_set, t, Vnone); } else { t = propagate_types(b->right, c, ok, Vnolabel, 0); @@ -2761,9 +2797,8 @@ analysis is a bit more interesting at this level. if (config2context(config)->scope_stack) abort(); }$ | ERROR ${ - fprintf(stderr, "%s:%d:%d: error: unhandled parse error.\n", - config2context(config)->file_name, $1.line, $1.col); - config2context(config)->parse_error = 1; + tok_err(config2context(config), + "error: unhandled parse error.", &$1); }$ Varlist -> Varlist ArgDecl ${