aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ast.h1
-rw-r--r--include/bytecode/bytecode.h33
-rw-r--r--include/defs.h1
-rw-r--r--include/parser.h2
-rw-r--r--include/ssa/ssa.h36
-rw-r--r--include/std/buffer.h10
6 files changed, 73 insertions, 10 deletions
diff --git a/include/ast.h b/include/ast.h
index d37fcb3..c010538 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -17,7 +17,6 @@
#define AST_ERR -1
#define AST_ERR_DEF_DUP -20
-typedef struct FunctionDecl FunctionDecl;
typedef struct FunctionCall FunctionCall;
typedef struct StructDecl StructDecl;
typedef struct StructField StructField;
diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h
new file mode 100644
index 0000000..3a141f0
--- /dev/null
+++ b/include/bytecode/bytecode.h
@@ -0,0 +1,33 @@
+#ifndef AMALGAM_BYTECODE_H
+#define AMALGAM_BYTECODE_H
+
+#include "../std/defs.h"
+#include "../std/misc.h"
+#include "../std/buffer.h"
+#include "../defs.h"
+
+#include <setjmp.h>
+
+typedef enum {
+ NOP, /* To allow hot-patching */
+
+} BytecodeInstruction;
+
+typedef u8 BytecodeInstructionType;
+
+typedef struct {
+ Buffer/*<instruction data>*/ instructions;
+} Bytecode;
+
+typedef struct {
+ jmp_buf env;
+ Bytecode *bytecode;
+ Parser *parser; /* borrowed */
+} BytecodeCompilerContext;
+
+CHECK_RESULT int bytecode_init(Bytecode *self, ScopedAllocator *allocator);
+
+/* longjump to self->env on failure */
+void generate_bytecode_from_ssa(BytecodeCompilerContext *self);
+
+#endif
diff --git a/include/defs.h b/include/defs.h
index 76e5e0d..d7f6692 100644
--- a/include/defs.h
+++ b/include/defs.h
@@ -6,5 +6,6 @@ typedef struct amal_compiler amal_compiler;
typedef struct Parser Parser;
typedef struct Scope Scope;
typedef struct FileScopeReference FileScopeReference;
+typedef struct FunctionDecl FunctionDecl;
#endif
diff --git a/include/parser.h b/include/parser.h
index 8a339ff..491815f 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -41,7 +41,7 @@ struct Parser {
bool has_func_parent;
ScopedAllocator *allocator; /* borrowed. Copied from @compiler for faster access to allocator */
amal_compiler *compiler;
- SsaCompilerContext *ssa_context;
+ Ssa *ssa;
bool started;
TokenizerError error;
ErrorContext error_context;
diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h
index 16ceb25..32d1ba6 100644
--- a/include/ssa/ssa.h
+++ b/include/ssa/ssa.h
@@ -20,7 +20,7 @@ typedef enum {
SSA_FUNC_END,
SSA_PUSH,
SSA_CALL
-} SsaInstructionType;
+} SsaInstruction;
typedef enum {
SSA_NUMBER_TYPE_INTEGER,
@@ -42,7 +42,8 @@ typedef usize SsaFuncIndex;
typedef struct {
Buffer/*instruction data*/ instructions;
- HashMap/*<SsaNumberType, SsaIntermediateIndex>*/ intermediates;
+ HashMap/*<SsaNumber, SsaIntermediateIndex>*/ intermediates_map;
+ Buffer/*SsaNumber*/ intermediates;
HashMap/*<BufferView, SsaStringIndex>*/ strings;
SsaIntermediateIndex intermediate_counter;
SsaStringIndex string_counter;
@@ -50,28 +51,51 @@ typedef struct {
SsaFuncIndex func_counter;
} Ssa;
+typedef struct {
+ SsaRegister lhs;
+ u16 rhs;
+} SsaInsForm1;
+
+typedef struct {
+ SsaRegister result;
+ SsaRegister lhs;
+ SsaRegister rhs;
+} SsaInsForm2;
+
+typedef struct {
+ SsaFuncIndex func_index;
+ u8 num_args;
+} SsaInsFuncStart;
+
+typedef struct {
+ SsaRegister result;
+ FunctionDecl *func_decl;
+} SsaInsFuncCall;
+
/* None of these functions are thread-safe */
SsaNumber create_ssa_integer(i64 value);
SsaNumber create_ssa_float(f64 value);
+SsaNumber ssa_get_intermediate(Ssa *self, SsaIntermediateIndex index);
+
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_binop(Ssa *self, SsaInstruction binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result);
CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result);
CHECK_RESULT int ssa_ins_func_end(Ssa *self);
CHECK_RESULT int ssa_ins_push(Ssa *self, SsaRegister reg);
-CHECK_RESULT int ssa_ins_call(Ssa *self, void *func, SsaRegister *result);
+CHECK_RESULT int ssa_ins_call(Ssa *self, FunctionDecl *func_decl, SsaRegister *result);
typedef struct {
jmp_buf env;
- Ssa ssa;
+ Ssa *ssa;
} SsaCompilerContext;
-/* longjump to compiler env on failure */
+/* longjump to context->env on failure */
void scope_generate_ssa(Scope *self, SsaCompilerContext *context);
#endif
diff --git a/include/std/buffer.h b/include/std/buffer.h
index 723ef6c..aa82bcc 100644
--- a/include/std/buffer.h
+++ b/include/std/buffer.h
@@ -16,13 +16,19 @@ typedef struct {
CHECK_RESULT int buffer_init(Buffer *self, struct ScopedAllocator *allocator);
-/* @data can be NULL */
+/*
+@data can't be null. Use @buffer_append_empty if you want to change the size
+of the buffer without adding data
+*/
CHECK_RESULT int buffer_append(Buffer *self, const void *data, usize size);
+CHECK_RESULT int buffer_append_empty(Buffer *self, usize size);
+/* Expand buffer capacity without changing size */
+CHECK_RESULT int buffer_expand(Buffer *self, usize size);
void* buffer_get(Buffer *self, usize index, usize type_size);
CHECK_RESULT int buffer_pop(Buffer *self, void *data, usize size);
/* Set buffer size to 0, doesn't reallocate */
void buffer_clear(Buffer *self);
-void* buffer_start(Buffer *self);
+void* buffer_begin(Buffer *self);
void* buffer_end(Buffer *self);
usize __buffer_get_size(Buffer *self, usize type_size);
#define buffer_get_size(self, type) __buffer_get_size((self), sizeof(type))