static void function_print(struct type *type, struct value *val, FILE *f)
{
+ fprintf(f, "\n");
print_exec(val->function, 1, 0);
}
} else
type_print(type->function.return_type, f);
}
- fprintf(f, "\n");
}
static void function_free_type(struct type *t)
if (bracket) printf(")");
break;
case Bracket:
- printf("(");
+ /* Avoid double brackets... */
+ if (!bracket) printf("(");
print_exec(b->right, indent, bracket);
- printf(")");
+ if (!bracket) printf(")");
break;
###### propagate binode cases
be declared at any time.
###### Binode types
- Assign, AssignRef,
- Declare, DeclareRef,
+ Assign,
+ Declare,
###### declare terminals
$TERM =
###### print binode cases
case Assign:
- case AssignRef:
do_indent(indent, "");
print_exec(b->left, -1, bracket);
printf(" = ");
break;
case Declare:
- case DeclareRef:
{
struct variable *v = cast(var, b->left)->var;
do_indent(indent, "");
###### propagate binode cases
case Assign:
- case AssignRef:
case Declare:
- case DeclareRef:
/* Both must match, or left may be ref and right an lval
* Type must support 'dup',
* For Assign, left must not be constant.
; // No more effort needed
else if (t->free == reference_free &&
t->reference.referent == t2 &&
- !(*perr_local & Erval)) {
- if (b->op == Assign)
- b->op = AssignRef;
- if (b->op == Declare)
- b->op = DeclareRef;
- }
+ !(*perr_local & Erval))
+ b->right = take_addr(b->right);
else if (t->free == reference_free &&
t->reference.referent == t2 &&
(*perr_local & Erval))
if (*perr & Erval)
type_err(c, "error: cannot assign to an rval", b,
NULL, 0, NULL);
- else if ((b->op == Assign || b->op == AssignRef) && (*perr & Econst)) {
+ else if (b->op == Assign && (*perr & Econst)) {
type_err(c, "error: Cannot assign to a constant: %v",
b->left, NULL, 0, NULL);
if (b->left->type == Xvar) {
###### interp binode cases
case Assign:
- case AssignRef:
lleft = linterp_exec(c, b->left, <ype);
- if (!lleft)
- // FIXME lleft==NULL probably means illegal array ref
- // should that cause a runtime error
- ;
- else if (b->op == AssignRef)
- lleft->ref = linterp_exec(c, b->right, &rtype);
- else
+ if (lleft)
dinterp_exec(c, b->right, lleft, ltype, 1);
ltype = Tnone;
break;
case Declare:
- case DeclareRef:
{
struct variable *v = cast(var, b->left)->var;
struct value *val;
v->type->prepare_type(c, v->type, 0);
if (!b->right)
val_init(v->type, val);
- else if (b->op == DeclareRef)
- val->ref = linterp_exec(c, b->right, &rtype);
else
dinterp_exec(c, b->right, val, v->type, 0);
break;
struct value *val = var_value(&context, v);
printf("func %.*s", v->name->name.len, v->name->name.txt);
v->type->print_type_decl(v->type, stdout);
- if (brackets)
- print_exec(val->function, 0, brackets);
- else
+ if (brackets) {
+ printf(" {\n");
+ print_exec(val->function, 1, brackets);
+ printf("}\n");
+ } else {
print_value(v->type, val, stdout);
+ }
printf("/* frame size %d */\n", v->type->function.local_size);
target -= 1;
}