]> ocean-lang.org Git - ocean/commitdiff
oceani: allow a variable to be declared with no value
authorNeilBrown <neil@brown.name>
Sun, 28 Apr 2019 00:40:12 +0000 (10:40 +1000)
committerNeilBrown <neil@brown.name>
Wed, 1 May 2019 08:07:28 +0000 (18:07 +1000)
 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 <neil@brown.name>
csrc/oceani.mdc

index df9a5c5f1847349088d5e1ceba95343a8cb4fe22..2be4d5db5a37a5512e85699f1be046a79098d280 100644 (file)
@@ -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: