From: Brendan Hansen Date: Tue, 11 Aug 2020 17:49:17 +0000 (-0500) Subject: readded UFC syntax using the ' operator X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=266c2058bda4aad7736605ea4a54f8a8092eefd1;p=onyx.git readded UFC syntax using the ' operator --- diff --git a/.vimspector.json b/.vimspector.json index 3423b8e3..f6625bc2 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -6,7 +6,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/onyx", - "args": ["-verbose", "-I", "progs/", "progs/stack_based.onyx"], + "args": ["-verbose", "progs/stack_based.onyx"], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], diff --git a/core/alloc.onyx b/core/alloc.onyx index 40b7a475..fda4cdb4 100644 --- a/core/alloc.onyx +++ b/core/alloc.onyx @@ -1,5 +1,6 @@ package memory +#include_file "memory" #include_file "intrinsics" use package intrinsics { memory_size, memory_grow } @@ -24,6 +25,10 @@ alloc :: proc (use a: ^Allocator, size: u32) -> rawptr { return func(data, AllocAction.Alloc, size, 16, null); } +resize :: proc (use a: ^Allocator, ptr: rawptr, size: u32) -> rawptr { + return func(data, AllocAction.Resize, size, 16, ptr); +} + free :: proc (use a: ^Allocator, ptr: rawptr) { func(data, AllocAction.Free, 0, 0, ptr); } @@ -120,9 +125,31 @@ heap_free :: proc (ptr: rawptr) { heap_state.free_list = hb_ptr; } +#private +heap_resize :: proc (ptr: rawptr, new_size: u32, align: u32) -> rawptr { + hb_ptr := cast(^heap_block) (cast(u32) ptr - sizeof heap_block); + + // If there is already enough space in the current allocated block, + // just return the block that already exists and has the memory in it. + if hb_ptr.size >= new_size do return ptr; + + // If we are at the end of the allocation space, just extend it + if hb_ptr.size + cast(u32) ptr >= cast(u32) heap_state.next_alloc { + hb_ptr.size = new_size; + heap_state.next_alloc = cast(rawptr) (cast(u32) ptr + hb_ptr.size); + return ptr; + } + + new_ptr := heap_alloc(new_size, align); + memory_copy(new_ptr, ptr, hb_ptr.size); + heap_free(ptr); + return new_ptr; +} + #private heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, oldptr: rawptr) -> rawptr { if aa == AllocAction.Alloc do return heap_alloc(size, align); + if aa == AllocAction.Resize do return heap_resize(oldptr, size, align); if aa == AllocAction.Free { heap_free(oldptr); return null; @@ -131,5 +158,6 @@ heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, o return null; } -malloc :: proc (size: u32) -> rawptr do return alloc(^heap_allocator, size); -mfree :: proc (ptr: rawptr) do free(^heap_allocator, ptr); +malloc :: proc (size: u32) -> rawptr do return alloc(^heap_allocator, size); +mfree :: proc (ptr: rawptr) do free(^heap_allocator, ptr); +mresize :: proc (ptr: rawptr, size: u32) -> rawptr do return resize(^heap_allocator, ptr, size); diff --git a/core/memory.onyx b/core/memory.onyx new file mode 100644 index 00000000..85f0db40 --- /dev/null +++ b/core/memory.onyx @@ -0,0 +1,19 @@ +package memory + +memory_copy :: proc (dst_: rawptr, src_: rawptr, len: u32) { + if len % 8 == 0 { + dst := cast(^u64) dst_; + src := cast(^u64) src_; + for i: 0, len >> 3 do dst[i] = src[i]; + + } elseif len % 4 == 0 { + dst := cast(^u32) dst_; + src := cast(^u32) src_; + for i: 0, len >> 2 do dst[i] = src[i]; + + } else { + dst := cast(^u8) dst_; + src := cast(^u8) src_; + for i: 0, len do dst[i] = src[i]; + } +} \ No newline at end of file diff --git a/docs/plan b/docs/plan index 9035a49f..d0424cfe 100644 --- a/docs/plan +++ b/docs/plan @@ -161,6 +161,12 @@ HOW: [X] Include other directories to search for files + [ ] Arrays need to be much better + - Currently, they are basically just a pointer. + - The length should be stored with the pointer + - Dynamic resizing? + - They are just very hard to use at the moment + [ ] 'use' enums and packages at an arbitrary scope [ ] Array literals diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 4168bc07..735df3b9 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -20,6 +20,7 @@ typedef struct AstAddressOf AstAddressOf; typedef struct AstDereference AstDereference; typedef struct AstArrayAccess AstArrayAccess; typedef struct AstFieldAccess AstFieldAccess; +typedef struct AstUfc AstUfc; typedef struct AstSizeOf AstSizeOf; typedef struct AstAlignOf AstAlignOf; typedef struct AstFileContents AstFileContents; @@ -112,6 +113,7 @@ typedef enum AstKind { Ast_Kind_Dereference, Ast_Kind_Array_Access, Ast_Kind_Field_Access, + Ast_Kind_Ufc, Ast_Kind_Size_Of, Ast_Kind_Align_Of, Ast_Kind_File_Contents, @@ -276,6 +278,7 @@ struct AstAddressOf { AstTyped_base; AstTyped *expr; }; struct AstDereference { AstTyped_base; AstTyped *expr; }; struct AstArrayAccess { AstTyped_base; AstTyped *addr; AstTyped *expr; u64 elem_size; }; struct AstFieldAccess { AstTyped_base; AstTyped *expr; u64 offset; }; +struct AstUfc { AstTyped_base; AstTyped *object; AstTyped *call; }; struct AstSizeOf { AstTyped_base; AstType *so_type; u64 size; }; struct AstAlignOf { AstTyped_base; AstType *ao_type; u64 alignment; }; struct AstFileContents { AstTyped_base; OnyxToken *filename; }; diff --git a/onyx b/onyx index 59c6e8c9..e19764a5 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/heap_resize_test.onyx b/progs/heap_resize_test.onyx new file mode 100644 index 00000000..75e3783f --- /dev/null +++ b/progs/heap_resize_test.onyx @@ -0,0 +1,45 @@ +#include_folder "./core" + +#include_file "printing" +#include_file "alloc" + +use package memory +use package printing + +proc #export "start" { + heap_init(); + + print("Creating initial memories"); + arr1 := cast(^u32) malloc(sizeof [10] u32); + print_hex(cast(u64) arr1); + + arr2 := cast(^u32) malloc(sizeof [40] u32); + print_hex(cast(u64) arr2); + + print("Freeing arr1"); + mfree(arr1); + + print("Resizing arr2 (shouldn't change location)"); + arr2 = cast(^u32) mresize(arr2, sizeof [60] u32); + print_hex(cast(u64) arr2); + + print("Allocating arr3 (should be bigger than arr2)"); + arr3 := cast(^u32) malloc(sizeof [30] u32); + print_hex(cast(u64) arr3); + + print("Allocating arr1 (should be in the same place as before)"); + arr1 = cast(^u32) malloc(sizeof [5] u32); + print_hex(cast(u64) arr1); + for i: 0, 5 do arr1[i] = i; + + print("Resizing arr1 (should be in the same place as before)"); + arr1 = cast(^u32) mresize(arr1, sizeof[10] u32); + print_hex(cast(u64) arr1); + + print("Resizing arr1 (should have moved to after arr3)"); + arr1 = cast(^u32) mresize(arr1, sizeof[100] u32); + print_hex(cast(u64) arr1); + + print("Testing if the data was copied."); + for i: 0, 5 do print(arr1[i]); +} \ No newline at end of file diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx index e9d52522..f07194e3 100644 --- a/progs/stack_based.onyx +++ b/progs/stack_based.onyx @@ -8,6 +8,18 @@ package main use package printing use package memory +sort :: proc (arr: [N]i32, cmp: proc (i32, i32) -> i32) { + for i: 0, N { + smallest_idx := i; + + for j: i, N do if cmp(arr[j], arr[smallest_idx]) < 0 do smallest_idx = j; + + tmp :: arr[i]; + arr[i] = arr[smallest_idx]; + arr[smallest_idx] = tmp; + } +} + ret_val :: proc (x: i32, y: i32) -> i32 { big_arr : [128] i32; big_arr[0] = 1234; @@ -73,7 +85,7 @@ start :: proc #export { arr[1][3] = 40; arr[1][4] = 50; arr[1][9] = 123; - print(sumN(arr[1])); + print(arr[1] 'sumN()); print(summing(cast(^i32) arr[1])); v1: Vec3; @@ -91,9 +103,10 @@ start :: proc #export { print(v3.x); print(v3.y); print(v3.z); - print(mag_squared(v3)); - print(ret_val(10, 4)); + print(v3'mag_squared()); + + print(10'ret_val(4)); for i: 0, N do print(arr[1][i]); @@ -108,4 +121,13 @@ start :: proc #export { fancy : [5 + 3 * 4] i32; fancy[2] = 123; print(fancy[2]); + + + something : [N] i32; + for i: 0, N do something[i] = N - i; + for i: 0, N do print(something[i]); + + something'sort(proc (a: i32, b: i32) -> i32 { return a - b; }); + + for i: 0, N do print(something[i]); } \ No newline at end of file diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 7a468ef9..881b0cfa 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -787,7 +787,7 @@ CHECK(expression, AstTyped** pexpr) { AstTyped* expr = *pexpr; if (expr->kind > Ast_Kind_Type_Start && expr->kind < Ast_Kind_Type_End) { onyx_message_add(Msg_Type_Literal, - (OnyxFilePos) { 0 }, + expr->token->pos, "type used as part of an expression"); return 1; } diff --git a/src/onyxparser.c b/src/onyxparser.c index ff1e915a..c58469b7 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -357,7 +357,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { return NULL; } - while (parser->curr->type == '[' || parser->curr->type == '.' || parser->curr->type == '(') { + while (1) { if (parser->hit_unexpected_token) return retval; switch ((u16) parser->curr->type) { @@ -414,9 +414,23 @@ static AstTyped* parse_factor(OnyxParser* parser) { retval = (AstTyped *) call_node; break; } + + case '\'': { + AstUfc* ufc_node = make_node(AstUfc, Ast_Kind_Ufc); + ufc_node->token = expect_token(parser, '\''); + ufc_node->object = retval; + ufc_node->call = parse_factor(parser); + + retval = (AstTyped *) ufc_node; + break; + } + + default: goto factor_parsed; } } +factor_parsed: + return retval; } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index f5c3e4bd..c6432ad0 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -61,8 +61,8 @@ static void symres_return(AstReturn* ret); static void symres_if(AstIf* ifnode); static void symres_while(AstWhile* whilenode); static void symres_for(AstFor* fornode); -static void symres_statement_chain(AstNode* walker, AstNode** trailer); -static b32 symres_statement(AstNode* stmt); +static void symres_statement_chain(AstNode** walker); +static b32 symres_statement(AstNode** stmt); static void symres_block(AstBlock* block); static void symres_function(AstFunction* func); static void symres_global(AstGlobal* global); @@ -183,7 +183,7 @@ static void symres_call(AstCall* call) { // call->arg_count++; // } - symres_statement_chain((AstNode *) call->arguments, (AstNode **) &call->arguments); + symres_statement_chain((AstNode **) &call->arguments); } static void symres_size_of(AstSizeOf* so) { @@ -222,6 +222,35 @@ static void symres_field_access(AstFieldAccess** fa) { } } +static void symres_ufc(AstUfc** ufc) { + if ((*ufc)->call->kind != Ast_Kind_Call) { + onyx_message_add(Msg_Type_Literal, + (*ufc)->token->pos, + "universal function call expected call on right side"); + return; + } + + symres_expression(&(*ufc)->object); + if ((*ufc)->object == NULL) return; + + AstCall* call_node = (AstCall *) (*ufc)->call; + + AstArgument* implicit_arg = onyx_ast_node_new(semstate.node_allocator, + sizeof(AstArgument), + Ast_Kind_Argument); + implicit_arg->value = (*ufc)->object; + implicit_arg->next = (AstNode *) call_node->arguments; + + call_node->arguments = implicit_arg; + call_node->arg_count++; + call_node->next = (*ufc)->next; + + symres_expression((AstTyped **) &call_node); + + // NOTE: Not a UFC node + *ufc = (AstUfc *) call_node; +} + static void symres_unaryop(AstUnaryOp** unaryop) { if ((*unaryop)->operation == Unary_Op_Cast) { (*unaryop)->type_node = symres_type((*unaryop)->type_node); @@ -252,6 +281,7 @@ static void symres_expression(AstTyped** expr) { case Ast_Kind_Address_Of: symres_expression(&((AstAddressOf *)(*expr))->expr); break; case Ast_Kind_Dereference: symres_expression(&((AstDereference *)(*expr))->expr); break; case Ast_Kind_Field_Access: symres_field_access((AstFieldAccess **) expr); break; + case Ast_Kind_Ufc: symres_ufc((AstUfc **) expr); break; case Ast_Kind_Size_Of: symres_size_of((AstSizeOf *)*expr); break; case Ast_Kind_Align_Of: symres_align_of((AstAlignOf *)*expr); break; @@ -284,8 +314,8 @@ static void symres_if(AstIf* ifnode) { // // The declaration will cause a problem but semantically the above // doesn't make sense. - if (ifnode->true_stmt != NULL) symres_statement((AstNode *) ifnode->true_stmt); - if (ifnode->false_stmt != NULL) symres_statement((AstNode *) ifnode->false_stmt); + if (ifnode->true_stmt != NULL) symres_statement((AstNode **) &ifnode->true_stmt); + if (ifnode->false_stmt != NULL) symres_statement((AstNode **) &ifnode->false_stmt); } static void symres_while(AstWhile* whilenode) { @@ -310,36 +340,33 @@ static void symres_for(AstFor* fornode) { } // NOTE: Returns 1 if the statment should be removed -static b32 symres_statement(AstNode* stmt) { - switch (stmt->kind) { - case Ast_Kind_Local: symres_local((AstLocal **) &stmt); return 1; - case Ast_Kind_Return: symres_return((AstReturn *) stmt); return 0; - case Ast_Kind_If: symres_if((AstIf *) stmt); return 0; - case Ast_Kind_While: symres_while((AstWhile *) stmt); return 0; - case Ast_Kind_For: symres_for((AstFor *) stmt); return 0; - case Ast_Kind_Call: symres_call((AstCall *) stmt); return 0; - case Ast_Kind_Argument: symres_expression((AstTyped **) &((AstArgument *)stmt)->value); return 0; - case Ast_Kind_Block: symres_block((AstBlock *) stmt); return 0; - case Ast_Kind_Defer: symres_statement(((AstDefer *) stmt)->stmt); return 0; +static b32 symres_statement(AstNode** stmt) { + switch ((*stmt)->kind) { + case Ast_Kind_Local: symres_local((AstLocal **) stmt); return 1; + case Ast_Kind_Return: symres_return((AstReturn *) *stmt); return 0; + case Ast_Kind_If: symres_if((AstIf *) *stmt); return 0; + case Ast_Kind_While: symres_while((AstWhile *) *stmt); return 0; + case Ast_Kind_For: symres_for((AstFor *) *stmt); return 0; + case Ast_Kind_Call: symres_call((AstCall *) *stmt); return 0; + case Ast_Kind_Argument: symres_expression((AstTyped **) &((AstArgument *) *stmt)->value); return 0; + case Ast_Kind_Block: symres_block((AstBlock *) *stmt); return 0; + case Ast_Kind_Defer: symres_statement(&((AstDefer *) *stmt)->stmt); return 0; case Ast_Kind_Break: return 0; case Ast_Kind_Continue: return 0; - default: symres_expression((AstTyped **) &stmt); return 0; + default: symres_expression((AstTyped **) stmt); return 0; } } -static void symres_statement_chain(AstNode* walker, AstNode** trailer) { - while (walker) { +static void symres_statement_chain(AstNode** walker) { + while (*walker) { if (symres_statement(walker)) { - *trailer = walker->next; - - AstNode* tmp = walker->next; - walker->next = NULL; - walker = tmp; + AstNode* tmp = (*walker)->next; + (*walker)->next = NULL; + (*walker) = tmp; } else { - trailer = &walker->next; - walker = walker->next; + walker = &(*walker)->next; } } } @@ -351,7 +378,7 @@ static void symres_block(AstBlock* block) { scope_enter(block->scope); if (block->body) - symres_statement_chain(block->body, &block->body); + symres_statement_chain(&block->body); scope_leave(); }