aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-08-24 00:48:40 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commit7212ea877ed85d3b85af90c902639df44fc493f2 (patch)
treec76d73e9882a832f82cef977efb6fb26fb0e4984 /include
parentd6f368a3f400fea3e89280262a8147e7ce5d855c (diff)
Add exported variable (only functions for now), export main func, start execution from main func
Diffstat (limited to 'include')
-rw-r--r--include/bytecode/bytecode.h60
-rw-r--r--include/program.h16
-rw-r--r--include/ssa/ssa.h11
-rw-r--r--include/tokenizer.h1
4 files changed, 56 insertions, 32 deletions
diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h
index 1e4c35d..64b54b4 100644
--- a/include/bytecode/bytecode.h
+++ b/include/bytecode/bytecode.h
@@ -25,7 +25,7 @@
6.1 Opcode(u8) + register(i8) + offset(i16)\
6.2 Opcode(u8) + register(i8) + intermediate(u16)\
6.3 Opcode(u8) + register(i8) + data(u16)\
- 6.4 Opcode(u8) + num_param_reg(u8) + num_local_var_reg(u16)
+ 6.4 Opcode(u8) + flags(u8) + num_local_var_reg(u16)
7. 5 bytes: Opcode(u8) + index(u16) + num_args(u8) + register(i8)
# Registers
Registers have a range of 128. Local variables start from register 0 and increment while parameters start from -1
@@ -33,30 +33,42 @@
*/
typedef enum {
AMAL_OP_NOP, /* No operation (do nothing). This can be used for patching code */
- AMAL_OP_SETZ, /* setz reg - Set register value to 0 */
- AMAL_OP_MOV, /* mov dst, src - Move src register to dst register */
- AMAL_OP_MOVI, /* movi dst, src - Move src intermediate to dst register */
- AMAL_OP_MOVD, /* movd dst, src - Move src data to dst register */
- AMAL_OP_ADD, /* add dst, reg1, reg2 - Add reg1 and reg2 and put the result in dst */
- AMAL_OP_SUB, /* sub dst, reg1, reg2 - Substract reg2 from reg1 and put the result in dst */
- AMAL_OP_IMUL, /* imul dst, reg1, reg2 - Signed multiplication */
- AMAL_OP_MUL, /* mul dst, reg1, reg2 - Unsigned multiplication */
- AMAL_OP_IDIV, /* idiv dst, reg1, reg2 - Signed division */
- AMAL_OP_DIV, /* div dst, reg1, reg2 - Unsigned division */
- AMAL_OP_PUSH, /* push reg - Push register onto stack */
- AMAL_OP_PUSHI, /* pushi int - Push intermediate onto stack */
- AMAL_OP_PUSHD, /* pushd data - Push data onto stack */
- AMAL_OP_CALL, /* call fi, num_args, dst - Call a function using function index (fi) and num_args arguments. The result is stored in register dst. fi is u16 and num_args is u8 */
- AMAL_OP_CALLR, /* callr reg, num_args - Call a function using a register. Used for function pointers. num_args is u8 */
- AMAL_OP_CALLE, /* calle efi, num_args, dst - Call an extern function using extern function index (efi) and num_args arguments. The result is stored in register dst. efi is u16 and num_args is u8 */
- AMAL_OP_CMP, /* cmp dst, reg1, reg2 - Set dst to 1 if reg1 equals reg2, otherwise set it to 0 */
- AMAL_OP_JZ, /* jz reg, offset - Jump to offset if reg is zero. offset is i16 */
- AMAL_OP_JMP, /* jmp offset - Unconditional jump to offset. offset is i16 */
- AMAL_OP_RET, /* ret reg - Return from the function with reg result */
- AMAL_OP_FUNC_START, /* func_start num_param_reg, num_local_var_reg - Start of a function which has num_param_reg parameter registers allocated and num_local_var_reg local variable registers allocated. num_param_reg is u8 and num_local_var_reg is u16 */
- AMAL_OP_FUNC_END /* func_end - End of a function. Implementation should do a ret here */
+ AMAL_OP_SETZ, /* setz reg - Set register value to 0 */
+ AMAL_OP_MOV, /* mov dst, src - Move src register to dst register */
+ AMAL_OP_MOVI, /* movi dst, src - Move src intermediate to dst register */
+ AMAL_OP_MOVD, /* movd dst, src - Move src data to dst register */
+ AMAL_OP_ADD, /* add dst, reg1, reg2 - Add reg1 and reg2 and put the result in dst */
+ AMAL_OP_SUB, /* sub dst, reg1, reg2 - Substract reg2 from reg1 and put the result in dst */
+ AMAL_OP_IMUL, /* imul dst, reg1, reg2 - Signed multiplication */
+ AMAL_OP_MUL, /* mul dst, reg1, reg2 - Unsigned multiplication */
+ AMAL_OP_IDIV, /* idiv dst, reg1, reg2 - Signed division */
+ AMAL_OP_DIV, /* div dst, reg1, reg2 - Unsigned division */
+ AMAL_OP_PUSH, /* push reg - Push register onto stack */
+ AMAL_OP_PUSHI, /* pushi int - Push intermediate onto stack */
+ AMAL_OP_PUSHD, /* pushd data - Push data onto stack */
+ AMAL_OP_CALL, /* call fi, num_args, dst - Call a function using function index (fi) and num_args arguments. The result is stored in register dst. fi is u16 and num_args is u8 */
+ AMAL_OP_CALLR, /* callr reg, num_args - Call a function using a register. Used for function pointers. num_args is u8 */
+ AMAL_OP_CALLE, /* calle efi, num_args, dst - Call an extern function using extern function index (efi) and num_args arguments. The result is stored in register dst. efi is u16 and num_args is u8 */
+ AMAL_OP_CMP, /* cmp dst, reg1, reg2 - Set dst to 1 if reg1 equals reg2, otherwise set it to 0 */
+ AMAL_OP_JZ, /* jz reg, offset - Jump to offset if reg is zero. offset is i16 */
+ AMAL_OP_JMP, /* jmp offset - Unconditional jump to offset. offset is i16 */
+ AMAL_OP_RET, /* ret reg - Return from the function with reg result */
+ AMAL_OP_FUNC_START, /* func_start flags, num_local_var_reg - Start of a function which has @num_local_var_reg local variable registers allocated and has the flag @flag. @flag is u8 and @num_local_var_reg is u16 */
+ AMAL_OP_FUNC_END /* func_end - End of a function. Implementation should do a ret here */
} AmalOpcode;
+#define AMAL_BYTECODE_MAGIC_NUMBER (u32)0xdec05eba
+#define AMAL_BYTECODE_MAJOR_VERSION 1
+#define AMAL_BYTECODE_MINOR_VERSION 0
+#define AMAL_BYTECODE_PATCH_VERSION 0
+
+#define AMAL_BYTECODE_NUM_REGISTERS 256
+
+typedef enum {
+ FUNC_FLAG_NONE = 0,
+ FUNC_FLAG_EXPORTED = (1 << 1)
+} amal_func_flag;
+
typedef u8 AmalOpcodeType;
typedef struct {
@@ -71,6 +83,8 @@ typedef struct {
CHECK_RESULT int bytecode_init(Bytecode *self, ArenaAllocator *allocator);
+CHECK_RESULT int buffer_append_header(Buffer *program_data);
+
/* longjump to self->env on failure */
void generate_bytecode_from_ssa(BytecodeCompilerContext *self);
diff --git a/include/program.h b/include/program.h
index 075bfca..e3a4ac9 100644
--- a/include/program.h
+++ b/include/program.h
@@ -31,13 +31,10 @@
#define AMAL_PROGRAM_INSTRUCTION_INVALID_EXTERN_FUNC_INDEX -19
#define AMAL_PROGRAM_NO_SUCH_EXTERNAL_FUNCTION -20
#define AMAL_PROGRAM_EXTERN_FUNC_ALREADY_EXISTS -21
-
-#define AMAL_PROGRAM_MAGIC_NUMBER (u32)0xdec05eba
-#define AMAL_PROGRAM_MAJOR_VERSION 1
-#define AMAL_PROGRAM_MINOR_VERSION 0
-#define AMAL_PROGRAM_PATCH_VERSION 0
-
-#define AMAL_PROGRAM_NUM_REGISTERS 256
+#define AMAL_PROGRAM_INVALID_EXPORTED_FUNCTIONS -22
+#define AMAL_PROGRAM_INVALID_EXPORTED_FUNCTIONS_SIZE -23
+#define AMAL_PROGRAM_INSTRUCTION_INVALID_EXPORTED_FUNC_INDEX -24
+#define AMAL_PROGRAM_NO_MAIN_FUNC -25
#define AMAL_PROGRAM_ARGS_SIZE_VARARGS -1
@@ -53,12 +50,17 @@ typedef struct {
u8 *intermediates_start; /* Reference inside @data */
u8 *strings_start; /* Reference inside @data */
u8 *extern_funcs_start; /* Reference inside @data */
+ u8 *exported_funcs; /* Reference inside @data */
+ u8 *exported_funcs_end; /* Reference inside @data */
+
usize read_index;
+ u32 main_func_instruction_offset;
u16 num_intermediates;
u16 num_strings;
u16 num_functions;
u16 num_extern_functions;
+ u16 num_exported_functions;
ArenaAllocator allocator; /* Owned. Used by @extern_funcs_map */
HashMapType(BufferView, ProgramExternFunc) extern_funcs_map;
diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h
index b2c8065..ed147bf 100644
--- a/include/ssa/ssa.h
+++ b/include/ssa/ssa.h
@@ -49,11 +49,17 @@ typedef struct {
BufferView name;
} SsaExternFunc;
+typedef struct {
+ FunctionSignature *func_sig;
+ BufferView name;
+} SsaExportFunc;
+
typedef i16 JumpOffset;
typedef i16 SsaRegister;
typedef u16 SsaIntermediateIndex;
typedef u16 SsaStringIndex;
typedef u16 SsaExternFuncIndex;
+typedef u16 SsaExportFuncIndex;
typedef u16 SsaFuncIndex;
typedef struct {
@@ -64,9 +70,11 @@ typedef struct {
Buffer/*BufferView*/ strings;
HashMapType(BufferView, SsaExternFuncIndex) extern_funcs_map;
Buffer/*SsaExternFunc*/ extern_funcs;
+ Buffer/*SsaExportFunc*/ export_funcs;
SsaIntermediateIndex intermediate_counter;
SsaStringIndex string_counter;
SsaExternFuncIndex extern_func_counter;
+ SsaExportFuncIndex export_func_counter;
SsaRegister reg_counter;
SsaRegister param_counter;
SsaFuncIndex func_counter;
@@ -85,8 +93,7 @@ typedef struct {
} SsaInsForm2;
typedef struct {
- SsaFuncIndex func_index;
- u16 num_params_regs;
+ u8 flags;
u16 num_local_vars_regs;
} SsaInsFuncStart;
diff --git a/include/tokenizer.h b/include/tokenizer.h
index 16123cc..57ed9de 100644
--- a/include/tokenizer.h
+++ b/include/tokenizer.h
@@ -38,6 +38,7 @@ typedef enum {
TOK_ELSE,
TOK_WHILE,
TOK_EXTERN,
+ TOK_EXPORT,
TOK_RETURN
} Token;