From fb9bb67ba42fe780a02f31da30d3e7e4f4d452c0 Mon Sep 17 00:00:00 2001 From: Robert-M-Lucas Date: Wed, 19 Jun 2024 14:55:00 +0100 Subject: [PATCH] More boolean operations --- .idea/workspace.xml | 29 +++++- build/out.asm | 33 +++++-- build/out.o | Bin 1072 -> 1184 bytes build/out.out | Bin 16880 -> 16944 bytes main.why | 5 +- src/root/builtin/types/bool/and.rs | 50 ++++++---- src/root/builtin/types/bool/mod.rs | 54 ++++++++++- src/root/builtin/types/bool/not.rs | 55 +++++++++++ src/root/builtin/types/bool/or.rs | 86 ++++++++++++++++++ src/root/builtin/types/bool/printb.rs | 3 +- .../parser/parse_function/parse_literal.rs | 3 +- .../parser/parse_function/parse_operator.rs | 8 +- test/test.asm | 75 ++++++--------- test/test.o | Bin 1136 -> 1104 bytes test/test.out | Bin 16776 -> 16880 bytes types.toml | 16 ++++ 16 files changed, 332 insertions(+), 85 deletions(-) create mode 100644 src/root/builtin/types/bool/not.rs create mode 100644 src/root/builtin/types/bool/or.rs 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 2f8c64927ac5a49d7b7fdbd770a44c0b554b0877..f52d4df5ce58753fb7fbf120a4a7b4097afe22ab 100644 GIT binary patch delta 338 zcmdnMv4C^J0>+Ao3(XlDCf>AXTrgRZ(O&cc69X71FhXcnAjLH~mrh7z`8uHP75vj9m(kM2;Q)VB^M zu>6-U*DsT~nN%crUVx1AXgAXESN0GXfL{fi2)2gKqv-QAk8s3mr12U*Pt#DD%n092R(07tbgEC2ui diff --git a/build/out.out b/build/out.out index 60e99e57ab7c5139c07c896230e30239dabcf15e..bd489dc9f938a312ee82efaca437a1828207ae15 100755 GIT binary patch delta 721 zcmey+%($V2ae@Zphl!f^Ikz%0fWg+yf{fuzA}7*}oi?;q$h{3%B-&B7v%YnvYTM=- z=H0xe3?7{?Jem*u_vm!}-sSqg!}V*I>sK3w61HQm-xyxA07*uV?ogoAw+<$-{Fg4* zFO#hWRU~*`%=-8Lzen>C9*^U$ZW#D6Q5O4t7rv|Z>Vee!^pzKMoUOol`v@kq3Inhj<@z&%@v)k-O4Ds>i@y46| z%@;CFKETAX`GaKwGh@c&KwEu8^lt97J^X*AM5*%>8^aP1sJtP3mZh(38zI z%)5D67`t5mPtFlkkz{;v`rrTm9?eG>J&wD6X9DW>=yv^n@-V~Z6@n3blUNNlDH!lE zR%|xZV`t&45Oe?=-!R$H$eyzt$}0!*q)~a3PZ+6iH$dfE1sx`DWKx`*V8yao#+Zju z(iL* ypFGi4A0CAjn@`#vXXc&23^7q2NQq6J>!{5+!3-jDW%5NwbIueC2+s@1lLr7lzHzVs 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 6aa11e9c27a2d9111b40ed35588f2eaf987599ce..93839048648cd18fbfc1bc005ee4fe137a6720c9 100644 GIT binary patch literal 1104 zcmbVKJ4*vW5S~k-(L^wXhzLSDtuE0-Y@TmS>Deie$;h^q6FG7hh93m-FsUXE#+yh$B|CF}hdc+0V?$cJ+rEN0m zk)cL!$fyG;GDL6<9pdf+pQ8_cF~EB&#P=xP0d0Mx`v__4DNUcr0B=B)4_+Qom3C0C zTPCY*XN$~oOc>J>`@(-}otu{&^b+IDuuWE~*Q_S!&bh;F&dvmCR{dFW+q9Tp6SRn& z@$3osa-)Lr$RCgIGWoI#-U1qIDGM!2{ZP?YJwCb4hScYkeB_yk{bW5|Nk+;|hv#t6 znNx)-tJJ_SHjTVDu0zAF)Ogt=Wuq)E(SzKFqC6*;#QVW77wjka_kk|c;8+4Y(X8-q I*S8@416UYpng9R* literal 1136 zcmb<-^>JfjWMqH=Mg}_u1P><4z~F#jLfH-s>*0W>~4 zkPp(2?ve#i{k&-ES2kJ-n6Ub-*s9*w!0|X#0$nEI%hkA5A^*HYO17sbL{s2w zqLRcUAgeMLLPPmQsX2)dr7)B5)1a_nVfgqTn<{3kIRX@Km@zL6Hh_^K8OiAa~X0IGxHbcN08XtT*>-#n`@^Qf?huk56iF-1|cR0-Q~ift;o zR*7`Y5RQ&T=}t3y`{-ZS&Pyx9S#$8p{^@sGAND;hedwvHACL_LtT@;CrVG5nI$6&9 z7C2!4nwwe7<+>U}AB$FvApn;YCY1=FTI2>F1u5OR+Dz;7+cj(?f&dJe3@ z!)>eI{A1fz;mS7aCv#0An9A3d7ooJI>}xn(r=Qm3_^V@MquI=fecJ1p(TOZn!$aef zS>B1YdtTW^)l& z?Tvc;bI$;qD|L6>W+hesieaRu1#fka`sNgak^s))yFKkV+_TGf#zD?-X{0U+rvWBv@G@TS4XP`G zRlvP%x9TQ_qe0&t3K=xPC7kW;NUe#e6}$<M^IPw%Z8K68j#piX?;AnIpIM zB>q6`XQFlo@Iii7zQ8AYgPG%eUuXbBuCQVpDD7LPs`i}U3%mjJn*08da79x8x698s z(zmiRo$gQTz;(CKxpZzKKQ7#S$?Pw)`k_odlOE4zhQ>~ezK@>RV(Dt^Yl*et Tz|Q^s{-J?Nbdcfw*z^AamS7J= delta 1287 zcmZ`&U1$?o6h3#F(u_9kj7dym)!c&rvLG}K^p*i8#pPuVW&vySY3mx^OEE<{gC*x5$Z7jkV==^jSjNZ>1 z3fU#oG}ZkIlq{-FKVLFPYxuuJYxs+%+{(G0c@sth!|17NW)ZlzG!U zML9xQr`(2z`0kyBIn&%m2o9Dh3Z)1Q7gdxBj)K!TNMj^7$`5;nOF1t75NDIQ=$>g- z-h8&>#K{xq5`63NHMzBsTWq-2hcBY1m_;pexI5*_fCxu(E#qL_|b`(cRJwvK0Dd6TSPtt|2NX=NiK@e~Ezi|aw zL*Uq9u`g7Bt`t@4n^W0MyKD71?^%2WL{{DRed1NA>VLb8;qML4)icL_IolcmD@CET zwJz7T_c6n8