aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh8
-rw-r--r--include/ast.h2
-rw-r--r--include/ssa/ssa.h7
-rw-r--r--src/ast.c4
-rw-r--r--src/compiler.c3
-rw-r--r--src/parser.c13
-rw-r--r--src/ssa/ssa.c58
7 files changed, 75 insertions, 20 deletions
diff --git a/build.sh b/build.sh
index 5ca2ea6..5cdade0 100755
--- a/build.sh
+++ b/build.sh
@@ -20,11 +20,15 @@ fi
CFLAGS+="-Wall -Wextra -Werror -g -O0 -DDEBUG -std=c89 -pedantic -D_GNU_SOURCE"
LIBS+="-pthread"
+BUILD_ARGS="$source_files $CFLAGS $LIBS -shared -fpic -o libamalgam.so"
set -x
-time "$CC" $source_files $CFLAGS $LIBS -shared -fpic -o libamalgam.so
+time "$CC" $BUILD_ARGS
+if [ ! -z "$SCAN_BUILD" ]; then
+ scan-build "$CC" $BUILD_ARGS
+fi
set +x
if [ -z "$NO_TEST" ]; then
source_files_tests=$(readlink -f $(find "$this_script_dir/tests" -name "*.c"))
set -x
time "$CC" $source_files_tests $CFLAGS $LIBS -o test "$this_script_dir/libamalgam.so"
-fi \ No newline at end of file
+fi
diff --git a/include/ast.h b/include/ast.h
index b63dab5..ae9b6b3 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -8,6 +8,7 @@
#include "std/scoped_allocator.h"
#include "std/hash_map.h"
#include "binop_type.h"
+#include "ssa/ssa.h"
#include <setjmp.h>
@@ -67,6 +68,7 @@ struct Scope {
struct FunctionDecl {
Scope body;
+ SsaFuncIndex ssa_func_index;
};
struct FunctionCall {
diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h
index 5411259..c374ffb 100644
--- a/include/ssa/ssa.h
+++ b/include/ssa/ssa.h
@@ -10,6 +10,7 @@
typedef enum {
SSA_ASSIGN_INTER,
+ SSA_ASSIGN_STRING,
SSA_ASSIGN_REG,
SSA_ADD,
SSA_SUB,
@@ -36,12 +37,15 @@ typedef struct {
typedef u16 SsaRegister;
typedef u16 SsaIntermediateIndex;
+typedef u16 SsaStringIndex;
typedef u32 SsaFuncIndex;
typedef struct {
Buffer/*instruction data*/ instructions;
- HashMap/*<SsaNumberType, IntermediateIndex>*/ intermediates;
+ HashMap/*<SsaNumberType, SsaIntermediateIndex>*/ intermediates;
+ HashMap/*<BufferView, SsaStringIndex>*/ strings;
SsaIntermediateIndex intermediate_counter;
+ SsaStringIndex string_counter;
SsaRegister reg_counter;
SsaFuncIndex func_counter;
} Ssa;
@@ -53,6 +57,7 @@ SsaNumber create_ssa_float(f64 value);
CHECK_RESULT int ssa_init(Ssa *self, ScopedAllocator *allocator);
CHECK_RESULT int ssa_get_unique_reg(Ssa *self, SsaRegister *result);
CHECK_RESULT int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number);
+CHECK_RESULT int ssa_ins_assign_string(Ssa *self, SsaRegister dest, BufferView str);
CHECK_RESULT int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegister src);
CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstructionType binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result);
CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result);
diff --git a/src/ast.c b/src/ast.c
index 079d45a..cfc1369 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -54,6 +54,7 @@ BufferView ast_get_name(Ast *self) {
}
int funcdecl_init(FunctionDecl *self, ScopedAllocator *allocator) {
+ self->ssa_func_index = 0;
return scope_init(&self->body, allocator);
}
@@ -223,5 +224,6 @@ void ast_resolve(Ast *self, AstCompilerContext *context) {
binop_resolve(self->value.binop, context);
break;
}
- /*self->resolve_status = AST_RESOLVED;*/
+ /* TODO: See comment at the top of this function */
+ self->resolve_status = AST_RESOLVED;
}
diff --git a/src/compiler.c b/src/compiler.c
index 08d0225..4e097ce 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -54,8 +54,7 @@ int amal_compiler_init(amal_compiler *self) {
return AMAL_COMPILER_OK;
cleanup:
- /* Ignore result */
- result = amal_compiler_deinit(self);
+ ignore_result_int(amal_compiler_deinit(self));
return AMAL_COMPILER_ERR;
}
diff --git a/src/parser.c b/src/parser.c
index f531705..1e51af4 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -115,11 +115,12 @@ static THROWABLE parser_parse_var_type_def(Parser *self, BufferView *type_name)
LHS = ('const' TOK_IDENTIFIER VAR_TYPE_DEF? '=') |
('var' TOK_IDENTIFIER VAR_TYPE_DEF? '='|';')
*/
-static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignment) {
+static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignment_or_rhs) {
bool is_const;
bool match;
BufferView var_name;
*result = NULL;
+ *assignment_or_rhs = bool_true;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_CONST, &is_const));
if(!is_const) {
@@ -138,11 +139,11 @@ static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignme
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_EQUALS, &match));
if(match) {
- *assignment = bool_true;
+ *assignment_or_rhs = bool_true;
return PARSER_OK;
}
- *assignment = bool_false;
+ *assignment_or_rhs = bool_false;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_SEMICOLON, &match));
if(match && is_const) {
self->error = tokenizer_create_error(&self->tokenizer,
@@ -426,13 +427,13 @@ BODY = LHS ';' |
(RHS_START BODY_SEMICOLON)
*/
int parser_parse_body(Parser *self, Ast *ast) {
- bool assignment;
+ bool assignment_or_rhs;
LhsExpr *lhs_expr;
Ast rhs_expr;
rhs_expr = ast_none();
- try(parser_parse_lhs(self, &lhs_expr, &assignment));
- if(!assignment) {
+ try(parser_parse_lhs(self, &lhs_expr, &assignment_or_rhs));
+ if(!assignment_or_rhs) {
ast_init(ast, lhs_expr, AST_LHS);
return PARSER_OK;
}
diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c
index 1b5ed3d..b8aa8b0 100644
--- a/src/ssa/ssa.c
+++ b/src/ssa/ssa.c
@@ -1,6 +1,7 @@
#include "../../include/ssa/ssa.h"
#include "../../include/std/mem.h"
#include "../../include/std/log.h"
+#include "../../include/std/hash.h"
#include "../../include/ast.h"
#include <assert.h>
@@ -47,7 +48,9 @@ SsaNumber create_ssa_float(f64 value) {
int ssa_init(Ssa *self, ScopedAllocator *allocator) {
return_if_error(buffer_init(&self->instructions, allocator));
return_if_error(hash_map_init(&self->intermediates, allocator, sizeof(SsaIntermediateIndex), compare_number, hash_number));
+ return_if_error(hash_map_init(&self->strings, allocator, sizeof(SsaStringIndex), hash_compare_string, amal_hash_string));
self->intermediate_counter = 0;
+ self->string_counter = 0;
self->reg_counter = 0;
self->func_counter = 0;
return 0;
@@ -91,6 +94,24 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, Ss
return hash_map_insert(&self->intermediates, key, result_index);
}
+static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringIndex *result_index) {
+ bool exists;
+ assert(result_index);
+
+ exists = hash_map_get(&self->strings, str, result_index);
+ if(exists)
+ return 0;
+
+ /* Overflow */
+ if(self->string_counter + 1 < self->string_counter)
+ return -1;
+
+ *result_index = self->string_counter;
+ ++self->string_counter;
+ amal_log_debug("s%u = \"%.*s\"", *result_index, str.size, str.data);
+ return hash_map_insert(&self->strings, str, result_index);
+}
+
static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstructionType ins_type, SsaRegister lhs, u16 rhs) {
usize index;
index = self->instructions.size;
@@ -128,6 +149,13 @@ int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number) {
return ssa_add_ins_form1(self, SSA_ASSIGN_INTER, dest, index);
}
+int ssa_ins_assign_string(Ssa *self, SsaRegister dest, BufferView str) {
+ SsaStringIndex index;
+ return_if_error(ssa_try_add_string(self, str, &index));
+ amal_log_debug("r%u = s%u", dest, index);
+ return ssa_add_ins_form1(self, SSA_ASSIGN_STRING, dest, index);
+}
+
int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegister src) {
amal_log_debug("r%u = r%u", dest, src);
return ssa_add_ins_form1(self, SSA_ASSIGN_INTER, dest, src);
@@ -208,30 +236,43 @@ static CHECK_RESULT SsaRegister number_generate_ssa(Number *self, SsaCompilerCon
static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCompilerContext *context) {
/* TODO: Implement */
+ throw_if_error(ssa_ins_func_start(&context->ssa, 0, &self->ssa_func_index));
scope_generate_ssa(&self->body, context);
+ throw_if_error(ssa_ins_func_end(&context->ssa));
return 0;
}
static CHECK_RESULT SsaRegister funccall_generate_ssa(FunctionCall *self, SsaCompilerContext *context) {
/* TODO: Implement */
- (void)self;
- (void)context;
- return 0;
+ Ast *ast;
+ Ast *ast_end;
+ SsaRegister reg;
+
+ ast = buffer_start(&self->args);
+ ast_end = buffer_end(&self->args);
+ for(; ast != ast_end; ++ast) {
+ SsaRegister arg_reg;
+ arg_reg = ast_generate_ssa(ast, context);
+ throw_if_error(ssa_ins_push(&context->ssa, arg_reg));
+ }
+ /* TODO: Use real func index */
+ throw_if_error(ssa_ins_call(&context->ssa, 0, &reg));
+ return reg;
}
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);
+ /* TODO: Is this correct? */
return rhs_reg;
}
static CHECK_RESULT SsaRegister string_generate_ssa(String *self, SsaCompilerContext *context) {
- /* TODO: Implement */
- (void)self;
- (void)context;
- return 0;
+ SsaRegister reg;
+ throw_if_error(ssa_get_unique_reg(&context->ssa, &reg));
+ throw_if_error(ssa_ins_assign_string(&context->ssa, reg, self->str));
+ return reg;
}
static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompilerContext *context) {
@@ -269,6 +310,7 @@ static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerConte
}
CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context) {
+ assert(self->resolve_status == AST_RESOLVED);
switch(self->type) {
case AST_NONE:
return 0;