From 0b31b1a489e740450c500be444a53788c986d7f4 Mon Sep 17 00:00:00 2001 From: Robert Lucas <100799838+Robert-M-Lucas@users.noreply.github.com> Date: Fri, 26 Apr 2024 00:26:31 +0100 Subject: [PATCH] Changes --- Cargo.lock | 2 +- Cargo.toml | 2 +- main.why | 2 +- src/main.rs | 1 - src/root.rs | 22 +- src/root/assembler/assemble.rs | 25 -- src/root/assembler/mod.rs | 1 - src/root/custom/functions/mod.rs | 2 - src/root/custom/functions/print.rs | 234 ----------- src/root/custom/functions/windows.rs | 65 --- src/root/custom/get.rs | 25 -- src/root/custom/mod.rs | 3 - src/root/custom/types/bool.rs | 208 --------- src/root/custom/types/float.rs | 514 ----------------------- src/root/custom/types/int.rs | 601 --------------------------- src/root/custom/types/mod.rs | 3 - src/root/name_resolver/mod.rs | 2 +- src/root/name_resolver/resolve.rs | 101 ++++- src/root/parser/mod.rs | 19 +- src/root/parser/parse_error.rs | 34 -- src/root/parser/parse_function.rs | 22 +- src/root/parser/parse_name.rs | 7 +- 22 files changed, 129 insertions(+), 1766 deletions(-) delete mode 100644 src/root/assembler/assemble.rs delete mode 100644 src/root/assembler/mod.rs delete mode 100644 src/root/custom/functions/mod.rs delete mode 100644 src/root/custom/functions/print.rs delete mode 100644 src/root/custom/functions/windows.rs delete mode 100644 src/root/custom/get.rs delete mode 100644 src/root/custom/mod.rs delete mode 100644 src/root/custom/types/bool.rs delete mode 100644 src/root/custom/types/float.rs delete mode 100644 src/root/custom/types/int.rs delete mode 100644 src/root/custom/types/mod.rs delete mode 100644 src/root/parser/parse_error.rs diff --git a/Cargo.lock b/Cargo.lock index 6b4c0e9..66e8047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -420,7 +420,7 @@ dependencies = [ ] [[package]] -name = "whython-7" +name = "whython-8" version = "0.1.0" dependencies = [ "b-box", diff --git a/Cargo.toml b/Cargo.toml index 640ce28..031d848 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "whython-7" +name = "whython-8" version = "0.1.0" edition = "2021" diff --git a/main.why b/main.why index 845e04a..42faafe 100644 --- a/main.why +++ b/main.why @@ -1,3 +1,3 @@ -fn main() ~ int { +fn main() -> int { printb(true); } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index b232137..ea21d62 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ mod root; -mod root; fn main() { root::main(); diff --git a/src/root.rs b/src/root.rs index a043a6b..607089a 100644 --- a/src/root.rs +++ b/src/root.rs @@ -1,6 +1,7 @@ +use crate::root::name_resolver::resolve::resolve_names; +use crate::root::parser::parse::parse; // use crate::root::assembler::assemble::generate_assembly; // use crate::root::name_resolver::processor::process; -use crate::root::utils::AnyError; use crate::time; use clap::Parser; use color_print::cprintln; @@ -19,12 +20,12 @@ use std::path::PathBuf; // use runner::link_gcc_experimental; // use crate::root::parser::parse::parse; -mod assembler; -mod custom; -mod parser; -mod runner; -mod utils; -mod name_resolver; +pub mod parser; +pub mod runner; +pub mod utils; +pub mod name_resolver; + +pub const POINTER_SIZE: usize = 8; /// Compiler for Whython files (.why) #[derive(Parser)] @@ -54,12 +55,12 @@ pub fn main() { let _ = main_args(args); } -pub fn main_args(args: Args) -> Result<(), AnyError> { +pub fn main_args(args: Args) { if let Some(path) = PathBuf::from(&args.output).parent() { if let Err(e) = fs::create_dir_all(path) { if !matches!(e.kind(), ErrorKind::AlreadyExists) { cprintln!("Failed to create directories for output files"); - return Err(AnyError::Other); + panic!(); } } } @@ -69,6 +70,8 @@ pub fn main_args(args: Args) -> Result<(), AnyError> { let parsed = parse(PathBuf::from(&args.input)).unwrap(); ); + resolve_names(parsed); + // print!("Compiling... "); // time!(generate_assembly(&args.output, functions);); @@ -113,5 +116,4 @@ pub fn main_args(args: Args) -> Result<(), AnyError> { // } cprintln!("Done!"); - Ok(()) } diff --git a/src/root/assembler/assemble.rs b/src/root/assembler/assemble.rs deleted file mode 100644 index 5129f26..0000000 --- a/src/root/assembler/assemble.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::root::compiler::compile_functions::Function; -use std::fs; - -pub fn generate_assembly(output: &str, functions: Vec>) { - let mut out = String::from( - " global main - extern ExitProcess - extern GetStdHandle - extern WriteFile - extern HeapAlloc - extern HeapFree - extern GetProcessHeap - extern printf - section .text\n", - ); - for f in functions { - out += "\r\n"; - out += &(f.get_asm()); - } - - out += "\nformatStr: - db `The int is %d\\n`,0"; - - fs::write(format!("{output}.asm"), out).expect("Failed to write assembly to file"); -} diff --git a/src/root/assembler/mod.rs b/src/root/assembler/mod.rs deleted file mode 100644 index 3c372be..0000000 --- a/src/root/assembler/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod assemble; diff --git a/src/root/custom/functions/mod.rs b/src/root/custom/functions/mod.rs deleted file mode 100644 index a43482a..0000000 --- a/src/root/custom/functions/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod print; -pub mod windows; diff --git a/src/root/custom/functions/print.rs b/src/root/custom/functions/print.rs deleted file mode 100644 index 9aa7690..0000000 --- a/src/root/custom/functions/print.rs +++ /dev/null @@ -1,234 +0,0 @@ -use lazy_static::lazy_static; -use unique_type_id::UniqueTypeId; - -use crate::root::basic_ast::symbol::BasicSymbol; -use crate::root::compiler::compile_functions::{Function, Line, UserFunction}; -use crate::root::compiler::generate_asm::{compile_user_function, get_function_sublabel}; -use crate::root::compiler::local_variable::TypeInfo; -use crate::root::custom::types::bool::Bool; -use crate::root::custom::types::float::Float; -use crate::root::custom::types::int::Int; -use crate::root::name_resolver::type_builder::TypedFunction; - -pub fn add_function_signatures(existing: &mut Vec<(Option, Box)>) { - let signatures: [(Option, Box); 3] = [ - (None, Box::new(PrintI {})), - (None, Box::new(PrintB {})), - (None, Box::new(PrintF {})), - ]; - - for s in signatures { - existing.push(s); - } -} - -pub fn add_function_implementations(existing: &mut Vec>) { - let functions: [Box; 3] = [ - Box::new(PrintI {}), - Box::new(PrintB {}), - Box::new(PrintF {}), - ]; - - for s in functions { - existing.push(s); - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct PrintI {} -lazy_static! { - static ref PRINT_I_ARGS: [(String, TypeInfo); 1] = - [(String::from("integer"), TypeInfo::new(Int::get_id(), 0))]; -} -impl TypedFunction for PrintI { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "printi" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - PRINT_I_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - None - } - - fn is_inline(&self) -> bool { - false - } - - fn contents(&self) -> &Vec<(BasicSymbol, LineInfo)> { - panic!() - } - - fn take_contents(&mut self) -> Vec<(BasicSymbol, LineInfo)> { - panic!() - } - - fn get_inline(&self, _args: Vec) -> Vec { - panic!() - } -} - -impl Function for PrintI { - fn get_asm(&self) -> String { - compile_user_function(&UserFunction { - id: TypedFunction::get_id(self), - local_variable_size: 8, - arg_count: 1, - lines: vec![Line::InlineAsm(vec![ - "mov dword [rbp-4], 0x000a".to_string(), - "mov dword [rbp-8], 0x646C6C25".to_string(), - "mov rcx, rbp".to_string(), - "sub rcx, 8".to_string(), - "mov rdx, qword [rbp+16]".to_string(), - "sub rsp, 40".to_string(), - "call printf".to_string(), - "add rsp, 40".to_string(), - ])], - name: "printi".to_string(), - }) - } - - fn get_id(&self) -> isize { - TypedFunction::get_id(self) - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct PrintB {} -lazy_static! { - static ref PRINT_B_ARGS: [(String, TypeInfo); 1] = - [(String::from("bool"), TypeInfo::new(Bool::get_id(), 0))]; -} -impl TypedFunction for PrintB { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "printb" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - PRINT_B_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - None - } - - fn is_inline(&self) -> bool { - false - } -} - -impl Function for PrintB { - fn get_asm(&self) -> String { - compile_user_function(&UserFunction { - id: TypedFunction::get_id(self), - local_variable_size: 32, - arg_count: 1, - lines: vec![Line::InlineAsm(vec![ - "mov dword [rbp-8], 0x65757274".to_string(), - "mov dword [rbp-4], 0x0D0A".to_string(), - "mov rax, qword [rbp+16]".to_string(), - "cmp rax, 0".to_string(), - format!( - "jz {}", - get_function_sublabel(TypedFunction::get_id(self), "true") - ), - "mov dword [rbp-8], 0x736C6166".to_string(), - "mov dword [rbp-4], 0x0D0A65".to_string(), - format!( - "{}:", - get_function_sublabel(TypedFunction::get_id(self), "true") - ), - "mov rcx, rbp".to_string(), - "sub rcx, 8".to_string(), - "mov rdx, qword [rbp+16]".to_string(), - "sub rsp, 40".to_string(), - "call printf".to_string(), - "add rsp, 40".to_string(), - ])], - name: "printb".to_string(), - }) - } - - fn get_id(&self) -> isize { - TypedFunction::get_id(self) - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct PrintF {} -lazy_static! { - static ref PRINT_F_ARGS: [(String, TypeInfo); 1] = - [(String::from("float"), TypeInfo::new(Float::get_id(), 0))]; -} -impl TypedFunction for PrintF { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "printf" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - PRINT_F_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - None - } - - fn is_inline(&self) -> bool { - false - } -} - -impl Function for PrintF { - fn get_asm(&self) -> String { - compile_user_function(&UserFunction { - id: TypedFunction::get_id(self), - local_variable_size: 8, - arg_count: 1, - lines: vec![Line::InlineAsm(vec![ - "mov dword [rbp-4], 0x00".to_string(), - "mov dword [rbp-8], 0x0a664C25".to_string(), - "mov rcx, rbp".to_string(), - "sub rcx, 8".to_string(), - "movsd xmm1, qword [rbp+16]".to_string(), - "mov rdx, qword [rbp+16]".to_string(), - "sub rsp, 40".to_string(), - "call printf".to_string(), - "add rsp, 40".to_string(), - ])], - name: "printf".to_string(), - }) - } - - fn get_id(&self) -> isize { - TypedFunction::get_id(self) - } -} diff --git a/src/root/custom/functions/windows.rs b/src/root/custom/functions/windows.rs deleted file mode 100644 index c352379..0000000 --- a/src/root/custom/functions/windows.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::root::basic_ast::symbol::BasicSymbol; -use crate::root::compiler::generate_asm::get_local_address; -use crate::root::compiler::local_variable::TypeInfo; -use crate::root::custom::types::int::Int; -use crate::root::name_resolver::type_builder::TypedFunction; -use crate::root::parser::line_info::LineInfo; -use lazy_static::lazy_static; -use unique_type_id::UniqueTypeId; - -pub fn add_function_signatures(existing: &mut Vec<(Option, Box)>) { - let signatures: [(Option, Box); 1] = - [(None, Box::new(WindowsExit {}))]; - - for s in signatures { - existing.push(s); - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct WindowsExit {} -lazy_static! { - static ref WINDOWS_EXIT_ARGS: [(String, TypeInfo); 1] = - [(String::from("exit_code"), TypeInfo::new(Int::get_id(), 0))]; -} -impl TypedFunction for WindowsExit { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "exit" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - WINDOWS_EXIT_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - None - } - - fn is_inline(&self) -> bool { - true - } - - fn contents(&self) -> &Vec<(BasicSymbol, LineInfo)> { - panic!() - } - - fn take_contents(&mut self) -> Vec<(BasicSymbol, LineInfo)> { - panic!() - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rcx, qword [{}]", get_local_address(args[0])), - "call ExitProcess".to_string(), - ] - } -} diff --git a/src/root/custom/get.rs b/src/root/custom/get.rs deleted file mode 100644 index 3a942b3..0000000 --- a/src/root/custom/get.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::root::compiler::compile_functions::Function; -use crate::root::custom::functions::{print, windows}; -use crate::root::custom::types::{bool, float, int}; -use crate::root::name_resolver::type_builder::TypedFunction; - -pub fn get_custom_function_signatures() -> Vec<(Option, Box)> { - let mut signatures = Vec::new(); - - bool::add_function_signatures(&mut signatures); - int::add_function_signatures(&mut signatures); - float::add_function_signatures(&mut signatures); - - windows::add_function_signatures(&mut signatures); - print::add_function_signatures(&mut signatures); - - signatures -} - -pub fn get_custom_function_implementations() -> Vec> { - let mut functions = Vec::new(); - - print::add_function_implementations(&mut functions); - - functions -} diff --git a/src/root/custom/mod.rs b/src/root/custom/mod.rs deleted file mode 100644 index 7516728..0000000 --- a/src/root/custom/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod functions; -pub mod get; -pub mod types; diff --git a/src/root/custom/types/bool.rs b/src/root/custom/types/bool.rs deleted file mode 100644 index 9fd9d14..0000000 --- a/src/root/custom/types/bool.rs +++ /dev/null @@ -1,208 +0,0 @@ -use lazy_static::lazy_static; -use unique_type_id::UniqueTypeId; - -use crate::root::ast::literals::Literal; -use crate::root::compiler::generate_asm::get_local_address; -use crate::root::compiler::local_variable::TypeInfo; -use crate::root::name_resolver::processor::ProcessorError; -use crate::root::name_resolver::type_builder::{Type, TypeTable, TypedFunction}; -use crate::root::parser::line_info::LineInfo; - -pub fn add_function_signatures(existing: &mut Vec<(Option, Box)>) { - let signatures: [(Option, Box); 3] = [ - (Some(Bool::get_id()), Box::new(BoolNot {})), - (Some(Bool::get_id()), Box::new(BoolEQ {})), - (Some(Bool::get_id()), Box::new(BoolNE {})), - ]; - for s in signatures { - existing.push(s); - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct Bool {} - -impl Bool { - pub fn new() -> Bool { - Bool {} - } - pub fn get_id() -> isize { - -(Self::id().0 as isize) - 1 - } -} - -impl Type for Bool { - fn get_id(&self) -> isize { - Self::get_id() - } - - fn get_name(&self) -> &str { - "bool" - } - - fn get_size( - &self, - _type_table: &TypeTable, - _path: Option>, - ) -> Result { - Ok(8) - } - - fn instantiate( - &self, - literal: Option<&Literal>, - local_address: isize, - ) -> Result, ProcessorError> { - if literal.is_none() { - return Ok(vec![]); - } - let Literal::Bool(val) = literal.unwrap() else { - panic!() - }; - - if *val { - Ok(vec![format!( - "mov qword [{}], 0", - get_local_address(local_address) - )]) - } else { - Ok(vec![format!( - "mov qword [{}], 1", - get_local_address(local_address) - )]) - } - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct BoolNot {} -lazy_static! { - static ref BOOL_NOT_ARGS: [(String, TypeInfo); 1] = - [(String::from("lhs"), TypeInfo::new(Bool::get_id(), 0))]; -} -impl TypedFunction for BoolNot { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "not" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - BOOL_NOT_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - "cmp rax, 0".to_string(), - "setz al".to_string(), - format!("mov qword [{}], rax", get_local_address(args[1])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct BoolEQ {} -lazy_static! { - static ref BOOL_EQ_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Bool::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Bool::get_id(), 0)) - ]; -} -impl TypedFunction for BoolEQ { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "eq" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - BOOL_EQ_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rcx, rax".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setnz [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct BoolNE {} -lazy_static! { - static ref BOOL_NE_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Bool::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Bool::get_id(), 0)) - ]; -} -impl TypedFunction for BoolNE { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "ne" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - BOOL_NE_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rcx, rax".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setz [{}]", get_local_address(args[2])), - ] - } -} diff --git a/src/root/custom/types/float.rs b/src/root/custom/types/float.rs deleted file mode 100644 index b0d15c7..0000000 --- a/src/root/custom/types/float.rs +++ /dev/null @@ -1,514 +0,0 @@ -use lazy_static::lazy_static; -use unique_type_id::UniqueTypeId; - -use crate::root::ast::literals::Literal; -use crate::root::compiler::generate_asm::get_local_address; -use crate::root::compiler::local_variable::TypeInfo; -use crate::root::custom::types::bool::Bool; -use crate::root::name_resolver::processor::ProcessorError; -use crate::root::name_resolver::type_builder::{Type, TypeTable, TypedFunction}; -use crate::root::parser::line_info::LineInfo; - -pub fn add_function_signatures(existing: &mut Vec<(Option, Box)>) { - let signatures: [(Option, Box); 10] = [ - (Some(Float::get_id()), Box::new(FloatAdd {})), - (Some(Float::get_id()), Box::new(FloatSub {})), - (Some(Float::get_id()), Box::new(FloatMul {})), - (Some(Float::get_id()), Box::new(FloatDiv {})), - (Some(Float::get_id()), Box::new(FloatLT {})), - (Some(Float::get_id()), Box::new(FloatGT {})), - (Some(Float::get_id()), Box::new(FloatLE {})), - (Some(Float::get_id()), Box::new(FloatGE {})), - (Some(Float::get_id()), Box::new(FloatEQ {})), - (Some(Float::get_id()), Box::new(FloatNE {})), - ]; - for s in signatures { - existing.push(s); - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct Float {} - -impl Float { - pub fn new() -> Float { - Float {} - } - - pub fn get_id() -> isize { - -(Self::id().0 as isize) - 1 - } -} - -impl Type for Float { - fn get_id(&self) -> isize { - Self::get_id() - } - - fn get_name(&self) -> &str { - "float" - } - - fn get_size( - &self, - _type_table: &TypeTable, - _path: Option>, - ) -> Result { - Ok(8) - } - - fn instantiate( - &self, - literal: Option<&Literal>, - local_address: isize, - ) -> Result, ProcessorError> { - if literal.is_none() { - return Ok(vec![]); - } - let Literal::Float(val) = literal.unwrap() else { - panic!() - }; - - Ok(vec![ - format!("mov rax, __float64__({:?})", *val), - format!("mov qword [{}], rax", get_local_address(local_address)), - ]) - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatAdd {} -lazy_static! { - static ref FLOAT_ADD_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatAdd { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "add" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_ADD_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Float::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("addsd xmm0, qword [{}]", get_local_address(args[1])), - format!("movsd qword [{}], xmm0", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatSub {} -lazy_static! { - static ref FLOAT_SUB_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatSub { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "sub" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_SUB_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Float::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("subsd xmm0, qword [{}]", get_local_address(args[1])), - format!("movsd qword [{}], xmm0", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatMul {} -lazy_static! { - static ref FLOAT_MUL_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatMul { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "mul" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_SUB_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Float::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("mulsd xmm0, qword [{}]", get_local_address(args[1])), - format!("movsd qword [{}], xmm0", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatDiv {} -lazy_static! { - static ref FLOAT_DIV_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatDiv { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "div" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_SUB_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Float::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("divsd xmm0, qword [{}]", get_local_address(args[1])), - format!("movsd qword [{}], xmm0", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatLT {} -lazy_static! { - static ref FLOAT_LT_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatLT { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "lt" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_LT_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("ucomisd xmm0, qword [{}]", get_local_address(args[1])), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("seta [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatGT {} -lazy_static! { - static ref FLOAT_GT_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatGT { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "gt" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_GT_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("ucomisd xmm0, qword [{}]", get_local_address(args[1])), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setb [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatLE {} -lazy_static! { - static ref FLOAT_LE_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatLE { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "le" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_LE_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("ucomisd xmm0, qword [{}]", get_local_address(args[1])), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setae [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatGE {} -lazy_static! { - static ref FLOAT_GE_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatGE { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "ge" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_GE_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("ucomisd xmm0, qword [{}]", get_local_address(args[1])), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setbe [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatEQ {} -lazy_static! { - static ref FLOAT_EQ_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatEQ { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "eq" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_EQ_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("ucomisd xmm0, qword [{}]", get_local_address(args[1])), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setne [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct FloatNE {} -lazy_static! { - static ref FLOAT_NE_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Float::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Float::get_id(), 0)) - ]; -} -impl TypedFunction for FloatNE { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "ne" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - FLOAT_NE_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("movsd xmm0, qword [{}]", get_local_address(args[0])), - format!("ucomisd xmm0, qword [{}]", get_local_address(args[1])), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("sete [{}]", get_local_address(args[2])), - ] - } -} diff --git a/src/root/custom/types/int.rs b/src/root/custom/types/int.rs deleted file mode 100644 index 4084e40..0000000 --- a/src/root/custom/types/int.rs +++ /dev/null @@ -1,601 +0,0 @@ -use lazy_static::lazy_static; -use unique_type_id::UniqueTypeId; - -use crate::root::ast::literals::Literal; -use crate::root::compiler::generate_asm::get_local_address; -use crate::root::compiler::local_variable::TypeInfo; -use crate::root::custom::types::bool::Bool; -use crate::root::name_resolver::processor::ProcessorError; -use crate::root::name_resolver::type_builder::{Type, TypeTable, TypedFunction}; -use crate::root::parser::line_info::LineInfo; - -pub fn add_function_signatures(existing: &mut Vec<(Option, Box)>) { - let signatures: [(Option, Box); 11] = [ - (Some(Int::get_id()), Box::new(IntAdd {})), - (Some(Int::get_id()), Box::new(IntSub {})), - (Some(Int::get_id()), Box::new(IntMul {})), - (Some(Int::get_id()), Box::new(IntDiv {})), - (Some(Int::get_id()), Box::new(IntMod {})), - (Some(Int::get_id()), Box::new(IntLT {})), - (Some(Int::get_id()), Box::new(IntGT {})), - (Some(Int::get_id()), Box::new(IntLE {})), - (Some(Int::get_id()), Box::new(IntGE {})), - (Some(Int::get_id()), Box::new(IntEQ {})), - (Some(Int::get_id()), Box::new(IntNE {})), - ]; - - for s in signatures { - existing.push(s); - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct Int {} - -impl Int { - pub fn new() -> Int { - Int {} - } - - pub fn get_id() -> isize { - -(Self::id().0 as isize) - 1 - } -} - -impl Int { - pub fn instantiate_local_ref(offset: isize, local_address: isize) -> Vec { - vec![ - "mov rax, rbp".to_string(), - format!("add rax, {offset}"), - format!("mov qword [{}], rax", get_local_address(local_address),), - ] - } - - pub fn instantiate_ref(base_variable: isize, offset: isize, ref_address: isize) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(base_variable)), - format!("add rax, {offset}"), - format!("mov qword [{}], rax", get_local_address(ref_address),), - ] - } -} - -impl Type for Int { - fn get_id(&self) -> isize { - Self::get_id() - } - - fn get_name(&self) -> &str { - "int" - } - - fn get_size( - &self, - _type_table: &TypeTable, - _path: Option>, - ) -> Result { - Ok(8) - } - - fn instantiate( - &self, - literal: Option<&Literal>, - local_address: isize, - ) -> Result, ProcessorError> { - if literal.is_none() { - return Ok(vec![]); - } - let Literal::Int(val) = literal.unwrap() else { - panic!() - }; - - // ? Hacky workaround as NASM doesn't appear to support 64-bit literals - let hex_str = format!("{:016x}", *val as i64); - let upper = &hex_str[..8]; - let lower = &hex_str[8..]; - - Ok(vec![ - format!( - "mov dword [{}], 0x{}", - get_local_address(local_address), - lower - ), - format!( - "mov dword [{}], 0x{}", - get_local_address(local_address + 4), - upper - ), - ]) - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntAdd {} -lazy_static! { - static ref INT_ADD_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntAdd { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "add" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_ADD_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Int::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("add rax, [{}]", get_local_address(args[1])), - format!("mov qword [{}], rax", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntSub {} -lazy_static! { - static ref INT_SUB_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntSub { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "sub" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_SUB_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Int::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("sub rax, [{}]", get_local_address(args[1])), - format!("mov [{}], rax", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntMul {} -lazy_static! { - static ref INT_MUL_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntMul { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "mul" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_SUB_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Int::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "mul rcx".to_string(), - format!("mov [{}], rax", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntDiv {} -lazy_static! { - static ref INT_DIV_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntDiv { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "div" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_SUB_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Int::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cqo".to_string(), - "idiv rcx".to_string(), - format!("mov [{}], rax", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntMod {} -lazy_static! { - static ref INT_MOD_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntMod { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "mod" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_MOD_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Int::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cqo".to_string(), - "idiv rcx".to_string(), - format!("mov [{}], rdx", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntLT {} -lazy_static! { - static ref INT_LT_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntLT { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "lt" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_LT_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rcx, rax".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setle [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntGT {} -lazy_static! { - static ref INT_GT_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntGT { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "gt" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_GT_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rax, rcx".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setle [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntLE {} -lazy_static! { - static ref INT_LE_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntLE { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "le" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_LE_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rax, rcx".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setnle [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntGE {} -lazy_static! { - static ref INT_GE_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntGE { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "ge" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_GE_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rcx, rax".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setnle [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntEQ {} -lazy_static! { - static ref INT_EQ_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntEQ { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "eq" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_EQ_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rcx, rax".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setnz [{}]", get_local_address(args[2])), - ] - } -} - -#[derive(UniqueTypeId)] -#[UniqueTypeIdType = "u16"] -pub struct IntNE {} -lazy_static! { - static ref INT_NE_ARGS: [(String, TypeInfo); 2] = [ - (String::from("lhs"), TypeInfo::new(Int::get_id(), 0)), - (String::from("rhs"), TypeInfo::new(Int::get_id(), 0)) - ]; -} -impl TypedFunction for IntNE { - fn get_id(&self) -> isize { - -(Self::id().0 as isize) - 1 - } - - fn get_name(&self) -> &str { - "ne" - } - - fn get_args(&self) -> &[(String, TypeInfo)] { - INT_NE_ARGS.as_ref() - } - - fn get_line(&self) -> LineInfo { - LineInfo::builtin() - } - - fn get_return_type(&self) -> Option { - Some(TypeInfo::new(Bool::get_id(), 0)) - } - - fn is_inline(&self) -> bool { - true - } - - fn get_inline(&self, args: Vec) -> Vec { - vec![ - format!("mov rax, qword [{}]", get_local_address(args[0])), - format!("mov rcx, [{}]", get_local_address(args[1])), - "cmp rcx, rax".to_string(), - format!("mov qword [{}], 0", get_local_address(args[2])), - format!("setz [{}]", get_local_address(args[2])), - ] - } -} diff --git a/src/root/custom/types/mod.rs b/src/root/custom/types/mod.rs deleted file mode 100644 index f10aa9b..0000000 --- a/src/root/custom/types/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod bool; -pub mod float; -pub mod int; diff --git a/src/root/name_resolver/mod.rs b/src/root/name_resolver/mod.rs index 4187d5b..3c6b865 100644 --- a/src/root/name_resolver/mod.rs +++ b/src/root/name_resolver/mod.rs @@ -1 +1 @@ -mod resolve; \ No newline at end of file +pub mod resolve; \ No newline at end of file diff --git a/src/root/name_resolver/resolve.rs b/src/root/name_resolver/resolve.rs index d52e35d..ae37b65 100644 --- a/src/root/name_resolver/resolve.rs +++ b/src/root/name_resolver/resolve.rs @@ -1,8 +1,13 @@ use std::collections::HashMap; -use derive_getters::Getters; +use derive_getters::{Dissolve, Getters}; +use itertools::Itertools; -use crate::root::parser::{parse::Location, parse_function::FunctionToken, parse_toplevel::TopLevelTokens}; +use crate::root::POINTER_SIZE; +use crate::root::parser::parse_name::NameToken; +use crate::root::parser::parse_function::FunctionToken; +use crate::root::parser::parse::Location; +use crate::root::parser::parse_toplevel::TopLevelTokens; #[derive(Getters)] struct TypeRef { @@ -16,6 +21,31 @@ impl TypeRef { } } +#[derive(Hash)] +struct TypeName { + name: String +} + +impl TypeName { + pub fn from_string(name: String) -> TypeName { + TypeName { name } + } + + pub fn from_name_token(name: NameToken) -> TypeName { + TypeName { name: name.dissolve().1 } + } +} + +impl PartialEq for TypeName { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +} + +impl Eq for TypeName {} + + +#[derive(Dissolve)] struct UnsizedUserType { id: isize, attributes: Vec<(String, TypeRef)>, @@ -23,11 +53,12 @@ struct UnsizedUserType { } impl UnsizedUserType { - pub fn new(id: isize, attributes: Vec, location: Location) -> UnsizedUserType { + pub fn new(id: isize, attributes: Vec<(String, TypeRef)>, location: Location) -> UnsizedUserType { UnsizedUserType { id, attributes, location } } } +#[derive(Getters)] struct UserType { id: isize, size: usize, @@ -35,6 +66,12 @@ struct UserType { location: Location } +impl UserType { + pub fn new(id: isize, size: usize, attributes: Vec<(usize, String, TypeRef)>, location: Location) -> UserType { + UserType { id, size, attributes, location } + } +} + struct Function { id: isize, args: Vec @@ -43,7 +80,7 @@ struct Function { // ! Intentionally unoptimised pub fn resolve_names(ast: Vec) { // ! User types > 1; Bultin Types < -1 - let mut type_names: HashMap = HashMap::new(); + let mut type_names: HashMap = HashMap::new(); let mut type_id: isize = 1; // ! (Name, (type, id)) - Type 0 means global let mut function_names: HashMap = HashMap::new(); @@ -54,11 +91,12 @@ pub fn resolve_names(ast: Vec) { for symbol in &ast { match symbol { TopLevelTokens::Struct(s) => { + let name = TypeName::from_string(s.name().clone()); // TODO: Name collision error - if type_names.contains_key(s.name()) { - panic!(); + if type_names.get(&name).is_none() { + todo!(); } - type_names.insert(s.name().clone(), type_id); + type_names.insert(name, type_id); type_id += 1; }, TopLevelTokens::Impl(_) => {}, @@ -73,12 +111,19 @@ pub fn resolve_names(ast: Vec) { match symbol { TopLevelTokens::Struct(s) => { let (location, name, attributes) = s.dissolve(); - let id = *type_names.get(&name).unwrap(); + let id = *type_names.get(&TypeName::from_string(name.clone())).unwrap(); + // TODO: Process indirection + let attributes = attributes.into_iter() + .map(|(name, type_name)| { + // TODO: Name error + (name, TypeRef::new(*type_names.get(&TypeName::from_name_token(type_name)).unwrap(), 0)) + } + ).collect_vec(); unsized_final_types.insert(id, UnsizedUserType::new(id, attributes, location)); }, TopLevelTokens::Impl(i) => { // TODO: Errors - let type_id = *type_names.get(i.name()).unwrap(); + let type_id = *type_names.get(&TypeName::from_string(i.name().clone())).unwrap(); for function in i.dissolve().2 { function_names.insert(function.name().clone(), (type_id, function_id)); @@ -95,12 +140,44 @@ pub fn resolve_names(ast: Vec) { } let mut final_types: HashMap = HashMap::new(); + + while !unsized_final_types.is_empty() { + let next_type_id = *unsized_final_types.keys().next().unwrap(); + let unsized_type = unsized_final_types.remove(&next_type_id).unwrap(); + resolve_types(unsized_type, &mut final_types, &mut unsized_final_types, &mut Vec::new()); + } } -fn resolve_types(id: isize, unsized_type: UnsizedUserType, final_types: &mut HashMap, path: &mut Vec) { +fn resolve_types(unsized_type: UnsizedUserType, final_types: &mut HashMap, unsized_types: &mut HashMap, path: &mut Vec) -> usize { + let (id, attributes, location) = unsized_type.dissolve(); + if path.contains(&id) { - // TODO: Circular type def - panic!() + // TODO: Circular type def error + todo!(); } + path.push(id); + + let mut size: usize = 0; + let mut processed_attributes: Vec<(usize, String, TypeRef)> = Vec::new(); + + for (attribute_name, attribute_type) in attributes { + let offset = size; + + if *attribute_type.indirection() != 0 { + size += POINTER_SIZE; + } + else if let Some(sized_type) = final_types.get(&attribute_type.type_id()) { + size += sized_type.size(); + } + else { + let unsized_type = unsized_types.remove(&attribute_type.type_id()).unwrap(); + size += resolve_types(unsized_type, final_types, unsized_types, path); + } + + processed_attributes.push((offset, attribute_name, attribute_type)); + } + + final_types.insert(id, UserType::new(id, size, processed_attributes, location)); + size } \ No newline at end of file diff --git a/src/root/parser/mod.rs b/src/root/parser/mod.rs index a19604a..8a279ae 100644 --- a/src/root/parser/mod.rs +++ b/src/root/parser/mod.rs @@ -1,13 +1,12 @@ pub mod parse; -mod parse_arguments; -mod parse_blocks; -mod parse_comments; -mod parse_error; +pub mod parse_arguments; +pub mod parse_blocks; +pub mod parse_comments; pub mod parse_function; -mod parse_impl; -mod parse_name; -mod parse_parameters; -mod parse_struct; +pub mod parse_impl; +pub mod parse_name; +pub mod parse_parameters; +pub mod parse_struct; pub mod parse_toplevel; -mod parse_util; -mod soft_alt; +pub mod parse_util; +pub mod soft_alt; diff --git a/src/root/parser/parse_error.rs b/src/root/parser/parse_error.rs deleted file mode 100644 index b51a5c5..0000000 --- a/src/root/parser/parse_error.rs +++ /dev/null @@ -1,34 +0,0 @@ -use crate::root::parser::line_info::LineInfo; -use std::io; -use std::path::PathBuf; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum ParseError { - #[error("File read error on path '{0}'")] - FileRead(PathBuf, io::Error), - #[error("Error: {1}\n{0}")] - Nested(LineInfo, Box), - #[error("Error: Operator '{1}' not recognised\n{0}")] - OperatorNotRecognised(LineInfo, String), - #[error("Error: 'mod' must be followed by a path\n{0}")] - ModNotFollowedByPath(LineInfo), - #[error("Error: Keyword ('{1}') cannot be followed by . or #\n{0}")] - KeywordFollowed(LineInfo, String), - #[error("Error: Closing '{1}' not found (started on line {2})\n{0}")] - NotClosed(LineInfo, char, usize), - #[error("Error: Unknown escape code '{1}'\n{0}")] - UnknownEscapeCode(LineInfo, char), - #[error("Error: String literal started on line {1} not closed\n{0}")] - UnclosedString(LineInfo, usize), - #[error("Error: Closing '{1}' found with no corresponding opening bracket\n{0}")] - NoOpening(LineInfo, char), - #[error("Error: Names cannot contain character '{1}' (UTF-8 Code: {2:?})\n{0}")] - BadName(LineInfo, char, Vec), - #[error("Initialiser must specify a type after '@'")] - NoInitialiserType(LineInfo), - #[error("Error: Initialiser type must be followed by braces containing attribute values\n{0}")] - NoInitialiserContents(LineInfo), - #[error("Error: Attribute cannot be empty (must be a value between commas)\n{0}")] - NoInitialiserAttribute(LineInfo), -} diff --git a/src/root/parser/parse_function.rs b/src/root/parser/parse_function.rs index 02a7cd6..4b1d05d 100644 --- a/src/root/parser/parse_function.rs +++ b/src/root/parser/parse_function.rs @@ -12,17 +12,17 @@ use crate::root::parser::parse_parameters::{parse_parameters, Parameters}; use crate::root::parser::parse_toplevel::{TopLevelTokens, ToplevelTestFn}; use crate::root::parser::parse_util::{discard_ignored, require_ignored}; -mod parse_assigner; -mod parse_assignment; -mod parse_break; -pub(crate) mod parse_evaluable; -mod parse_if; -mod parse_initialisation; -mod parse_line; -mod parse_literal; -mod parse_operator; -mod parse_return; -mod parse_while; +pub mod parse_assigner; +pub mod parse_assignment; +pub mod parse_break; +pub mod parse_evaluable; +pub mod parse_if; +pub mod parse_initialisation; +pub mod parse_line; +pub mod parse_literal; +pub mod parse_operator; +pub mod parse_return; +pub mod parse_while; #[derive(Debug, Getters)] pub struct FunctionToken { diff --git a/src/root/parser/parse_name.rs b/src/root/parser/parse_name.rs index b77897b..cb05e62 100644 --- a/src/root/parser/parse_name.rs +++ b/src/root/parser/parse_name.rs @@ -1,5 +1,6 @@ use crate::root::parser::parse::{ErrorTree, Location, ParseResult, Span}; use crate::root::parser::parse_function::parse_evaluable::EvaluableToken; +use derive_getters::Dissolve; use nom::bytes::complete::take_till; use nom::Err::Error; use nom::InputTake; @@ -9,12 +10,12 @@ use crate::root::parser::parse_blocks::{default_section, section}; use crate::root::parser::parse_util::discard_ignored; #[derive(Debug)] -enum NameConnectors { +pub enum NameConnectors { NonStatic, Static, } -#[derive(Debug)] +#[derive(Debug, Dissolve)] pub struct NameToken { location: Location, base: String, @@ -34,7 +35,7 @@ impl NameToken { } pub fn parse_full_name(s: Span) -> ParseResult { - // TODO: Handle function calls + // TODO: Handle indirection let (s, _) = discard_ignored(s)?;