###### Grammar
$*var
- VariableDecl -> IDENTIFIER : = ${ {
+ VariableDecl -> IDENTIFIER : ${ {
struct variable *v = var_decl(config2context(config), $1.txt);
$0 = new_pos(var, $1);
$0->var = v;
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;
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;
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;
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
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");
}
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)
###### interp binode cases
case Assign:
- case Declare:
{
struct variable *v = cast(var, b->left)->var;
if (v->merged)
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
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: