aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ast.h19
-rw-r--r--include/bytecode/bytecode.h5
-rw-r--r--include/compiler.h15
-rw-r--r--include/parser.h7
-rw-r--r--include/program.h18
-rw-r--r--include/std/buffer.h1
-rw-r--r--include/std/hash_map.h2
-rw-r--r--include/std/scoped_allocator.h4
8 files changed, 47 insertions, 24 deletions
diff --git a/include/ast.h b/include/ast.h
index 34e62b8..2925f6c 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -76,6 +76,7 @@ typedef enum {
typedef struct {
LhsExpr *type;
AstResolveStatus status;
+ Parser *parser; /* Borrowed. This is the parser that is currently parsing the expression */
} AstResolveData;
typedef struct {
@@ -140,6 +141,11 @@ typedef struct {
} value;
} VariableType;
+/*
+ Note: When resolving AST, more than one thread can end up resolving the same expressions at the same time.
+ This is intentional. Instead of using mutex for every expression and locking/unlocking everytime
+ which uses more memory and affects performance, we assume such race conditions are rare and let them happen.
+*/
struct LhsExpr {
bool is_extern;
bool is_pub;
@@ -147,10 +153,6 @@ struct LhsExpr {
BufferView var_name;
VariableType type;
Ast *rhs_expr;
- /*
- TODO: Find a better way to store this. This most likely will use too much memory.
- */
- amal_mutex *mutex;
};
struct AssignmentExpr {
@@ -204,7 +206,12 @@ struct WhileStatement {
typedef struct {
jmp_buf env;
- amal_compiler *compiler;
+ amal_compiler *compiler; /* Borrowed */
+ Parser *parser; /* Borrowed. This is the parser that belongs to the thread */
+ /*
+ Borrowed. This is the current scope. Note that this scope can belong to another parser (and thread),
+ as such, @parser and scope_get_parser(@scope) parser may not be the same
+ */
Scope *scope;
} AstCompilerContext;
@@ -215,7 +222,7 @@ CHECK_RESULT int funcdecl_init(FunctionDecl *self, FunctionSignature *signature,
CHECK_RESULT int funccall_init(FunctionCall *self, BufferView name, ScopedAllocator *allocator);
CHECK_RESULT int structdecl_init(StructDecl *self, Scope *parent, ScopedAllocator *allocator);
void structfield_init(StructField *self, BufferView name, BufferView type_name);
-CHECK_RESULT int lhsexpr_init(LhsExpr *self, bool is_extern, bool is_pub, bool is_const, BufferView var_name, ScopedAllocator *allocator);
+void lhsexpr_init(LhsExpr *self, bool is_extern, bool is_pub, bool is_const, BufferView var_name);
void assignmentexpr_init(AssignmentExpr *self, Ast *lhs_expr, Ast *rhs_expr);
void import_init(Import *self, BufferView path);
CHECK_RESULT int string_init(String *self, BufferView str);
diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h
index 600c9f2..739aa79 100644
--- a/include/bytecode/bytecode.h
+++ b/include/bytecode/bytecode.h
@@ -9,7 +9,6 @@
#include <setjmp.h>
/*doc(Opcode)
- # Opcode
Variable length opcodes. Sizes range from 1 to 4 bytes.
# Instruction formats
Instructions can be in 6 different formats:
@@ -50,12 +49,12 @@ typedef enum {
typedef u8 AmalOpcodeType;
typedef struct {
- Buffer/*<instruction data>*/ instructions;
+ Buffer/*<headers + instruction data>*/ data;
} Bytecode;
typedef struct {
jmp_buf env;
- Bytecode *bytecode;
+ Bytecode bytecode;
Parser *parser; /* borrowed */
} BytecodeCompilerContext;
diff --git a/include/compiler.h b/include/compiler.h
index 3a31ad9..0ae8532 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -8,6 +8,7 @@
#include "std/thread.h"
#include "compiler_options.h"
#include "ast.h"
+#include "program.h"
#define AMAL_COMPILER_OK 0
/* General error */
@@ -32,6 +33,7 @@ typedef struct {
struct amal_compiler {
amal_default_types default_types;
amal_compiler_options options;
+ amal_program *program;
ScopedAllocator allocator;
Scope root_scope;
Buffer/*<Parser*>*/ parsers;
@@ -40,22 +42,19 @@ struct amal_compiler {
ParserThreadData *threads;
int usable_thread_count;
bool started;
- bool used;
amal_mutex mutex;
int generic_work_object_index;
};
void amal_compiler_options_init(amal_compiler_options *self);
-/* If @options is NULL, then default values are used */
-CHECK_RESULT int amal_compiler_init(amal_compiler *self, const amal_compiler_options *options);
-CHECK_RESULT int amal_compiler_deinit(amal_compiler *self);
/*
-This function creates a copy of @filepath in the same thread it's called from
-so it doesn't have to survive longer than this function call.
+ If @options is NULL, then default values are used.
+ You should run @amal_program_deinit even @amal_compiler_load_file fails, to cleanup memory.
+ This function creates a copy of @filepath so it doesn't have to survive longer than this function call.
+ The file has to be in utf-8 format and it can optionally have utf-8 BOM.
*/
-CHECK_RESULT int amal_compiler_load_file(amal_compiler *self, const char *filepath);
+CHECK_RESULT int amal_compiler_load_file(amal_compiler_options *options, amal_program *program, const char *filepath);
CHECK_RESULT int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath, FileScopeReference **file_scope);
-/* TODO: amal_compiler_unload_file */
#endif
diff --git a/include/parser.h b/include/parser.h
index 491815f..bc205f0 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -4,6 +4,7 @@
#include "std/buffer_view.h"
#include "std/scoped_allocator.h"
#include "std/thread.h"
+#include "bytecode/bytecode.h"
#include "tokenizer.h"
#include "ast.h"
#include "defs.h"
@@ -39,17 +40,19 @@ struct Parser {
LhsExpr file_decl;
Scope *current_scope;
bool has_func_parent;
- ScopedAllocator *allocator; /* borrowed. Copied from @compiler for faster access to allocator */
+ /* Borrowed from @compiler for faster access to allocator. The allocator is thread-specific */
+ ScopedAllocator *allocator;
amal_compiler *compiler;
Ssa *ssa;
bool started;
TokenizerError error;
ErrorContext error_context;
jmp_buf parse_env;
+ Bytecode bytecode;
};
CHECK_RESULT int parser_thread_data_init(ParserThreadData *self);
-CHECK_RESULT int parser_thread_data_deinit(ParserThreadData *self);
+void parser_thread_data_deinit(ParserThreadData *self);
CHECK_RESULT int parser_thread_data_start(ParserThreadData *self, AmalThreadCallbackFunc callback_func, void *userdata);
CHECK_RESULT int parser_thread_data_join(ParserThreadData *self, void **result);
diff --git a/include/program.h b/include/program.h
new file mode 100644
index 0000000..cbd9432
--- /dev/null
+++ b/include/program.h
@@ -0,0 +1,18 @@
+#ifndef AMAL_PROGRAM_H
+#define AMAL_PROGRAM_H
+
+#include "std/buffer.h"
+#include "bytecode/bytecode.h"
+
+typedef struct {
+ Buffer/*<...>*/ data;
+} amal_program;
+
+void amal_program_init(amal_program *self);
+void amal_program_deinit(amal_program *self);
+
+CHECK_RESULT int amal_program_append_bytecode(amal_program *self, Bytecode *bytecode);
+CHECK_RESULT int amal_program_run(amal_program *self);
+CHECK_RESULT int amal_program_save(amal_program *self, const char *filepath);
+
+#endif
diff --git a/include/std/buffer.h b/include/std/buffer.h
index af6b986..7a74d33 100644
--- a/include/std/buffer.h
+++ b/include/std/buffer.h
@@ -18,6 +18,7 @@ typedef struct {
} Buffer;
CHECK_RESULT int buffer_init(Buffer *self, struct ScopedAllocator *allocator);
+void buffer_deinit(Buffer *self);
/*
@data can't be null. Use @buffer_append_empty if you want to change the size
diff --git a/include/std/hash_map.h b/include/std/hash_map.h
index 97b0745..9b31213 100644
--- a/include/std/hash_map.h
+++ b/include/std/hash_map.h
@@ -33,6 +33,6 @@ Expected @value size to be @self->value_type_size.
*/
CHECK_RESULT bool hash_map_get(HashMap *self, BufferView key, void *value);
-int hash_compare_string(const void *a, const void *b);
+int hash_map_compare_string(const void *a, const void *b);
#endif
diff --git a/include/std/scoped_allocator.h b/include/std/scoped_allocator.h
index 60abcce..f037ea5 100644
--- a/include/std/scoped_allocator.h
+++ b/include/std/scoped_allocator.h
@@ -16,9 +16,6 @@ struct ScopedAllocator {
ScopedAllocatorNode head;
ScopedAllocatorNode *current;
Buffer/*<void*>*/ mems;
- /* TODO: Use linked-list instead, since the elements are dynamically allocated anyways */
- /* Find another way to store mutexes */
- Buffer/*<amal_mutex*>*/ mutexes;
};
CHECK_RESULT int scoped_allocator_node_init(ScopedAllocatorNode *self);
@@ -28,6 +25,5 @@ CHECK_RESULT int scoped_allocator_init(ScopedAllocator *self);
void scoped_allocator_deinit(ScopedAllocator *self);
CHECK_RESULT int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem);
CHECK_RESULT int scoped_allocator_add_mem(ScopedAllocator *self, usize *result_index);
-CHECK_RESULT int scoped_allocator_create_mutex(ScopedAllocator *self, amal_mutex **mutex);
#endif