}
/* Initialize main ast node aprts */
-static void ast_node_init(ast_node *self, lex_ctx ctx, int nodetype)
+static void ast_node_init(ast_node *self, lex_ctx_t ctx, int nodetype)
{
self->context = ctx;
self->destroy = &_ast_node_destroy;
}
}
-static ast_expression* ast_shallow_type(lex_ctx ctx, int vtype)
+static ast_expression* ast_shallow_type(lex_ctx_t ctx, int vtype)
{
ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
ast_expression_init(self, NULL);
return self;
}
-ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
+ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex)
{
size_t i;
const ast_expression *fromex;
}
static bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out);
-ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
+ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int t)
{
ast_instantiate(ast_value, ctx, ast_value_delete);
ast_expression_init((ast_expression*)self,
return !!self->name;
}
-ast_binary* ast_binary_new(lex_ctx ctx, int op,
+ast_binary* ast_binary_new(lex_ctx_t ctx, int op,
ast_expression* left, ast_expression* right)
{
ast_instantiate(ast_binary, ctx, ast_binary_delete);
mem_d(self);
}
-ast_binstore* ast_binstore_new(lex_ctx ctx, int storop, int op,
+ast_binstore* ast_binstore_new(lex_ctx_t ctx, int storop, int op,
ast_expression* left, ast_expression* right)
{
ast_instantiate(ast_binstore, ctx, ast_binstore_delete);
mem_d(self);
}
-ast_unary* ast_unary_new(lex_ctx ctx, int op,
+ast_unary* ast_unary_new(lex_ctx_t ctx, int op,
ast_expression *expr)
{
ast_instantiate(ast_unary, ctx, ast_unary_delete);
if (op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) {
self->expression.vtype = TYPE_FLOAT;
} else
- compile_error(ctx, "cannot determine type of unary operation %s", asm_instr[op].m);
+ compile_error(ctx, "cannot determine type of unary operation %s", util_instr_str[op]);
return self;
}
mem_d(self);
}
-ast_return* ast_return_new(lex_ctx ctx, ast_expression *expr)
+ast_return* ast_return_new(lex_ctx_t ctx, ast_expression *expr)
{
ast_instantiate(ast_return, ctx, ast_return_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_return_codegen);
mem_d(self);
}
-ast_entfield* ast_entfield_new(lex_ctx ctx, ast_expression *entity, ast_expression *field)
+ast_entfield* ast_entfield_new(lex_ctx_t ctx, ast_expression *entity, ast_expression *field)
{
if (field->vtype != TYPE_FIELD) {
compile_error(ctx, "ast_entfield_new with expression not of type field");
return ast_entfield_new_force(ctx, entity, field, field->next);
}
-ast_entfield* ast_entfield_new_force(lex_ctx ctx, ast_expression *entity, ast_expression *field, const ast_expression *outtype)
+ast_entfield* ast_entfield_new_force(lex_ctx_t ctx, ast_expression *entity, ast_expression *field, const ast_expression *outtype)
{
ast_instantiate(ast_entfield, ctx, ast_entfield_delete);
mem_d(self);
}
-ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field, const char *name)
+ast_member* ast_member_new(lex_ctx_t ctx, ast_expression *owner, unsigned int field, const char *name)
{
ast_instantiate(ast_member, ctx, ast_member_delete);
if (field >= 3) {
return !!self->name;
}
-ast_array_index* ast_array_index_new(lex_ctx ctx, ast_expression *array, ast_expression *index)
+ast_array_index* ast_array_index_new(lex_ctx_t ctx, ast_expression *array, ast_expression *index)
{
ast_expression *outtype;
ast_instantiate(ast_array_index, ctx, ast_array_index_delete);
mem_d(self);
}
-ast_argpipe* ast_argpipe_new(lex_ctx ctx, ast_expression *index)
+ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index)
{
ast_instantiate(ast_argpipe, ctx, ast_argpipe_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_argpipe_codegen);
mem_d(self);
}
-ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
+ast_ifthen* ast_ifthen_new(lex_ctx_t ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
{
ast_instantiate(ast_ifthen, ctx, ast_ifthen_delete);
if (!ontrue && !onfalse) {
mem_d(self);
}
-ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
+ast_ternary* ast_ternary_new(lex_ctx_t ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
{
ast_expression *exprtype = ontrue;
ast_instantiate(ast_ternary, ctx, ast_ternary_delete);
mem_d(self);
}
-ast_loop* ast_loop_new(lex_ctx ctx,
+ast_loop* ast_loop_new(lex_ctx_t ctx,
ast_expression *initexpr,
ast_expression *precond, bool pre_not,
ast_expression *postcond, bool post_not,
mem_d(self);
}
-ast_breakcont* ast_breakcont_new(lex_ctx ctx, bool iscont, unsigned int levels)
+ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels)
{
ast_instantiate(ast_breakcont, ctx, ast_breakcont_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_breakcont_codegen);
mem_d(self);
}
-ast_switch* ast_switch_new(lex_ctx ctx, ast_expression *op)
+ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op)
{
ast_instantiate(ast_switch, ctx, ast_switch_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_switch_codegen);
mem_d(self);
}
-ast_label* ast_label_new(lex_ctx ctx, const char *name, bool undefined)
+ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined)
{
ast_instantiate(ast_label, ctx, ast_label_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_label_codegen);
vec_push(self->gotos, g);
}
-ast_goto* ast_goto_new(lex_ctx ctx, const char *name)
+ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name)
{
ast_instantiate(ast_goto, ctx, ast_goto_delete);
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_goto_codegen);
self->target = label;
}
-ast_call* ast_call_new(lex_ctx ctx,
+ast_call* ast_call_new(lex_ctx_t ctx,
ast_expression *funcexpr)
{
ast_instantiate(ast_call, ctx, ast_call_delete);
return retval;
}
-ast_store* ast_store_new(lex_ctx ctx, int op,
+ast_store* ast_store_new(lex_ctx_t ctx, int op,
ast_expression *dest, ast_expression *source)
{
ast_instantiate(ast_store, ctx, ast_store_delete);
mem_d(self);
}
-ast_block* ast_block_new(lex_ctx ctx)
+ast_block* ast_block_new(lex_ctx_t ctx)
{
ast_instantiate(ast_block, ctx, ast_block_delete);
ast_expression_init((ast_expression*)self,
ast_type_adopt(self, from);
}
-ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
+ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype)
{
ast_instantiate(ast_function, ctx, ast_function_delete);
self->return_value = NULL;
return self;
-
+
cleanup:
mem_d(self);
return NULL;
/* update the block which will get the jump - because short-logic or ternaries may have changed this */
cond = func->curblock;
+ /* eliminate branches if value is constant */
+ if (condval->vtype == TYPE_FLOAT && condval->hasvalue && condval->cvq == CV_CONST) {
+ /* don't generate if statements */
+ if (condval->constval.vfloat == 1.0f && self->on_true) {
+ if (!(ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "ontrue"))))
+ return false;
+ /* generate */
+ if (!(*(cgen = self->on_true->codegen))((ast_expression*)(self->on_true), func, false, &dummy))
+ return false;
+ if (!ir_block_create_jump(func->curblock, ast_ctx(self), ontrue))
+ return false;
+ func->curblock = ontrue;
+ return true;
+ } else if (condval->constval.vfloat == 0.0f && self->on_false) {
+ if (!(onfalse = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "onfalse"))))
+ return false;
+ /* generate */
+ if (!(*(cgen = self->on_false->codegen))((ast_expression*)(self->on_false), func, false, &dummy))
+ return false;
+ if (!ir_block_create_jump(func->curblock, ast_ctx(self), onfalse))
+ return false;
+ func->curblock = onfalse;
+ return true;
+ }
+ }
/* on-true path */
if (self->on_true) {
/* Now all blocks are in place */
/* From 'bin' we jump to whatever comes first */
if (bprecond) tmpblock = bprecond;
- else if (bbody) tmpblock = bbody;
+ else tmpblock = bbody; /* can never be null */
+
+ /* DEAD CODE
else if (bpostcond) tmpblock = bpostcond;
else tmpblock = bout;
+ */
+
if (!ir_block_create_jump(bin, ast_ctx(self), tmpblock))
return false;
ir_block *ontrue, *onfalse;
ontrue = bbody; /* can never be null */
- /* all of this is dead code
+ /* all of this is dead code
else if (bincrement) ontrue = bincrement;
else ontrue = bpostcond;
*/
if (bprecond) ontrue = bprecond;
else ontrue = bbody; /* can never be null */
- /* all of this is dead code
+ /* all of this is dead code
else if (bincrement) ontrue = bincrement;
else ontrue = bpostcond;
*/