From: Brendan Hansen Date: Mon, 27 Jul 2020 03:50:23 +0000 (-0500) Subject: Started basics of pointers to sized data X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3a14a6ef4c9582c93b8cd47bc5bc42d4d1aba63f;p=onyx.git Started basics of pointers to sized data --- diff --git a/docs/plan b/docs/plan index aa24c32e..6c4426ba 100644 --- a/docs/plan +++ b/docs/plan @@ -121,6 +121,10 @@ HOW: [ ] 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. diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 785cda91..078a9803 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -43,8 +43,10 @@ typedef struct AstEnumType AstEnumType; 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; @@ -66,6 +68,8 @@ typedef enum AstKind { Ast_Kind_Package, Ast_Kind_Include_File, Ast_Kind_Use_Package, + Ast_Kind_Alias, + Ast_Kind_Memres, Ast_Kind_Binding, Ast_Kind_Function, @@ -329,13 +333,18 @@ struct AstEnumValue { AstTyped_base; AstNumLit* value; }; // 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; @@ -390,6 +399,7 @@ typedef enum EntityType { 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, @@ -411,6 +421,7 @@ typedef struct Entity { AstStrLit *strlit; AstStructType *struct_type; AstEnumType *enum_type; + AstMemRes *mem_res; }; } Entity; diff --git a/onyx b/onyx index 90f0812b..137784d6 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/ez.onyx b/progs/ez.onyx index 0ab71b5f..58d61414 100644 --- a/progs/ez.onyx +++ b/progs/ez.onyx @@ -1,6 +1,10 @@ use "progs/print_funcs" -use package printing +use package printing { + print, PrintableArray, + print_f32 as pf32, + print_buf +} Foo :: struct { x : i32; @@ -17,13 +21,35 @@ asdf :: proc (pa: PrintableArray) { 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); @@ -43,6 +69,6 @@ proc #export "main" { print(1234); - print_f32(123.0f); + pf32(123.0f); } diff --git a/progs/print_funcs.onyx b/progs/print_funcs.onyx index 3f48aab3..dd092040 100644 --- a/progs/print_funcs.onyx +++ b/progs/print_funcs.onyx @@ -1,5 +1,9 @@ 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) --- @@ -55,3 +59,5 @@ print :: proc #overloaded { print_str, print_str_len, } + +print_buf : [buf_size] u8 \ No newline at end of file diff --git a/src/onyx.c b/src/onyx.c index 76d1a3bc..4da00e57 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -244,6 +244,13 @@ static void merge_parse_results(CompilerState* compiler_state, ParseResults* res 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; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index eb943630..232e4984 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -657,6 +657,8 @@ CHECK(expression, AstTyped** pexpr) { case Ast_Kind_Overloaded_Function: break; case Ast_Kind_Enum_Value: break; + case Ast_Kind_Memres: break; + default: retval = 1; DEBUG_HERE; @@ -952,6 +954,8 @@ void onyx_type_check() { case Entity_Type_Use_Package: break; + case Entity_Type_Memory_Reservation: break; + default: DEBUG_HERE; break; } } diff --git a/src/onyxparser.c b/src/onyxparser.c index 9c54464d..865efd39 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1180,9 +1180,17 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) { 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, ','); @@ -1212,39 +1220,61 @@ static AstNode* parse_top_level_statement(OnyxParser* 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; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 029a062b..7c0bbccd 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -63,6 +63,7 @@ static void symres_global(AstGlobal* global); 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) @@ -395,16 +396,16 @@ static void symres_use_package(AstUsePackage* package) { } 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); } } @@ -454,6 +455,29 @@ static void symres_enum(AstEnumType* enum_node) { } } +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; @@ -477,6 +501,7 @@ void onyx_resolve_symbols() { 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; } diff --git a/src/onyxutils.c b/src/onyxutils.c index 8c53165b..ed3bd9da 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -14,6 +14,7 @@ static const char* ast_node_names[] = { "PACKAGE", "PROGRAM", "USE", + "ALIAS", "BINDING", "FUNCTION", diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 1a0f5e98..aa03c2d7 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -992,6 +992,12 @@ COMPILE_FUNC(expression, AstTyped* expr) { 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; @@ -1343,6 +1349,30 @@ static void compile_string_literal(OnyxWasmModule* mod, AstStrLit* strlit) { 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, @@ -1438,6 +1468,18 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) { 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;