mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-30 19:08:12 +03:00
jaf: support assignment expressions
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user