From: NeilBrown Date: Sun, 28 Apr 2019 00:40:12 +0000 (+1000) Subject: oceani: allow a variable to be declared with no value X-Git-Tag: JamisonCreek-3~38 X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=commitdiff_plain;h=2770ad454dcc49b478e5452dfda69803c8f94c69 oceani: allow a variable to be declared with no value var:type is now allowed. "var:" is not - there must be either a type or an initial value. If only the type is given, the type's 'init' function is called to provide an initial value. Signed-off-by: NeilBrown --- diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index df9a5c5..2be4d5d 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -1589,7 +1589,7 @@ link to find the primary instance. ###### Grammar $*var - VariableDecl -> IDENTIFIER : = ${ { + VariableDecl -> IDENTIFIER : ${ { struct variable *v = var_decl(config2context(config), $1.txt); $0 = new_pos(var, $1); $0->var = v; @@ -1604,7 +1604,7 @@ link to find the primary instance. v->where_decl, Tnone, 0, Tnone); } } }$ - | IDENTIFIER :: = ${ { + | IDENTIFIER :: ${ { struct variable *v = var_decl(config2context(config), $1.txt); $0 = new_pos(var, $1); $0->var = v; @@ -1620,7 +1620,7 @@ link to find the primary instance. v->where_decl, Tnone, 0, Tnone); } } }$ - | IDENTIFIER : Type = ${ { + | IDENTIFIER : Type ${ { struct variable *v = var_decl(config2context(config), $1.txt); $0 = new_pos(var, $1); $0->var = v; @@ -1637,7 +1637,7 @@ link to find the primary instance. v->where_decl, Tnone, 0, Tnone); } } }$ - | IDENTIFIER :: Type = ${ { + | IDENTIFIER :: Type ${ { struct variable *v = var_decl(config2context(config), $1.txt); $0 = new_pos(var, $1); $0->var = v; @@ -2456,11 +2456,23 @@ it is declared, and error will be raised as the name is created as v->var->where_decl, NULL, 0, NULL); } } }$ - | VariableDecl Expression ${ + | VariableDecl = Expression ${ $0 = new(binode); $0->op = Declare; $0->left = $<1; - $0->right =$<2; + $0->right =$<3; + }$ + + | VariableDecl ${ + if ($1->var->where_set == NULL) { + type_err(config2context(config), "Variable declared with no type or value: %v", + $1, NULL, 0, NULL); + } else { + $0 = new(binode); + $0->op = Declare; + $0->left = $<1; + $0->right = NULL; + } }$ ###### print binode cases @@ -2481,18 +2493,21 @@ it is declared, and error will be raised as the name is created as print_exec(b->left, indent, 0); if (cast(var, b->left)->var->constant) { if (v->where_decl == v->where_set) - printf("::%.*s = ", v->val.type->name.len, + printf("::%.*s ", v->val.type->name.len, v->val.type->name.txt); else - printf(" ::= "); + printf(" ::"); } else { if (v->where_decl == v->where_set) - printf(":%.*s = ", v->val.type->name.len, + printf(":%.*s ", v->val.type->name.len, v->val.type->name.txt); else - printf(" := "); + printf(" :"); + } + if (b->right) { + printf("= "); + print_exec(b->right, indent, 0); } - print_exec(b->right, indent, 0); if (indent >= 0) printf("\n"); } @@ -2504,6 +2519,9 @@ it is declared, and error will be raised as the name is created as case Declare: /* Both must match and not be labels, result is Tnone */ t = propagate_types(b->left, c, ok, NULL, Rnolabel); + if (!b->right) + return Tnone; + if (t) { if (propagate_types(b->right, c, ok, t, 0) != t) if (b->left->type == Xvar) @@ -2521,7 +2539,6 @@ it is declared, and error will be raised as the name is created as ###### interp binode cases case Assign: - case Declare: { struct variable *v = cast(var, b->left)->var; if (v->merged) @@ -2533,6 +2550,21 @@ it is declared, and error will be raised as the name is created as break; } + case Declare: + { + struct variable *v = cast(var, b->left)->var; + if (v->merged) + v = v->merged; + if (b->right) + right = interp_exec(b->right); + else + right = val_init(v->val.type); + free_value(v->val); + v->val = right; + right.type = NULL; + break; + } + ### The `use` statement The `use` statement is the last "simple" statement. It is needed when @@ -3216,7 +3248,8 @@ Fibonacci, and performs a binary search for a number. double := A*2 print "double", A, "is only", double - a := A; + a : number + a = A; b:number = B if a > 0 and b > 0: while a != b: