diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 110b6eb..135d947 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -7,12 +7,22 @@ - - + + + + + + + + + + + + @@ -501,7 +519,8 @@ - diff --git a/build/out.asm b/build/out.asm index f42e6fb..894a3de 100644 --- a/build/out.asm +++ b/build/out.asm @@ -5,24 +5,41 @@ section .text main: push rbp mov rbp, rsp - mov byte [rbp-1], 1 - + mov byte [rbp-1], 0 + mov rax, rbp + add rax, -1 + mov qword [rbp-9], rax mov al, byte [rbp-1] + mov byte [rbp-11], al + mov al, byte [rbp-11] cmp al, 0 jz __7_0 - mov rdi, __7_t_fstr + mov byte [rbp-10], 0 jmp __7_1 __7_0: - mov rdi, __7_f_fstr + mov byte [rbp-10], 1 __7_1: + mov rdx, qword [rbp-9] + mov al, byte [rbp-10] + mov byte [rdx], al + mov al, byte [rbp-1] + mov byte [rbp-12], al + mov al, byte [rbp-12] + cmp al, 0 + jz __7_2 + mov rdi, __7_t_fstr + jmp __7_3 + __7_2: + mov rdi, __7_f_fstr + __7_3: mov rsi, 0 mov al, 0 - sub rsp, 1 + sub rsp, 12 extern printf call printf - add rsp, 1 - mov qword [rbp-9], 2 - mov rax, qword [rbp-9] + add rsp, 12 + mov qword [rbp-20], 2 + mov rax, qword [rbp-20] leave ret diff --git a/build/out.o b/build/out.o index 2f8c649..f52d4df 100644 Binary files a/build/out.o and b/build/out.o differ diff --git a/build/out.out b/build/out.out index 60e99e5..bd489dc 100755 Binary files a/build/out.out and b/build/out.out differ diff --git a/main.why b/main.why index 03e502d..3708e59 100644 --- a/main.why +++ b/main.why @@ -1,5 +1,8 @@ fn main() -> int { - printb(true); + let a: bool = true; + &a = !a; + + printb(a); return 2; } diff --git a/src/root/builtin/types/bool/and.rs b/src/root/builtin/types/bool/and.rs index 7f610d3..d7ec258 100644 --- a/src/root/builtin/types/bool/and.rs +++ b/src/root/builtin/types/bool/and.rs @@ -1,6 +1,7 @@ use unique_type_id::UniqueTypeId; use crate::root::builtin::{BuiltinInlineFunction, InlineFunctionGenerator, f_id}; use crate::root::builtin::types::bool::BoolType; +use crate::root::builtin::types::bool::printb::PrintB; use crate::root::builtin::types::int::IntType; use crate::root::name_resolver::resolve_function_signatures::FunctionSignature; @@ -28,56 +29,73 @@ impl BuiltinInlineFunction for BoolAnd { } fn inline(&self) -> InlineFunctionGenerator { - |args: &[LocalAddress], return_into: Option, _, _| -> String { + |args: &[LocalAddress], return_into, gt, sz| -> String { + + let jmp_false = gt.get_unique_tag(PrintB::id()); + let jmp_end = gt.get_unique_tag(PrintB::id()); + let lhs = args[0]; let rhs = args[1]; let return_into = return_into.unwrap(); format!( -" mov rax, qword {lhs} - mov rbx, qword {rhs} - or rax, rbx - mov qword {return_into}, rax\n") +" mov al, byte {lhs} + cmp al, 0 + jz {jmp_false} + mov al, byte {rhs} + mov byte {return_into}, al + jmp {jmp_end} + {jmp_false}: + mov byte {return_into}, 0 + {jmp_end}: +") } } fn parent_type(&self) -> Option { - Some(IntType::id()) + Some(BoolType::id()) } } #[derive(UniqueTypeId)] #[UniqueTypeIdType = "u16"] -pub struct IntAsAdd; +pub struct BoolAsAnd; -impl BuiltinInlineFunction for IntAsAdd { +impl BuiltinInlineFunction for BoolAsAnd { fn id(&self) -> FunctionID { - f_id(IntAsAdd::unique_type_id().0) + f_id(BoolAsAnd::unique_type_id().0) } fn name(&self) -> &'static str { - "as_add" + "as_and" } fn signature(&self) -> FunctionSignature { FunctionSignature::new_inline_builtin( true, - &[("lhs", IntType::id().with_indirection(1)), ("rhs", IntType::id().immediate())], + &[("lhs", BoolType::id().with_indirection(1)), ("rhs", BoolType::id().immediate())], None ) } fn inline(&self) -> InlineFunctionGenerator { - |args: &[LocalAddress], return_into: Option, _, _| -> String { + |args: &[LocalAddress], _, gt, sz| -> String { + + let jmp_true = gt.get_unique_tag(PrintB::id()); + let lhs = args[0]; let rhs = args[1]; format!( -" mov rax, qword {lhs} - mov rdx, qword {rhs} - add qword [rax], rdx\n") +" mov al, byte {rhs} + cmp al, 0 + jnz {jmp_true} + mov rax, qword {lhs} + mov byte [rax], 0 + {jmp_true}: +") } } fn parent_type(&self) -> Option { - Some(IntType::id()) + Some(BoolType::id()) } } \ No newline at end of file diff --git a/src/root/builtin/types/bool/mod.rs b/src/root/builtin/types/bool/mod.rs index 11b3677..1f73fdb 100644 --- a/src/root/builtin/types/bool/mod.rs +++ b/src/root/builtin/types/bool/mod.rs @@ -1,19 +1,32 @@ mod printb; mod and; +mod or; +mod not; use b_box::b; use unique_type_id::UniqueTypeId; -use crate::root::builtin::t_id; +use crate::root::builtin::{BuiltinInlineFunction, f_id, InlineFunctionGenerator, t_id}; +use crate::root::builtin::types::bool::and::{BoolAnd, BoolAsAnd}; +use crate::root::builtin::types::bool::not::BoolNot; +use crate::root::builtin::types::bool::or::{BoolAsOr, BoolOr}; use crate::root::builtin::types::bool::printb::PrintB; +use crate::root::builtin::types::int::IntType; use crate::root::errors::WErr; use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable; +use crate::root::name_resolver::resolve_function_signatures::FunctionSignature; use crate::root::parser::parse_function::parse_literal::{LiteralToken, LiteralTokens}; -use crate::root::shared::common::{ByteSize, LocalAddress, TypeID}; +use crate::root::shared::common::{ByteSize, FunctionID, 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); + global_table.register_inline_function(&BoolAssign); + global_table.register_inline_function(&BoolAnd); + global_table.register_inline_function(&BoolAsAnd); + global_table.register_inline_function(&BoolOr); + global_table.register_inline_function(&BoolAsOr); + global_table.register_inline_function(&BoolNot); } #[derive(UniqueTypeId)] @@ -58,3 +71,40 @@ impl Type for BoolType { }) } } + +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct BoolAssign; + +impl BuiltinInlineFunction for BoolAssign { + fn id(&self) -> FunctionID { + f_id(BoolAssign::unique_type_id().0) + } + + fn name(&self) -> &'static str { + "assign" + } + + fn signature(&self) -> FunctionSignature { + FunctionSignature::new_inline_builtin( + true, + &[("lhs", BoolType::id().with_indirection(1)), ("rhs", BoolType::id().immediate())], + None + ) + } + + fn inline(&self) -> InlineFunctionGenerator { + |args: &[LocalAddress], return_into: Option, _, _| -> String { + let lhs = args[0]; + let rhs = args[1]; + format!( + " mov rdx, qword {lhs} + mov al, byte {rhs} + mov byte [rdx], al\n") + } + } + + fn parent_type(&self) -> Option { + Some(BoolType::id()) + } +} \ No newline at end of file diff --git a/src/root/builtin/types/bool/not.rs b/src/root/builtin/types/bool/not.rs new file mode 100644 index 0000000..c42642f --- /dev/null +++ b/src/root/builtin/types/bool/not.rs @@ -0,0 +1,55 @@ +use unique_type_id::UniqueTypeId; +use crate::root::builtin::{BuiltinInlineFunction, InlineFunctionGenerator, f_id}; +use crate::root::builtin::types::bool::BoolType; +use crate::root::builtin::types::bool::printb::PrintB; +use crate::root::builtin::types::int::IntType; +use crate::root::name_resolver::resolve_function_signatures::FunctionSignature; + +use crate::root::shared::common::{FunctionID, LocalAddress, TypeID}; + +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct BoolNot; + +impl BuiltinInlineFunction for BoolNot { + fn id(&self) -> FunctionID { + f_id(BoolNot::unique_type_id().0) + } + + fn name(&self) -> &'static str { + "p_not" + } + + fn signature(&self) -> FunctionSignature { + FunctionSignature::new_inline_builtin( + true, + &[("lhs", BoolType::id().immediate())], + Some(BoolType::id().immediate()) + ) + } + + fn inline(&self) -> InlineFunctionGenerator { + |args: &[LocalAddress], return_into, gt, sz| -> String { + + let jmp_false = gt.get_unique_tag(PrintB::id()); + let jmp_end = gt.get_unique_tag(PrintB::id()); + + let lhs = args[0]; + let return_into = return_into.unwrap(); + format!( +" mov al, byte {lhs} + cmp al, 0 + jz {jmp_false} + mov byte {return_into}, 0 + jmp {jmp_end} + {jmp_false}: + mov byte {return_into}, 1 + {jmp_end}: +") + } + } + + fn parent_type(&self) -> Option { + Some(BoolType::id()) + } +} \ No newline at end of file diff --git a/src/root/builtin/types/bool/or.rs b/src/root/builtin/types/bool/or.rs new file mode 100644 index 0000000..012ed00 --- /dev/null +++ b/src/root/builtin/types/bool/or.rs @@ -0,0 +1,86 @@ +use unique_type_id::UniqueTypeId; +use crate::root::builtin::{BuiltinInlineFunction, InlineFunctionGenerator, f_id}; +use crate::root::builtin::types::bool::BoolType; +use crate::root::builtin::types::bool::printb::PrintB; +use crate::root::builtin::types::int::IntType; +use crate::root::name_resolver::resolve_function_signatures::FunctionSignature; + +use crate::root::shared::common::{FunctionID, LocalAddress, TypeID}; + +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct BoolOr; + +impl BuiltinInlineFunction for BoolOr { + fn id(&self) -> FunctionID { + f_id(BoolOr::unique_type_id().0) + } + + fn name(&self) -> &'static str { + "or" + } + + fn signature(&self) -> FunctionSignature { + FunctionSignature::new_inline_builtin( + true, + &[("lhs", BoolType::id().immediate()), ("rhs", BoolType::id().immediate())], + Some(BoolType::id().immediate()) + ) + } + + fn inline(&self) -> InlineFunctionGenerator { + |args: &[LocalAddress], return_into, gt, sz| -> String { + let lhs = args[0]; + let rhs = args[1]; + let return_into = return_into.unwrap(); + format!( +" mov al, byte {lhs} + or al, byte {rhs} + mov byte {return_into}, al +") + } + } + + fn parent_type(&self) -> Option { + Some(BoolType::id()) + } +} + +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct BoolAsOr; + +impl BuiltinInlineFunction for BoolAsOr { + fn id(&self) -> FunctionID { + f_id(BoolAsOr::unique_type_id().0) + } + + fn name(&self) -> &'static str { + "as_or" + } + + fn signature(&self) -> FunctionSignature { + FunctionSignature::new_inline_builtin( + true, + &[("lhs", BoolType::id().with_indirection(1)), ("rhs", BoolType::id().immediate())], + None + ) + } + + fn inline(&self) -> InlineFunctionGenerator { + |args: &[LocalAddress], _, gt, sz| -> String { + let lhs = args[0]; + let rhs = args[1]; + format!( +" mov rdx, qword {lhs} + mov al, byte [rdx] + or al, byte {rhs} + mov byte [rdx], al +") + } + } + + fn parent_type(&self) -> Option { + Some(BoolType::id()) + } +} \ No newline at end of file diff --git a/src/root/builtin/types/bool/printb.rs b/src/root/builtin/types/bool/printb.rs index c63de61..c0fe128 100644 --- a/src/root/builtin/types/bool/printb.rs +++ b/src/root/builtin/types/bool/printb.rs @@ -48,8 +48,7 @@ impl BuiltinInlineFunction for PrintB { let lhs = args[0]; format!( -" - mov al, byte {lhs} +" mov al, byte {lhs} cmp al, 0 jz {jmp_false} mov rdi, {id_true} diff --git a/src/root/parser/parse_function/parse_literal.rs b/src/root/parser/parse_function/parse_literal.rs index bf00076..0e1897b 100644 --- a/src/root/parser/parse_function/parse_literal.rs +++ b/src/root/parser/parse_function/parse_literal.rs @@ -2,6 +2,7 @@ use derive_getters::{Dissolve, Getters}; use crate::root::parser::parse::{Location, ParseResult, Span}; use nom::branch::alt; use nom::bytes::complete::tag; +use crate::root::builtin::types::bool::BoolType; use crate::root::builtin::types::int::IntType; use crate::root::parser::parse_util::discard_ignored; use crate::root::shared::common::TypeID; @@ -23,7 +24,7 @@ impl LiteralTokens { pub fn default_type(&self) -> TypeID { match self { LiteralTokens::Bool(_) => { - todo!() + BoolType::id() } LiteralTokens::Int(_) => { IntType::id() diff --git a/src/root/parser/parse_function/parse_operator.rs b/src/root/parser/parse_function/parse_operator.rs index 508d83d..738f66b 100644 --- a/src/root/parser/parse_function/parse_operator.rs +++ b/src/root/parser/parse_function/parse_operator.rs @@ -25,11 +25,11 @@ const OPERATOR_MAPS: [(&str, OperatorTokens, PrefixOrInfix, &str); 18] = [ ("*=", OperatorTokens::AsMul, PrefixOrInfix::Infix, "as_mul"), ("/=", OperatorTokens::AsDiv, PrefixOrInfix::Infix, "as_div"), ("%=", OperatorTokens::AsMod, PrefixOrInfix::Infix, "as_mod"), + ("&&", OperatorTokens::And, PrefixOrInfix::Infix, "and"), + ("&=", OperatorTokens::AsAnd, PrefixOrInfix::Infix, "as_and"), ("&", OperatorTokens::Reference, PrefixOrInfix::Prefix, "ref"), - ("&&", OperatorTokens::And, PrefixOrInfix::Prefix, "and"), - ("&=", OperatorTokens::AsAnd, PrefixOrInfix::Prefix, "as_and"), - ("||", OperatorTokens::Or, PrefixOrInfix::Prefix, "or"), - ("|=", OperatorTokens::AsOr, PrefixOrInfix::Prefix, "as_or"), + ("||", OperatorTokens::Or, PrefixOrInfix::Infix, "or"), + ("|=", OperatorTokens::AsOr, PrefixOrInfix::Infix, "as_or"), ("+", OperatorTokens::Add, PrefixOrInfix::Both, "add"), ("-", OperatorTokens::Subtract, PrefixOrInfix::Both, "sub"), ("*", OperatorTokens::Multiply, PrefixOrInfix::Both, "mul"), diff --git a/test/test.asm b/test/test.asm index e668ed3..6f2ae44 100644 --- a/test/test.asm +++ b/test/test.asm @@ -5,56 +5,39 @@ 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 byte [rbp-1], 0 + + mov rax, rbp + add rax, -1 + mov qword [rbp-9], rax ; rbp - 1 + mov byte [rbp-10], 1 + + mov rax, qword [rbp-9] ; rbp - 1 + mov al, byte [rax] ; 0 + or al, byte [rbp-10] ; al = 1 + mov rax, qword [rbp-9] ; rbp - 1 + mov byte [rax], al ; + + mov al, byte [rbp-1] + cmp al, 0 + jz __7_0 + mov rdi, __7_t_fstr + jmp __7_1 + __7_0: + mov rdi, __7_f_fstr + __7_1: + mov rsi, 0 mov al, 0 - sub rsp, 26 + sub rsp, 11 extern printf call printf - add rsp, 26 - - mov qword [rbp-34], 13 - mov rax, qword [rbp-34] + add rsp, 11 + mov qword [rbp-19], 2 + mov rax, qword [rbp-19] 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 +section .data_readonly + __7_f_fstr db `Boolean: False`,0 + __7_t_fstr db `Boolean: True`,0 \ No newline at end of file diff --git a/test/test.o b/test/test.o index 6aa11e9..9383904 100644 Binary files a/test/test.o and b/test/test.o differ diff --git a/test/test.out b/test/test.out index bec97dc..a2ece71 100755 Binary files a/test/test.out and b/test/test.out differ diff --git a/types.toml b/types.toml index 0e7c089..beb85dd 100644 --- a/types.toml +++ b/types.toml @@ -52,3 +52,19 @@ Bool=50 BoolA=51 BoolAn=52 BoolAnd=53 +BoolAs=54 +BoolAsA=55 +BoolAsAnb=56 +BoolAsAnbd=57 +BoolAsAn=58 +BoolAsAnd=59 +BoolOr=60 +BoolAsO=61 +BoolAsOr=62 +BoolN=63 +BoolNo=64 +BoolNot=65 +BoolAss=66 +BoolAssi=67 +BoolAssig=68 +BoolAssign=69