From 439a2155e40db0f8015bf2bf6d53d35210fa069d Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sun, 11 Dec 2022 20:33:07 -0500 Subject: [PATCH] added string constants to llvm output --- cerise/backend/ssa/codegen.c | 32 ++++++++++++++++++++++++++++---- cerise/inc/cerise.h | 1 + cerise/src/grammar.c | 22 ++++++++++++++-------- cerise/src/type_checks.c | 18 ++++++++++++++++++ cerise/tests/Module.m | 2 ++ 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index ab73c04..4099bc5 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -116,7 +116,7 @@ void codegen_init(Parser* p) fout(p, "%%Bool = type i1\n"); fout(p, "%%Int = type i64\n"); fout(p, "%%Real = type double\n"); - fout(p, "%%String = type { i64, i8* }\n"); + fout(p, "%%String = type i8*\n"); } void codegen_symbol(Parser* p, Symbol* sym) @@ -136,6 +136,10 @@ void codegen_symbol(Parser* p, Symbol* sym) { fout(p, " 0.0\n"); } + else if (sym->type->form == FORM_STRING) + { + fout(p, " null\n"); + } else { fout(p, " 0\n"); @@ -209,8 +213,6 @@ static void topsort(Bitset* set, SsaBlock** sorted, SsaBlock* block) static void print_ident(Parser* p, SsaVar* var) { -// fout("%ld\n", var->symid); -// fflush(stdout); Symbol* s = symbol_getbyid(p, var->symid); assert(s); assert(s->name); @@ -237,6 +239,10 @@ static void print_const(Parser* p, Type* type, SsaValue* val) { fout(p, " %f", val->val.f); } + else if (type->form == FORM_STRING) + { + fout(p, " @const.%p", val->val.s); + } else { assert(!"not implemented"); @@ -528,6 +534,24 @@ void codegen_block(Parser* p, SsaBlock* block) fout(p, "\n"); } +void codegen_const(Parser* p, SsaNode* expr) +{ + assert(expr->mode == MODE_CONST); + if (expr->type->form == FORM_STRING) + { + fout(p, + "@const.%p = private unnamed_addr constant [%d x i8] c\"%s\\00\", align 1\n", + SSA_VAL(expr).s, + (int)strlen(SSA_VAL(expr).s)+1, + SSA_VAL(expr).s + ); + } + else + { + assert(!"unimplemented constant declaration"); + } +} + void codegen_main(Parser* p) { if (!p->genmain) return; // Bail if no main required @@ -544,4 +568,4 @@ void codegen_main(Parser* p) fout(p, " call void @%s()\n", p->name); fout(p, " ret i32 0\n"); fout(p, "}\n"); -} \ No newline at end of file +} diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index ab3bab5..192d725 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -350,5 +350,6 @@ extern Type VoidType, BoolType, IntType, RealType, StringType; void codegen_init(Parser* p); void codegen_symbol(Parser* p, Symbol* sym); void codegen_block(Parser* p, SsaBlock* block); +void codegen_const(Parser* p, SsaNode* expr); void codegen_main(Parser* p); diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index ef7abc5..2fdc586 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -156,6 +156,12 @@ static SsaNode* factor(Parser* p) consume(p); break; + case STRING: + expr = ssa_string(p, peek(p)->text); + codegen_const(p, expr); + consume(p); + break; + case '(': expect(p, '('); expr = expression(p); @@ -566,18 +572,18 @@ Symbol* proc_type(Parser* p) return proc; } -void proc_body(Parser* p, Type* proctype) +void proc_body(Parser* p, Symbol* proc) { expect(p, BEGIN); SsaBlock* block = ssa_block(p); p->curr_join = ssa_block(p); block->links[1] = p->curr_join; block->links[0] = statement_seq(p); - if (proctype->base != &VoidType) + if (proc->type->base != &VoidType) { expect(p, RETURN); SsaNode* retval = expression(p); - check_type(p, proctype->base, retval); + check_type(p, proc->type->base, retval); expect(p, ';'); ssa_return(p, retval); } @@ -586,6 +592,7 @@ void proc_body(Parser* p, Type* proctype) ssa_return(p, NULL); } expect(p, END); + codegen_symbol(p, proc); codegen_block(p, block); } @@ -625,8 +632,7 @@ void proc_decl(Parser* p) else { proc->forward = 0; - codegen_symbol(p, proc); - proc_body(p, proc->type); + proc_body(p, proc); } EXIT_RULE(); @@ -779,7 +785,7 @@ static void compile_module(Parser* p, char* path, bool genmain) if (fs_modtime(obj_path) < fs_modtime(path)) { /* run llc to generate assembly listing */ - char* llc_cmd = strmcat("llc -o \"", asm_path , "\" \"", p->outpath, "\"", 0); + char* llc_cmd = strmcat("llc -opaque-pointers -o \"", asm_path , "\" \"", p->outpath, "\"", 0); printf("%s\n", llc_cmd); if (system(llc_cmd) != 0) { @@ -788,7 +794,7 @@ static void compile_module(Parser* p, char* path, bool genmain) remove(p->outpath); /* compile the object file now */ - char* as_cmd = strmcat("clang -c -o \"", obj_path, "\" \"", asm_path, "\"", 0); + char* as_cmd = strmcat("clang -static -c -o \"", obj_path, "\" \"", asm_path, "\"", 0); printf("%s\n", as_cmd); if (system(as_cmd) != 0) { @@ -867,7 +873,7 @@ void compile(char* path) { Parser p = {0}; compile_module(&p, path, true); - char* link_cmd = strmcat("clang -o ", p.name, " ", 0); + char* link_cmd = strmcat("clang -static -o ", p.name, " ", 0); for (size_t i = 0; i < p.nmods; i++) { char* object = strdup(p.mods[i].path); diff --git a/cerise/src/type_checks.c b/cerise/src/type_checks.c index 603ab82..a5802da 100644 --- a/cerise/src/type_checks.c +++ b/cerise/src/type_checks.c @@ -64,12 +64,26 @@ void check_bool(Parser* p, SsaNode* a) } } +void check_string(Parser* p, SsaNode* a) +{ + if (a->type->form != FORM_STRING) + { + error(p, "not an string"); + } +} + void check_bools(Parser* p, SsaNode* a, SsaNode* b) { check_bool(p, a); check_bool(p, b); } +void check_strings(Parser* p, SsaNode* a, SsaNode* b) +{ + check_string(p, a); + check_string(p, b); +} + void check_type(Parser* p, Type* type, SsaNode* a) { if (type->form == FORM_REAL) @@ -108,6 +122,10 @@ void check_types(Parser* p, SsaNode* a, SsaNode* b) { check_bools(p, a, b); } + else if (a->type->form == FORM_STRING) + { + check_strings(p, a, b); + } // else if (a->type->form == FORM_ARRAY) // { // } diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 7dca4f8..a70872d 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -24,6 +24,7 @@ var a : Int b : array 5 of Int end + vString : String procedure TestReturnVoid*() begin @@ -49,6 +50,7 @@ begin vBool = true; vInt = 42; vReal = 42.0; + vString = ""; end procedure TestIntArithOps() -- 2.49.0