From 656904f3e3803638548b2ed657298ecf83d44571 Mon Sep 17 00:00:00 2001 From: Jamesbarford Date: Tue, 30 Jan 2024 08:55:34 +0000 Subject: [PATCH 1/3] fixes --- src/Makefile | 4 ++-- src/ast.c | 6 +++++ src/ast.h | 1 + src/cctrl.c | 20 ---------------- src/cctrl.h | 1 - src/compile.c | 21 ++++------------- src/holyc-lib/io.HC | 5 ++-- src/main.c | 47 +++++++++++++++++++++++++++++++++++--- src/parser.c | 20 +++++++++++----- src/x86.c | 10 +++----- tests/02_pointer_simple.HC | 1 + tests/03_malloc_array.HC | 1 + tests/17_varargs.HC | 5 ++-- 13 files changed, 82 insertions(+), 60 deletions(-) diff --git a/src/Makefile b/src/Makefile index 302a076..1c0ebd5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,7 +6,7 @@ OUT := . LIB_SRC?=./holyc-lib SYNTAX?=./syntax-highlighting PREFIX?=/usr/local -BUILT_IN_LOCATION?=~/.holyc-lib +BUILT_IN_LOCATION?=$(HOME)/.holyc-lib .PHONY: unit-test @@ -63,7 +63,7 @@ install: prsasm-test: gcc -O0 -g -DPRSASM_TEST ./prsasm.c ./cctrl.c ./dict.c ./ast.c ./aostr.c ./list.c ./lexer.c ./prsutil.c -unit-test: install +unit-test: cd ../tests && ./tests.sh $(OUT)/dict.o: dict.c dict.h aostr.h diff --git a/src/ast.c b/src/ast.c index 1a91036..3e1dc18 100644 --- a/src/ast.c +++ b/src/ast.c @@ -42,6 +42,12 @@ AstType *AstTypeNew(void) { return at; } +AstType *AstTypeCopy(AstType *type) { + AstType *copy = AstTypeNew(); + memcpy(copy,type,sizeof(AstType)); + return copy; +} + Ast *AstUnaryOperator(AstType *type, long kind, Ast *operand) { Ast *ast = AstNew(); ast->type = type; diff --git a/src/ast.h b/src/ast.h index d2dde2c..afe26b0 100644 --- a/src/ast.h +++ b/src/ast.h @@ -240,6 +240,7 @@ extern AstType *ast_void_type; extern Ast *placeholder_arg; Ast *AstNew(void); +AstType *AstTypeCopy(AstType *type); void AstRelease(Ast *ast); void AstReleaseList(List *ast_list); diff --git a/src/cctrl.c b/src/cctrl.c index c0f729d..c296b50 100644 --- a/src/cctrl.c +++ b/src/cctrl.c @@ -180,26 +180,6 @@ lexeme *CctrlTokenGet(Cctrl *cc) { return NULL; } -/* Look ahead by `n` */ -lexeme *CctrlTokenPeekBy(Cctrl *cc, int steps) { - List *ll = cc->tkit->cur; - /* We are already positioned one ahead */ - while (--steps && ll != cc->tkit->tokens) { - if (ll == cc->tkit->tokens) { - loggerWarning("All tokens consume." - " Possible unexpected end of input\n"); - return NULL; - } - ll = ll->next; - } - if (ll == cc->tkit->tokens) { - loggerWarning("All tokens consume." - " Possible unexpected end of input\n"); - return NULL; - } - return ll->value; -} - /* Assert the token we are currently pointing at is a TK_PUNCT and the 'i64' * matches 'expected'. Then consume this token else throw an error */ void CctrlTokenExpect(Cctrl *cc, long expected) { diff --git a/src/cctrl.h b/src/cctrl.h index 534e891..f9b6b6c 100644 --- a/src/cctrl.h +++ b/src/cctrl.h @@ -103,7 +103,6 @@ Cctrl *CctrlNew(void); void CctrlInitTokenIter(Cctrl *cc, List *tokens); lexeme *CctrlTokenGet(Cctrl *cc); lexeme *CctrlTokenPeek(Cctrl *cc); -lexeme *CctrlTokenPeekBy(Cctrl *cc, int steps); void CctrlTokenIterSetCur(Cctrl *cc, List *cur); void CctrlTokenRewind(Cctrl *cc); void CctrlTokenExpect(Cctrl *cc, long expected); diff --git a/src/compile.c b/src/compile.c index 236efcb..2e36a68 100644 --- a/src/compile.c +++ b/src/compile.c @@ -89,8 +89,9 @@ int CompileToAst(Cctrl *cc, char *filepath, int lexer_flags) { lexer l; aoStr *file_path; char *src, *strpath; - Dict *seen_files = DictNew(&default_table_type); - + Dict *seen_files; + + seen_files = DictNew(&default_table_type); tokens = ListNew(); code_list = ListNew(); @@ -101,7 +102,6 @@ int CompileToAst(Cctrl *cc, char *filepath, int lexer_flags) { while ((file_path = ListPop(l.files)) != NULL) { if (DictGetLen(seen_files,file_path->data,file_path->len) != NULL) { - loggerDebug("saw: %s\n",file_path->data); aoStrRelease(file_path); continue; } @@ -110,6 +110,7 @@ int CompileToAst(Cctrl *cc, char *filepath, int lexer_flags) { ListAppend(code_list,src); l.ptr = src; l.lineno = 1; + loggerDebug("lexing: %s\n",file_path->data); next_tokens = lexToLexemes(cc->macro_defs,&l); if (!next_tokens || next_tokens->next == next_tokens) { @@ -153,17 +154,3 @@ aoStr *CompileCode(Cctrl *cc, char *code, int lexer_flags) { free(l.files); return asm_str; } - -/* Essentially uses GCC's assembler on the generated assembly in asmvbuf */ -void CompileAssembleToFile(aoStr *asmbuf, char *filename) { - int fd = open(filename, O_CREAT|O_RDWR|O_TRUNC, 0666); - write(fd,asmbuf->data,asmbuf->len); - - aoStr *cmd = aoStrNew(); - aoStrCatPrintf(cmd, "gcc-13 ./%s -o ./a.out", filename); - printf("%s\n", cmd->data); - system(cmd->data); - aoStrRelease(cmd); - aoStrRelease(asmbuf); - close(fd); -} diff --git a/src/holyc-lib/io.HC b/src/holyc-lib/io.HC index 6436070..3379500 100644 --- a/src/holyc-lib/io.HC +++ b/src/holyc-lib/io.HC @@ -91,7 +91,7 @@ public U8 *FileRead(U8 *path, I64 *_size=NULL) public Bool FileWrite(U8 *filename, U8 *buf, I64 size, I64 flags=O_CREAT|O_RDWR) { - I64 towrite = size, total=0, nwritten = 0; + I64 towrite = size, nwritten = 0; I32 fd; if ((fd = open(filename,flags,438)) == -1) { @@ -104,7 +104,8 @@ public Bool FileWrite(U8 *filename, U8 *buf, I64 size, close(fd); return FALSE; } - total += nwritten; + + buf += nwritten; towrite -= nwritten; } close(fd); diff --git a/src/main.c b/src/main.c index 06bac22..4049540 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,6 @@ +#include #include +#include #include #include #include @@ -9,6 +11,8 @@ #include "cctrl.h" #include "util.h" +#define ASM_TMP_FILE "/tmp/holyc-asm.s" + typedef struct mccOptions { int print_ast; int print_tokens; @@ -67,6 +71,39 @@ void execGcc(char *filename, aoStr *asmbuf, aoStr *cmd) { system(cmd->data); } +int writeAsmToTmp(aoStr *asmbuf) { + int fd; + ssize_t written; + size_t towrite = 0; + char *ptr; + ptr = asmbuf->data; + + if ((fd = open(ASM_TMP_FILE,O_RDWR|O_TRUNC|O_CREAT,0644)) == -1) { + loggerPanic("Failed to create file for intermediary assembly: %s\n", + strerror(errno)); + } + + towrite = asmbuf->len; + ptr = asmbuf->data; + + while (towrite > 0) { + written = write(fd,ptr,towrite); + if (written < 0) { + if (written == EINTR) { + continue; + } + close(fd); + loggerPanic("Failed to create file for intermediary assembly: %s\n", + strerror(errno)); + } + printf("%ld\n",written); + towrite -= written; + ptr += written; + } + close(fd); + return 1; +} + void emitFile(aoStr *asmbuf, mccOptions *opts) { aoStr *cmd = aoStrNew(); @@ -81,10 +118,14 @@ void emitFile(aoStr *asmbuf, mccOptions *opts) { write(fd,asmbuf->data,asmbuf->len); close(fd); } else { - aoStr *escaped = aoStrEscapeString(asmbuf); - aoStrCatPrintf(cmd, "echo \"%s\" | gcc -x assembler -o ./a.out -", escaped->data); - aoStrRelease(escaped); + // aoStr *escaped = aoStrEscapeString(asmbuf); + writeAsmToTmp(asmbuf); + aoStrCatPrintf(cmd, "gcc %s -lm -lc -o ./a.out", ASM_TMP_FILE); // escaped->data); + // aoStrRelease(escaped); + loggerDebug("%s\n",cmd->data); system(cmd->data); + remove(ASM_TMP_FILE); + } aoStrRelease(cmd); aoStrRelease(asmbuf); diff --git a/src/parser.c b/src/parser.c index b35702a..3c40d6f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -116,12 +116,20 @@ Ast *ParseDeclArrayInitInt(Cctrl *cc, AstType *type) { return AstArrayInit(initlist); } -void ParseFlattenAnnonymous(AstType *anon, Dict *fields_dict, int offset) { +void ParseFlattenAnnonymous(AstType *anon, Dict *fields_dict, + int offset, int make_copy) +{ + AstType *base, *type; for (int i = 0; i < anon->fields->capacity; ++i) { for (DictNode *dn = anon->fields->body[i]; dn; dn = dn->next) { - AstType *type = (AstType *)dn->val; + base = (AstType *)dn->val; + if (make_copy) { + type = AstTypeCopy(base); + } else { + type = base; + } type->offset += offset; - DictSet(fields_dict,type->clsname->data,type); + DictSet(fields_dict,dn->key,type); } } } @@ -268,7 +276,7 @@ Dict *ParseClassOffsets(int *real_size, List *fields, AstType *base_class, if (base_class) { offset = base_class->size; - ParseFlattenAnnonymous(base_class,fields_dict,0); + ParseFlattenAnnonymous(base_class,fields_dict,0,1); } else { offset = 0; } @@ -291,7 +299,7 @@ Dict *ParseClassOffsets(int *real_size, List *fields, AstType *base_class, field = it->value; if (field->clsname == NULL && ParseIsClassOrUnion(field->kind)) { offset += CalcPadding(offset,field->size); - ParseFlattenAnnonymous(field,fields_dict,offset); + ParseFlattenAnnonymous(field,fields_dict,offset,0); offset += field->size; continue; } else { @@ -329,7 +337,7 @@ Dict *ParseUnionOffsets(int *real_size, List *fields) { max_size = field->size; } if (field->clsname == NULL && ParseIsClassOrUnion(field->kind)) { - ParseFlattenAnnonymous(field,fields_dict,0); + ParseFlattenAnnonymous(field,fields_dict,0,0); continue; } diff --git a/src/x86.c b/src/x86.c index bf973d7..2c529b6 100644 --- a/src/x86.c +++ b/src/x86.c @@ -1088,9 +1088,9 @@ void AsmAddr(Cctrl *cc, aoStr *buf, Ast *ast) { case AST_LVAR: { if (ast->operand->type->kind == AST_TYPE_POINTER) { /* XXX: this feels extremely hacky */ + aoStrCatPrintf(buf, "# ADDR of %s\n\t", + AstKindToString(ast->operand->type->ptr->kind)); switch (ast->operand->type->ptr->kind) { - aoStrCatPrintf(buf, "# ADDR of %s\n\t", - AstKindToString(ast->operand->type->ptr->kind)); case AST_TYPE_ARRAY: case AST_TYPE_CHAR: case AST_TYPE_CLASS: @@ -1938,11 +1938,7 @@ void AsmDataSection(Cctrl *cc, aoStr *buf) { ptr = str; while (*ptr) { switch (*ptr) { - case '\\': { - /* XXX: this is weird but works */ - aoStrCatPrintf(escaped,"\\\\"); - break; - } + case '\\': aoStrCatPrintf(escaped,"\\"); break; case '\n': aoStrCatPrintf(escaped,"\\n"); break; case '\t': aoStrCatPrintf(escaped,"\\t"); break; case '\r': aoStrCatPrintf(escaped,"\\r"); break; diff --git a/tests/02_pointer_simple.HC b/tests/02_pointer_simple.HC index ed0b1f7..bc6d6ba 100644 --- a/tests/02_pointer_simple.HC +++ b/tests/02_pointer_simple.HC @@ -21,5 +21,6 @@ U0 Main() I64 *p = &e->x; Assign(p); PrintResult(*p == 9, 1); + Free(e); "====\n"; } diff --git a/tests/03_malloc_array.HC b/tests/03_malloc_array.HC index 7c18ec0..d325442 100644 --- a/tests/03_malloc_array.HC +++ b/tests/03_malloc_array.HC @@ -9,6 +9,7 @@ Bool ArrayJuggling() { I64 *ptr = 0; I64 arr[5][5]; + arr[0][0] = 0; arr[0][0] += 1; // arr[0][0] = 1 arr[0][0]++; // arr[0][0] = 2 ++(arr[0][0]); // arr[0][0] = 3 diff --git a/tests/17_varargs.HC b/tests/17_varargs.HC index 0f964c5..ad14937 100644 --- a/tests/17_varargs.HC +++ b/tests/17_varargs.HC @@ -71,6 +71,7 @@ I64 Wrap(I64 i) U0 Main() { + "Test - Variable arguments: "; I64 res, correct=0, tests = 15; if (!StrNCmp("foo bar baz", Concat("foo", "bar", "baz"), 11)) { correct++; @@ -82,8 +83,8 @@ U0 Main() res = Arg3(5,6,7,1); if (res == 19) correct++; - if (AddS(2,2,2,4,4) == 14) correct++; - res = AddS(2,2,2,4,4); + if (AddS(2,2,2,4,4,0) == 14) correct++; + res = AddS(2,2,2,4,4,0); if (res == 14) correct++; /* assign and check */ From 08826355be430e893ffe14cb51cc43df6190bb48 Mon Sep 17 00:00:00 2001 From: Jamesbarford Date: Tue, 30 Jan 2024 09:01:59 +0000 Subject: [PATCH 2/3] remove comments and fix the object file creation --- src/main.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main.c b/src/main.c index 4049540..128573c 100644 --- a/src/main.c +++ b/src/main.c @@ -108,21 +108,17 @@ void emitFile(aoStr *asmbuf, mccOptions *opts) { aoStr *cmd = aoStrNew(); if (opts->emit_object) { - aoStr *escaped = aoStrEscapeString(asmbuf); - aoStrCatPrintf(cmd, "echo \"%s\" | gcc -x assembler -c -o ./%s -", - escaped->data, opts->obj_outfile); - aoStrRelease(escaped); + writeAsmToTmp(asmbuf); + aoStrCatPrintf(cmd, "gcc %s -lm -lc -c -o ./%s", + ASM_TMP_FILE,opts->obj_outfile); system(cmd->data); } else if (opts->asm_outfile && opts->assemble_only) { int fd = open(opts->asm_outfile, O_CREAT|O_RDWR|O_TRUNC, 0666); write(fd,asmbuf->data,asmbuf->len); close(fd); } else { - // aoStr *escaped = aoStrEscapeString(asmbuf); writeAsmToTmp(asmbuf); - aoStrCatPrintf(cmd, "gcc %s -lm -lc -o ./a.out", ASM_TMP_FILE); // escaped->data); - // aoStrRelease(escaped); - loggerDebug("%s\n",cmd->data); + aoStrCatPrintf(cmd, "gcc %s -lm -lc -o ./a.out", ASM_TMP_FILE); system(cmd->data); remove(ASM_TMP_FILE); From d629c8977cc0d44b728b3b66d85c917168c80f1b Mon Sep 17 00:00:00 2001 From: Jamesbarford Date: Tue, 30 Jan 2024 09:04:18 +0000 Subject: [PATCH 3/3] actual fix for creating object files --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 128573c..12e5259 100644 --- a/src/main.c +++ b/src/main.c @@ -109,7 +109,7 @@ void emitFile(aoStr *asmbuf, mccOptions *opts) { if (opts->emit_object) { writeAsmToTmp(asmbuf); - aoStrCatPrintf(cmd, "gcc %s -lm -lc -c -o ./%s", + aoStrCatPrintf(cmd, "gcc -c %s -lm -lc -o ./%s", ASM_TMP_FILE,opts->obj_outfile); system(cmd->data); } else if (opts->asm_outfile && opts->assemble_only) {