[ ] Static pointers to sized data
+ [ ] 'using' parameters
+ - The following example will bring the members of the struct into the scope as field accesses
+ and allow for a more OO style programming, without diving into the crap that is OO
+
[ ] Start work on evaluating compile time known values.
- An expression marked COMPTIME will be reduced to its value in the parse tree.
typedef struct AstEnumValue AstEnumValue;
typedef struct AstBinding AstBinding;
+typedef struct AstMemRes AstMemRes;
typedef struct AstIncludeFile AstIncludeFile;
typedef struct AstUsePackage AstUsePackage;
+typedef struct AstAlias AstAlias;
typedef struct AstGlobal AstGlobal;
typedef struct AstFunction AstFunction;
typedef struct AstOverloadedFunction AstOverloadedFunction;
Ast_Kind_Package,
Ast_Kind_Include_File,
Ast_Kind_Use_Package,
+ Ast_Kind_Alias,
+ Ast_Kind_Memres,
Ast_Kind_Binding,
Ast_Kind_Function,
// Top level nodes
struct AstBinding { AstTyped_base; AstNode* node; };
+struct AstMemRes { AstTyped_base; u64 addr; }; // HACK: This has to be the same size as AstDereference
struct AstIncludeFile { AstNode_base; OnyxToken *filename; };
struct AstUsePackage {
AstNode_base;
AstPackage *package;
OnyxToken *alias;
- bh_arr(OnyxToken *) only;
+ bh_arr(AstAlias *) only;
+};
+struct AstAlias {
+ AstNode_base;
+ OnyxToken *alias;
};
struct AstGlobal {
AstTyped_base;
Entity_Type_String_Literal,
Entity_Type_Enum,
Entity_Type_Struct,
+ Entity_Type_Memory_Reservation,
Entity_Type_Function_Header,
Entity_Type_Global_Header,
Entity_Type_Expression,
AstStrLit *strlit;
AstStructType *struct_type;
AstEnumType *enum_type;
+ AstMemRes *mem_res;
};
} Entity;
use "progs/print_funcs"
-use package printing
+use package printing {
+ print, PrintableArray,
+ print_f32 as pf32,
+ print_buf
+}
Foo :: struct {
x : i32;
for i: 0, pa.len print(pa.data[i] as i32);
}
-SomeType :: enum #flags { Value1; Value2; Value3; Value4; }
+SomeType :: enum {
+ Value1;
+ Value2;
+ Value3;
+ Value4;
+}
print_st :: proc (st: SomeType) {
print(st as i32);
}
+single_int : u8
+
+array : [N] Foo
+N :: 1024
+
proc #export "main" {
+ print("Hello World! this is slightly longer\n");
+
+ print(__heap_start as i32);
+
+ print(print_buf as i32);
+
+ single_int = 10 as u8;
+ print(single_int as i32);
+
+ array[4].y = 1234;
+ print(array[4].y);
+
st := SomeType.Value4;
print_st(st);
print(1234);
- print_f32(123.0f);
+ pf32(123.0f);
}
package printing
+use package main {
+ N as buf_size
+}
+
print_bool :: proc #foreign "host" "print" (value: bool) ---
print_i32 :: proc #foreign "host" "print" (value: i32) ---
print_f32 :: proc #foreign "host" "print" (value: f32) ---
print_str,
print_str_len,
}
+
+print_buf : [buf_size] u8
\ No newline at end of file
break;
}
+ case Ast_Kind_Memres: {
+ ent.type = Entity_Type_Memory_Reservation;
+ ent.mem_res = (AstMemRes *) node;
+ bh_arr_push(compiler_state->prog_info.entities, ent);
+ break;
+ }
+
default: {
ent.type = Entity_Type_Expression;
ent.expr = (AstTyped *) node;
case Ast_Kind_Overloaded_Function: break;
case Ast_Kind_Enum_Value: break;
+ case Ast_Kind_Memres: break;
+
default:
retval = 1;
DEBUG_HERE;
case Entity_Type_Use_Package: break;
+ case Entity_Type_Memory_Reservation: break;
+
default: DEBUG_HERE; break;
}
}
bh_arr_new(global_heap_allocator, upack->only, 4);
while (parser->curr->type != '}') {
- OnyxToken* only_token = expect_token(parser, Token_Type_Symbol);
+ AstAlias* alias = make_node(AstAlias, Ast_Kind_Alias);
+ alias->token = expect_token(parser, Token_Type_Symbol);
- bh_arr_push(upack->only, only_token);
+ if (parser->curr->type == Token_Type_Keyword_Cast) {
+ consume_token(parser);
+ alias->alias = expect_token(parser, Token_Type_Symbol);
+ } else {
+ alias->alias = alias->token;
+ }
+
+ bh_arr_push(upack->only, alias);
if (parser->curr->type != '}')
expect_token(parser, ',');
consume_token(parser);
expect_token(parser, ':');
- expect_token(parser, ':');
- AstTyped* node = parse_top_level_expression(parser);
+ if (parser->curr->type == ':') {
+ expect_token(parser, ':');
+
+ AstTyped* node = parse_top_level_expression(parser);
- if (node->kind == Ast_Kind_Function) {
- AstFunction* func = (AstFunction *) node;
+ if (node->kind == Ast_Kind_Function) {
+ AstFunction* func = (AstFunction *) node;
- if (func->exported_name == NULL)
- func->exported_name = symbol;
+ if (func->exported_name == NULL)
+ func->exported_name = symbol;
- } else if (node->kind == Ast_Kind_Global) {
- AstGlobal* global = (AstGlobal *) node;
+ } else if (node->kind == Ast_Kind_Global) {
+ AstGlobal* global = (AstGlobal *) node;
- if (global->exported_name == NULL)
- global->exported_name = symbol;
+ if (global->exported_name == NULL)
+ global->exported_name = symbol;
- } else if (node->kind != Ast_Kind_Overloaded_Function
- && node->kind != Ast_Kind_StrLit) {
+ } else if (node->kind != Ast_Kind_Overloaded_Function
+ && node->kind != Ast_Kind_StrLit) {
- if (node->kind == Ast_Kind_Struct_Type || node->kind == Ast_Kind_Enum_Type) {
- ((AstStructType *)node)->name = bh_aprintf(global_heap_allocator,
- "%b", symbol->text, symbol->length);
+ if (node->kind == Ast_Kind_Struct_Type || node->kind == Ast_Kind_Enum_Type) {
+ ((AstStructType *)node)->name = bh_aprintf(global_heap_allocator,
+ "%b", symbol->text, symbol->length);
+ }
+
+ // HACK
+ add_node_to_process(parser, (AstNode *) node);
}
- // HACK
- add_node_to_process(parser, (AstNode *) node);
- }
+ AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
+ binding->token = symbol;
+ binding->node = (AstNode *) node;
- AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
- binding->token = symbol;
- binding->node = (AstNode *) node;
+ return (AstNode *) binding;
+ } else {
+ if (parser->curr->type == '=') {
+ onyx_message_add(Msg_Type_Literal,
+ parser->curr->pos,
+ "assigning initial values to memory reservations isn't allowed yet.");
+ break;
+ }
+
+ AstMemRes* memres = make_node(AstMemRes, Ast_Kind_Memres);
+ memres->token = symbol;
+ memres->type_node = parse_type(parser);
- return (AstNode *) binding;
+ add_node_to_process(parser, (AstNode *) memres);
+
+ AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
+ binding->token = symbol;
+ binding->node = (AstNode *) memres;
+
+ return (AstNode *) binding;
+ }
}
default: break;
static void symres_overloaded_function(AstOverloadedFunction* ofunc);
static void symres_use_package(AstUsePackage* package);
static void symres_enum(AstEnumType* enum_node);
+static void symres_memres(AstMemRes** memres);
static void scope_enter(Scope* new_scope) {
if (new_scope->parent == NULL)
}
if (package->only != NULL) {
- bh_arr_each(OnyxToken *, tkn, package->only) {
+ bh_arr_each(AstAlias *, alias, package->only) {
- AstNode* thing = symbol_resolve(p->scope, *tkn);
+ AstNode* thing = symbol_resolve(p->scope, (*alias)->token);
if (thing == NULL) {
onyx_message_add(Msg_Type_Literal,
- (*tkn)->pos,
+ (*alias)->token->pos,
"not found in package");
return;
}
- symbol_introduce(semstate.curr_package->scope, *tkn, thing);
+ symbol_introduce(semstate.curr_package->scope, (*alias)->alias, thing);
}
}
}
}
+static void symres_memres(AstMemRes** memres) {
+ (*memres)->type_node = symres_type((*memres)->type_node);
+ (*memres)->type = type_build_from_ast(semstate.allocator, (*memres)->type_node);
+
+ if ((*memres)->type->kind != Type_Kind_Array) {
+ Type* ptr_type = type_make_pointer(semstate.allocator, (*memres)->type);
+ (*memres)->type = ptr_type;
+
+ AstMemRes* new_memres = onyx_ast_node_new(semstate.node_allocator, sizeof(AstMemRes), Ast_Kind_Memres);
+ memcpy(new_memres, (*memres), sizeof(AstMemRes));
+
+ // BIG HACK: converting the (*memres) node to a dereference node to not break
+ // already resolved symbols
+ ((AstDereference *) (*memres))->kind = Ast_Kind_Dereference;
+ ((AstDereference *) (*memres))->type_node = (*memres)->type_node;
+ ((AstDereference *) (*memres))->type = (*memres)->type->Pointer.elem;
+ ((AstDereference *) (*memres))->expr = (AstTyped *) new_memres;
+
+ // BUT retain the 'old' memres in the entity list
+ *memres = new_memres;
+ }
+}
+
void onyx_resolve_symbols() {
semstate.curr_scope = semstate.program->global_scope;
case Entity_Type_Expression: symres_expression(&entity->expr); break;
case Entity_Type_Struct: symres_type((AstType *) entity->struct_type); break;
case Entity_Type_Enum: symres_enum(entity->enum_type); break;
+ case Entity_Type_Memory_Reservation: symres_memres(&entity->mem_res); break;
default: break;
}
"PACKAGE",
"PROGRAM",
"USE",
+ "ALIAS",
"BINDING",
"FUNCTION",
break;
}
+ case Ast_Kind_Memres: {
+ AstMemRes* memres = (AstMemRes *) expr;
+ WID(WI_I32_CONST, memres->addr);
+ break;
+ }
+
default:
bh_printf("Unhandled case: %d\n", expr->kind);
DEBUG_HERE;
bh_arr_push(mod->data, datum);
}
+static void compile_memory_reservation(OnyxWasmModule* mod, AstMemRes* memres) {
+ u64 alignment = type_alignment_of(memres->type);
+ u64 size = type_size_of(memres->type);
+
+ u32 offset = mod->next_datum_offset;
+ if (offset % alignment != 0) {
+ offset += alignment - (offset % alignment);
+ }
+
+ ptr data = bh_alloc_array(global_heap_allocator, i8, size);
+ memset(data, 0, size);
+
+ WasmDatum datum = {
+ .offset = offset,
+ .length = size,
+ .data = data
+ };
+
+ memres->addr = offset;
+ mod->next_datum_offset = offset + size;
+
+ bh_arr_push(mod->data, datum);
+}
+
OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) {
OnyxWasmModule module = {
.allocator = alloc,
break;
}
+ case Entity_Type_Memory_Reservation: {
+ compile_memory_reservation(module, (AstMemRes *) entity->mem_res);
+
+ // HACK: To put this here
+ // NOTE: Round up to the nearest multiple of 16
+ builtin_heap_start.value.i =
+ (module->next_datum_offset & 15)
+ ? ((module->next_datum_offset >> 4) + 1) << 4
+ : module->next_datum_offset;
+ break;
+ }
+
case Entity_Type_Function: compile_function(module, entity->function); break;
case Entity_Type_Global: compile_global(module, entity->global); break;