From: Brendan Hansen Date: Mon, 10 Aug 2020 17:43:49 +0000 (-0500) Subject: added memory reservation initial values X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=b0e41c5980dac2c0fbb3ebb9e24533e759ebc4b5;p=onyx.git added memory reservation initial values --- diff --git a/docs/plan b/docs/plan index 6ef779a7..838906d8 100644 --- a/docs/plan +++ b/docs/plan @@ -161,6 +161,13 @@ HOW: [ ] Array literals + [ ] Struct literals + + [ ] Top level variable initialization + - Works for numeric literals + + [ ] 'use' enums and packages at an arbitrary scope + [ ] Better checking for casts - Checking which things are allowed to cast to/from should be checked in the checker, not in the wasm generatation diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 6e9401f6..6d242e73 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -350,7 +350,7 @@ struct AstTypeAlias { AstType_base; AstType* to; }; // 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 AstMemRes { AstTyped_base; u64 addr; AstTyped *initial_value; }; // HACK: This has to be the same size or bigger as AstDereference struct AstIncludeFile { AstNode_base; OnyxToken *filename; }; struct AstUsePackage { AstNode_base; diff --git a/include/onyxtypes.h b/include/onyxtypes.h index fb2fa7e9..7d17297c 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -125,6 +125,7 @@ b32 type_is_struct(Type* type); b32 type_is_bool(Type* type); b32 type_is_integer(Type* type); b32 type_is_numeric(Type* type); +b32 type_is_compound(Type* type); b32 type_results_in_void(Type* type); #endif // #ifndef ONYX_TYPES diff --git a/onyx b/onyx index bedfe214..144ca80f 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx index d3a048c1..5483f7c9 100644 --- a/progs/stack_based.onyx +++ b/progs/stack_based.onyx @@ -44,9 +44,12 @@ vec_add :: proc (v: Vec3, u: Vec3, use out: ^Vec3) { z = v.z + u.z; } +some_value := #char "A"; + start :: proc #export { heap_init(); print("Hello, World!"); + print_hex(cast(u64) some_value); print("Hello, World!"); print_ptr(__heap_start); print_ptr(__stack_base); @@ -54,9 +57,7 @@ start :: proc #export { print_bin(42l); print_hex(42l); - for i: #char "a", #char "f" { - print_hex(cast(u64) i); - } + for i: #char "a", #char "f" do print_hex(cast(u64) i); a := 12345; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 3fb2967e..1a32875c 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -26,6 +26,7 @@ CHECK(function, AstFunction* func); CHECK(overloaded_function, AstOverloadedFunction* func); CHECK(struct, AstStructType* s_node); CHECK(function_header, AstFunction* func); +CHECK(memres, AstMemRes* memres); static inline void fill_in_type(AstTyped* node) { if (node->type == NULL) @@ -1071,6 +1072,27 @@ CHECK(function_header, AstFunction* func) { return 0; } +CHECK(memres, AstMemRes* memres) { + fill_in_type((AstTyped *) memres); + + if (memres->initial_value != NULL) { + fill_in_type(memres->initial_value); + + Type* memres_type = memres->type; + if (!type_is_compound(memres_type)) memres_type = memres_type->Pointer.elem; + + if (!types_are_compatible(memres_type, memres->initial_value->type)) { + onyx_message_add(Msg_Type_Binop_Mismatch, + memres->token->pos, + type_get_name(memres_type), + type_get_name(memres->initial_value->type)); + return 1; + } + } + + return 0; +} + CHECK(node, AstNode* node) { switch (node->kind) { case Ast_Kind_Function: return check_function((AstFunction *) node); @@ -1119,6 +1141,10 @@ void onyx_type_check() { if (check_struct((AstStructType *) entity->type_alias)) return; break; + case Entity_Type_Memory_Reservation: + if (check_memres(entity->mem_res)) return; + break; + case Entity_Type_Enum: break; case Entity_Type_String_Literal: break; @@ -1129,8 +1155,6 @@ 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 8849e451..6cab7515 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -169,10 +169,6 @@ static AstTyped* parse_factor(OnyxParser* parser) { negate_node->operation = Unary_Op_Negate; negate_node->expr = factor; - if ((factor->flags & Ast_Flag_Comptime) != 0) { - negate_node->flags |= Ast_Flag_Comptime; - } - retval = (AstTyped *) negate_node; break; } @@ -183,10 +179,6 @@ static AstTyped* parse_factor(OnyxParser* parser) { not_node->token = expect_token(parser, '!'); not_node->expr = parse_factor(parser); - if ((not_node->expr->flags & Ast_Flag_Comptime) != 0) { - not_node->flags |= Ast_Flag_Comptime; - } - retval = (AstTyped *) not_node; break; } @@ -572,10 +564,6 @@ static AstTyped* parse_expression(OnyxParser* parser) { right = parse_factor(parser); bin_op->right = right; - - if ((left->flags & Ast_Flag_Comptime) != 0 && (right->flags & Ast_Flag_Comptime) != 0) { - bin_op->flags |= Ast_Flag_Comptime; - } } } @@ -1460,16 +1448,21 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) { 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); + + if (parser->curr->type == '=') { + consume_token(parser); + memres->initial_value = parse_expression(parser); + + } else { + memres->type_node = parse_type(parser); + + if (parser->curr->type == '=') { + consume_token(parser); + memres->initial_value = parse_expression(parser); + } + } if (is_private) memres->flags |= Ast_Flag_Private_Package; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 116eb158..8a095b04 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -495,11 +495,26 @@ static void symres_enum(AstEnumType* enum_node) { static void symres_memres(AstMemRes** memres) { (*memres)->type_node = symres_type((*memres)->type_node); - if ((*memres)->type_node == NULL) return; + if ((*memres)->initial_value != NULL) { + symres_expression(&(*memres)->initial_value); + + if (((*memres)->initial_value->flags & Ast_Flag_Comptime) == 0) { + onyx_message_add(Msg_Type_Literal, + (*memres)->initial_value->token->pos, + "top level expressions must be compile time known"); + return; + } + + if ((*memres)->type_node == NULL) + (*memres)->type_node = (*memres)->initial_value->type_node; + + } else { + if ((*memres)->type_node == NULL) return; + } (*memres)->type = type_build_from_ast(semstate.allocator, (*memres)->type_node); - if ((*memres)->type->kind != Type_Kind_Array && (*memres)->type->kind != Type_Kind_Struct) { + if (!type_is_compound((*memres)->type)) { Type* ptr_type = type_make_pointer(semstate.allocator, (*memres)->type); (*memres)->type = ptr_type; diff --git a/src/onyxtypes.c b/src/onyxtypes.c index df03d677..b61e05fd 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -483,6 +483,11 @@ b32 type_is_numeric(Type* type) { return type->Basic.kind >= Basic_Kind_I8 && type->Basic.kind <= Basic_Kind_F64; } +b32 type_is_compound(Type* type) { + return type->kind == Type_Kind_Array + || type->kind == Type_Kind_Struct; +} + b32 type_results_in_void(Type* type) { return (type == NULL) || (type->kind == Type_Kind_Basic && type->Basic.kind == Basic_Kind_Void) diff --git a/src/onyxwasm.c b/src/onyxwasm.c index dc821569..665cd82f 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1645,25 +1645,72 @@ static void compile_string_literal(OnyxWasmModule* mod, AstStrLit* strlit) { bh_arr_push(mod->data, datum); } +static void compile_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node) { + switch (node->kind) { + case Ast_Kind_NumLit: { + switch (node->type->Basic.kind) { + case Basic_Kind_Bool: + case Basic_Kind_I8: + case Basic_Kind_U8: + case Basic_Kind_I16: + case Basic_Kind_U16: + case Basic_Kind_I32: + case Basic_Kind_U32: + case Basic_Kind_Rawptr: + *((i32 *) data) = ((AstNumLit *) node)->value.i; + return; + + case Basic_Kind_I64: + case Basic_Kind_U64: + *((i64 *) data) = ((AstNumLit *) node)->value.l; + return; + + case Basic_Kind_F32: + *((f32 *) data) = ((AstNumLit *) node)->value.f; + return; + + case Basic_Kind_F64: + *((f64 *) data) = ((AstNumLit *) node)->value.d; + return; + + default: break; + } + + //fallthrough + } + default: onyx_message_add(Msg_Type_Literal, + node->token->pos, + "invalid data"); + } +} + static void compile_memory_reservation(OnyxWasmModule* mod, AstMemRes* memres) { - u64 alignment = type_alignment_of(memres->type); - u64 size = type_size_of(memres->type); + Type* effective_type = memres->type; + if (!type_is_compound(effective_type)) effective_type = effective_type->Pointer.elem; + + u64 alignment = type_alignment_of(effective_type); + u64 size = type_size_of(effective_type); u32 offset = mod->next_datum_offset; if (offset % alignment != 0) { offset += alignment - (offset % alignment); } - // WasmDatum datum = { - // .offset = offset, - // .length = size, - // .data = NULL - // }; + if (memres->initial_value != NULL) { + u8* data = bh_alloc(mod->allocator, size); + compile_raw_data(mod, data, memres->initial_value); + + WasmDatum datum = { + .offset = offset, + .length = size, + .data = data, + }; + + bh_arr_push(mod->data, datum); + } memres->addr = offset; mod->next_datum_offset = offset + size; - - // bh_arr_push(mod->data, datum); } static void compile_file_contents(OnyxWasmModule* mod, AstFileContents* fc) {