]> git.mdlowis.com Git - proto/obnc.git/commitdiff
added string constants to llvm output
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 12 Dec 2022 01:33:07 +0000 (20:33 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 12 Dec 2022 01:33:07 +0000 (20:33 -0500)
cerise/backend/ssa/codegen.c
cerise/inc/cerise.h
cerise/src/grammar.c
cerise/src/type_checks.c
cerise/tests/Module.m

index ab73c04c6a9ef179f036a8e2f634bec5ff54c586..4099bc5c6ea2ba630a5c0b43c29a6a703fb8bab0 100644 (file)
@@ -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
+}
index ab3bab502743625703f8aa2186cc629d3937ab76..192d72566bf55ebc23da0bba824dd5f31be4c6a6 100644 (file)
@@ -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);
 
index ef7abc53261b640cdc8277aeee7075183f46babf..2fdc586174ae488142a9dec500b3a2ce12baca5f 100644 (file)
@@ -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);
index 603ab82951bed1e13053f2903850b790be44654c..a5802da0fcc1249cd5d7fcfb19b70e5c545d42c4 100644 (file)
@@ -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)
 //    {
 //    }
index 7dca4f887f5e3b599452f3ca924a0b615d7ed7f6..a70872d4f108afd31e06f01f0a9f50172ecd06a3 100644 (file)
@@ -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()