From e494f6af1a52788d0b7767b7cbadb0e9ecafde9b Mon Sep 17 00:00:00 2001 From: Robert-M-Lucas Date: Thu, 20 Jun 2024 14:23:51 +0100 Subject: [PATCH] Boolean comparators --- .idea/workspace.xml | 23 +++- build/out.asm | 32 ++--- build/out.o | Bin 1168 -> 1168 bytes build/out.out | Bin 16944 -> 16944 bytes main.why | 2 +- src/root/builtin/types/bool/comparators.rs | 122 ++++++++++++++++++ src/root/builtin/types/bool/mod.rs | 4 + src/root/builtin/types/int/comparators.rs | 68 ++++++++-- src/root/builtin/types/int/mod.rs | 3 +- .../parser/parse_function/parse_operator.rs | 4 +- types.toml | 34 +++++ 11 files changed, 258 insertions(+), 34 deletions(-) create mode 100644 src/root/builtin/types/bool/comparators.rs create mode 100644 types.toml diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1815c0d..cfb0f76 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -7,16 +7,16 @@ - - + + - + + - @@ -525,7 +533,8 @@ - diff --git a/build/out.asm b/build/out.asm index dd7d088..3690569 100644 --- a/build/out.asm +++ b/build/out.asm @@ -5,24 +5,24 @@ section .text main: push rbp mov rbp, rsp - mov qword [rbp-9], 2 - mov qword [rbp-17], 3 - mov rax, qword [rbp-17] - cmp rax, qword [rbp-9] - jg __5_0 + mov qword [rbp-9], 1 + mov qword [rbp-17], 2 + mov rax, qword [rbp-9] + cmp rax, qword [rbp-17] + jnz __2_0 mov byte [rbp-1], 0 - jmp __5_1 - __5_0: + jmp __2_1 + __2_0: mov byte [rbp-1], 1 - __5_1: + __2_1: mov al, byte [rbp-1] cmp al, 0 - jz __7_2 - mov rdi, __7_t_fstr - jmp __7_3 - __7_2: - mov rdi, __7_f_fstr - __7_3: + jz __23_2 + mov rdi, __23_t_fstr + jmp __23_3 + __23_2: + mov rdi, __23_f_fstr + __23_3: mov rsi, 0 mov al, 0 sub rsp, 17 @@ -36,5 +36,5 @@ main: section .data_readonly - __7_f_fstr db `Boolean: False`,0 - __7_t_fstr db `Boolean: True`,0 \ No newline at end of file + __23_f_fstr db `Boolean: False`,0 + __23_t_fstr db `Boolean: True`,0 \ No newline at end of file diff --git a/build/out.o b/build/out.o index 5044bbf374118d60d60e723ad372e8f26143de45..2f1c0755c27cc22a100f05450a62cd96823d12af 100644 GIT binary patch delta 148 zcmbQhIe~M-0!BvP$qO0NMHv|w7(9-W|UL|3NbJ+GPr_i z1YtaRBC|N7-Q< z_po+-U%J^>P+D2?I8cazfsdh7&;iVX5$7g1nutr@0&@i!mGzli2$T&5 z$_g>@Gt5A9TO?R-4p3GAi{8q~7lC>^fU<&20t_5zE}uG?(M()&30SWbg8-VnD<>NQ zWs5-e0>i{X0OBe&1_(GfIT0v(7Oa<#!2r!wmnKg%6KA|Pd8OG|4WoDihWL1+cta3r t9B%}nj3HE7d|Giy5tzMsmiZ*6%?4Hr*cqQpzUXMqxx@lul^2jF4*+v0Rzv^* delta 475 zcmdnc!ngs5GMGhHJ>1~CF7*5+o9hB6K3q#@k9&4badQpx9$rx<1_lO?_R-{xCgO~*C!aLY zm;4D-!^j}Uz+s1~hH0{(sko#lBS=<);e|b_toCF_pllXUR)Im1fx`h+)?;!ZP}UzP zE5yXlFaynPp&sB3=;^7>oblG=m1bvEOydn0;^R%@4S}S2 wyb+i*29s&=X~iW)Am-+I=98EvA7EnHY+$v3o$#Iy0E~E7J^%m! diff --git a/main.why b/main.why index 28a3af5..ed02cbd 100644 --- a/main.why +++ b/main.why @@ -1,5 +1,5 @@ fn main() -> int { - printb(2 < 3); + printb(1 != 2); return 2; } diff --git a/src/root/builtin/types/bool/comparators.rs b/src/root/builtin/types/bool/comparators.rs new file mode 100644 index 0000000..2c9b8fe --- /dev/null +++ b/src/root/builtin/types/bool/comparators.rs @@ -0,0 +1,122 @@ +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::name_resolver::resolve_function_signatures::FunctionSignature; +use crate::root::shared::common::{FunctionID, LocalAddress, TypeID}; + +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct BoolEq; + +impl BoolEq { + pub const fn id() -> FunctionID { + f_id(BoolEq::unique_type_id().0) + } +} + +impl BuiltinInlineFunction for BoolEq { + fn id(&self) -> FunctionID { + BoolEq::id() + } + + fn name(&self) -> &'static str { + "eq" + } + + 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: Option, gt, _| -> String { + let lhs = args[0]; + let rhs = args[1]; + let return_into = return_into.unwrap(); + let jmp_false = gt.get_unique_tag(BoolEq::id()); + let jmp_true = gt.get_unique_tag(BoolEq::id()); + let jmp_end = gt.get_unique_tag(BoolEq::id()); + + format!( +" cmp byte {lhs}, 0 + jz {jmp_false} + mov al, byte {rhs} + mov byte {return_into}, al + jmp {jmp_end} + {jmp_false}: + cmp byte {rhs}, 0 + jnz {jmp_true} + mov byte {return_into}, 1 + jmp {jmp_end} + {jmp_true}: + mov byte {return_into}, 0 + {jmp_end}:\n") + } + } + + fn parent_type(&self) -> Option { + Some(BoolType::id()) + } +} + +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct BoolNE; + +impl BoolNE { + pub const fn id() -> FunctionID { + f_id(BoolNE::unique_type_id().0) + } +} + +impl BuiltinInlineFunction for BoolNE { + fn id(&self) -> FunctionID { + BoolNE::id() + } + + fn name(&self) -> &'static str { + "ne" + } + + 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: Option, gt, _| -> String { + let lhs = args[0]; + let rhs = args[1]; + let return_into = return_into.unwrap(); + let jmp_false = gt.get_unique_tag(BoolNE::id()); + let jmp_true = gt.get_unique_tag(BoolNE::id()); + let jmp_end = gt.get_unique_tag(BoolNE::id()); + + format!( + " cmp byte {lhs}, 0 + jnz {jmp_true} + mov al, byte {rhs} + mov byte {return_into}, al + jmp {jmp_end} + {jmp_true}: + cmp byte {rhs}, 0 + jnz {jmp_false} + mov byte {return_into}, 1 + jmp {jmp_end} + {jmp_false}: + mov byte {return_into}, 0 + {jmp_end}:\n") + } + } + + fn parent_type(&self) -> Option { + Some(BoolType::id()) + } +} diff --git a/src/root/builtin/types/bool/mod.rs b/src/root/builtin/types/bool/mod.rs index 1f73fdb..018bef8 100644 --- a/src/root/builtin/types/bool/mod.rs +++ b/src/root/builtin/types/bool/mod.rs @@ -2,11 +2,13 @@ mod printb; mod and; mod or; mod not; +mod comparators; use b_box::b; use unique_type_id::UniqueTypeId; 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::comparators::{BoolEq, BoolNE}; 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; @@ -22,6 +24,8 @@ 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(&BoolEq); + global_table.register_inline_function(&BoolNE); global_table.register_inline_function(&BoolAnd); global_table.register_inline_function(&BoolAsAnd); global_table.register_inline_function(&BoolOr); diff --git a/src/root/builtin/types/int/comparators.rs b/src/root/builtin/types/int/comparators.rs index a92e26d..214afb3 100644 --- a/src/root/builtin/types/int/comparators.rs +++ b/src/root/builtin/types/int/comparators.rs @@ -58,6 +58,58 @@ impl BuiltinInlineFunction for IntEq { } } +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct IntNE; + +impl IntNE { + pub const fn id() -> FunctionID { + f_id(IntNE::unique_type_id().0) + } +} + +impl BuiltinInlineFunction for IntNE { + fn id(&self) -> FunctionID { + IntNE::id() + } + + fn name(&self) -> &'static str { + "ne" + } + + fn signature(&self) -> FunctionSignature { + FunctionSignature::new_inline_builtin( + true, + &[("lhs", IntType::id().immediate()), ("rhs", IntType::id().immediate())], + Some(BoolType::id().immediate()) + ) + } + + fn inline(&self) -> InlineFunctionGenerator { + |args: &[LocalAddress], return_into: Option, gt, _| -> String { + let lhs = args[0]; + let rhs = args[1]; + let return_into = return_into.unwrap(); + let jmp_true = gt.get_unique_tag(IntNE::id()); + let jmp_end = gt.get_unique_tag(IntNE::id()); + + format!( + " mov rax, qword {lhs} + cmp rax, qword {rhs} + jnz {jmp_true} + mov byte {return_into}, 0 + jmp {jmp_end} + {jmp_true}: + mov byte {return_into}, 1 + {jmp_end}:\n") + } + } + + fn parent_type(&self) -> Option { + Some(IntType::id()) + } +} + #[derive(UniqueTypeId)] #[UniqueTypeIdType = "u16"] pub struct IntGT; @@ -90,8 +142,8 @@ impl BuiltinInlineFunction for IntGT { let lhs = args[0]; let rhs = args[1]; let return_into = return_into.unwrap(); - let jmp_true = gt.get_unique_tag(IntEq::id()); - let jmp_end = gt.get_unique_tag(IntEq::id()); + let jmp_true = gt.get_unique_tag(IntGT::id()); + let jmp_end = gt.get_unique_tag(IntGT::id()); format!( " mov rax, qword {lhs} @@ -142,8 +194,8 @@ impl BuiltinInlineFunction for IntLT { let lhs = args[0]; let rhs = args[1]; let return_into = return_into.unwrap(); - let jmp_true = gt.get_unique_tag(IntEq::id()); - let jmp_end = gt.get_unique_tag(IntEq::id()); + let jmp_true = gt.get_unique_tag(IntLT::id()); + let jmp_end = gt.get_unique_tag(IntLT::id()); format!( " mov rax, qword {rhs} @@ -194,8 +246,8 @@ impl BuiltinInlineFunction for IntGE { let lhs = args[0]; let rhs = args[1]; let return_into = return_into.unwrap(); - let jmp_true = gt.get_unique_tag(IntEq::id()); - let jmp_end = gt.get_unique_tag(IntEq::id()); + let jmp_true = gt.get_unique_tag(IntGE::id()); + let jmp_end = gt.get_unique_tag(IntGE::id()); format!( " mov rax, qword {lhs} @@ -246,8 +298,8 @@ impl BuiltinInlineFunction for IntLE { let lhs = args[0]; let rhs = args[1]; let return_into = return_into.unwrap(); - let jmp_true = gt.get_unique_tag(IntEq::id()); - let jmp_end = gt.get_unique_tag(IntEq::id()); + let jmp_true = gt.get_unique_tag(IntLE::id()); + let jmp_end = gt.get_unique_tag(IntLE::id()); format!( " mov rax, qword {rhs} diff --git a/src/root/builtin/types/int/mod.rs b/src/root/builtin/types/int/mod.rs index 100c5b6..8c81141 100644 --- a/src/root/builtin/types/int/mod.rs +++ b/src/root/builtin/types/int/mod.rs @@ -3,7 +3,7 @@ use unique_type_id::UniqueTypeId; use crate::root::builtin::{BuiltinInlineFunction, f_id, InlineFunctionGenerator, t_id}; use crate::root::builtin::types::int::add::{IntAdd, IntAsAdd}; -use crate::root::builtin::types::int::comparators::{IntEq, IntGE, IntGT, IntLE, IntLT}; +use crate::root::builtin::types::int::comparators::{IntEq, IntGE, IntGT, IntLE, IntLT, IntNE}; use crate::root::builtin::types::int::div::{IntAsDiv, IntDiv}; use crate::root::builtin::types::int::modulo::{IntAsMod, IntMod}; use crate::root::builtin::types::int::mul::{IntAsMul, IntMul}; @@ -43,6 +43,7 @@ pub fn register_int(global_table: &mut GlobalDefinitionTable) { global_table.register_inline_function(&IntMod); global_table.register_inline_function(&IntAsMod); global_table.register_inline_function(&IntEq); + global_table.register_inline_function(&IntNE); global_table.register_inline_function(&IntGT); global_table.register_inline_function(&IntLT); global_table.register_inline_function(&IntGE); diff --git a/src/root/parser/parse_function/parse_operator.rs b/src/root/parser/parse_function/parse_operator.rs index 434836c..556fc12 100644 --- a/src/root/parser/parse_function/parse_operator.rs +++ b/src/root/parser/parse_function/parse_operator.rs @@ -19,7 +19,7 @@ pub enum PrefixOrInfixEx { Infix } -const OPERATOR_MAPS: [(&str, OperatorTokens, PrefixOrInfix, &str); 22] = [ +const OPERATOR_MAPS: [(&str, OperatorTokens, PrefixOrInfix, &str); 23] = [ ("+=", OperatorTokens::AsAdd, PrefixOrInfix::Infix, "as_add"), ("-=", OperatorTokens::AsSub, PrefixOrInfix::Infix, "as_sub"), ("*=", OperatorTokens::AsMul, PrefixOrInfix::Infix, "as_mul"), @@ -40,6 +40,7 @@ const OPERATOR_MAPS: [(&str, OperatorTokens, PrefixOrInfix, &str); 22] = [ ("/", OperatorTokens::Divide, PrefixOrInfix::Both, "div"), ("%", OperatorTokens::Modulo, PrefixOrInfix::Both, "mod"), ("==", OperatorTokens::Equals, PrefixOrInfix::Infix, "eq"), + ("!=", OperatorTokens::NotEqual, PrefixOrInfix::Infix, "ne"), ("=", OperatorTokens::Assign, PrefixOrInfix::Infix, "assign"), ("!", OperatorTokens::Not, PrefixOrInfix::Prefix, "not"), ]; @@ -69,6 +70,7 @@ pub enum OperatorTokens { Modulo, Not, Equals, + NotEqual, And, Or, GreaterEqual, diff --git a/types.toml b/types.toml new file mode 100644 index 0000000..9a2dee6 --- /dev/null +++ b/types.toml @@ -0,0 +1,34 @@ +IntN=0 +IntNE=1 +IntAdd=2 +IntAsAdd=3 +IntSub=4 +IntPSub=5 +IntAsSub=6 +PrintI=7 +IntPAdd=8 +IntMul=9 +IntAsMul=10 +IntDiv=11 +IntAsDiv=12 +IntMod=13 +IntAsMod=14 +IntEq=15 +IntGT=16 +IntLT=17 +IntGE=18 +IntLE=19 +IntType=20 +IntAssign=21 +PrintB=22 +BoolAnd=23 +BoolAsAnd=24 +BoolOr=25 +BoolAsOr=26 +BoolNot=27 +BoolType=28 +BoolAssign=29 +ExitFunction=30 +BoolE=31 +BoolEq=32 +BoolNE=33