Compilation process gets a new predefined constants structure each step of the process.
Closed this issue · 2 comments
kevinramharak commented
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.
adam-mcdaniel commented
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?
kevinramharak commented
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() {