From ad54d804fef1e1eb646d8ea4bd7ce65363e94fa8 Mon Sep 17 00:00:00 2001
From: dec05eba <dec05eba@protonmail.com>
Date: Wed, 13 Mar 2019 00:22:31 +0100
Subject: Fix bugs

Fix hash map bug on rorder (invalid size).
Fix string to int/float conversion in tokenizer.
Add more ssa functions
---
 src/ssa/ssa.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 133 insertions(+), 11 deletions(-)

(limited to 'src/ssa')

diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c
index f5187af..1b5ed3d 100644
--- a/src/ssa/ssa.c
+++ b/src/ssa/ssa.c
@@ -4,12 +4,21 @@
 #include "../../include/ast.h"
 #include <assert.h>
 
+#define throw(result) do { longjmp(context->env, (result)); } while(0)
+#define throw_if_error(result) \
+do { \
+    int return_if_result; \
+    return_if_result = (result); \
+    if((return_if_result) != 0) \
+        throw(return_if_result); \
+} while(0)
+
 static int compare_number(const void *a, const void *b) {
     const SsaNumber *lhs;
     const SsaNumber *rhs;
     lhs = a;
     rhs = b;
-    if(rhs->type == lhs->type && rhs->value == lhs->value)
+    if(rhs->type == lhs->type && rhs->value.integer == lhs->value.integer)
         return 0;
     return 1;
 }
@@ -18,13 +27,20 @@ static usize hash_number(const u8 *data, usize size) {
     SsaNumber number;
     assert(size == sizeof(SsaNumber));
     am_memcpy(&number, data, size);
-    return number.value;
+    return number.value.integer;
+}
+
+SsaNumber create_ssa_integer(i64 value) {
+    SsaNumber result;
+    result.value.integer = value;
+    result.type = SSA_NUMBER_TYPE_INTEGER;
+    return result;
 }
 
-SsaNumber create_ssa_number(i64 value, SsaNumberType type) {
+SsaNumber create_ssa_float(f64 value) {
     SsaNumber result;
-    result.value = value;
-    result.type = type;
+    result.value.floating = value;
+    result.type = SSA_NUMBER_TYPE_FLOAT;
     return result;
 }
 
@@ -45,13 +61,11 @@ int ssa_get_unique_reg(Ssa *self, SsaRegister *result) {
     return 0;
 }
 
-static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, i64 intermediate, SsaNumberType number_type, SsaIntermediateIndex *result_index) {
-    SsaNumber number;
+static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, SsaIntermediateIndex *result_index) {
     bool exists;
     BufferView key;
 
     assert(result_index);
-    number = create_ssa_number(intermediate, number_type);
     key = create_buffer_view((const char*)&number, sizeof(number));
 
     exists = hash_map_get(&self->intermediates, key, result_index);
@@ -64,6 +78,16 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, i64 intermediate, Ss
     
     *result_index = self->intermediate_counter;
     ++self->intermediate_counter;
+    switch(number.type) {
+        case SSA_NUMBER_TYPE_INTEGER: {
+            amal_log_debug("i%u = %lld", *result_index, number.value.integer);
+            break;
+        }
+        case SSA_NUMBER_TYPE_FLOAT: {
+            amal_log_debug("i%u = %f", *result_index, number.value.floating);
+            break;
+        }
+    }
     return hash_map_insert(&self->intermediates, key, result_index);
 }
 
@@ -99,7 +123,7 @@ static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstructionType ins_type
 
 int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number) {
     SsaIntermediateIndex index;
-    return_if_error(ssa_try_add_intermediate(self, number.value, number.type, &index));
+    return_if_error(ssa_try_add_intermediate(self, number, &index));
     amal_log_debug("r%u = i%u", dest, index);
     return ssa_add_ins_form1(self, SSA_ASSIGN_INTER, dest, index);
 }
@@ -165,10 +189,108 @@ int ssa_ins_call(Ssa *self, SsaFuncIndex func, SsaRegister *result) {
     return 0;
 }
 
-static void ast_generate_ssa(Ast *self, SsaCompilerContext *context) {
+static CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context);
+
+static CHECK_RESULT SsaRegister number_generate_ssa(Number *self, SsaCompilerContext *context) {
+    SsaRegister reg;
+    SsaNumber number;
+    if(self->is_integer) {
+        number = create_ssa_integer(self->value.integer);
+        throw_if_error(ssa_get_unique_reg(&context->ssa, &reg));
+        throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number));
+    } else {
+        number = create_ssa_float(self->value.floating);
+        throw_if_error(ssa_get_unique_reg(&context->ssa, &reg));
+        throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number));
+    }
+    return reg;
+}
+
+static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCompilerContext *context) {
+    /* TODO: Implement */
+    scope_generate_ssa(&self->body, context);
+    return 0;
+}
+
+static CHECK_RESULT SsaRegister funccall_generate_ssa(FunctionCall *self, SsaCompilerContext *context) {
+    /* TODO: Implement */
+    (void)self;
+    (void)context;
+    return 0;
+}
+
+static CHECK_RESULT SsaRegister lhs_generate_ssa(LhsExpr *self, SsaCompilerContext *context) {
+    /* TODO: Implement */
+    SsaRegister rhs_reg;
+    amal_log_debug("lhs_generate_ssa");
+    rhs_reg = ast_generate_ssa(&self->rhs_expr, context);
+    return rhs_reg;
+}
+
+static CHECK_RESULT SsaRegister string_generate_ssa(String *self, SsaCompilerContext *context) {
     /* TODO: Implement */
     (void)self;
     (void)context;
+    return 0;
+}
+
+static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompilerContext *context) {
+    /* TODO: Implement */
+    (void)self;
+    (void)context;
+    return 0;
+}
+
+static SsaInstructionType binop_type_to_ssa_type(BinopType binop_type) {
+    switch(binop_type) {
+        case BINOP_ADD:
+            return SSA_ADD;
+        case BINOP_SUB:
+            return SSA_SUB;
+        case BINOP_MUL:
+            return SSA_MUL;
+        case BINOP_DIV:
+            return SSA_DIV;
+        case BINOP_DOT:
+            assert(bool_false && "TODO: Implement dot access");
+            return 0;
+    }
+    return 0;
+}
+
+static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerContext *context) {
+    SsaRegister lhs_reg;
+    SsaRegister rhs_reg;
+    SsaRegister reg;
+    lhs_reg = ast_generate_ssa(&self->lhs, context);
+    rhs_reg = ast_generate_ssa(&self->rhs, context);
+    throw_if_error(ssa_ins_binop(&context->ssa, binop_type_to_ssa_type(self->type), lhs_reg, rhs_reg, &reg));
+    return reg;
+}
+
+CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context) {
+    switch(self->type) {
+        case AST_NONE:
+            return 0;
+        case AST_NUMBER:
+            return number_generate_ssa(self->value.number, context);
+        case AST_FUNCTION_DECL:
+            return funcdecl_generate_ssa(self->value.func_decl, context);
+        case AST_FUNCTION_CALL:
+            return funccall_generate_ssa(self->value.func_call, context);
+        case AST_LHS:
+            return lhs_generate_ssa(self->value.lhs_expr, context);
+        case AST_IMPORT:
+            /* TODO: When @import(...).data syntax is added, implement the generate ssa for it */
+            return 0;
+        case AST_STRING:
+            return string_generate_ssa(self->value.string, context);
+        case AST_VARIABLE:
+            return variable_generate_ssa(self->value.variable, context);
+        case AST_BINOP:
+            return binop_generate_ssa(self->value.binop, context);
+    }
+    return 0;
 }
 
 void scope_generate_ssa(Scope *self, SsaCompilerContext *context) {
@@ -177,6 +299,6 @@ void scope_generate_ssa(Scope *self, SsaCompilerContext *context) {
     ast = buffer_start(&self->ast_objects);
     ast_end = buffer_end(&self->ast_objects);
     for(; ast != ast_end; ++ast) {
-        ast_generate_ssa(ast, context);
+        ignore_result_int(ast_generate_ssa(ast, context));
     }
 }
-- 
cgit v1.2.3-70-g09d2