diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 3433c62..021cb71 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -7,19 +7,23 @@
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
+
@@ -72,9 +76,10 @@
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.rust.reset.selective.auto.import": "true",
+ "Shell Script.Test Asm.executor": "Run",
"git-widget-placeholder": "master",
"ignore.virus.scanning.warn.message": "true",
- "last_opened_file_path": "/home/robertlucas/RustroverProjects/whython-8/src/root/builtin/int",
+ "last_opened_file_path": "/home/robertlucas/RustroverProjects/whython-8/src/root/builtin/types",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
@@ -83,12 +88,13 @@
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
"org.rust.first.attach.projects": "true",
- "settings.editor.selected.configurable": "terminal",
+ "settings.editor.selected.configurable": "preferences.keymap",
"vue.rearranger.settings.migration": "true"
}
}]]>
+
@@ -133,6 +139,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -179,7 +205,10 @@
-
+
+
+
+
@@ -405,7 +434,15 @@
1718558898901
-
+
+
+ 1718636633009
+
+
+
+ 1718636633009
+
+
@@ -441,7 +478,8 @@
-
+
+
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..613fb5c
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,8 @@
+use std::fs;
+use std::path::PathBuf;
+
+fn main() {
+ if PathBuf::from("types.toml").is_file() {
+ fs::remove_file(PathBuf::from("types.toml")).unwrap();
+ }
+}
\ No newline at end of file
diff --git a/build/out.asm b/build/out.asm
index 2740025..06f1ecf 100644
--- a/build/out.asm
+++ b/build/out.asm
@@ -5,62 +5,54 @@ section .text
main:
push rbp
mov rbp, rsp
-
- mov qword [rbp-8], 0
- mov qword [rbp-16], 1
- mov rax, qword [rbp-16]
- mov qword [rbp-40], rax
+ mov qword [rbp-8], 3
+ mov qword [rbp-16], 4
+ mov byte [rbp-17], 1
+ mov al, byte [rbp-17]
+ mov byte [rbp-18], al
+ mov rdi, __6_fstr
+ mov rsi, 0
+ mov sil, [rbp-18]
+ mov al, 0
+ sub rsp, 18
+ extern printf
+ call printf
+ add rsp, 18
+ mov al, byte [rbp-17]
+ mov byte [rbp-19], al
+ cmp byte [rbp-19], 0
+ jz main_0
mov rax, qword [rbp-8]
- mov qword [rbp-48], rax
- sub rsp, 48
- call _1
- add rsp, 48
- mov qword [rbp-40], 255
- mov rax, qword [rbp-40]
- leave
- ret
-
-_1:
- push rbp
- mov rbp, rsp
-
- mov rax, qword [rbp+16]
- mov qword [rbp-8], rax
-
- mov rdi, __10_fstr
- mov rsi, [rbp-8]
+ mov qword [rbp-27], rax
+ mov rdi, __4_fstr
+ mov rsi, [rbp-27]
mov al, 0
- sub rsp, 8
+ sub rsp, 27
extern printf
call printf
- add rsp, 8
-
- mov rax, qword [rbp+16]
- mov qword [rbp-24], rax
- mov rax, qword [rbp+24]
- mov qword [rbp-32], rax
- mov rax, qword [rbp-24]
- add rax, qword [rbp-32]
- mov qword [rbp-16], rax
- mov rax, qword [rbp+24]
- mov qword [rbp-40], rax
- mov qword [rbp-48], 12
- mov rax, 60
- mov rdi, [rbp-48]
- syscall
- mov rax, qword [rbp-40]
- mov qword [rbp-56], rax
+ add rsp, 27
+ mov qword [rbp-35], 13
+ mov rax, qword [rbp-35]
+ leave
+ ret
+ jmp main_1
+ main_0:
mov rax, qword [rbp-16]
- mov qword [rbp-64], rax
- mov rax, qword [rbp-64]
- mov qword [rbp-88], rax
- mov rax, qword [rbp-56]
- mov qword [rbp-96], rax
- sub rsp, 96
- call _1
- add rsp, 96
- leave
- ret
+ mov qword [rbp-27], rax
+ mov rdi, __4_fstr
+ mov rsi, [rbp-27]
+ mov al, 0
+ sub rsp, 27
+ extern printf
+ call printf
+ add rsp, 27
+ mov qword [rbp-35], 12
+ mov rax, qword [rbp-35]
+ leave
+ ret
+ main_1:
+
-section .data
- __10_fstr db `Integer: %d\n`,0
\ No newline at end of file
+section .data_readonly
+ __6_fstr db `Boolean: %d\n`,0
+ __4_fstr db `Integer: %d\n`,0
\ No newline at end of file
diff --git a/build/out.o b/build/out.o
index 120e41f..a350db6 100644
Binary files a/build/out.o and b/build/out.o differ
diff --git a/build/out.out b/build/out.out
index 2bcb0cf..a78d355 100755
Binary files a/build/out.out and b/build/out.out differ
diff --git a/main.why b/main.why
index 770974e..a88ebe4 100644
--- a/main.why
+++ b/main.why
@@ -1,12 +1,15 @@
-fn fib(a: int, b: int) {
- printi(a);
- let d: int = a + b;
- let c: int = b;
- exit(12);
- fib(c, d);
-}
-
fn main() -> int {
- fib(0, 1);
- return 255;
+ let i: int = 3;
+ let j: int = 4;
+ let x: bool = true;
+ printb(x);
+
+ if (x) {
+ printi(i);
+ return 13;
+ }
+ else {
+ printi(j);
+ return 12;
+ }
}
diff --git a/src/root/assembler/assembly_builder.rs b/src/root/assembler/assembly_builder.rs
new file mode 100644
index 0000000..8e3b1b2
--- /dev/null
+++ b/src/root/assembler/assembly_builder.rs
@@ -0,0 +1,29 @@
+
+pub struct AssemblyBuilder {
+ inner: String
+}
+
+impl AssemblyBuilder {
+ pub fn new() -> AssemblyBuilder {
+ AssemblyBuilder { inner: String::new() }
+ }
+
+ pub fn line(&mut self, line: &str) {
+ self.inner += " ";
+ self.inner += line;
+ self.inner.push('\n');
+ }
+
+ pub fn toplevel(&mut self, line: &str) {
+ self.inner += line;
+ self.inner.push('\n');
+ }
+
+ pub fn other(&mut self, other: &str) {
+ self.inner += other;
+ }
+
+ pub fn finish(self) -> String {
+ self.inner
+ }
+}
\ No newline at end of file
diff --git a/src/root/assembler/mod.rs b/src/root/assembler/mod.rs
index e69de29..4bf604d 100644
--- a/src/root/assembler/mod.rs
+++ b/src/root/assembler/mod.rs
@@ -0,0 +1 @@
+pub mod assembly_builder;
\ No newline at end of file
diff --git a/src/root/builtin/mod.rs b/src/root/builtin/mod.rs
index d278c39..5ada487 100644
--- a/src/root/builtin/mod.rs
+++ b/src/root/builtin/mod.rs
@@ -2,6 +2,7 @@ pub mod types;
pub mod functions;
use crate::root::builtin::functions::register_functions;
+use crate::root::builtin::types::bool::register_bool;
use crate::root::builtin::types::int::register_int;
use crate::root::compiler::global_tracker::GlobalTracker;
use crate::root::errors::WErr;
@@ -13,6 +14,7 @@ use crate::root::shared::types::Type;
pub fn register_builtin(global_table: &mut GlobalDefinitionTable) {
register_functions(global_table);
register_int(global_table);
+ register_bool(global_table);
}
pub type InlineFunctionGenerator = fn(&[LocalAddress], Option, &mut GlobalTracker, ByteSize) -> String;
diff --git a/src/root/builtin/types/bool/mod.rs b/src/root/builtin/types/bool/mod.rs
new file mode 100644
index 0000000..86ec615
--- /dev/null
+++ b/src/root/builtin/types/bool/mod.rs
@@ -0,0 +1,59 @@
+mod printb;
+
+use b_box::b;
+use unique_type_id::UniqueTypeId;
+use crate::root::builtin::t_id;
+use crate::root::builtin::types::bool::printb::PrintB;
+use crate::root::errors::WErr;
+use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable;
+use crate::root::parser::parse_function::parse_literal::{LiteralToken, LiteralTokens};
+use crate::root::shared::common::{ByteSize, LocalAddress, TypeID};
+use crate::root::shared::types::Type;
+
+pub fn register_bool(global_table: &mut GlobalDefinitionTable) {
+ global_table.register_builtin_type(b!(BoolType));
+ global_table.register_inline_function(&PrintB);
+}
+
+#[derive(UniqueTypeId)]
+#[UniqueTypeIdType = "u16"]
+pub struct BoolType;
+
+impl BoolType {
+ pub const fn id() -> TypeID {
+ t_id(BoolType::unique_type_id().0)
+ }
+}
+
+impl Type for BoolType {
+ fn id(&self) -> TypeID { Self::id() }
+
+ fn size(&self) -> ByteSize {
+ ByteSize(1)
+ }
+
+ fn name(&self) -> &str {
+ "bool"
+ }
+
+ fn instantiate_from_literal(&self, location: &LocalAddress, literal: &LiteralToken) -> Result {
+ Ok(match literal.literal() {
+ LiteralTokens::Bool(value) => {
+ if *value {
+ format!(" mov byte {location}, 1\n")
+ }
+ else {
+ format!(" mov byte {location}, 0\n")
+ }
+ }
+ LiteralTokens::Int(value) => {
+ if *value == 0 {
+ format!(" mov byte {location}, 0\n")
+ }
+ else {
+ format!(" mov byte {location}, 1\n")
+ }
+ }
+ })
+ }
+}
diff --git a/src/root/builtin/types/bool/printb.rs b/src/root/builtin/types/bool/printb.rs
new file mode 100644
index 0000000..c195478
--- /dev/null
+++ b/src/root/builtin/types/bool/printb.rs
@@ -0,0 +1,63 @@
+use unique_type_id::UniqueTypeId;
+use crate::root::builtin::{BuiltinInlineFunction, f_id, InlineFunctionGenerator};
+use crate::root::builtin::types::bool::BoolType;
+use crate::root::builtin::types::int::IntType;
+use crate::root::errors::WErr;
+use crate::root::name_resolver::name_resolvers::NameResult::Function;
+use crate::root::name_resolver::resolve_function_signatures::FunctionSignature;
+
+use crate::root::shared::common::{FunctionID, Indirection, LocalAddress, TypeID, TypeRef};
+
+#[derive(UniqueTypeId)]
+#[UniqueTypeIdType = "u16"]
+pub struct PrintB;
+
+impl PrintB {
+ pub const fn id() -> FunctionID {
+ f_id(PrintB::unique_type_id().0)
+ }
+}
+
+impl BuiltinInlineFunction for PrintB {
+ fn id(&self) -> FunctionID {
+ Self::id()
+ }
+
+ fn name(&self) -> &'static str {
+ "printb"
+ }
+
+ fn signature(&self) -> FunctionSignature {
+ FunctionSignature::new_inline_builtin(
+ false,
+ &[("lhs", BoolType::id().immediate())],
+ None
+ )
+ }
+
+ fn inline(&self) -> InlineFunctionGenerator {
+ |args: &[LocalAddress], _, gt, sz| -> String {
+ let id = format!("{}_fstr", Self::id().string_id());
+
+ let data = format!("{id} db `Boolean: %d\\n`,0");
+
+ gt.add_readonly_data(&id, &data);
+
+ let lhs = args[0];
+ format!(
+" mov rdi, {id}
+ mov rsi, 0
+ mov sil, {lhs}
+ mov al, 0
+ sub rsp, {sz}
+ extern printf
+ call printf
+ add rsp, {sz}
+")
+ }
+ }
+
+ fn parent_type(&self) -> Option {
+ None
+ }
+}
diff --git a/src/root/builtin/types/int/mod.rs b/src/root/builtin/types/int/mod.rs
index 55a2925..078ddf8 100644
--- a/src/root/builtin/types/int/mod.rs
+++ b/src/root/builtin/types/int/mod.rs
@@ -49,14 +49,14 @@ impl Type for IntType {
Ok(match literal.literal() {
LiteralTokens::Bool(value) => {
if *value {
- format!(" mov qword {location}, 0")
+ format!(" mov qword {location}, 0\n")
}
else {
- format!(" mov qword {location}, 1")
+ format!(" mov qword {location}, 1\n")
}
}
LiteralTokens::Int(value) => {
- format!(" mov qword {location}, {value}")
+ format!(" mov qword {location}, {value}\n")
}
})
}
diff --git a/src/root/builtin/types/int/printi.rs b/src/root/builtin/types/int/printi.rs
index 3b6b02d..45cb4fc 100644
--- a/src/root/builtin/types/int/printi.rs
+++ b/src/root/builtin/types/int/printi.rs
@@ -36,8 +36,6 @@ impl BuiltinInlineFunction for PrintI {
fn inline(&self) -> InlineFunctionGenerator {
|args: &[LocalAddress], _, gt, sz| -> String {
- let lhs = &args[0];
-
let id = format!("{}_fstr", Self::id().string_id());
let data = format!("{id} db `Integer: %d\\n`,0");
@@ -46,15 +44,14 @@ impl BuiltinInlineFunction for PrintI {
let lhs = args[0];
format!(
- "
- mov rdi, {id}
+" mov rdi, {id}
mov rsi, {lhs}
mov al, 0
sub rsp, {sz}
extern printf
call printf
add rsp, {sz}
- ")
+")
}
}
diff --git a/src/root/builtin/types/mod.rs b/src/root/builtin/types/mod.rs
index 8aa5d8f..f2fe61d 100644
--- a/src/root/builtin/types/mod.rs
+++ b/src/root/builtin/types/mod.rs
@@ -1 +1,2 @@
pub mod int;
+pub mod bool;
\ No newline at end of file
diff --git a/src/root/compiler/assembly/utils.rs b/src/root/compiler/assembly/utils.rs
index 47bb6bc..f75a17f 100644
--- a/src/root/compiler/assembly/utils.rs
+++ b/src/root/compiler/assembly/utils.rs
@@ -1,4 +1,5 @@
use std::fmt::format;
+use crate::root::assembler::assembly_builder::AssemblyBuilder;
use crate::root::shared::common::{ByteSize, FunctionID, LocalAddress};
@@ -82,36 +83,34 @@ pub fn copy(from: LocalAddress, to: LocalAddress, amount: ByteSize) -> String {
let to = to.0;
let mut written = 0;
- let mut output = String::new();
+ let mut output = AssemblyBuilder::new();
loop {
let to_write = amount.0 - written;
if to_write >= 8 {
- output += &format!(" mov rax, qword {}\n", LocalAddress(from + written as isize));
- output += &format!(" mov qword {}, rax", &LocalAddress(to + written as isize));
+ output.line(&format!("mov rax, qword {}", LocalAddress(from + written as isize)));
+ output.line(&format!("mov qword {}, rax", &LocalAddress(to + written as isize)));
written += 8;
}
else if to_write >= 4 {
- output += &format!(" mov rax, dword {}\n", LocalAddress(from + written as isize));
- output += &format!(" mov dword {}, rax", &LocalAddress(to + written as isize));
+ output.line(&format!("mov eax, dword {}", LocalAddress(from + written as isize)));
+ output.line(&format!("mov dword {}, eax", &LocalAddress(to + written as isize)));
written += 4;
}
else if to_write >= 2 {
- output += &format!(" mov rax, word {}\n", LocalAddress(from + written as isize));
- output += &format!(" mov word {}, rax", &LocalAddress(to + written as isize));
+ output.line(&format!("mov ax, word {}", LocalAddress(from + written as isize)));
+ output.line(&format!("mov word {}, ax", &LocalAddress(to + written as isize)));
written += 2;
}
else if to_write >= 1 {
- output += &format!(" mov rax, byte {}\n", LocalAddress(from + written as isize));
- output += &format!(" mov byte {}, rax", &LocalAddress(to + written as isize));
+ output.line(&format!("mov al, byte {}", LocalAddress(from + written as isize)));
+ output.line(&format!("mov byte {}, al", &LocalAddress(to + written as isize)));
written += 1;
}
else {
break;
}
if written == amount.0 { break; }
- output += "\n";
}
-
- output
+ output.finish()
}
\ No newline at end of file
diff --git a/src/root/compiler/compile.rs b/src/root/compiler/compile.rs
index 42a077e..da01c20 100644
--- a/src/root/compiler/compile.rs
+++ b/src/root/compiler/compile.rs
@@ -53,7 +53,7 @@ section .text
}
if !global_tracker.readonly_data_section().is_empty() {
- s += "section .data";
+ s += "section .data_readonly";
s += global_tracker.readonly_data_section();
}
diff --git a/src/root/compiler/compile_evaluable.rs b/src/root/compiler/compile_evaluable.rs
index d19542e..3099733 100644
--- a/src/root/compiler/compile_evaluable.rs
+++ b/src/root/compiler/compile_evaluable.rs
@@ -111,8 +111,6 @@ pub fn compile_evaluable_into(
t.instantiate_from_literal(target.local_address(), literal)?
}
EvaluableTokens::InfixOperator(lhs, op, rhs) => {
- let mut code = String::new();
-
let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, global_tracker)?;
let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Infix)?;
let signature = global_table.get_function_signature(op_fn);
@@ -144,13 +142,9 @@ pub fn compile_evaluable_into(
let (c, _) = call_function(fid, op_fn, &[Left(lhs), Left(rhs)], Some(target), global_table, local_variables, global_tracker)?;
- code += &c;
-
- code
+ c
},
EvaluableTokens::PrefixOperator(op, lhs) => {
- let mut code = String::new();
-
let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, global_tracker)?;
let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Prefix)?;
let signature = global_table.get_function_signature(op_fn);
@@ -181,10 +175,7 @@ pub fn compile_evaluable_into(
}
let (c, _) = call_function(fid, op_fn, &[Left(lhs)], Some(target), global_table, local_variables, global_tracker)?;
-
- code += &c;
-
- code
+ c
},
EvaluableTokens::DynamicAccess(_, _) => todo!(), // Accessed methods must be called
EvaluableTokens::StaticAccess(_, n) => return Err(WErr::n(NRErrors::CannotFindConstantAttribute(n.name().clone()), n.location().clone())), // Accessed methods must be called
@@ -225,7 +216,7 @@ pub fn compile_evaluable_reference(
NameResult::Function(_) => return Err(WErr::n(EvalErrs::FunctionMustBeCalled(name.name().clone()), name.location().clone())),
NameResult::Type(_) => return Err(WErr::n(EvalErrs::CannotEvalStandaloneType(name.name().clone()), name.location().clone())),
NameResult::Variable(address) => {
- ("".to_string(), Some(address))
+ (String::new(), Some(address))
}
}
},
diff --git a/src/root/compiler/compile_function.rs b/src/root/compiler/compile_function.rs
index 79e3ad3..bf50186 100644
--- a/src/root/compiler/compile_function.rs
+++ b/src/root/compiler/compile_function.rs
@@ -1,4 +1,7 @@
use std::collections::HashSet;
+use std::fmt::format;
+use crate::root::assembler::assembly_builder::AssemblyBuilder;
+use crate::root::builtin::types::bool::BoolType;
use crate::root::builtin::types::int::IntType;
use crate::root::compiler::assembly::utils::{align_16_bytes, align_16_bytes_plus_8};
use crate::root::compiler::compile_evaluable::{compile_evaluable, compile_evaluable_into, compile_evaluable_reference};
@@ -51,24 +54,21 @@ pub fn compile_function(fid: FunctionID, function: FunctionToken, global_table:
"{}:
push rbp
mov rbp, rsp
- {}",
+{}",
fid.string_id(),
full_contents
);
// if fid.is_main() {
- final_contents += "\n\tleave\n\tret";
+ // final_contents += "\n\tleave\n\tret";
// }
Ok(final_contents)
}
fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_variable: &Option, local_variables: &mut LocalVariableTable, global_table: &mut GlobalDefinitionTable, global_tracker: &mut GlobalTracker) -> Result {
- for i in lines {
- println!("{:#?}", i);
- }
local_variables.enter_block();
- let mut contents = String::new();
+ let mut contents = AssemblyBuilder::new();
let mut last_is_return = false;
@@ -78,11 +78,30 @@ fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_varia
LineTokens::Initialisation(it) => {
let (name, type_name, value) = (it.name(), it.type_name(), it.value());
let address = global_table.add_local_variable_named(name.name().clone(), type_name, local_variables)?;
- contents += "\n";
- contents += &compile_evaluable_into(fid, value, address, local_variables, global_table, global_tracker)?;
+ contents.other(&compile_evaluable_into(fid, value, address, local_variables, global_table, global_tracker)?);
},
LineTokens::Assignment(_) => todo!(),
- LineTokens::If(_) => todo!(),
+ LineTokens::If(if_token) => {
+ let condition_addr = global_table.add_local_variable_unnamed_base(BoolType::id().immediate(), local_variables);
+ contents.other(&compile_evaluable_into(fid, if_token.if_condition(), condition_addr.clone(), local_variables, global_table, global_tracker)?);
+ contents.line(&format!("cmp byte {}, 0", condition_addr.local_address()));
+
+ let end_if_tag = global_tracker.get_unique_tag(fid);
+ contents.line(&format!("jz {end_if_tag}"));
+ contents.other(&recursively_compile_lines(fid, if_token.if_contents(), &None, local_variables, global_table, global_tracker)?);
+
+ if let Some(else_contents) = if_token.else_contents() {
+ let end_else_tag = global_tracker.get_unique_tag(fid);
+ contents.line(&format!("jmp {end_else_tag}"));
+ contents.line(&format!("{end_if_tag}:"));
+ contents.other(&recursively_compile_lines(fid, else_contents, &None, local_variables, global_table, global_tracker)?);
+ contents.line(&format!("{end_else_tag}:"));
+ }
+ else {
+ contents.line(&format!("{end_if_tag}:"));
+ }
+
+ },
LineTokens::While(_) => todo!(),
LineTokens::Return(rt) => {
last_is_return = true;
@@ -92,10 +111,8 @@ fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_varia
}
let address = global_table.add_local_variable_unnamed_base(TypeRef::new(IntType::id(), Indirection(0)), local_variables);
- let code = compile_evaluable_into(fid, rt.return_value().as_ref().unwrap(), address.clone(), local_variables, global_table, global_tracker)?;
- contents += "\n";
- contents += &code;
- contents += &format!("\n\tmov rax, qword {}", address.local_address());
+ contents.other(&compile_evaluable_into(fid, rt.return_value().as_ref().unwrap(), address.clone(), local_variables, global_table, global_tracker)?);
+ contents.line(&format!("mov rax, qword {}", address.local_address()));
}
else {
if let Some(return_value) = rt.return_value() {
@@ -103,33 +120,26 @@ fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_varia
todo!()
}
- let code = compile_evaluable_into(fid, return_value, return_variable.clone().unwrap(), local_variables, global_table, global_tracker)?;
- contents += "\n";
- contents += &code;
+ contents.other(&compile_evaluable_into(fid, return_value, return_variable.clone().unwrap(), local_variables, global_table, global_tracker)?);
}
else {
if return_variable.is_some() {
todo!()
}
}
-
- contents += "\n leave";
- contents += "\n ret";
}
+
+ contents.line("leave");
+ contents.line("ret");
}
LineTokens::Break(_) => todo!(),
LineTokens::NoOp(et) => {
- contents += "\n";
- contents += &compile_evaluable_reference(fid, et, local_variables, global_table, global_tracker)?.0;
+ contents.other(&compile_evaluable_reference(fid, et, local_variables, global_table, global_tracker)?.0);
}
}
}
- if (return_variable.is_some() || fid.is_main()) && !last_is_return {
- todo!()
- }
-
local_variables.leave_block();
- Ok(contents)
+ Ok(contents.finish())
}
\ No newline at end of file
diff --git a/src/root/compiler/compile_function_call.rs b/src/root/compiler/compile_function_call.rs
index 682b5b7..aed95d0 100644
--- a/src/root/compiler/compile_function_call.rs
+++ b/src/root/compiler/compile_function_call.rs
@@ -1,6 +1,7 @@
use std::collections::HashSet;
use either::Either;
use itertools::Itertools;
+use crate::root::assembler::assembly_builder::AssemblyBuilder;
use crate::root::compiler::assembly::utils::{align_16_bytes, align_16_bytes_plus_8, copy};
use crate::root::compiler::compile_evaluable::{compile_evaluable, compile_evaluable_into};
use crate::root::compiler::global_tracker::GlobalTracker;
@@ -29,7 +30,7 @@ pub fn call_function(
let inline_o = inline.clone();
- let mut code = String::new();
+ let mut code = AssemblyBuilder::new();
let return_into = if let Some(expected_return) = global_table.get_function(fid).0.return_type().clone() {
if let Some(return_address) = return_address {
@@ -59,12 +60,7 @@ pub fn call_function(
Either::Left(eval) => {
let into = global_table.add_local_variable_unnamed_base(signature_args[i].clone(), local_variables);
let c = compile_evaluable_into(parent_fid, eval, into.clone(), local_variables, global_table, global_tracker)?;
-
- if i != 0 {
- code += "\n";
- }
-
- code += &c;
+ code.other(&c);
args.push(*into.local_address());
}
Either::Right(addr) => {
@@ -74,12 +70,11 @@ pub fn call_function(
}
}
- code += "\n";
- code += &inline_o(&args, return_into.as_ref().map(|x| *x.local_address()), global_tracker, local_variables.stack_size());
- Ok((code, return_into))
+ code.other(&inline_o(&args, return_into.as_ref().map(|x| *x.local_address()), global_tracker, local_variables.stack_size()));
+ Ok((code.finish(), return_into))
}
else {
- let mut code = String::new();
+ let mut code = AssemblyBuilder::new();
// TODO: Check args length
let mut args = Vec::new();
@@ -92,10 +87,7 @@ pub fn call_function(
let into = global_table.add_local_variable_unnamed_base(signature_args[i].clone(), local_variables);
size += global_table.get_size(into.type_ref());
let c = compile_evaluable_into(parent_fid, eval, into.clone(), local_variables, global_table, global_tracker)?;
- if i != 0 {
- code += "\n";
- }
- code += &c;
+ code.other(&c);
args.push(into);
}
Either::Right(addr) => {
@@ -131,13 +123,12 @@ pub fn call_function(
// ? Arguments
for arg in args.iter().rev() {
let into = global_table.add_local_variable_unnamed_base(arg.type_ref().clone(), local_variables);
- code += "\n";
- code += ©(*arg.local_address(), *into.local_address(), global_table.get_size(into.type_ref()));
+ code.other(©(*arg.local_address(), *into.local_address(), global_table.get_size(into.type_ref())));
}
- code += &format!("\n sub rsp, {}", local_variables.stack_size().0);
- code += &format!("\n call {}", fid.string_id());
- code += &format!("\n add rsp, {}", local_variables.stack_size().0);
+ code.line(&format!("sub rsp, {}", local_variables.stack_size().0));
+ code.line(&format!("call {}", fid.string_id()));
+ code.line(&format!("add rsp, {}", local_variables.stack_size().0));
// ? Leave block (invalidate parameters)
local_variables.leave_block();
@@ -147,14 +138,13 @@ pub fn call_function(
todo!()
}
- code += "\n";
- code += ©(*return_addr.as_ref().unwrap().local_address(), *return_address.local_address(), global_table.get_size(return_addr.as_ref().unwrap().type_ref()));
+ code.other(©(*return_addr.as_ref().unwrap().local_address(), *return_address.local_address(), global_table.get_size(return_addr.as_ref().unwrap().type_ref())));
Some(return_address)
}
else {
return_addr
};
- Ok((code, return_addr))
+ Ok((code.finish(), return_addr))
}
}
\ No newline at end of file
diff --git a/src/root/compiler/global_tracker.rs b/src/root/compiler/global_tracker.rs
index 898c076..4749d7b 100644
--- a/src/root/compiler/global_tracker.rs
+++ b/src/root/compiler/global_tracker.rs
@@ -6,7 +6,8 @@ use crate::root::shared::common::FunctionID;
pub struct GlobalTracker {
function_calls: HashSet,
readonly_contents: HashSet,
- readonly_data_section: String
+ readonly_data_section: String,
+ unique_tag_counter: usize
}
impl GlobalTracker {
@@ -29,4 +30,10 @@ impl GlobalTracker {
self.readonly_data_section += data;
}
}
+
+ pub fn get_unique_tag(&mut self, function: FunctionID) -> String {
+ let r = format!("{}_{}", function.string_id(), self.unique_tag_counter);
+ self.unique_tag_counter += 1;
+ r
+ }
}
\ No newline at end of file
diff --git a/src/root/parser/parse_function/parse_if.rs b/src/root/parser/parse_function/parse_if.rs
index 14c919b..6ef0755 100644
--- a/src/root/parser/parse_function/parse_if.rs
+++ b/src/root/parser/parse_function/parse_if.rs
@@ -1,4 +1,4 @@
-
+use derive_getters::Getters;
use nom::sequence::Tuple;
use nom_supreme::tag::complete::tag;
@@ -9,7 +9,7 @@ use crate::root::parser::parse_function::parse_line::{parse_lines, LineTestFn, L
use crate::root::parser::parse_name::SimpleNameToken;
use crate::root::parser::parse_util::{discard_ignored, require_ignored};
-#[derive(Debug)]
+#[derive(Debug, Getters)]
pub struct IfToken {
location: Location,
if_condition: EvaluableToken,
diff --git a/test/test.asm b/test/test.asm
new file mode 100644
index 0000000..e668ed3
--- /dev/null
+++ b/test/test.asm
@@ -0,0 +1,60 @@
+ global main
+
+section .text
+
+main:
+ push rbp
+ mov rbp, rsp
+
+ mov qword [rbp-8], 3
+ mov qword [rbp-16], 4
+
+ mov rax, qword [rbp-16]
+ leave
+ ret
+
+ mov qword [rbp-17], 0
+ mov al, byte [rbp-17]
+ mov byte [rbp-18], al
+ cmp byte [rbp-18], 0
+
+
+
+ jz main_0
+
+ mov rax, qword [rbp-8]
+ mov qword [rbp-26], rax
+
+ mov rdi, __4_fstr
+ mov rsi, [rbp-26]
+ mov al, 0
+ sub rsp, 26
+ extern printf
+ call printf
+ add rsp, 26
+
+ mov qword [rbp-34], 13
+ mov rax, qword [rbp-34]
+ leave
+ ret
+ jmp main_1
+ main_0:
+ mov rax, qword [rbp-16]
+ mov qword [rbp-26], rax
+
+ mov rdi, __4_fstr
+ mov rsi, [rbp-26]
+ mov al, 0
+ sub rsp, 26
+ extern printf
+ call printf
+ add rsp, 26
+
+ mov qword [rbp-34], 12
+ mov rax, qword [rbp-34]
+ leave
+ ret
+ main_1:
+
+section .data
+ __4_fstr db `Integer: %d\n`,0
\ No newline at end of file
diff --git a/types.toml b/types.toml
deleted file mode 100644
index 684024f..0000000
--- a/types.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-IntType=0
-IntAdd=1
-IntSub=2
-IntPSub=3
-P=4
-Pr=5
-Pri=6
-Prin=7
-Print=8
-PrintI=9
-E=10
-Ex=11
-Exi=12
-Exit=13
-ExitF=14
-ExitFu=15
-ExitFun=16
-ExitFunctio=17
-ExitFunction=18
-ExitFunctions=19