adam-mcdaniel/oakc

Compilation process gets a new predefined constants structure each step of the process.

Closed this issue · 2 comments

Was updating my backend to the newer commits and noticed that this line gets a new BTree of constants while compiling the user program, core and std lib. This breaks include guards if 2 or more of those compilation entry points include the same file, resulting in a function '__ffi_pass_arg_by_value' is defined multiple times type of error.

Whoops, this should be a super easy fix. Do you have a sample bit of source I can test against to verify a correct solution?

Change std.ok to:

#[if(!is_defined("OAK_STD")) {
    const OAK_STD = 1;
    extern fn prend();
    extern fn prs as putstr(s: &char);
    extern fn prn as putnum(n: num);
    extern fn prc as putchar(ch: char);
    extern fn getch as get_char() -> char;

    fn putstrln(s: &char) -> void { putstr(s); prend(); }

    fn putnumln(n: num) -> void { putnum(n); prend(); }

    fn putcharln(ch: char) -> void { putchar(ch); prend(); }

    fn putbool(b: bool) -> void {
        if b {
            putchar('t');
            putchar('r');
            putchar('u');
            putchar('e');
        }
        else {
            putchar('f');
            putchar('a');
            putchar('l');
            putchar('s');
            putchar('e');
        }
    }

    fn putboolln(b: bool) -> void { putbool(b); prend(); }
}]

add examples/bug.ok

#[std]
#[include("../src/std.ok")]

fn main() {

}
cargo run -- c examples/bug.ok
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s
     Running `target\debug\oak.exe c examples/bug.ok`
compilation error: function 'prend' is defined multiple times
error: process didn't exit successfully: `target\debug\oak.exe c examples/bug.ok` (exit code: 1)

A fix could be:

diff --git a/src/lib.rs b/src/lib.rs
index 96b0810..45c3be9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -88,13 +88,14 @@ pub fn generate_docs(
     // The target to use for the documented code's TARGET const
     target: impl Target,
 ) -> String {
-    match parse(filename, input).compile(cwd, &mut get_predefined_constants(&target)) {
+    let mut constants = &mut get_predefined_constants(&target);
+    match parse(filename, input).compile(cwd, constants) {
         Ok(output) => output,
         Err(e) => print_compile_error(e),
     }
     .generate_docs(
         filename.to_string(),
-        &mut get_predefined_constants(&target),
+        constants,
         false,
     )
 }
@@ -118,8 +119,9 @@ pub fn compile(
 ) -> Result<()> {
     // Get the TIR code for the user's Oak code
     let mut tir = parse(filename, input);
+    let mut constants = &mut get_predefined_constants(&target);
     // Convert the TIR to HIR
-    let mut hir = match tir.compile(cwd, &mut get_predefined_constants(&target)) {
+    let mut hir = match tir.compile(cwd, constants) {
         Ok(output) => output,
         Err(e) => print_compile_error(e),
     };
@@ -127,7 +129,7 @@ pub fn compile(
     // Add the core library code to the users code
     hir.extend_declarations(
         match parse("core.ok", include_str!("core.ok"))
-            .compile(cwd, &mut get_predefined_constants(&target))
+            .compile(cwd, constants)
         {
             Ok(output) => output,
             Err(e) => print_compile_error(e),
@@ -140,7 +142,7 @@ pub fn compile(
         // Then add the standard library code to the users code
         hir.extend_declarations(
             match parse("std.ok", include_str!("std.ok"))
-                .compile(cwd, &mut get_predefined_constants(&target))
+                .compile(cwd, constants)
             {
                 Ok(output) => output,
                 Err(e) => print_compile_error(e),
@@ -149,7 +151,7 @@ pub fn compile(
         );
     }
 
-    match hir.compile(cwd, &mut get_predefined_constants(&target)) {
+    match hir.compile(cwd, constants) {
         Ok(mir) => match mir.assemble() {
             Ok(asm) => match asm.assemble(&target) {
                 Ok(result) => target.compile(if hir.use_std() {