ast_value* ast_value_copy(const ast_value *self)
{
- const ast_expression *fromex;
- ast_expression *selfex;
- ast_value *cp = ast_value_new(self->expression.context, self->name, self->expression.vtype);
- if (self->expression.next) {
- cp->expression.next = ast_type_copy(self->expression.context, self->expression.next);
+ ast_value *cp = ast_value_new(self->context, self->name, self->vtype);
+ if (self->next) {
+ cp->next = ast_type_copy(self->context, self->next);
}
- fromex = &self->expression;
- selfex = &cp->expression;
+ const ast_expression *fromex = self;
+ ast_expression *selfex = cp;
selfex->count = fromex->count;
selfex->flags = fromex->flags;
for (auto &it : fromex->type_params) {
ast_instantiate(ast_value, ctx, ast_value_delete);
ast_expression_init((ast_expression*)self,
(ast_expression_codegen*)&ast_value_codegen);
- self->expression.keep_node = true; /* keep */
+ self->keep_node = true; /* keep */
self->name = name ? util_strdup(name) : nullptr;
- self->expression.vtype = t;
- self->expression.next = nullptr;
+ self->vtype = t;
+ self->next = nullptr;
self->isfield = false;
self->cvq = CV_NONE;
self->hasvalue = false;
if (self->argcounter)
mem_d((void*)self->argcounter);
if (self->hasvalue) {
- switch (self->expression.vtype)
+ switch (self->vtype)
{
case TYPE_STRING:
mem_d((void*)self->constval.vstring);
mem_d(self->desc);
// initlist imples an array which implies .next in the expression exists.
- if (self->initlist.size() && self->expression.next->vtype == TYPE_STRING) {
+ if (self->initlist.size() && self->next->vtype == TYPE_STRING) {
for (auto &it : self->initlist)
if (it.vstring)
mem_d(it.vstring);
void ast_value_params_add(ast_value *self, ast_value *p)
{
- self->expression.type_params.push_back(p);
+ self->type_params.push_back(p);
}
bool ast_value_set_name(ast_value *self, const char *name)
ast_propagate_effects(self, right);
if (op >= INSTR_EQ_F && op <= INSTR_GT)
- self->expression.vtype = TYPE_FLOAT;
+ self->vtype = TYPE_FLOAT;
else if (op == INSTR_AND || op == INSTR_OR) {
if (OPTS_FLAG(PERL_LOGIC))
ast_type_adopt(self, right);
else
- self->expression.vtype = TYPE_FLOAT;
+ self->vtype = TYPE_FLOAT;
}
else if (op == INSTR_BITAND || op == INSTR_BITOR)
- self->expression.vtype = TYPE_FLOAT;
+ self->vtype = TYPE_FLOAT;
else if (op == INSTR_MUL_VF || op == INSTR_MUL_FV)
- self->expression.vtype = TYPE_VECTOR;
+ self->vtype = TYPE_VECTOR;
else if (op == INSTR_MUL_V)
- self->expression.vtype = TYPE_FLOAT;
+ self->vtype = TYPE_FLOAT;
else
- self->expression.vtype = left->vtype;
+ self->vtype = left->vtype;
/* references all */
self->refs = AST_REF_ALL;
ast_propagate_effects(self, expr);
if ((op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) || op == VINSTR_NEG_F) {
- self->expression.vtype = TYPE_FLOAT;
+ self->vtype = TYPE_FLOAT;
} else if (op == VINSTR_NEG_V) {
- self->expression.vtype = TYPE_VECTOR;
+ self->vtype = TYPE_VECTOR;
} else {
compile_error(ctx, "cannot determine type of unary operation %s", util_instr_str[op]);
}
}
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_member_codegen);
- self->expression.keep_node = true; /* keep */
+ self->keep_node = true; /* keep */
if (owner->vtype == TYPE_VECTOR) {
- self->expression.vtype = TYPE_FLOAT;
- self->expression.next = nullptr;
+ self->vtype = TYPE_FLOAT;
+ self->next = nullptr;
} else {
- self->expression.vtype = TYPE_FIELD;
- self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT);
+ self->vtype = TYPE_FIELD;
+ self->next = ast_shallow_type(ctx, TYPE_FLOAT);
}
self->rvalue = false;
ast_type_adopt(self, outtype);
if (array->vtype == TYPE_FIELD && outtype->vtype == TYPE_ARRAY) {
- if (self->expression.vtype != TYPE_ARRAY) {
+ if (self->vtype != TYPE_ARRAY) {
compile_error(ast_ctx(self), "array_index node on type");
ast_array_index_delete(self);
return nullptr;
}
self->array = outtype;
- self->expression.vtype = TYPE_FIELD;
+ self->vtype = TYPE_FIELD;
}
return self;
ast_instantiate(ast_argpipe, ctx, ast_argpipe_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_argpipe_codegen);
self->index = index;
- self->expression.vtype = TYPE_NOEXPR;
+ self->vtype = TYPE_NOEXPR;
return self;
}
ast_instantiate(ast_label, ctx, ast_label_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_label_codegen);
- self->expression.vtype = TYPE_NOEXPR;
+ self->vtype = TYPE_NOEXPR;
self->name = util_strdup(name);
self->irblock = nullptr;
{
ast_propagate_effects(self, e);
self->exprs.push_back(e);
- if (self->expression.next) {
- ast_delete(self->expression.next);
- self->expression.next = nullptr;
+ if (self->next) {
+ ast_delete(self->next);
+ self->next = nullptr;
}
ast_type_adopt(self, e);
return true;
void ast_block_set_type(ast_block *self, ast_expression *from)
{
- if (self->expression.next)
- ast_delete(self->expression.next);
+ if (self->next)
+ ast_delete(self->next);
ast_type_adopt(self, from);
}
if (!vtype) {
compile_error(ast_ctx(self), "internal error: ast_function_new condition 0");
goto cleanup;
- } else if (vtype->hasvalue || vtype->expression.vtype != TYPE_FUNCTION) {
+ } else if (vtype->hasvalue || vtype->vtype != TYPE_FUNCTION) {
compile_error(ast_ctx(self), "internal error: ast_function_new condition %i %i type=%i (probably 2 bodies?)",
(int)!vtype,
(int)vtype->hasvalue,
- vtype->expression.vtype);
+ vtype->vtype);
goto cleanup;
}
out->outtype = self->next->vtype;
}
-#define codegen_output_type(a,o) (_ast_codegen_output_type(&((a)->expression),(o)))
+#define codegen_output_type(a,o) (_ast_codegen_output_type(static_cast<ast_expression*>((a)),(o)))
bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out)
{
(void)func;
(void)lvalue;
- if (self->expression.vtype == TYPE_NIL) {
+ if (self->vtype == TYPE_NIL) {
*out = func->ir_func->owner->nil;
return true;
}
- /* NOTE: This is the codegen for a variable used in an expression.
+ /* NOTE: This is the codegen for a variable used in an
* It is not the codegen to generate the value. For this purpose,
* ast_local_codegen and ast_global_codegen are to be used before this
* is executed. ast_function_codegen should take care of its locals,
size_t count = self->initlist.size();
size_t i;
- if (count > self->expression.count) {
+ if (count > self->count) {
compile_error(ast_ctx(self), "too many elements in initializer");
- count = self->expression.count;
+ count = self->count;
}
- else if (count < self->expression.count) {
+ else if (count < self->count) {
/* add this?
compile_warning(ast_ctx(self), "not all elements are initialized");
*/
}
for (i = 0; i != count; ++i) {
- switch (self->expression.next->vtype) {
+ switch (self->next->vtype) {
case TYPE_FLOAT:
if (!ir_value_set_float(self->ir_values[i], self->initlist[i].vfloat))
return false;
return false;
break;
default:
- compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
+ compile_error(ast_ctx(self), "TODO: global constant type %i", self->vtype);
break;
}
}
static bool check_array(ast_value *self, ast_value *array)
{
- if (array->expression.flags & AST_FLAG_ARRAY_INIT && array->initlist.empty()) {
+ if (array->flags & AST_FLAG_ARRAY_INIT && array->initlist.empty()) {
compile_error(ast_ctx(self), "array without size: %s", self->name);
return false;
}
/* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
- if (!array->expression.count || array->expression.count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE)) {
- compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count);
+ if (!array->count || array->count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE)) {
+ compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->count);
return false;
}
return true;
{
ir_value *v = nullptr;
- if (self->expression.vtype == TYPE_NIL) {
+ if (self->vtype == TYPE_NIL) {
compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL");
return false;
}
- if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
+ if (self->hasvalue && self->vtype == TYPE_FUNCTION)
{
- ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->vtype);
+ ir_function *func = ir_builder_create_function(ir, self->name, self->next->vtype);
if (!func)
return false;
func->context = ast_ctx(self);
self->constval.vfunc->ir_func = func;
self->ir_v = func->value;
- if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+ if (self->flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
- if (self->expression.flags & AST_FLAG_ERASEABLE)
+ if (self->flags & AST_FLAG_ERASEABLE)
self->ir_v->flags |= IR_FLAG_ERASABLE;
- if (self->expression.flags & AST_FLAG_BLOCK_COVERAGE)
+ if (self->flags & AST_FLAG_BLOCK_COVERAGE)
func->flags |= IR_FLAG_BLOCK_COVERAGE;
/* The function is filled later on ast_function_codegen... */
return true;
}
- if (isfield && self->expression.vtype == TYPE_FIELD) {
- ast_expression *fieldtype = self->expression.next;
+ if (isfield && self->vtype == TYPE_FIELD) {
+ ast_expression *fieldtype = self->next;
if (self->hasvalue) {
compile_error(ast_ctx(self), "TODO: constant field pointers with value");
if (!check_array(self, array))
return false;
- elemtype = array->expression.next;
+ elemtype = array->next;
vtype = elemtype->vtype;
v = ir_builder_create_field(ir, self->name, vtype);
v->locked = true;
array->ir_v = self->ir_v = v;
- if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+ if (self->flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
- if (self->expression.flags & AST_FLAG_ERASEABLE)
+ if (self->flags & AST_FLAG_ERASEABLE)
self->ir_v->flags |= IR_FLAG_ERASABLE;
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
util_strncpy(name, self->name, namelen);
- array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count);
+ array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->count);
array->ir_values[0] = v;
- for (ai = 1; ai < array->expression.count; ++ai) {
+ for (ai = 1; ai < array->count; ++ai) {
util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
array->ir_values[ai] = ir_builder_create_field(ir, name, vtype);
if (!array->ir_values[ai]) {
array->ir_values[ai]->context = ast_ctx(self);
array->ir_values[ai]->unique_life = true;
array->ir_values[ai]->locked = true;
- if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+ if (self->flags & AST_FLAG_INCLUDE_DEF)
self->ir_values[ai]->flags |= IR_FLAG_INCLUDE_DEF;
}
mem_d(name);
}
else
{
- v = ir_builder_create_field(ir, self->name, self->expression.next->vtype);
+ v = ir_builder_create_field(ir, self->name, self->next->vtype);
if (!v)
return false;
v->context = ast_ctx(self);
self->ir_v = v;
- if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+ if (self->flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
- if (self->expression.flags & AST_FLAG_ERASEABLE)
+ if (self->flags & AST_FLAG_ERASEABLE)
self->ir_v->flags |= IR_FLAG_ERASABLE;
}
return true;
}
- if (self->expression.vtype == TYPE_ARRAY) {
+ if (self->vtype == TYPE_ARRAY) {
size_t ai;
char *name;
size_t namelen;
- ast_expression *elemtype = self->expression.next;
+ ast_expression *elemtype = self->next;
int vtype = elemtype->vtype;
- if (self->expression.flags & AST_FLAG_ARRAY_INIT && !self->expression.count) {
+ if (self->flags & AST_FLAG_ARRAY_INIT && !self->count) {
compile_error(ast_ctx(self), "array `%s' has no size", self->name);
return false;
}
v->unique_life = true;
v->locked = true;
- if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+ if (self->flags & AST_FLAG_INCLUDE_DEF)
v->flags |= IR_FLAG_INCLUDE_DEF;
- if (self->expression.flags & AST_FLAG_ERASEABLE)
+ if (self->flags & AST_FLAG_ERASEABLE)
self->ir_v->flags |= IR_FLAG_ERASABLE;
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
util_strncpy(name, self->name, namelen);
- self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
+ self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->count);
self->ir_values[0] = v;
- for (ai = 1; ai < self->expression.count; ++ai) {
+ for (ai = 1; ai < self->count; ++ai) {
util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
self->ir_values[ai] = ir_builder_create_global(ir, name, vtype);
if (!self->ir_values[ai]) {
self->ir_values[ai]->context = ast_ctx(self);
self->ir_values[ai]->unique_life = true;
self->ir_values[ai]->locked = true;
- if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+ if (self->flags & AST_FLAG_INCLUDE_DEF)
self->ir_values[ai]->flags |= IR_FLAG_INCLUDE_DEF;
}
mem_d(name);
/* Arrays don't do this since there's no "array" value which spans across the
* whole thing.
*/
- v = ir_builder_create_global(ir, self->name, self->expression.vtype);
+ v = ir_builder_create_global(ir, self->name, self->vtype);
if (!v) {
compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", self->name);
return false;
v->cvq = self->cvq;
self->ir_v = v;
- if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+ if (self->flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
- if (self->expression.flags & AST_FLAG_ERASEABLE)
+ if (self->flags & AST_FLAG_ERASEABLE)
self->ir_v->flags |= IR_FLAG_ERASABLE;
/* initialize */
if (self->hasvalue) {
- switch (self->expression.vtype)
+ switch (self->vtype)
{
case TYPE_FLOAT:
if (!ir_value_set_float(v, self->constval.vfloat))
goto error;
break;
default:
- compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
+ compile_error(ast_ctx(self), "TODO: global constant type %i", self->vtype);
break;
}
}
{
ir_value *v = nullptr;
- if (self->expression.vtype == TYPE_NIL) {
+ if (self->vtype == TYPE_NIL) {
compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL");
return false;
}
- if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
+ if (self->hasvalue && self->vtype == TYPE_FUNCTION)
{
/* Do we allow local functions? I think not...
* this is NOT a function pointer atm.
return false;
}
- if (self->expression.vtype == TYPE_ARRAY) {
+ if (self->vtype == TYPE_ARRAY) {
size_t ai;
char *name;
size_t namelen;
- ast_expression *elemtype = self->expression.next;
+ ast_expression *elemtype = self->next;
int vtype = elemtype->vtype;
func->flags |= IR_FLAG_HAS_ARRAYS;
- if (param && !(self->expression.flags & AST_FLAG_IS_VARARG)) {
+ if (param && !(self->flags & AST_FLAG_IS_VARARG)) {
compile_error(ast_ctx(self), "array-parameters are not supported");
return false;
}
if (!check_array(self, self))
return false;
- self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
+ self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->count);
if (!self->ir_values) {
compile_error(ast_ctx(self), "failed to allocate array values");
return false;
util_strncpy(name, self->name, namelen);
self->ir_values[0] = v;
- for (ai = 1; ai < self->expression.count; ++ai) {
+ for (ai = 1; ai < self->count; ++ai) {
util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
self->ir_values[ai] = ir_function_create_local(func, name, vtype, param);
if (!self->ir_values[ai]) {
}
else
{
- v = ir_function_create_local(func, self->name, self->expression.vtype, param);
+ v = ir_function_create_local(func, self->name, self->vtype, param);
if (!v)
return false;
codegen_output_type(self, v);
* I suppose the IR will have to deal with this
*/
if (self->hasvalue) {
- switch (self->expression.vtype)
+ switch (self->vtype)
{
case TYPE_FLOAT:
if (!ir_value_set_float(v, self->constval.vfloat))
goto error;
break;
default:
- compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
+ compile_error(ast_ctx(self), "TODO: global constant type %i", self->vtype);
break;
}
}
bool warn = OPTS_WARN(WARN_USED_UNINITIALIZED);
if (!self->setter || !self->getter)
return true;
- for (i = 0; i < self->expression.count; ++i) {
+ for (i = 0; i < self->count; ++i) {
if (!self->ir_values) {
compile_error(ast_ctx(self), "internal error: no array values generated for `%s`", self->name);
return false;
return false;
}
}
- for (i = 0; i < self->expression.count; ++i) {
+ for (i = 0; i < self->count; ++i) {
vec_free(self->ir_values[i]->life);
}
opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
}
/* fill the parameter list */
- ec = &self->function_type->expression;
+ ec = self->function_type;
for (auto &it : ec->type_params) {
- if (it->expression.vtype == TYPE_FIELD)
- vec_push(irf->params, it->expression.next->vtype);
+ if (it->vtype == TYPE_FIELD)
+ vec_push(irf->params, it->next->vtype);
else
- vec_push(irf->params, it->expression.vtype);
+ vec_push(irf->params, it->vtype);
if (!self->builtin) {
if (!ast_local_codegen(it, self->ir_func, true))
return false;
if (self->varargs) {
if (!ast_local_codegen(self->varargs, self->ir_func, true))
return false;
- irf->max_varargs = self->varargs->expression.count;
+ irf->max_varargs = self->varargs->count;
}
if (self->builtin) {
ir_value *sub;
if (!ast_local_codegen(self->argc, self->ir_func, true))
return false;
- cgen = self->argc->expression.codegen;
+ cgen = self->argc->codegen;
if (!(*cgen)((ast_expression*)(self->argc), self, false, &va_count))
return false;
- cgen = self->fixedparams->expression.codegen;
+ cgen = self->fixedparams->codegen;
if (!(*cgen)((ast_expression*)(self->fixedparams), self, false, &fixed))
return false;
sub = ir_block_create_binop(self->curblock, ast_ctx(self),
}
for (auto &it : self->blocks) {
- cgen = it->expression.codegen;
+ cgen = it->codegen;
if (!(*cgen)((ast_expression*)it, self, false, &dummy))
return false;
}
/* TODO: check return types */
if (!self->curblock->final)
{
- if (!self->function_type->expression.next ||
- self->function_type->expression.next->vtype == TYPE_VOID)
+ if (!self->function_type->next ||
+ self->function_type->next->vtype == TYPE_VOID)
{
return ir_block_create_return(self->curblock, ast_ctx(self), nullptr);
}
else if (vec_size(self->curblock->entries) || self->curblock == irf->first)
{
if (self->return_value) {
- cgen = self->return_value->expression.codegen;
+ cgen = self->return_value->codegen;
if (!(*cgen)((ast_expression*)(self->return_value), self, false, &dummy))
return false;
return ir_block_create_return(self->curblock, ast_ctx(self), dummy);
return false;
}
- if (self->expression.outr) {
- *out = self->expression.outr;
+ if (self->outr) {
+ *out = self->outr;
return true;
}
return false;
}
- self->expression.outr = *out;
+ self->outr = *out;
return true;
}
ast_value *idx = 0;
ast_array_index *ai = nullptr;
- if (lvalue && self->expression.outl) {
- *out = self->expression.outl;
+ if (lvalue && self->outl) {
+ *out = self->outl;
return true;
}
- if (!lvalue && self->expression.outr) {
- *out = self->expression.outr;
+ if (!lvalue && self->outr) {
+ *out = self->outr;
return true;
}
return false;
}
- cgen = idx->expression.codegen;
+ cgen = idx->codegen;
if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
return false;
- cgen = arr->setter->expression.codegen;
+ cgen = arr->setter->codegen;
if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
return false;
return false;
ir_call_param(call, iridx);
ir_call_param(call, right);
- self->expression.outr = right;
+ self->outr = right;
}
else
{
/* lvalue! */
if (!(*cgen)((ast_expression*)(self->dest), func, true, &left))
return false;
- self->expression.outl = left;
+ self->outl = left;
cgen = self->source->codegen;
/* rvalue! */
if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->op, left, right))
return false;
- self->expression.outr = right;
+ self->outr = right;
}
/* Theoretically, an assinment returns its left side as an
return false;
}
- if (self->expression.outr) {
- *out = self->expression.outr;
+ if (self->outr) {
+ *out = self->outr;
return true;
}
func->curblock = merge;
phi = ir_block_create_phi(func->curblock, ast_ctx(self),
ast_function_label(func, "sce_value"),
- self->expression.vtype);
+ self->vtype);
ir_phi_add(phi, from_left, left);
ir_phi_add(phi, from_right, right);
*out = ir_phi_value(phi);
}
}
- self->expression.outr = *out;
+ self->outr = *out;
codegen_output_type(self, *out);
return true;
}
self->op, left, right);
if (!*out)
return false;
- self->expression.outr = *out;
+ self->outr = *out;
codegen_output_type(self, *out);
return true;
ast_array_index *ai = nullptr;
ir_value *iridx = nullptr;
- if (lvalue && self->expression.outl) {
- *out = self->expression.outl;
+ if (lvalue && self->outl) {
+ *out = self->outl;
return true;
}
- if (!lvalue && self->expression.outr) {
- *out = self->expression.outr;
+ if (!lvalue && self->outr) {
+ *out = self->outr;
return true;
}
/* for a binstore we need both an lvalue and an rvalue for the left side */
/* rvalue of destination! */
if (ai) {
- cgen = idx->expression.codegen;
+ cgen = idx->codegen;
if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
return false;
}
/* now the binary */
bin = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "binst"),
self->opbin, leftr, right);
- self->expression.outr = bin;
-
+ self->outr = bin;
if (ai) {
/* we need to call the setter */
return false;
}
- cgen = arr->setter->expression.codegen;
+ cgen = arr->setter->codegen;
if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
return false;
return false;
ir_call_param(call, iridx);
ir_call_param(call, bin);
- self->expression.outr = bin;
+ self->outr = bin;
} else {
/* now store them */
cgen = self->dest->codegen;
/* lvalue of destination */
if (!(*cgen)((ast_expression*)(self->dest), func, true, &leftl))
return false;
- self->expression.outl = leftl;
+ self->outl = leftl;
if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->opstore, leftl, bin))
return false;
- self->expression.outr = bin;
+ self->outr = bin;
}
/* Theoretically, an assinment returns its left side as an
return false;
}
- if (self->expression.outr) {
- *out = self->expression.outr;
+ if (self->outr) {
+ *out = self->outr;
return true;
}
self->op, operand);
if (!*out)
return false;
- self->expression.outr = *out;
+ self->outr = *out;
return true;
}
return false;
}
- if (self->expression.outr) {
+ if (self->outr) {
compile_error(ast_ctx(self), "internal error: ast_return cannot be reused, it bears no result!");
return false;
}
- self->expression.outr = (ir_value*)1;
+ self->outr = (ir_value*)1;
if (self->operand) {
cgen = self->operand->codegen;
* value in a temp.
*/
- if (lvalue && self->expression.outl) {
- *out = self->expression.outl;
+ if (lvalue && self->outl) {
+ *out = self->outl;
return true;
}
- if (!lvalue && self->expression.outr) {
- *out = self->expression.outr;
+ if (!lvalue && self->outr) {
+ *out = self->outr;
return true;
}
ent, field);
} else {
*out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"),
- ent, field, self->expression.vtype);
+ ent, field, self->vtype);
/* Done AFTER error checking:
codegen_output_type(self, *out);
*/
if (!*out) {
compile_error(ast_ctx(self), "failed to create %s instruction (output type %s)",
(lvalue ? "ADDRESS" : "FIELD"),
- type_name[self->expression.vtype]);
+ type_name[self->vtype]);
return false;
}
if (!lvalue)
codegen_output_type(self, *out);
if (lvalue)
- self->expression.outl = *out;
+ self->outl = *out;
else
- self->expression.outr = *out;
+ self->outr = *out;
/* Hm that should be it... */
return true;
compile_error(ast_ctx(self), "not an l-value (member access)");
return false;
}
- if (self->expression.outl) {
- *out = self->expression.outl;
+ if (self->outl) {
+ *out = self->outl;
return true;
}
}
*out = ir_value_vector_member(vec, self->field);
- self->expression.outl = *out;
+ self->outl = *out;
return (*out != nullptr);
}
ast_value *arr;
ast_value *idx;
- if (!lvalue && self->expression.outr) {
- *out = self->expression.outr;
+ if (!lvalue && self->outr) {
+ *out = self->outr;
return true;
}
- if (lvalue && self->expression.outl) {
- *out = self->expression.outl;
+ if (lvalue && self->outl) {
+ *out = self->outl;
return true;
}
if (!(*cgen)((ast_expression*)(self->index), func, false, &iridx))
return false;
- cgen = arr->getter->expression.codegen;
+ cgen = arr->getter->codegen;
if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
return false;
ir_call_param(call, iridx);
*out = ir_call_value(call);
- self->expression.outr = *out;
- (*out)->vtype = self->expression.vtype;
+ self->outr = *out;
+ (*out)->vtype = self->vtype;
codegen_output_type(self, *out);
return true;
}
- if (idx->expression.vtype == TYPE_FLOAT) {
+ if (idx->vtype == TYPE_FLOAT) {
unsigned int arridx = idx->constval.vfloat;
if (arridx >= self->array->count)
{
}
*out = arr->ir_values[arridx];
}
- else if (idx->expression.vtype == TYPE_INTEGER) {
+ else if (idx->vtype == TYPE_INTEGER) {
unsigned int arridx = idx->constval.vint;
if (arridx >= self->array->count)
{
compile_error(ast_ctx(self), "array indexing here needs an integer constant");
return false;
}
- (*out)->vtype = self->expression.vtype;
+ (*out)->vtype = self->vtype;
codegen_output_type(self, *out);
return true;
}
(void)out;
(void)lvalue;
- if (self->expression.outr) {
+ if (self->outr) {
compile_error(ast_ctx(self), "internal error: ast_ifthen cannot be reused, it bears no result!");
return false;
}
- self->expression.outr = (ir_value*)1;
+ self->outr = (ir_value*)1;
/* generate the condition */
cgen = self->cond->codegen;
* may still happen, thus we remember a created ir_value and simply return one
* if it already exists.
*/
- if (self->expression.outr) {
- *out = self->expression.outr;
+ if (self->outr) {
+ *out = self->outr;
return true;
}
}
/* create PHI */
- phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), self->expression.vtype);
+ phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), self->vtype);
if (!phi) {
compile_error(ast_ctx(self), "internal error: failed to generate phi node");
return false;
ir_phi_add(phi, ontrue_out, trueval);
ir_phi_add(phi, onfalse_out, falseval);
- self->expression.outr = ir_phi_value(phi);
- *out = self->expression.outr;
+ self->outr = ir_phi_value(phi);
+ *out = self->outr;
codegen_output_type(self, *out);
(void)lvalue;
(void)out;
- if (self->expression.outr) {
+ if (self->outr) {
compile_error(ast_ctx(self), "internal error: ast_loop cannot be reused, it bears no result!");
return false;
}
- self->expression.outr = (ir_value*)1;
+ self->outr = (ir_value*)1;
/* NOTE:
* Should we ever need some kind of block ordering, better make this function
return false;
}
- if (self->expression.outr) {
+ if (self->outr) {
compile_error(ast_ctx(self), "internal error: ast_breakcont cannot be reused!");
return false;
}
- self->expression.outr = (ir_value*)1;
+ self->outr = (ir_value*)1;
if (self->is_continue)
target = func->continueblocks[func->continueblocks.size()-1-self->levels];
return false;
}
- if (self->expression.outr) {
+ if (self->outr) {
compile_error(ast_ctx(self), "internal error: ast_switch cannot be reused!");
return false;
}
- self->expression.outr = (ir_value*)1;
+ self->outr = (ir_value*)1;
(void)lvalue;
(void)out;
compile_error(ast_ctx(self), "not an l-value (state operation)");
return false;
}
- if (self->expression.outr) {
+ if (self->outr) {
compile_error(ast_ctx(self), "internal error: ast_state cannot be reused!");
return false;
}
return false;
}
- self->expression.outr = (ir_value*)1;
+ self->outr = (ir_value*)1;
return true;
}
return false;
}
- if (self->expression.outr) {
- *out = self->expression.outr;
+ if (self->outr) {
+ *out = self->outr;
return true;
}
ir_call_param(callinstr, it);
*out = ir_call_value(callinstr);
- self->expression.outr = *out;
+ self->outr = *out;
codegen_output_type(self, *out);