From cf724a8d13c9436d8e00b408b1d19b534978f607 Mon Sep 17 00:00:00 2001 From: Timerix Date: Wed, 26 Nov 2025 20:56:58 +0500 Subject: [PATCH] updated tlibc --- dependencies/tlibc | 2 +- dependencies/tlibc.config | 14 +-- project.config | 98 ++++++++++--------- project.config.user.default | 11 +++ src/VM/Display/Display.c | 2 + src/VM/VM.c | 2 +- src/compiler/AST.c | 34 +++---- src/compiler/AST.h | 9 ++ src/compiler/Binary.c | 20 ++-- src/compiler/Binary.h | 7 ++ src/compiler/Compiler.c | 164 ++++++++++++++++---------------- src/compiler/Compiler.h | 1 + src/compiler/Lexer.c | 52 +++++----- src/compiler/Parser.c | 91 +++++++++--------- src/compiler/Token.c | 6 +- src/compiler/Token.h | 2 + src/instructions/impl/NOP.c | 1 + src/instructions/instructions.c | 7 +- src/instructions/registers.c | 8 +- 19 files changed, 289 insertions(+), 242 deletions(-) create mode 100644 project.config.user.default diff --git a/dependencies/tlibc b/dependencies/tlibc index c415e2c..6a7f0a8 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit c415e2ca8ff51f41984ace8fe796187e6ad0fa27 +Subproject commit 6a7f0a8715c54029ef71ce8152cd690815f950aa diff --git a/dependencies/tlibc.config b/dependencies/tlibc.config index 94d8d2f..3db058f 100644 --- a/dependencies/tlibc.config +++ b/dependencies/tlibc.config @@ -1,17 +1,17 @@ #!/usr/bin/env bash -########################################################### -# Copy this file to your cbuild DEPENDENCY_CONFIGS_DIR # -# and enable it (ENABLED_DEPENDENCIES=tlibc). # -########################################################### -DEP_WORKING_DIR="dependencies/tlibc" -DEP_PRE_BUILD_COMMAND="" -DEP_POST_BUILD_COMMAND="" + +# This is a dependency config. +# You can copy it to another project to add tlibc dependency. + +DEP_WORKING_DIR="$DEPENDENCIES_DIR/tlibc" if [[ "$TASK" = *_dbg ]]; then dep_build_target="build_static_lib_dbg" else dep_build_target="build_static_lib" fi +DEP_PRE_BUILD_COMMAND="" DEP_BUILD_COMMAND="cbuild $dep_build_target" +DEP_POST_BUILD_COMMAND="" DEP_CLEAN_COMMAND="cbuild clean" DEP_DYNAMIC_OUT_FILES="" DEP_STATIC_OUT_FILES="bin/tlibc.a" diff --git a/project.config b/project.config index 263ec4d..ec26aae 100755 --- a/project.config +++ b/project.config @@ -1,13 +1,22 @@ #!/usr/bin/env bash -CBUILD_VERSION=2.2.3 +CBUILD_VERSION=2.3.2 PROJECT="tcpu" CMP_C="gcc" CMP_CPP="g++" -STD_C="c11" +STD_C="c99" STD_CPP="c++11" -WARN_C="-Wall -Wextra -Werror=return-type -Werror=pointer-arith -Wno-unused-parameter" -WARN_CPP="-Wall -Wextra -Werror=return-type -Werror=pointer-arith -Wno-unused-parameter" +WARN_C="-Wall -Wextra + -Wduplicated-branches + -Wduplicated-cond + -Wformat=2 + -Wmissing-include-dirs + -Wshadow + -Werror=return-type + -Werror=pointer-arith + -Werror=init-self + -Werror=incompatible-pointer-types" +WARN_CPP="$WARN_C" SRC_C="$(find src -name '*.c')" SRC_CPP="$(find src -name '*.cpp')" @@ -24,9 +33,9 @@ ENABLED_DEPENDENCIES='tlibc' # └── profile/ - gcc *.gcda profiling info files OBJDIR="obj" OUTDIR="bin" -STATIC_LIB_FILE="lib$PROJECT.a" +STATIC_LIB_FILE="$PROJECT.a" -INCLUDE="-Isrc -Idependencies/tlibc/include" +INCLUDE="-Isrc -I$DEPENDENCIES_DIR/tlibc/include" # OS-specific options case "$OS" in @@ -58,61 +67,61 @@ case "$TASK" in C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" - PRE_TASK_SCRIPT= - TASK_SCRIPT=cbuild/default_tasks/build_exec.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="" + TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" + POST_TASK_SCRIPT="@cbuild/default_tasks/strip_exec.sh" ;; # creates executable with debug info and no optimizations build_exec_dbg) C_ARGS="-O0 -g3" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" - PRE_TASK_SCRIPT= - TASK_SCRIPT=cbuild/default_tasks/build_exec.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="" + TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" + POST_TASK_SCRIPT="" ;; # creates shared library build_shared_lib) C_ARGS="-O2 -fpic -flto -shared" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" - PRE_TASK_SCRIPT= - TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="" + TASK_SCRIPT="@cbuild/default_tasks/build_shared_lib.sh" + POST_TASK_SCRIPT="" ;; # creates shared library with debug symbols and no optimizations build_shared_lib_dbg) C_ARGS="-O0 -g3 -fpic -shared" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" - PRE_TASK_SCRIPT= - TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="" + TASK_SCRIPT="@cbuild/default_tasks/build_shared_lib.sh" + POST_TASK_SCRIPT="" ;; # creates static library build_static_lib) C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections" CPP_ARGS="$C_ARGS" - PRE_TASK_SCRIPT= - TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="" + TASK_SCRIPT="@cbuild/default_tasks/build_static_lib.sh" + POST_TASK_SCRIPT="" ;; # creates static library with debug symbols and no optimizations build_static_lib_dbg) C_ARGS="-O0 -g3" CPP_ARGS="$C_ARGS" - PRE_TASK_SCRIPT= - TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="" + TASK_SCRIPT="@cbuild/default_tasks/build_static_lib.sh" + POST_TASK_SCRIPT="" ;; # executes $EXEC_FILE exec) - TASK_SCRIPT=cbuild/default_tasks/exec.sh + TASK_SCRIPT="@cbuild/default_tasks/exec.sh" ;; # executes $EXEC_FILE with valgrind memory checker valgrind) - VALGRIND_ARGS="-s --read-var-info=yes --track-origins=yes --fullpath-after=$(pwd) --leak-check=full --show-leak-kinds=all" - TASK_SCRIPT=cbuild/default_tasks/valgrind.sh + VALGRIND_ARGS="-s --read-var-info=yes --track-origins=yes --fullpath-after=$(pwd)/ --leak-check=full --show-leak-kinds=all" + TASK_SCRIPT="@cbuild/default_tasks/valgrind.sh" ;; # generates profiling info profile) @@ -126,22 +135,25 @@ case "$TASK" in C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" - PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh - TASK_SCRIPT=cbuild/default_tasks/profile.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" + TASK_SCRIPT="@cbuild/default_tasks/profile.sh" + POST_TASK_SCRIPT="" ;; # compiles program with -pg and runs it with gprof # uses gprof2dot python script to generate function call tree (pip install gprof2dot) # requires graphviz (https://www.graphviz.org/download/source/) gprof) OUTDIR="$OUTDIR/gprof" - # -pg adds code to executable, that generates file containing function call info (gmon.out) - C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg" + # arguments that emit some call counter code and disable optimizations to see function names + # https://github.com/msys2/MINGW-packages/issues/8503#issuecomment-1365475205 + C_ARGS="-O0 -g -pg -no-pie -fno-omit-frame-pointer + -fno-inline-functions -fno-inline-functions-called-once + -fno-optimize-sibling-calls -fopenmp" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" - PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh - TASK_SCRIPT=cbuild/default_tasks/gprof.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" + TASK_SCRIPT="@cbuild/default_tasks/gprof.sh" + POST_TASK_SCRIPT="" ;; # compiles program and runs it with callgrind (part of valgrind) # uses gprof2dot python script to generate function call tree (pip install gprof2dot) @@ -153,9 +165,9 @@ case "$TASK" in C_ARGS="-O2 -flto=auto -fuse-linker-plugin" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" - PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh - TASK_SCRIPT=cbuild/default_tasks/callgrind.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" + TASK_SCRIPT="@cbuild/default_tasks/callgrind.sh" + POST_TASK_SCRIPT="" ;; # compiles executable with sanitizers and executes it to find errors and warnings sanitize) @@ -163,19 +175,19 @@ case "$TASK" in C_ARGS="-O0 -g3 -fsanitize=undefined,address" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" - PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh - TASK_SCRIPT=cbuild/default_tasks/exec.sh - POST_TASK_SCRIPT= + PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" + TASK_SCRIPT="@cbuild/default_tasks/exec.sh" + POST_TASK_SCRIPT="" ;; # rebuilds specified dependencies # EXAMPLE: `cbuild rebuild_dependencies=libexample1,fonts` # 'all' can be specified to rebuild all dependencies rebuild_dependencies) - TASK_SCRIPT=cbuild/default_tasks/rebuild_dependencies.sh + TASK_SCRIPT="@cbuild/default_tasks/rebuild_dependencies.sh" ;; # deletes generated files clean) - TASK_SCRIPT=cbuild/default_tasks/clean.sh + TASK_SCRIPT="@cbuild/default_tasks/clean.sh" ;; # nothing to do "" | no_task) diff --git a/project.config.user.default b/project.config.user.default new file mode 100644 index 0000000..f77d4b2 --- /dev/null +++ b/project.config.user.default @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# Project user config is ignored by git. +# Here you can add variables that users might want to change +# on their local machine, without commiting to the repository. + +# Directory where you install dependencies. +# Do not confuse with DEPENDENCY_CONFIGS_DIR +# Example: +# libexample source code is at `../libexample`, and dependency config +# that specifies how to build this lib is at `dependencies/libexample.config` +DEPENDENCIES_DIR="dependencies" diff --git a/src/VM/Display/Display.c b/src/VM/Display/Display.c index ac3c165..338d6ac 100644 --- a/src/VM/Display/Display.c +++ b/src/VM/Display/Display.c @@ -15,6 +15,8 @@ static Display _d = {0}; static cstr _title = "TCPU v" TCPU_VERSION_CSTR; bool Display_init(i32 w, i32 h, DisplayFlags flags){ + (void)flags; + _d.width = w; _d.height = h; _d.window = NULL; diff --git a/src/VM/VM.c b/src/VM/VM.c index 4515221..1f48e00 100644 --- a/src/VM/VM.c +++ b/src/VM/VM.c @@ -12,7 +12,7 @@ void _VM_setError(VM* vm, cstr context, cstr format, ...){ sprintf(position_str, "[at 0x%x][", (u32)vm->current_pos); char* real_format = strcat_malloc(position_str, context, "] ", format); va_start(argv, format); - char* NULLABLE(buf) = vsprintf_malloc(256, real_format, argv); + char* NULLABLE(buf) = vsprintf_malloc(real_format, argv); va_end(argv); free(real_format); if(buf == NULL){ diff --git a/src/compiler/AST.c b/src/compiler/AST.c index 3e2f092..de21f99 100644 --- a/src/compiler/AST.c +++ b/src/compiler/AST.c @@ -1,5 +1,7 @@ #include "AST.h" +Array_declare(str); + static Array(str) _ArgumentType_str_array = ARRAY(str, { STR("Unset"), STR("Register"), @@ -10,40 +12,40 @@ static Array(str) _ArgumentType_str_array = ARRAY(str, { }); str ArgumentType_toString(ArgumentType t){ - if(t >= Array_len(&_ArgumentType_str_array, str)) + if(t >= _ArgumentType_str_array.len) return STR("!!ArgumentType INDEX_ERROR!!"); - return ((str*)_ArgumentType_str_array.data)[t]; + return _ArgumentType_str_array.data[t]; } void Section_construct(Section* sec, str name){ sec->name = name; - sec->data_definitions_list = List_alloc(DataDefinition, 256); - sec->operations_list = List_alloc(Operation, 1024); + sec->data_definitions_list = List_DataDefinition_alloc(256); + sec->operations_list = List_Operation_alloc(1024); } void Section_destroy(Section* sec){ - for(u32 i = 0; i < Array_len(&sec->data_definitions_list, DataDefinition); i++){ - DataDefinition* dd = (DataDefinition*)sec->data_definitions_list.data + i; - free(dd->data_bytes.data); + for(u32 i = 0; i < sec->data_definitions_list.len; i++){ + DataDefinition* dd = sec->data_definitions_list.data + i; + List_u8_destroy(&dd->data_bytes); } - free(sec->data_definitions_list.data); + List_DataDefinition_destroy(&sec->data_definitions_list); - for(u32 i = 0; i < Array_len(&sec->operations_list, Operation); i++){ - Operation* op = (Operation*)sec->operations_list.data + i; - free(op->args.data); + for(u32 i = 0; i < sec->operations_list.len; i++){ + Operation* op = sec->operations_list.data + i; + List_Argument_destroy(&op->args); } - free(sec->operations_list.data); + List_Operation_destroy(&sec->operations_list); } void AST_construct(AST* ast){ - ast->sections = List_alloc(Section, 32); + ast->sections = List_Section_alloc(32); } void AST_destroy(AST* ast){ - for(u32 i = 0; i != Array_len(&ast->sections, Section); i++){ - Section_destroy((Section*)ast->sections.data + i); + for(u32 i = 0; i != ast->sections.len; i++){ + Section_destroy(ast->sections.data + i); } - free(ast->sections.data); + List_Section_destroy(&ast->sections); } diff --git a/src/compiler/AST.h b/src/compiler/AST.h index dfe6336..3734fdc 100644 --- a/src/compiler/AST.h +++ b/src/compiler/AST.h @@ -4,6 +4,7 @@ #include "instructions/instructions.h" #include "instructions/registers.h" #include "tlibc/collections/List.h" +#include "tlibc/collections/List_impl/List_u8.h" typedef enum ArgumentType { ArgumentType_Unset, @@ -26,12 +27,16 @@ typedef struct Argument { } value; } Argument; +List_declare(Argument); + typedef struct Operation { List(Argument) args; Opcode opcode; } Operation; +List_declare(Operation); + typedef struct DataDefinition { str name; @@ -39,6 +44,8 @@ typedef struct DataDefinition { u32 element_size; } DataDefinition; +List_declare(DataDefinition); + typedef struct Section { str name; @@ -46,6 +53,8 @@ typedef struct Section { List(Operation) operations_list; } Section; +List_declare(Section); + void Section_construct(Section* Section, str name); void Section_destroy(Section* Section); diff --git a/src/compiler/Binary.c b/src/compiler/Binary.c index d26c8eb..25b2b6d 100644 --- a/src/compiler/Binary.c +++ b/src/compiler/Binary.c @@ -4,20 +4,20 @@ void CompiledSection_construct(CompiledSection* ptr, str name){ ptr->name = name; ptr->next = NULL; ptr->offset = 0; - ptr->const_data_props_list = List_construct(ConstDataProps, NULL, 0, 0); - ptr->named_refs = List_construct(NamedRef, NULL, 0, 0); - ptr->bytes = List_alloc(u8, 64); + ptr->const_data_props_list = List_ConstDataProps_construct(NULL, 0, 0); + ptr->named_refs = List_NamedRef_construct(NULL, 0, 0); + ptr->bytes = List_u8_alloc(128); } void CompiledSection_destroy(CompiledSection* ptr){ - free(ptr->const_data_props_list.data); - free(ptr->named_refs.data); - free(ptr->bytes.data); + List_ConstDataProps_destroy(&ptr->const_data_props_list); + List_NamedRef_destroy(&ptr->named_refs); + List_u8_destroy(&ptr->bytes); } void BinaryObject_construct(BinaryObject* ptr){ - ptr->comp_sec_list = List_alloc(CompiledSection, 64); + ptr->comp_sec_list = List_CompiledSection_alloc(64); HashMap_construct(&ptr->comp_sec_i_map, u32, NULL); HashMap_construct(&ptr->const_data_props_map, ConstDataProps, NULL); ptr->main_sec = NULL; @@ -25,11 +25,11 @@ void BinaryObject_construct(BinaryObject* ptr){ } void BinaryObject_destroy(BinaryObject* ptr){ - for(u32 i = 0; i < List_len(&ptr->comp_sec_list, CompiledSection); i++){ - CompiledSection* sec_ptr = (CompiledSection*)ptr->comp_sec_list.data + i; + for(u32 i = 0; i < ptr->comp_sec_list.len; i++){ + CompiledSection* sec_ptr = ptr->comp_sec_list.data + i; CompiledSection_destroy(sec_ptr); } - free(ptr->comp_sec_list.data); + List_CompiledSection_destroy(&ptr->comp_sec_list); HashMap_destroy(&ptr->comp_sec_i_map); HashMap_destroy(&ptr->const_data_props_map); diff --git a/src/compiler/Binary.h b/src/compiler/Binary.h index 7a08615..ce69d1d 100644 --- a/src/compiler/Binary.h +++ b/src/compiler/Binary.h @@ -4,6 +4,7 @@ #include "instructions/instructions.h" #include "instructions/registers.h" #include "tlibc/collections/List.h" +#include "tlibc/collections/List_impl/List_u8.h" #include "tlibc/collections/HashMap.h" #include "AST.h" @@ -14,6 +15,8 @@ typedef struct ConstDataProps { u32 offset; // offset in bytes from section start } ConstDataProps; +List_declare(ConstDataProps) + #define ConstDataProps_construct(NAME, SIZE, OFFSET) ((ConstDataProps){ .name = NAME, .size = SIZE, .offset = OFFSET}) @@ -29,6 +32,8 @@ typedef struct NamedRef { u32 offset; // offset in bytes from section start } NamedRef; +List_declare(NamedRef); + #define NamedRef_construct(NAME, TYPE, OFFSET) ((NamedRef){ .name = NAME, .type = TYPE, .offset = OFFSET}) @@ -41,6 +46,8 @@ typedef struct CompiledSection { List(u8) bytes; } CompiledSection; +List_declare(CompiledSection) + void CompiledSection_construct(CompiledSection* ptr, str name); void CompiledSection_destroy(CompiledSection* ptr); diff --git a/src/compiler/Compiler.c b/src/compiler/Compiler.c index 8b4f9a6..b39ee6f 100644 --- a/src/compiler/Compiler.c +++ b/src/compiler/Compiler.c @@ -3,27 +3,27 @@ void Compiler_construct(Compiler* cmp){ memset(cmp, 0, sizeof(Compiler)); cmp->state = CompilerState_Initial; - cmp->tokens = List_alloc(Token, 4096); - cmp->line_lengths = List_alloc(u32, 1024); + cmp->tokens = List_Token_alloc(4096); + cmp->line_lengths = List_u32_alloc(1024); AST_construct(&cmp->ast); BinaryObject_construct(&cmp->binary); } void Compiler_destroy(Compiler* cmp){ - free(cmp->code.data); - free(cmp->tokens.data); - free(cmp->line_lengths.data); + str_destroy(cmp->code); + List_Token_destroy(&cmp->tokens); + List_u32_destroy(&cmp->line_lengths); AST_destroy(&cmp->ast); BinaryObject_destroy(&cmp->binary); } CodePos Compiler_getLineAndColumn(Compiler* cmp, u32 pos){ u32 prev_lines_len = 0; - if(pos >= cmp->code.size) + if(pos >= cmp->code.len) return CodePos_create(0, 0); - for(u32 i = 0; i < List_len(&cmp->line_lengths, u32); i++){ - u32 line_len = ((u32*)cmp->line_lengths.data)[i]; + for(u32 i = 0; i < cmp->line_lengths.len; i++){ + u32 line_len = cmp->line_lengths.data[i]; if(prev_lines_len + line_len > pos) return CodePos_create(i + 1, pos + 1 - prev_lines_len); prev_lines_len += line_len; @@ -34,15 +34,15 @@ CodePos Compiler_getLineAndColumn(Compiler* cmp, u32 pos){ void _Compiler_setError(Compiler* cmp, cstr context, cstr format, ...){ // happens at the end of file - if(cmp->pos >= cmp->code.size) - cmp->pos = cmp->code.size - 1; + if(cmp->pos >= cmp->code.len) + cmp->pos = cmp->code.len - 1; char position_str[32]; CodePos code_pos = Compiler_getLineAndColumn(cmp, cmp->pos); sprintf(position_str, "[at %u:%u][", code_pos.line, code_pos.column); char* real_format = strcat_malloc(position_str, context, "] ", format); va_list argv; va_start(argv, format); - char* NULLABLE(buf) = vsprintf_malloc(512, real_format, argv); + char* NULLABLE(buf) = vsprintf_malloc(real_format, argv); va_end(argv); free(real_format); if(buf == NULL){ @@ -62,21 +62,24 @@ str Compiler_constructTokenStr(Compiler* cmp, Token t){ return s; } +#define List_u8_pushStruct(L_PTR, S_PTR) List_u8_pushMany((L_PTR), (void*)(S_PTR), sizeof(*(S_PTR))) + static bool compileSection(Compiler* cmp, Section* sec){ - u32 cs_index = List_len(&cmp->binary.comp_sec_list, CompiledSection); - CompiledSection* cs = List_expand_size(&cmp->binary.comp_sec_list, sizeof(CompiledSection)); + u32 cs_index = cmp->binary.comp_sec_list.len; + CompiledSection* cs = List_CompiledSection_expand(&cmp->binary.comp_sec_list, 1); CompiledSection_construct(cs, sec->name); if(!HashMap_tryPush(&cmp->binary.comp_sec_i_map, cs->name, &cs_index)){ returnError("duplicate section '%s'", str_copy(sec->name).data); } // compile code - u8 zeroes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - for(u32 i = 0; i < List_len(&sec->operations_list, Operation); i++){ - Operation* op = (Operation*)sec->operations_list.data + i; - List_pushMany(&cs->bytes, u8, &op->opcode, sizeof(op->opcode)); - for(u32 j = 0; j < List_len(&op->args, Argument); j++){ - Argument* arg = (Argument*)op->args.data + j; + u8 zeroes_8[8]; + memset(zeroes_8, 0, sizeof(zeroes_8)); + for(u32 i = 0; i < sec->operations_list.len; i++){ + Operation* op = sec->operations_list.data + i; + List_u8_pushStruct(&cs->bytes, &op->opcode); + for(u32 j = 0; j < op->args.len; j++){ + Argument* arg = op->args.data + j; switch(arg->type){ case ArgumentType_VarDataName: returnError("argument type 'VarDataName' is not supported yet"); @@ -86,35 +89,41 @@ static bool compileSection(Compiler* cmp, Section* sec){ returnError("invalid ArgumentType %i", arg->type); case ArgumentType_Register: - List_push(&cs->bytes, u8, arg->value.register_code); + List_u8_push(&cs->bytes, arg->value.register_code); break; case ArgumentType_ConstValue: - List_pushMany(&cs->bytes, u8, &arg->value.i, 8); + List_u8_pushStruct(&cs->bytes, &arg->value.i); break; case ArgumentType_ConstDataPointer: - List_push(&cs->named_refs, NamedRef, NamedRef_construct( + List_NamedRef_push(&cs->named_refs, + NamedRef_construct( arg->value.data_name, NamedRefType_Ptr, - cs->bytes.size)); - List_pushMany(&cs->bytes, u8, zeroes, 8); + cs->bytes.len + ) + ); + List_u8_pushStruct(&cs->bytes, zeroes_8); break; case ArgumentType_ConstDataSize: - List_push(&cs->named_refs, NamedRef, NamedRef_construct( + List_NamedRef_push(&cs->named_refs, + NamedRef_construct( arg->value.data_name, NamedRefType_Size, - cs->bytes.size)); - List_pushMany(&cs->bytes, u8, zeroes, 8); + cs->bytes.len + ) + ); + List_u8_pushStruct(&cs->bytes, zeroes_8); break; } } } // compile data - for(u32 i = 0; i < List_len(&sec->data_definitions_list, DataDefinition); i++){ - DataDefinition* dd = (DataDefinition*)sec->data_definitions_list.data + i; - List_push(&cs->const_data_props_list, ConstDataProps, - ConstDataProps_construct(dd->name, dd->data_bytes.size, cs->bytes.size)); - List_pushMany(&cs->bytes, u8, dd->data_bytes.data, dd->data_bytes.size); + for(u32 i = 0; i < sec->data_definitions_list.len; i++){ + DataDefinition* dd = sec->data_definitions_list.data + i; + ConstDataProps cd_props = ConstDataProps_construct(dd->name, dd->data_bytes.len, cs->bytes.len); + List_ConstDataProps_push(&cs->const_data_props_list, cd_props); + List_u8_pushMany(&cs->bytes, dd->data_bytes.data, dd->data_bytes.len); } // TODO: push padding @@ -126,8 +135,8 @@ static bool compileBinary(Compiler* cmp){ returnErrorIf_auto(cmp->state != CompilerState_Parsing); cmp->state = CompilerState_Compiling; - for(u32 i = 0; i < List_len(&cmp->ast.sections, Section); i++){ - Section* sec = (Section*)cmp->ast.sections.data + i; + for(u32 i = 0; i < cmp->ast.sections.len; i++){ + Section* sec = cmp->ast.sections.data + i; if(!compileSection(cmp, sec)){ return false; } @@ -140,25 +149,25 @@ static bool compileBinary(Compiler* cmp){ returnError("no 'main' section was defined"); } u32 main_sec_i = *main_sec_i_ptr; - cmp->binary.main_sec = (CompiledSection*)cmp->binary.comp_sec_list.data + main_sec_i; + cmp->binary.main_sec = cmp->binary.comp_sec_list.data + main_sec_i; // create linked list of CompiledSection where main is the first CompiledSection* prev_sec = cmp->binary.main_sec; u32 total_size = 0; - for(u32 i = 0; i < List_len(&cmp->binary.comp_sec_list, CompiledSection); i++){ - CompiledSection* sec = (CompiledSection*)cmp->binary.comp_sec_list.data + i; - total_size += sec->bytes.size; + for(u32 i = 0; i < cmp->binary.comp_sec_list.len; i++){ + CompiledSection* sec = cmp->binary.comp_sec_list.data + i; + total_size += sec->bytes.len; bool is_main_sec = str_equals(sec->name, main_sec_name); if(!is_main_sec){ - sec->offset = prev_sec->offset + prev_sec->bytes.size; + sec->offset = prev_sec->offset + prev_sec->bytes.len; } - ConstDataProps cd = ConstDataProps_construct(sec->name, sec->bytes.size, sec->offset); + ConstDataProps cd = ConstDataProps_construct(sec->name, sec->bytes.len, sec->offset); if(!HashMap_tryPush(&cmp->binary.const_data_props_map, cd.name, &cd)){ returnError("duplicate named data '%s'", str_copy(cd.name).data); } - for(u32 j = 0; j < List_len(&sec->const_data_props_list, ConstDataProps); j++){ - cd = ((ConstDataProps*)sec->const_data_props_list.data)[j]; + for(u32 j = 0; j < sec->const_data_props_list.len; j++){ + cd = sec->const_data_props_list.data[j]; cd.offset += sec->offset; if(!HashMap_tryPush(&cmp->binary.const_data_props_map, cd.name, &cd)){ returnError("duplicate named data '%s'", str_copy(cd.name).data); @@ -172,10 +181,10 @@ static bool compileBinary(Compiler* cmp){ } // insert calculated offsets into sections - for(u32 i = 0; i < List_len(&cmp->binary.comp_sec_list, CompiledSection); i++){ - CompiledSection* sec = (CompiledSection*)cmp->binary.comp_sec_list.data + i; - for(u32 j = 0; j < List_len(&sec->named_refs, NamedRef); j++){ - NamedRef* ref = (NamedRef*)sec->named_refs.data +j; + for(u32 i = 0; i < cmp->binary.comp_sec_list.len; i++){ + CompiledSection* sec = cmp->binary.comp_sec_list.data + i; + for(u32 j = 0; j < sec->named_refs.len; j++){ + NamedRef* ref = sec->named_refs.data + j; ConstDataProps* target_data = HashMap_tryGetPtr( &cmp->binary.const_data_props_map, ref->name); @@ -206,7 +215,7 @@ static bool writeBinaryFile(Compiler* cmp, FILE* f){ CompiledSection* sec = cmp->binary.main_sec; while(sec){ - fwrite(sec->bytes.data, 1, sec->bytes.size, f); + fwrite(sec->bytes.data, 1, sec->bytes.len, f); fflush(f); sec = sec->next; } @@ -232,7 +241,7 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name, } fclose(f); - if(sb.buffer.size == 0){ + if(sb.buffer.len == 0){ StringBuilder_destroy(&sb); returnError("soucre file is empty"); } @@ -257,13 +266,13 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name, if(debug_log){ printf("------------------------------------[lines]------------------------------------\n"); - for(u32 i = 0; i < List_len(&cmp->line_lengths, u32); i++){ - printf("[%u] length: %u\n", i+1, ((u32*)cmp->line_lengths.data)[i]); + for(u32 i = 0; i < cmp->line_lengths.len; i++){ + printf("[%u] length: %u\n", i+1, cmp->line_lengths.data[i]); } printf("------------------------------------[tokens]-----------------------------------\n"); - for(u32 i = 0; i < List_len(&cmp->tokens, Token); i++){ - Token t = ((Token*)cmp->tokens.data)[i]; + for(u32 i = 0; i < cmp->tokens.len; i++){ + Token t = cmp->tokens.data[i]; CodePos pos = Compiler_getLineAndColumn(cmp, t.begin); char* tokstr = malloc(4096); strncpy(tokstr, cmp->code.data + t.begin, t.length); @@ -290,23 +299,21 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name, if (debug_log){ printf("-------------------------------------[AST]-------------------------------------\n"); - for(u32 i = 0; i < List_len(&cmp->ast.sections, Section); i++){ - Section* sec = (Section*)cmp->ast.sections.data + i; - str tmpstr = str_copy(sec->name); - printf("section '%s'\n", tmpstr.data); - free(tmpstr.data); + for(u32 i = 0; i < cmp->ast.sections.len; i++){ + Section* sec = cmp->ast.sections.data + i; + printf("section '"FMT_str"'\n", sec->name.len, sec->name.data); - for(u32 j = 0; j < List_len(&sec->data_definitions_list, DataDefinition); j++){ - DataDefinition* dd = (DataDefinition*)sec->data_definitions_list.data + j; - tmpstr = str_copy(dd->name); - printf(" const%u %s (len %u)\n", dd->element_size * 8, tmpstr.data, - dd->data_bytes.size/dd->element_size); - free(tmpstr.data); + for(u32 j = 0; j < sec->data_definitions_list.len; j++){ + DataDefinition* dd = sec->data_definitions_list.data + j; + printf(" const%u "FMT_str" (len %u)\n", + dd->element_size * 8, + dd->name.len, dd->name.data, + dd->data_bytes.len/dd->element_size); } - for(u32 j = 0; j < List_len(&sec->operations_list, Operation); j++){ - Operation* op = (Operation*)sec->operations_list.data + j; + for(u32 j = 0; j < sec->operations_list.len; j++){ + Operation* op = sec->operations_list.data + j; const Instruction* instr = Instruction_getByOpcode(op->opcode); if(instr == NULL){ fclose(f); @@ -314,8 +321,8 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name, } printf(" %s", instr->name.data); - for(u32 k = 0; k < List_len(&op->args, Argument); k++){ - Argument* arg = (Argument*)op->args.data + k; + for(u32 k = 0; k < op->args.len; k++){ + Argument* arg = op->args.data + k; printf(" %s(", ArgumentType_toString(arg->type).data); switch(arg->type){ @@ -325,25 +332,19 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name, case ArgumentType_Register:; str register_name = RegisterCode_toString(arg->value.register_code); printf("%s 0x%x", register_name.data, arg->value.register_code); - free(register_name.data); + str_destroy(register_name); break; case ArgumentType_ConstValue: printf(IFWIN("%lli", "%li"), arg->value.i); break; case ArgumentType_ConstDataPointer: - tmpstr = str_copy(arg->value.data_name); - printf("@%s", tmpstr.data); - free(tmpstr.data); + printf("@"FMT_str, arg->value.data_name.len, arg->value.data_name.data); break; case ArgumentType_ConstDataSize: - tmpstr = str_copy(arg->value.data_name); - printf("#%s", tmpstr.data); - free(tmpstr.data); + printf("#"FMT_str, arg->value.data_name.len, arg->value.data_name.data); break; case ArgumentType_VarDataName: - tmpstr = str_copy(arg->value.data_name); - printf("%s", tmpstr.data); - free(tmpstr.data); + printf(FMT_str, arg->value.data_name.len, arg->value.data_name.data); break; } @@ -365,11 +366,10 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name, success = compileBinary(cmp); if(debug_log){ - for(u32 i = 0; i < List_len(&cmp->binary.comp_sec_list, CompiledSection); i++){ - CompiledSection* sec = (CompiledSection*)cmp->binary.comp_sec_list.data + i; - str tmpstr = str_copy(sec->name); - printf("compiled section '%s' to %u bytes with offset 0x%x\n", tmpstr.data, sec->bytes.size, sec->offset); - free(tmpstr.data); + for(u32 i = 0; i < cmp->binary.comp_sec_list.len; i++){ + CompiledSection* sec = cmp->binary.comp_sec_list.data + i; + printf("compiled section '"FMT_str"' to %u bytes with offset 0x%x\n", + sec->name.len, sec->name.data, sec->bytes.len, sec->offset); } } diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h index 0c050bf..9652a48 100644 --- a/src/compiler/Compiler.h +++ b/src/compiler/Compiler.h @@ -2,6 +2,7 @@ #include "tlibc/std.h" #include "tlibc/string/str.h" #include "tlibc/collections/List.h" +#include "tlibc/collections/List_impl/List_u32.h" #include "tlibc/collections/HashMap.h" #include "Token.h" #include "Binary.h" diff --git a/src/compiler/Lexer.c b/src/compiler/Lexer.c index 76a39e9..f55cda2 100644 --- a/src/compiler/Lexer.c +++ b/src/compiler/Lexer.c @@ -9,7 +9,7 @@ #define Error_endOfFile "unexpected end of file" static void completeLine(Compiler* cmp){ - List_push(&cmp->line_lengths, u32, cmp->column); + List_u32_push(&cmp->line_lengths, cmp->column); cmp->column = 0; } @@ -19,12 +19,12 @@ static void readCommentSingleLine(Compiler* cmp){ cmp->column++; cmp->pos++; - while(cmp->pos < cmp->code.size){ + while(cmp->pos < cmp->code.len){ c = cmp->code.data[cmp->pos]; // end of line if(c == '\r' || c == '\n'){ tok.length = cmp->pos - tok.begin; - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); // cmp->line will be increased in lex() return; } @@ -35,7 +35,7 @@ static void readCommentSingleLine(Compiler* cmp){ // end of file tok.length = cmp->pos - tok.begin; - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); } static void readCommentMultiLine(Compiler* cmp){ @@ -44,12 +44,12 @@ static void readCommentMultiLine(Compiler* cmp){ cmp->column++; cmp->pos++; - while(cmp->pos < cmp->code.size){ + while(cmp->pos < cmp->code.len){ c = cmp->code.data[cmp->pos]; // closing comment if(cmp->pos > tok.begin + 3 && c == '/' && cmp->code.data[cmp->pos - 1] == '*') { tok.length = cmp->pos - tok.begin + 1; - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); return; } @@ -65,7 +65,7 @@ static void readCommentMultiLine(Compiler* cmp){ static void readComment(Compiler* cmp){ char c; // '/' - if(cmp->pos + 1 == cmp->code.size){ + if(cmp->pos + 1 == cmp->code.len){ setError(Error_endOfFile); return; } @@ -91,19 +91,19 @@ static void readLabel(Compiler* cmp){ cmp->column++; Token tok = Token_construct(TokenType_Label, cmp->pos, 0); - while(cmp->pos < cmp->code.size){ + while(cmp->pos < cmp->code.len){ c = cmp->code.data[cmp->pos]; // end of line if(c == ':' || c == '\r' || c == '\n'){ tok.length = cmp->pos - tok.begin; if(tok.length > 0) - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); else setError(Error_unexpectedCharacter(cmp->code.data[--cmp->pos])); // cmp->line will be increased in lex() return; } - if(!isAlphabeticalLower(c) && !isAlphabeticalUpper(c) && !isDigit(c) && + if(!char_isLatinLower(c) && !char_isLatinUpper(c) && !char_isDigit(c) && c != '_' && c != '.'){ setError(Error_unexpectedCharacter(c)); return; @@ -116,7 +116,7 @@ static void readLabel(Compiler* cmp){ // end of file tok.length = cmp->pos - tok.begin; if(tok.length > 0) - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); else setError(Error_endOfFile); } @@ -125,7 +125,7 @@ static void readArguments(Compiler* cmp){ Token tok = Token_construct(TokenType_Unset, cmp->pos, 0); char quot = '\0'; // quotation character of a string value - while(cmp->pos < cmp->code.size){ + while(cmp->pos < cmp->code.len){ c = cmp->code.data[cmp->pos]; // string argument reading @@ -143,7 +143,7 @@ static void readArguments(Compiler* cmp){ else if(c == '\r' || c == '\n' || c == ';'){ tok.length = cmp->pos - tok.begin; if(tok.length > 0) - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); // cmp->line will be increased in lex() return; } @@ -152,7 +152,7 @@ static void readArguments(Compiler* cmp){ else if(c == ' ' || c == '\t'){ tok.length = cmp->pos - tok.begin; if(tok.length > 0) - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); tok = Token_construct(TokenType_Unset, cmp->pos + 1, 0); } @@ -169,7 +169,7 @@ static void readArguments(Compiler* cmp){ tok.type = TokenType_NamedDataPointer; else if(c == '#') tok.type = TokenType_NamedDataSize; - else if(isDigit(c)) + else if(char_isDigit(c)) tok.type = TokenType_Number; else tok.type = TokenType_Name; } @@ -181,7 +181,7 @@ static void readArguments(Compiler* cmp){ // end of file tok.length = cmp->pos - tok.begin; if(tok.length > 0) - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); } static void readInstruction(Compiler* cmp){ @@ -189,14 +189,14 @@ static void readInstruction(Compiler* cmp){ cmp->pos++; cmp->column++; - while(cmp->pos < cmp->code.size){ + while(cmp->pos < cmp->code.len){ char c = cmp->code.data[cmp->pos]; // end of line if(c == '\r' || c == '\n' || c == ';'){ tok.length = cmp->pos - tok.begin; - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); tok = Token_construct(TokenType_OperationEnd, cmp->pos, 1); - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); // cmp->line will be increased in lex() return; } @@ -204,14 +204,14 @@ static void readInstruction(Compiler* cmp){ // arguments begin if(c == ' ' || c == '\t'){ tok.length = cmp->pos - tok.begin; - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); readArguments(cmp); tok = Token_construct(TokenType_OperationEnd, cmp->pos, 1); - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); return; } - if(!isAlphabeticalLower(c) && !isAlphabeticalUpper(c) && !isDigit(c)){ + if(!char_isLatinLower(c) && !char_isLatinUpper(c) && !char_isDigit(c)){ setError(Error_unexpectedCharacter(c)); return; } @@ -222,9 +222,9 @@ static void readInstruction(Compiler* cmp){ // end of file tok.length = cmp->pos - tok.begin; - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); tok = Token_construct(TokenType_OperationEnd, cmp->pos, 1); - List_push(&cmp->tokens, Token, tok); + List_Token_push(&cmp->tokens, tok); } bool Compiler_lex(Compiler* cmp){ @@ -232,7 +232,7 @@ bool Compiler_lex(Compiler* cmp){ cmp->state = CompilerState_Lexing; cmp->column = 1; - while(cmp->pos < cmp->code.size){ + while(cmp->pos < cmp->code.len){ char c = cmp->code.data[cmp->pos]; switch(c){ // skip blank characters @@ -248,7 +248,7 @@ bool Compiler_lex(Compiler* cmp){ break; default: // try read instruction - if(isAlphabeticalLower(c) || isAlphabeticalUpper(c)) + if(char_isLatinLower(c) || char_isLatinUpper(c)) readInstruction(cmp); else returnError(Error_unexpectedCharacter(c)); break; diff --git a/src/compiler/Parser.c b/src/compiler/Parser.c index c92c838..620143e 100644 --- a/src/compiler/Parser.c +++ b/src/compiler/Parser.c @@ -1,42 +1,37 @@ #include "Compiler_internal.h" #define setError(FORMAT, ...) {\ - cmp->pos = ((Token*)cmp->tokens.data)[cmp->tok_i].begin;\ + cmp->pos = cmp->tokens.data[cmp->tok_i].begin;\ Compiler_setError(cmp, FORMAT, ##__VA_ARGS__);\ } #define setError_unexpectedToken(T) {\ - str tok_str = str_copy(Compiler_constructTokenStr(cmp, T));\ + str tok_str_tmp = Compiler_constructTokenStr(cmp, T);\ cmp->pos = T.begin;\ - Compiler_setError(cmp, "unexpected token '%s'", tok_str.data);\ - free(tok_str.data);\ + Compiler_setError(cmp, "unexpected token '"FMT_str"'", tok_str_tmp.len, tok_str_tmp.data);\ } #define setError_unexpectedTokenChar(T, I) {\ cmp->pos = T.begin + I;\ - Compiler_setError(cmp, "unexpected token '%c'", cmp->code.data[cmp->pos]);\ + Compiler_setError(cmp, "unexpected character '%c'", cmp->code.data[cmp->pos]);\ } #define setError_unexpectedInstruction(T) {\ - str tok_str = str_copy(Compiler_constructTokenStr(cmp, T));\ + str tok_str_tmp = Compiler_constructTokenStr(cmp, T);\ cmp->pos = T.begin;\ - Compiler_setError(cmp, "unexpected instruction '%s'", tok_str.data);\ - free(tok_str.data);\ + Compiler_setError(cmp, "unexpected instruction '"FMT_str"'", tok_str_tmp.len, tok_str_tmp.data);\ } #define Error_TokenUnset "token of undefined type" #define Error_BitSize "invalid size in bits" -#define List_pushAsBytes(L, VAL_PTR, START_INDEX, COUNT)\ - List_push_size(L, (u8*)(VAL_PTR) + START_INDEX, COUNT) - static inline bool isVarSizeBits(u32 B) { return (B == 8 || B == 16 || B == 32 || B == 64); } static NULLABLE(str) resolveEscapeSequences(Compiler* cmp, str src){ - StringBuilder sb = StringBuilder_alloc(src.size); + StringBuilder sb = StringBuilder_alloc(src.len); char c; bool escaped = false; - for(u32 i = 0; i < src.size; i++){ + for(u32 i = 0; i < src.len; i++){ c = src.data[i]; if(c == '\\'){ escaped = !escaped; @@ -71,7 +66,7 @@ static NULLABLE(str) resolveEscapeSequences(Compiler* cmp, str src){ StringBuilder_append_char(&sb, c); break; default: - setError_unexpectedTokenChar(((Token*)cmp->tokens.data)[cmp->tok_i], i); + setError_unexpectedTokenChar(cmp->tokens.data[cmp->tok_i], i); StringBuilder_destroy(&sb); return str_null; } @@ -86,15 +81,15 @@ static void parseDataDefinition(Compiler* cmp, str instr_name, DataDefinition* d i32 _element_size_bits; str _instr_name_zero_terminated = str_copy(instr_name); if(sscanf(_instr_name_zero_terminated.data, "const%i", &_element_size_bits) != 1 || !isVarSizeBits(_element_size_bits)){ - free(_instr_name_zero_terminated.data); + str_destroy(_instr_name_zero_terminated); setError(Error_BitSize); return; } - free(_instr_name_zero_terminated.data); + str_destroy(_instr_name_zero_terminated); ddf->element_size = _element_size_bits / 8; - ddf->data_bytes = List_alloc(u8, 32); + ddf->data_bytes = List_u8_alloc(32); - Token tok = ((Token*)cmp->tokens.data)[++cmp->tok_i]; + Token tok = cmp->tokens.data[++cmp->tok_i]; if(tok.type != TokenType_Name){ setError_unexpectedToken(tok); return; @@ -104,8 +99,8 @@ static void parseDataDefinition(Compiler* cmp, str instr_name, DataDefinition* d str processed_str = str_null; ddf->name = tok_str; - while(++cmp->tok_i < List_len(&cmp->tokens, Token)){ - tok = ((Token*)cmp->tokens.data)[cmp->tok_i]; + while(++cmp->tok_i < cmp->tokens.len){ + tok = cmp->tokens.data[cmp->tok_i]; switch(tok.type){ case TokenType_SingleLineComment: case TokenType_MultiLineComment: @@ -126,13 +121,17 @@ static void parseDataDefinition(Compiler* cmp, str instr_name, DataDefinition* d processed_str = str_copy(tok_str); if(str_seekChar(tok_str, '.', 0) != -1){ f64 f = atof(processed_str.data); - List_pushAsBytes(&ddf->data_bytes, &f, 8 - ddf->element_size, ddf->element_size); + // for numbers smaller than 64 bits + u8* value_part = (u8*)&f + 8 - ddf->element_size; + List_u8_pushMany(&ddf->data_bytes, value_part, ddf->element_size); } else { i64 i = atoll(processed_str.data); - List_pushAsBytes(&ddf->data_bytes, &i, 8 - ddf->element_size, ddf->element_size); + // for numbers smaller than 64 bits + u8* value_part = (u8*)&i + 8 - ddf->element_size; + List_u8_pushMany(&ddf->data_bytes, value_part, ddf->element_size); } - free(processed_str.data); + str_destroy(processed_str); break; case TokenType_Char: tok.begin += 1; @@ -140,20 +139,20 @@ static void parseDataDefinition(Compiler* cmp, str instr_name, DataDefinition* d tok_str = Compiler_constructTokenStr(cmp, tok); processed_str = resolveEscapeSequences(cmp, tok_str); - if(processed_str.size != ddf->element_size){ - setError("can't fit char of size %i in %u bit variable", processed_str.size, _element_size_bits); + if(processed_str.len != ddf->element_size){ + setError("can't fit char of size %i in %u bit variable", processed_str.len, _element_size_bits); return; } - List_pushAsBytes(&ddf->data_bytes, processed_str.data, 0, processed_str.size); - free(processed_str.data); + List_u8_pushMany(&ddf->data_bytes, (u8*)processed_str.data, processed_str.len); + str_destroy(processed_str); break; case TokenType_String: tok.begin += 1; tok.length -= 2; tok_str = Compiler_constructTokenStr(cmp, tok); processed_str = resolveEscapeSequences(cmp, tok_str); - List_pushAsBytes(&ddf->data_bytes, processed_str.data, 0, processed_str.size); - free(processed_str.data); + List_u8_pushMany(&ddf->data_bytes, (u8*)processed_str.data, processed_str.len); + str_destroy(processed_str); break; } } @@ -161,7 +160,7 @@ static void parseDataDefinition(Compiler* cmp, str instr_name, DataDefinition* d static void parseOperation(Compiler* cmp, str instr_name, Operation* operPtr){ - Token tok = ((Token*)cmp->tokens.data)[cmp->tok_i]; + Token tok = cmp->tokens.data[cmp->tok_i]; const Instruction* instr = Instruction_getByName(instr_name); if(instr == NULL){ setError_unexpectedInstruction(tok); @@ -169,12 +168,12 @@ static void parseOperation(Compiler* cmp, str instr_name, Operation* operPtr){ } operPtr->opcode = instr->opcode; - operPtr->args = List_alloc(Argument, 8); + operPtr->args = List_Argument_alloc(4); Argument arg = (Argument){ .type = ArgumentType_Unset, .value.i = 0 }; str tok_str = str_null; str processed_str = str_null; - while(++cmp->tok_i < List_len(&cmp->tokens, Token)){ - tok = ((Token*)cmp->tokens.data)[cmp->tok_i]; + while(++cmp->tok_i < cmp->tokens.len){ + tok = cmp->tokens.data[cmp->tok_i]; switch(tok.type){ case TokenType_SingleLineComment: case TokenType_MultiLineComment: @@ -200,8 +199,8 @@ static void parseOperation(Compiler* cmp, str instr_name, Operation* operPtr){ else { arg.value.i = atoll(processed_str.data); } - free(processed_str.data); - List_push(&operPtr->args, Argument, arg); + str_destroy(processed_str); + List_Argument_push(&operPtr->args, arg); break; case TokenType_Name: tok_str = Compiler_constructTokenStr(cmp, tok); @@ -213,23 +212,23 @@ static void parseOperation(Compiler* cmp, str instr_name, Operation* operPtr){ arg.type = ArgumentType_VarDataName; arg.value.data_name = tok_str; } - List_push(&operPtr->args, Argument, arg); + List_Argument_push(&operPtr->args, arg); break; case TokenType_NamedDataPointer: tok_str = Compiler_constructTokenStr(cmp, tok); tok_str.data++; - tok_str.size--; + tok_str.len--; arg.type = ArgumentType_ConstDataPointer; arg.value.data_name = tok_str; - List_push(&operPtr->args, Argument, arg); + List_Argument_push(&operPtr->args, arg); break; case TokenType_NamedDataSize: tok_str = Compiler_constructTokenStr(cmp, tok); tok_str.data++; - tok_str.size--; + tok_str.len--; arg.type = ArgumentType_ConstDataSize; arg.value.data_name = tok_str; - List_push(&operPtr->args, Argument, arg); + List_Argument_push(&operPtr->args, arg); break; } } @@ -241,8 +240,8 @@ bool Compiler_parse(Compiler* cmp){ Token tok; Section* sec = NULL; - while(cmp->tok_i < List_len(&cmp->tokens, Token)){ - tok = ((Token*)cmp->tokens.data)[cmp->tok_i]; + while(cmp->tok_i < cmp->tokens.len){ + tok = cmp->tokens.data[cmp->tok_i]; switch(tok.type){ case TokenType_Unset: returnError(Error_TokenUnset); @@ -252,7 +251,7 @@ bool Compiler_parse(Compiler* cmp){ break; case TokenType_Label: // create new section - sec = List_expand_size(&cmp->ast.sections, sizeof(Section)); + sec = List_Section_expand(&cmp->ast.sections, 1); Section_construct(sec, Compiler_constructTokenStr(cmp, tok)); break; case TokenType_Instruction: @@ -261,14 +260,12 @@ bool Compiler_parse(Compiler* cmp){ str instr_name = Compiler_constructTokenStr(cmp, tok); // data definition starts with const if(str_startsWith(instr_name, STR("const"))){ - DataDefinition* dataDefPtr = List_expand_size( - &sec->data_definitions_list, sizeof(DataDefinition)); + DataDefinition* dataDefPtr = List_DataDefinition_expand(&sec->data_definitions_list, 1); memset(dataDefPtr, 0, sizeof(DataDefinition)); parseDataDefinition(cmp, instr_name, dataDefPtr); } else { - Operation* operPtr = List_expand_size( - &sec->operations_list, sizeof(Operation)); + Operation* operPtr = List_Operation_expand(&sec->operations_list, 1); memset(operPtr, 0, sizeof(Operation)); parseOperation(cmp, instr_name, operPtr); } diff --git a/src/compiler/Token.c b/src/compiler/Token.c index 04768fc..ab22a9b 100644 --- a/src/compiler/Token.c +++ b/src/compiler/Token.c @@ -1,5 +1,7 @@ #include "Token.h" +Array_declare(str); + static Array(str) _TokenType_str_array = ARRAY(str, { STR("Unset"), STR("SingleLineComment"), @@ -16,7 +18,7 @@ static Array(str) _TokenType_str_array = ARRAY(str, { }); str TokenType_toString(TokenType t){ - if(t >= Array_len(&_TokenType_str_array, str)) + if(t >= _TokenType_str_array.len) return STR("!!TokenType INDEX_ERROR!!"); - return ((str*)_TokenType_str_array.data)[t]; + return _TokenType_str_array.data[t]; } diff --git a/src/compiler/Token.h b/src/compiler/Token.h index 964c138..86ac525 100644 --- a/src/compiler/Token.h +++ b/src/compiler/Token.h @@ -26,4 +26,6 @@ typedef struct Token { TokenType type : 8; // type of token (8 bits) } Token; +List_declare(Token) + #define Token_construct(TYPE, BEGIN, LEN) ((Token){ .type = TYPE, .begin = BEGIN, .length = LEN }) diff --git a/src/instructions/impl/NOP.c b/src/instructions/impl/NOP.c index e14facb..7102c45 100644 --- a/src/instructions/impl/NOP.c +++ b/src/instructions/impl/NOP.c @@ -2,5 +2,6 @@ /// NOP i32 NOP_impl(VM* vm){ + (void)vm; return 0; } diff --git a/src/instructions/instructions.c b/src/instructions/instructions.c index 8f1027a..c482562 100644 --- a/src/instructions/instructions.c +++ b/src/instructions/instructions.c @@ -30,6 +30,7 @@ i32 JMP_impl(VM* vm); i32 JNZ_impl(VM* vm); i32 JZ_impl(VM* vm); +Array_declare(Instruction); static const Array(Instruction) instructions_array = ARRAY(Instruction, { Instruction_construct(NOP), @@ -63,7 +64,7 @@ static const Array(Instruction) instructions_array = ARRAY(Instruction, { }); const Instruction* Instruction_getByOpcode(Opcode opcode){ - if(opcode >= Array_len(&instructions_array, Instruction)) + if((u32)opcode >= instructions_array.len) return NULL; return (Instruction*)instructions_array.data + opcode; @@ -75,7 +76,7 @@ static HashMap(Opcode)* opcode_map = NULL; static void _opcode_map_construct(){ opcode_map = malloc(sizeof(*opcode_map)); HashMap_construct(opcode_map, Opcode, NULL); - for(u32 i = 0; i < Array_len(&instructions_array, Instruction); i++){ + for(u32 i = 0; i < instructions_array.len; i++){ Instruction* instr_ptr = (Instruction*)instructions_array.data + i; HashMap_tryPush(opcode_map, instr_ptr->name, &instr_ptr->opcode); } @@ -87,7 +88,7 @@ const Instruction* Instruction_getByName(str name){ str name_upper = str_toUpper(name); Opcode* op_ptr = HashMap_tryGetPtr(opcode_map, name_upper); - free(name_upper.data); + str_destroy(name_upper); if(op_ptr == NULL) return NULL; return Instruction_getByOpcode(*op_ptr); diff --git a/src/instructions/registers.c b/src/instructions/registers.c index 35326b2..a97154a 100644 --- a/src/instructions/registers.c +++ b/src/instructions/registers.c @@ -30,7 +30,7 @@ RegisterCode RegisterCode_parse(str r){ else check_code(dl) else check_code(dh) - free(lower.data); + str_destroy(lower); return code; } @@ -60,15 +60,15 @@ str RegisterCode_toString(RegisterCode code){ break; case 4: buf_str.data += 1; - buf_str.size -= 1; + buf_str.len -= 1; break; case 7: buf_str.data[0] = 'l'; - buf_str.size -= 1; + buf_str.len -= 1; break; case 8: buf_str.data[0] = 'h'; - buf_str.size -= 1; + buf_str.len -= 1; break; }