jaf: support assignment expressions

This commit is contained in:
Nunuhara Cabbage
2020-06-17 18:45:20 -07:00
parent 2908e6fcdc
commit c283366edd
3 changed files with 52 additions and 7 deletions
+25 -1
View File
@@ -182,6 +182,24 @@ static void compile_unary(struct ain *ain, struct buffer *out, struct jaf_expres
}
}
static void compile_lvalue(possibly_unused struct ain *ain, struct buffer *out, struct jaf_expression *expr)
{
if (expr->type == JAF_EXP_IDENTIFIER) {
if (expr->ident.var_type == AIN_VAR_GLOBAL) {
write_instruction0(out, PUSHGLOBALPAGE);
} else if (expr->ident.var_type == AIN_VAR_LOCAL) {
write_instruction0(out, PUSHLOCALPAGE);
} else {
ERROR("Invalid variable type as lvalue");
}
write_instruction1(out, PUSH, expr->ident.var_no);
} else if (expr->type == JAF_EXP_MEMBER) {
ERROR("struct member lvalues not supported");
} else {
ERROR("Invalid lvalue");
}
}
static void compile_binary(struct ain *ain, struct buffer *out, struct jaf_expression *expr)
{
switch (expr->op) {
@@ -223,7 +241,10 @@ static void compile_binary(struct ain *ain, struct buffer *out, struct jaf_expre
case JAF_XOR_ASSIGN:
case JAF_OR_ASSIGN:
case JAF_REF_ASSIGN:
ERROR("Assignment not supported");
compile_lvalue(ain, out, expr->lhs);
compile_expression(ain, out, expr->rhs);
write_instruction0(out, jaf_op_to_opcode(expr->op, expr->value_type.type));
break;
default:
ERROR("Invalid binary operator");
}
@@ -340,6 +361,7 @@ static void compile_vardecl(struct ain *ain, struct buffer *out, struct jaf_decl
write_instruction1(out, PUSH, 0);
}
write_instruction0(out, ASSIGN);
write_instruction0(out, POP);
break;
case JAF_FLOAT:
write_instruction0(out, PUSHLOCALPAGE);
@@ -349,6 +371,8 @@ static void compile_vardecl(struct ain *ain, struct buffer *out, struct jaf_decl
} else {
write_instruction1(out, F_PUSH, 0);
}
write_instruction0(out, F_ASSIGN);
write_instruction0(out, POP);
break;
case JAF_STRING:
ERROR("strings not supported");
+6 -5
View File
@@ -321,12 +321,13 @@ static void jaf_resolve_types(struct ain *ain, struct jaf_block *block)
}
}
static void init_variable(struct ain *ain, struct ain_variable *var, struct string *name, struct jaf_type_specifier *type)
static void init_variable(struct ain *ain, struct ain_variable *var, struct jaf_declaration *decl, int var_no)
{
var->name = encode_text_to_input_format(name->text);
var->name = encode_text_to_input_format(decl->name->text);
if (ain->version >= 12)
var->name2 = strdup("");
jaf_to_ain_type(ain, &var->type, type);
jaf_to_ain_type(ain, &var->type, decl->type);
decl->var_no = var_no;
}
static struct ain_variable *block_get_vars(struct ain *ain, struct jaf_block *block, struct ain_variable *vars, int *nr_vars);
@@ -338,7 +339,7 @@ static struct ain_variable *block_item_get_vars(struct ain *ain, struct jaf_bloc
if (!item->decl.name)
break;
vars = xrealloc_array(vars, *nr_vars, *nr_vars + 1, sizeof(struct ain_variable));
init_variable(ain, vars + *nr_vars, item->decl.name, item->decl.type);
init_variable(ain, vars + *nr_vars, &item->decl, *nr_vars);
(*nr_vars)++;
break;
case JAF_STMT_LABELED:
@@ -397,7 +398,7 @@ static void function_init_vars(struct ain *ain, struct ain_function *f, struct j
assert(decl->params->items[i]->kind == JAF_DECLARATION);
assert(decl->params->items[i]->decl.name);
struct jaf_declaration *param = &decl->params->items[i]->decl;
init_variable(ain, &f->vars[i], param->name, param->type);
init_variable(ain, &f->vars[i], param, i);
}
f->vars = block_get_vars(ain, decl->body, f->vars, &f->nr_vars);
}
+21 -1
View File
@@ -78,6 +78,21 @@ static enum jaf_type jaf_merge_types(enum jaf_type a, enum jaf_type b)
ERROR("Incompatible types");
}
static void jaf_check_types_lvalue(struct jaf_env *env, struct jaf_expression *e)
{
// TODO: array subscripts
if (e->type != JAF_EXP_IDENTIFIER && e->type != JAF_EXP_MEMBER)
ERROR("Invalid expression as lvalue");
switch (e->value_type.type) {
case JAF_INT:
case JAF_FLOAT:
case JAF_STRING:
break;
default:
ERROR("Invalid type as lvalue");
}
}
static void jaf_check_types_unary(struct jaf_env *env, struct jaf_expression *expr)
{
jaf_derive_types(env, expr->expr);
@@ -105,6 +120,7 @@ static void jaf_check_types_binary(struct jaf_env *env, struct jaf_expression *e
{
jaf_derive_types(env, expr->lhs);
jaf_derive_types(env, expr->rhs);
switch (expr->op) {
// real ops
case JAF_MULTIPLY:
@@ -153,7 +169,11 @@ static void jaf_check_types_binary(struct jaf_env *env, struct jaf_expression *e
case JAF_XOR_ASSIGN:
case JAF_OR_ASSIGN:
case JAF_REF_ASSIGN:
ERROR("Assignment expressions not supported");
jaf_check_types_lvalue(env, expr->lhs);
// FIXME: need to coerce types (?)
jaf_check_type(expr->rhs, &expr->lhs->value_type);
expr->value_type.type = expr->lhs->value_type.type;
break;
default:
ERROR("Unhandled binary operator");
}