self->name = name ? util_strdup(name) : NULL;
self->expression.vtype = t;
self->expression.next = NULL;
+ self->isfield = false;
self->cvq = CV_NONE;
self->hasvalue = false;
self->uses = 0;
self->params = NULL;
self->func = funcexpr;
+/*
self->expression.vtype = funcexpr->expression.next->expression.vtype;
if (funcexpr->expression.next->expression.next)
self->expression.next = ast_type_copy(ctx, funcexpr->expression.next->expression.next);
+*/
+ ast_type_adopt(self, funcexpr->expression.next);
return self;
}
* But I can't imagine a pituation where the output is truly unnecessary.
*/
+void _ast_codegen_output_type(ast_expression_common *self, ir_value *out)
+{
+ if (out->vtype == TYPE_FIELD)
+ out->fieldtype = self->next->expression.vtype;
+ if (out->vtype == TYPE_FUNCTION)
+ out->outtype = self->next->expression.vtype;
+}
+
+#define codegen_output_type(a,o) (_ast_codegen_output_type(&((a)->expression),(o)))
+#define codegen_output_type_expr(a,o) (_ast_codegen_output_type(a,(o)))
+
bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out)
{
(void)func;
compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", self->name);
return false;
}
- if (vtype == TYPE_FIELD)
- v->fieldtype = elemtype->next->expression.vtype;
v->context = ast_ctx(self);
array->ir_v = self->ir_v = v;
compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", name);
return false;
}
- if (vtype == TYPE_FIELD)
- array->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
array->ir_values[ai]->context = ast_ctx(self);
}
mem_d(name);
compile_error(ast_ctx(self), "ir_builder_create_global failed `%s`", self->name);
return false;
}
- if (vtype == TYPE_FIELD)
- v->fieldtype = elemtype->next->expression.vtype;
v->context = ast_ctx(self);
namelen = strlen(self->name);
compile_error(ast_ctx(self), "ir_builder_create_global failed `%s`", name);
return false;
}
- if (vtype == TYPE_FIELD)
- self->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
self->ir_values[ai]->context = ast_ctx(self);
}
mem_d(name);
compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", self->name);
return false;
}
- if (self->expression.vtype == TYPE_FIELD)
- v->fieldtype = self->expression.next->expression.vtype;
+ codegen_output_type(self, v);
v->context = ast_ctx(self);
}
/* Cannot generate an IR value for a function,
* need a pointer pointing to a function rather.
*/
+ case TYPE_FIELD:
+ if (!self->constval.vfield) {
+ compile_error(ast_ctx(self), "field constant without vfield set");
+ goto error;
+ }
+ if (!self->constval.vfield->ir_v) {
+ compile_error(ast_ctx(self), "field constant generated before its field");
+ goto error;
+ }
+ if (!ir_value_set_field(v, self->constval.vfield->ir_v))
+ goto error;
+ break;
default:
compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
break;
compile_error(ast_ctx(self), "ir_function_create_local failed");
return false;
}
- if (vtype == TYPE_FIELD)
- v->fieldtype = elemtype->next->expression.vtype;
v->context = ast_ctx(self);
namelen = strlen(self->name);
compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", name);
return false;
}
- if (vtype == TYPE_FIELD)
- self->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
self->ir_values[ai]->context = ast_ctx(self);
}
}
v = ir_function_create_local(func, self->name, self->expression.vtype, param);
if (!v)
return false;
- if (self->expression.vtype == TYPE_FIELD)
- v->fieldtype = self->expression.next->expression.vtype;
+ codegen_output_type(self, v);
v->context = ast_ctx(self);
}
} else {
*out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"),
ent, field, self->expression.vtype);
+ codegen_output_type(self, *out);
}
if (!*out) {
compile_error(ast_ctx(self), "failed to create %s instruction (output type %s)",
bbreak = bout;
/* The loop body... */
- if (self->body)
+ /* if (self->body) */
{
bbody = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "loop_body"));
if (!bbody)
func->continueblock = bbody;
/* generate */
- cgen = self->body->expression.codegen;
- if (!(*cgen)((ast_expression*)(self->body), func, false, &dummy))
- return false;
+ if (self->body) {
+ cgen = self->body->expression.codegen;
+ if (!(*cgen)((ast_expression*)(self->body), func, false, &dummy))
+ return false;
+ }
end_bbody = func->curblock;
func->breakblock = old_bbreak;
*out = ir_call_value(callinstr);
self->expression.outr = *out;
+ codegen_output_type(self, *out);
+
vec_free(params);
return true;
error: