From 6ddc900b4ee62461eaba52aec09c6b2a256f8c45 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Thu, 13 Jun 2024 23:30:57 +0200 Subject: [PATCH] Implement opcodes for *= and friends --- Sources/backends/cstyle.c | 22 ++++++++- Sources/compiler.c | 94 +++++++++++++++++++-------------------- Sources/compiler.h | 4 ++ 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/Sources/backends/cstyle.c b/Sources/backends/cstyle.c index e42383e..5902358 100644 --- a/Sources/backends/cstyle.c +++ b/Sources/backends/cstyle.c @@ -29,6 +29,10 @@ void cstyle_write_opcode(char *code, size_t *offset, opcode *o, type_string_func *offset += sprintf(&code[*offset], "\t_%" PRIu64 " = _%" PRIu64 ";\n", o->op_store_var.to.index, o->op_store_var.from.index); break; case OPCODE_STORE_MEMBER: + case OPCODE_SUB_AND_STORE_MEMBER: + case OPCODE_ADD_AND_STORE_MEMBER: + case OPCODE_DIVIDE_AND_STORE_MEMBER: + case OPCODE_MULTIPLY_AND_STORE_MEMBER: *offset += sprintf(&code[*offset], "\t_%" PRIu64, o->op_store_member.to.index); type *s = get_type(o->op_store_member.member_parent_type); bool is_array = o->op_store_member.member_parent_array; @@ -45,7 +49,23 @@ void cstyle_write_opcode(char *code, size_t *offset, opcode *o, type_string_func s = get_type(s->members.m[o->op_store_member.member_indices[i]].type.type); } } - *offset += sprintf(&code[*offset], " = _%" PRIu64 ";\n", o->op_store_member.from.index); + switch (o->type) { + case OPCODE_STORE_MEMBER: + *offset += sprintf(&code[*offset], " = _%" PRIu64 ";\n", o->op_store_member.from.index); + break; + case OPCODE_SUB_AND_STORE_MEMBER: + *offset += sprintf(&code[*offset], " -= _%" PRIu64 ";\n", o->op_store_member.from.index); + break; + case OPCODE_ADD_AND_STORE_MEMBER: + *offset += sprintf(&code[*offset], " += _%" PRIu64 ";\n", o->op_store_member.from.index); + break; + case OPCODE_DIVIDE_AND_STORE_MEMBER: + *offset += sprintf(&code[*offset], " /= _%" PRIu64 ";\n", o->op_store_member.from.index); + break; + case OPCODE_MULTIPLY_AND_STORE_MEMBER: + *offset += sprintf(&code[*offset], " *= _%" PRIu64 ";\n", o->op_store_member.from.index); + break; + } break; case OPCODE_LOAD_CONSTANT: *offset += sprintf(&code[*offset], "\t%s _%" PRIu64 " = %f;\n", type_string(o->op_load_constant.to.type.type), o->op_load_constant.to.index, diff --git a/Sources/compiler.c b/Sources/compiler.c index e033a70..2b86ca6 100644 --- a/Sources/compiler.c +++ b/Sources/compiler.c @@ -94,13 +94,29 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { error(context, "not implemented"); case OPERATOR_LESS_EQUAL: error(context, "not implemented"); - case OPERATOR_MINUS: { + case OPERATOR_MINUS: + case OPERATOR_PLUS: + case OPERATOR_DIVIDE: + case OPERATOR_MULTIPLY: { variable right_var = emit_expression(code, parent, right); variable left_var = emit_expression(code, parent, left); variable result_var = allocate_variable(right_var.type); opcode o; - o.type = OPCODE_SUB; + switch (e->kind) { + case OPERATOR_MINUS: + o.type = OPCODE_SUB; + break; + case OPERATOR_PLUS: + o.type = OPCODE_ADD; + break; + case OPERATOR_DIVIDE: + o.type = OPCODE_DIVIDE; + break; + case OPERATOR_MULTIPLY: + o.type = OPCODE_MULTIPLY; + break; + } o.size = OP_SIZE(o, op_add); o.op_sub.right = right_var; o.op_sub.left = left_var; @@ -109,51 +125,6 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { return result_var; } - case OPERATOR_PLUS: { - variable right_var = emit_expression(code, parent, right); - variable left_var = emit_expression(code, parent, left); - variable result_var = allocate_variable(right_var.type); - - opcode o; - o.type = OPCODE_ADD; - o.size = OP_SIZE(o, op_add); - o.op_add.right = right_var; - o.op_add.left = left_var; - o.op_add.result = result_var; - emit_op(code, &o); - - return result_var; - } - case OPERATOR_DIVIDE: { - variable right_var = emit_expression(code, parent, right); - variable left_var = emit_expression(code, parent, left); - variable result_var = allocate_variable(right_var.type); - - opcode o; - o.type = OPCODE_DIVIDE; - o.size = OP_SIZE(o, op_multiply); - o.op_divide.right = right_var; - o.op_divide.left = left_var; - o.op_divide.result = result_var; - emit_op(code, &o); - - return result_var; - } - case OPERATOR_MULTIPLY: { - variable right_var = emit_expression(code, parent, right); - variable left_var = emit_expression(code, parent, left); - variable result_var = allocate_variable(right_var.type); - - opcode o; - o.type = OPCODE_MULTIPLY; - o.size = OP_SIZE(o, op_multiply); - o.op_multiply.right = right_var; - o.op_multiply.left = left_var; - o.op_multiply.result = result_var; - emit_op(code, &o); - - return result_var; - } case OPERATOR_NOT: { debug_context context = {0}; error(context, "not implemented"); @@ -170,11 +141,20 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { debug_context context = {0}; error(context, "not implemented"); } - case OPERATOR_ASSIGN: { + case OPERATOR_ASSIGN: + case OPERATOR_MINUS_ASSIGN: + case OPERATOR_PLUS_ASSIGN: + case OPERATOR_DIVIDE_ASSIGN: + case OPERATOR_MULTIPLY_ASSIGN: + { variable v = emit_expression(code, parent, right); switch (left->kind) { case EXPRESSION_VARIABLE: { + if (e->kind != OPERATOR_ASSIGN) { + debug_context context = {0}; + error(context, "operator can not initialize a variable"); + } opcode o; o.type = OPCODE_STORE_VARIABLE; o.size = OP_SIZE(o, op_store_var); @@ -187,7 +167,23 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { variable member_var = emit_expression(code, parent, left->member.left); opcode o; - o.type = OPCODE_STORE_MEMBER; + switch (e->kind) { + case OPERATOR_ASSIGN: + o.type = OPCODE_STORE_MEMBER; + break; + case OPERATOR_MINUS_ASSIGN: + o.type = OPCODE_SUB_AND_STORE_MEMBER; + break; + case OPERATOR_PLUS_ASSIGN: + o.type = OPCODE_ADD_AND_STORE_MEMBER; + break; + case OPERATOR_DIVIDE_ASSIGN: + o.type = OPCODE_DIVIDE_AND_STORE_MEMBER; + break; + case OPERATOR_MULTIPLY_ASSIGN: + o.type = OPCODE_MULTIPLY_AND_STORE_MEMBER; + break; + } o.size = OP_SIZE(o, op_store_member); o.op_store_member.from = v; o.op_store_member.to = member_var; diff --git a/Sources/compiler.h b/Sources/compiler.h index 551ec9e..ee0fc47 100644 --- a/Sources/compiler.h +++ b/Sources/compiler.h @@ -17,6 +17,10 @@ typedef struct opcode { OPCODE_NOT, OPCODE_STORE_VARIABLE, OPCODE_STORE_MEMBER, + OPCODE_SUB_AND_STORE_MEMBER, + OPCODE_ADD_AND_STORE_MEMBER, + OPCODE_DIVIDE_AND_STORE_MEMBER, + OPCODE_MULTIPLY_AND_STORE_MEMBER, OPCODE_LOAD_CONSTANT, OPCODE_LOAD_MEMBER, OPCODE_RETURN,