From 41ef12b3af355a870cd472468f69bae4fb24ccdf Mon Sep 17 00:00:00 2001 From: Robert-M-Lucas Date: Tue, 18 Jun 2024 22:06:47 +0100 Subject: [PATCH] Added referencing --- Cargo.lock | 62 +++++++++++ Cargo.toml | 2 + build/out.asm | 64 ++++++------ build/out.o | Bin 1088 -> 1200 bytes main.why | 6 +- src/main.rs | 12 +++ src/root.rs | 1 + src/root/builtin/types/int/add.rs | 37 +++++++ src/root/builtin/types/int/mod.rs | 3 +- src/root/compiler/compile_evaluable.rs | 97 +++++++++++++++--- src/root/compiler/compile_function.rs | 4 +- src/root/compiler/compile_function_call.rs | 12 +-- src/root/name_resolver/name_resolvers.rs | 19 ++-- .../resolve_function_signatures.rs | 8 ++ src/root/ob.rs | 22 ++++ .../parser/parse_function/parse_assignment.rs | 4 +- .../parser/parse_function/parse_evaluable.rs | 4 +- src/root/parser/parse_function/parse_line.rs | 2 +- .../parser/parse_function/parse_operator.rs | 20 ++-- src/root/shared/common.rs | 7 ++ types.toml | 5 + 21 files changed, 312 insertions(+), 79 deletions(-) create mode 100644 src/root/ob.rs diff --git a/Cargo.lock b/Cargo.lock index 8fcbbaf..8e2e080 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,6 +51,28 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "arr_macro" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c49336e062fa2ae8aca17a2f99c34d9c1a5d30827e8aff1cb4c294f253afe992" +dependencies = [ + "arr_macro_impl", + "proc-macro-hack", + "proc-macro-nested", +] + +[[package]] +name = "arr_macro_impl" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c6368f9ae5c6ec403ca910327ae0c9437b0a85255b6950c90d497e6177f6e5e" +dependencies = [ + "proc-macro-hack", + "quote", + "syn 1.0.109", +] + [[package]] name = "arrayvec" version = "0.7.4" @@ -288,6 +310,44 @@ dependencies = [ "nom", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pinned-init" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d20d2610806fec7557ff2c210ccc77e68b6e4a74815582cdc63bd35cb3f39cde" +dependencies = [ + "paste", + "pinned-init-macro", +] + +[[package]] +name = "pinned-init-macro" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "569a3fcf0e6334c6c46c1507f83a99ba30ae9cdc5761bdb2ca40f7eb55138bd4" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + [[package]] name = "proc-macro2" version = "1.0.85" @@ -458,6 +518,7 @@ dependencies = [ name = "whython-8" version = "0.1.0" dependencies = [ + "arr_macro", "b-box", "clap", "color-print", @@ -469,6 +530,7 @@ dependencies = [ "nom", "nom-supreme", "nom_locate", + "pinned-init", "same-file", "strum", "strum_macros", diff --git a/Cargo.toml b/Cargo.toml index 733a372..76fe9ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,8 @@ nom-supreme = "0.8.0" substring = "1.4.5" derive-getters = "0.4.0" derive_more = "0.99.17" +pinned-init = "0.0.7" +arr_macro = "0.2.1" [profile.release] opt-level = 3 diff --git a/build/out.asm b/build/out.asm index 270fd6f..2af51ad 100644 --- a/build/out.asm +++ b/build/out.asm @@ -6,50 +6,46 @@ main: push rbp mov rbp, rsp mov qword [rbp-8], 0 - mov qword [rbp-16], 0 main_0: - mov rax, qword [rbp-8] - mov qword [rbp-25], rax - mov qword [rbp-33], 0 - mov rax, qword [rbp-25] - cmp rax, qword [rbp-33] - jz __5_2 - mov byte [rbp-17], 0 - jmp __5_3 - __5_2: - mov byte [rbp-17], 1 - __5_3: - cmp byte [rbp-17], 0 + mov byte [rbp-9], 1 + cmp byte [rbp-9], 0 jz main_1 + mov rax, rbp + add rax, -8 + mov qword [rbp-17], rax + mov qword [rbp-25], 1 + mov rax, qword [rbp-17] + mov rdx, qword [rbp-25] + add qword [rax], rdx mov rax, qword [rbp-8] - mov qword [rbp-41], rax + mov qword [rbp-33], rax mov rdi, __4_fstr - mov rsi, [rbp-41] + mov rsi, [rbp-33] mov al, 0 - sub rsp, 41 + sub rsp, 33 extern printf call printf - add rsp, 41 - mov rax, qword [rbp-16] - mov qword [rbp-50], rax - mov qword [rbp-58], 0 - mov rax, qword [rbp-50] - cmp rax, qword [rbp-58] - jz __5_4 - mov byte [rbp-42], 0 - jmp __5_5 - __5_4: - mov byte [rbp-42], 1 - __5_5: - cmp byte [rbp-42], 0 - jz main_6 + add rsp, 33 + mov rax, qword [rbp-8] + mov qword [rbp-42], rax + mov qword [rbp-50], 12 + mov rax, qword [rbp-42] + cmp rax, qword [rbp-50] + jz __5_2 + mov byte [rbp-34], 0 + jmp __5_3 + __5_2: + mov byte [rbp-34], 1 + __5_3: + cmp byte [rbp-34], 0 + jz main_4 jmp main_1 - main_7: - main_6: + main_5: + main_4: jmp main_0 main_1: - mov qword [rbp-41], 2 - mov rax, qword [rbp-41] + mov qword [rbp-17], 2 + mov rax, qword [rbp-17] leave ret diff --git a/build/out.o b/build/out.o index 3629837addb39396cc528f63791be886716d6712..d5ea85626895bd432bfee9be484f4844ce325153 100644 GIT binary patch literal 1200 zcmbVLJ4*vW5T1)M5fx1#BG{-PSe@|^5ET*RWCa@w>*FM+2J+C$222qYf=Ebh?@#a_ zC@6}JrKMJ)5J9c95OijD&m8NC;K1$7eDlrB&JMS0EiXn41AH-H4w{~i0?ao}WzRz# zS_0_*OzK5nOizzU;84R8njc4>@)i9%dZd7^Z$ujUY`qAFO>wO9Xa2|^z_{Lf)UhV{gY8iSXMk=>Gw}!Kv8{)(0dA`I0?CwtM^}JwR?7Hy%Xoc zdNcMaZ@{-%?U7Ya-&xIi#^3`bvO3!J)dyxI(4^2EJE1HRRxjNh1FJp_J_@&bKB!1H zn19_VDAo;|v95XS!n%b<6i;k+3p~<@H1?78OfN=VuFj~2lBGO%H(YOeU^ts@C(PvT z4hJ*saL4vsCtb*A%U~8ai`?VR8d~L?)XMkVtRr*$lA)SLjKb?@Sgb9KhXFK!vA^CZp0HIbM*^cD-v|q zN||hWv{2%vQ_Mlm$>hahCt=IW8KAt*aUolHAPM0nZQpljewR@4&ILZ48F=-^5AFZ2UCdhAwU zU|wR69=!y6=wLSwfz7-f)1E@m1N~;c`M#O=-tOM%r^j<14~&)vj$oXPSb*d>fNkiou$8&5pMd- ztRIoi800+6xQRG(K9jqw8-Y512Mg+%NUJd!Vjd!E14;HazJh2!It2StY zQU3@!L>cv$Ad31jZtD&;GA!LO8oG_xM|?$b!dY>}2^8ByS7diua)zaADC?suI4O(Vd9HF0 z+0HIt7l5e9T?>e2O<_W`dQlY>VP-J8DY?jbC08_EsdWAMM_1s3Pden(^3ME%=s8cn zDeKbhfvnPHL*~=^5c1lL{;QH#noydl6^hxt%bJLq)e@A int { let a: int = 0; - let b: int = 0; - while (a == 0) { + while (true) { + &a += 1; printi(a); - if (b == 0) { + if (a == 12) { break; } } diff --git a/src/main.rs b/src/main.rs index ea21d62..ae3f7a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,17 @@ +use std::mem::MaybeUninit; +use std::hint::black_box; +use arr_macro::arr; +use pinned_init::{pin_data, pin_init}; +use std::mem; + mod root; +#[pin_data] +struct Large { + #[pin] + inner: [u8; 10_000] +} + fn main() { root::main(); } diff --git a/src/root.rs b/src/root.rs index c5cb1c5..f7a7391 100644 --- a/src/root.rs +++ b/src/root.rs @@ -33,6 +33,7 @@ pub mod shared; pub mod compiler; pub mod assembler; pub mod errors; +mod ob; pub const POINTER_SIZE: ByteSize = ByteSize(8); diff --git a/src/root/builtin/types/int/add.rs b/src/root/builtin/types/int/add.rs index 51257bb..a00bde2 100644 --- a/src/root/builtin/types/int/add.rs +++ b/src/root/builtin/types/int/add.rs @@ -44,3 +44,40 @@ impl BuiltinInlineFunction for IntAdd { Some(IntType::id()) } } + +#[derive(UniqueTypeId)] +#[UniqueTypeIdType = "u16"] +pub struct IntAsAdd; + +impl BuiltinInlineFunction for IntAsAdd { + fn id(&self) -> FunctionID { + f_id(IntAsAdd::unique_type_id().0) + } + + fn name(&self) -> &'static str { + "as_add" + } + + fn signature(&self) -> FunctionSignature { + FunctionSignature::new_inline_builtin( + true, + &[("lhs", IntType::id().with_indirection(1)), ("rhs", IntType::id().immediate())], + None + ) + } + + fn inline(&self) -> InlineFunctionGenerator { + |args: &[LocalAddress], return_into: Option, _, _| -> String { + let lhs = args[0]; + let rhs = args[1]; + format!( +" mov rax, qword {lhs} + mov rdx, qword {rhs} + add qword [rax], rdx\n") + } + } + + fn parent_type(&self) -> Option { + Some(IntType::id()) + } +} \ No newline at end of file diff --git a/src/root/builtin/types/int/mod.rs b/src/root/builtin/types/int/mod.rs index 93cd16e..b2aef87 100644 --- a/src/root/builtin/types/int/mod.rs +++ b/src/root/builtin/types/int/mod.rs @@ -8,7 +8,7 @@ use std::fmt::format; use b_box::b; use unique_type_id::UniqueTypeId; use crate::root::builtin::t_id; -use crate::root::builtin::types::int::add::IntAdd; +use crate::root::builtin::types::int::add::{IntAdd, IntAsAdd}; use crate::root::builtin::types::int::eq::IntEq; use crate::root::builtin::types::int::p_sub::IntPSub; use crate::root::builtin::types::int::printi::PrintI; @@ -22,6 +22,7 @@ use crate::root::shared::types::Type; pub fn register_int(global_table: &mut GlobalDefinitionTable) { global_table.register_builtin_type(b!(IntType)); global_table.register_inline_function(&IntAdd); + global_table.register_inline_function(&IntAsAdd); global_table.register_inline_function(&IntSub); global_table.register_inline_function(&IntPSub); global_table.register_inline_function(&IntEq); diff --git a/src/root/compiler/compile_evaluable.rs b/src/root/compiler/compile_evaluable.rs index 3099733..e677290 100644 --- a/src/root/compiler/compile_evaluable.rs +++ b/src/root/compiler/compile_evaluable.rs @@ -2,6 +2,7 @@ use std::any::Any; use std::collections::HashSet; use either::{Left, Right}; use itertools::Itertools; +use crate::root::assembler::assembly_builder::AssemblyBuilder; use crate::root::compiler::assembly::utils::copy; use crate::root::compiler::compile_function_call::call_function; use crate::root::compiler::global_tracker::GlobalTracker; @@ -12,14 +13,24 @@ use crate::root::errors::name_resolver_errors::NRErrors; use crate::root::errors::WErr; use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable, NameResult}; use crate::root::parser::parse_function::parse_evaluable::{EvaluableToken, EvaluableTokens}; -use crate::root::parser::parse_function::parse_operator::PrefixOrInfixEx; -use crate::root::shared::common::{FunctionID, Indirection, TypeRef}; +use crate::root::parser::parse_function::parse_operator::{OperatorTokens, PrefixOrInfixEx}; +use crate::root::shared::common::{FunctionID, Indirection, LocalAddress, TypeRef}; use crate::root::shared::common::AddressedTypeRef; fn expect_addr(r: (String, Option)) -> Result<(String, AddressedTypeRef), WErr> { Ok((r.0, r.1.unwrap())) // TODO } +pub fn set_reference(to_ref: AddressedTypeRef, into: AddressedTypeRef) -> Result { + if to_ref.type_ref().type_id().with_indirection(to_ref.type_ref().indirection().0 + 1) != *into.type_ref() { + todo!() + } + + Ok(format!(" mov rax, rbp + add rax, {} + mov qword {}, rax\n", to_ref.local_address().0, into.local_address())) +} + /// Will always evaluate into new address pub fn compile_evaluable( fid: FunctionID, @@ -49,7 +60,38 @@ pub fn compile_evaluable( (t.instantiate_from_literal(address.local_address(), literal)?, Some(address)) } - EvaluableTokens::InfixOperator(_, _, _) => todo!(), + EvaluableTokens::InfixOperator(lhs, op, rhs) => { + let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, global_tracker)?; + let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Infix)?; + let signature = global_table.get_function_signature(op_fn); + + if signature.get().args().len() != 2 { + return Err( + WErr::n( + EvalErrs::InfixOpWrongArgumentCount( + op.operator().to_str().to_string(), + global_table.get_type(*lhs_type.type_id()).name().to_string(), + op.operator().get_method_name(PrefixOrInfixEx::Infix).unwrap(), + signature.get().args().len() + ), + op.location().clone() + ) + ); + } + + let return_into = match signature.get().return_type() { + None => { + None + } + Some(rt) => { + Some(global_table.add_local_variable_unnamed_base(rt.clone(), local_variables)) + } + }; + + let (c, _) = call_function(fid, op_fn, &[Left(lhs), Left(rhs)], return_into.clone(), global_table, local_variables, global_tracker)?; + + (c, return_into) + }, EvaluableTokens::PrefixOperator(_, _) => todo!(), EvaluableTokens::DynamicAccess(_, _) => todo!(), // Accessed methods must be called EvaluableTokens::StaticAccess(_, n) => return Err(WErr::n(NRErrors::CannotFindConstantAttribute(n.name().clone()), n.location().clone())), // Accessed methods must be called @@ -57,7 +99,7 @@ pub fn compile_evaluable( let (slf, ifid) = compile_evaluable_function_only(fid, inner, local_variables, global_table, global_tracker)?; let signature = global_table.get_function_signature(ifid); - let return_into = signature.return_type().clone().and_then(|r| Some(global_table.add_local_variable_unnamed_base(r, local_variables))); + let return_into = signature.get().return_type().clone().and_then(|r| Some(global_table.add_local_variable_unnamed_base(r, local_variables))); let mut n_args = if let Some(slf) = slf.as_ref() { let mut v = Vec::with_capacity(args.len() + 1); @@ -115,21 +157,21 @@ pub fn compile_evaluable_into( let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Infix)?; let signature = global_table.get_function_signature(op_fn); - if signature.args().len() != 2 { + if signature.get().args().len() != 2 { return Err( WErr::n( EvalErrs::InfixOpWrongArgumentCount( op.operator().to_str().to_string(), global_table.get_type(*lhs_type.type_id()).name().to_string(), op.operator().get_method_name(PrefixOrInfixEx::Infix).unwrap(), - signature.args().len() + signature.get().args().len() ), op.location().clone() ) ); } - match signature.return_type() { + match signature.get().return_type() { None => { return Err(WErr::n(OpNoReturn(global_table.get_type_name(target.type_ref())), op.location().clone())) } @@ -146,24 +188,40 @@ pub fn compile_evaluable_into( }, EvaluableTokens::PrefixOperator(op, lhs) => { let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, global_tracker)?; + + match op.operator() { + OperatorTokens::Reference => { + let (mut c, val) = compile_evaluable_reference(fid, lhs, local_variables, global_table, global_tracker)?; + let Some(val) = val else { todo!() }; + if *val.type_ref() != lhs_type { + todo!() + } + + c += &set_reference(val, target)?; + + return Ok(c); + } + _ => {} + } + let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Prefix)?; let signature = global_table.get_function_signature(op_fn); - if signature.args().len() != 1 { + if signature.get().args().len() != 1 { return Err( WErr::n( EvalErrs::InfixOpWrongArgumentCount( op.operator().to_str().to_string(), global_table.get_type(*lhs_type.type_id()).name().to_string(), op.operator().get_method_name(PrefixOrInfixEx::Prefix).unwrap(), - signature.args().len() + signature.get().args().len() ), op.location().clone() ) ); } - match signature.return_type() { + match signature.get().return_type() { None => { return Err(WErr::n(OpNoReturn(global_table.get_type_name(target.type_ref())), op.location().clone())) } @@ -282,19 +340,32 @@ pub fn compile_evaluable_type_only( // let (mut code, lhs) = compile_evaluable(fid, lhs, local_variables, global_table, global_tracker)?; let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, global_tracker)?; + // code += "\n"; let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Infix)?; let signature = global_table.get_function_signature(op_fn); - signature.return_type().as_ref().unwrap().clone() + signature.get().return_type().as_ref().unwrap().clone() + }, + EvaluableTokens::PrefixOperator(op, lhs) => { + let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, global_tracker)?; + + match op.operator() { + OperatorTokens::Reference => return Ok(lhs_type.plus_one_indirect()), + _ => {} + } + + // code += "\n"; + let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Prefix)?; + let signature = global_table.get_function_signature(op_fn); + signature.get().return_type().as_ref().unwrap().clone() }, - EvaluableTokens::PrefixOperator(_, _) => todo!(), EvaluableTokens::DynamicAccess(_, _) => todo!(), // Accessed methods must be called EvaluableTokens::StaticAccess(_, n) => return Err(WErr::n(NRErrors::CannotFindConstantAttribute(n.name().clone()), n.location().clone())), // Accessed methods must be called EvaluableTokens::FunctionCall(inner, args) => { let (slf, ifid) = compile_evaluable_function_only(fid, inner, local_variables, global_table, global_tracker)?; let signature = global_table.get_function_signature(ifid); - let return_type = signature.return_type().clone().unwrap(); // TODO: Check type + let return_type = signature.get().return_type().clone().unwrap(); // TODO: Check type return_type } }) diff --git a/src/root/compiler/compile_function.rs b/src/root/compiler/compile_function.rs index db5b9e3..c9788c8 100644 --- a/src/root/compiler/compile_function.rs +++ b/src/root/compiler/compile_function.rs @@ -80,7 +80,9 @@ fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_varia let address = global_table.add_local_variable_named(name.name().clone(), type_name, local_variables)?; contents.other(&compile_evaluable_into(fid, value, address, local_variables, global_table, global_tracker)?); }, - LineTokens::Assignment(_) => todo!(), + LineTokens::Assignment(at) => { + + }, LineTokens::If(if_token) => { let condition_addr = global_table.add_local_variable_unnamed_base(BoolType::id().immediate(), local_variables); contents.other(&compile_evaluable_into(fid, if_token.if_condition(), condition_addr.clone(), local_variables, global_table, global_tracker)?); diff --git a/src/root/compiler/compile_function_call.rs b/src/root/compiler/compile_function_call.rs index aed95d0..fd1887e 100644 --- a/src/root/compiler/compile_function_call.rs +++ b/src/root/compiler/compile_function_call.rs @@ -9,7 +9,7 @@ use crate::root::compiler::local_variable_table::LocalVariableTable; use crate::root::errors::WErr; use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable; use crate::root::parser::parse_function::parse_evaluable::EvaluableToken; -use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, LocalAddress}; +use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, LocalAddress, TypeRef}; use crate::root::utils::warn; @@ -27,12 +27,10 @@ pub fn call_function( warn("Unchecked Function Arguments"); if let Some(inline) = global_table.get_function(fid).1 { - - let inline_o = inline.clone(); let mut code = AssemblyBuilder::new(); - let return_into = if let Some(expected_return) = global_table.get_function(fid).0.return_type().clone() { + let return_into = if let Some(expected_return) = global_table.get_function(fid).0.get().return_type().clone() { if let Some(return_address) = return_address { if return_address.type_ref() != &expected_return { todo!() @@ -53,7 +51,7 @@ pub fn call_function( // TODO: Check arg lengths let mut args = Vec::new(); - let signature_args = global_table.get_function(fid).0.args().iter().map(|(_, t)| t.clone()).collect_vec(); + let signature_args = global_table.get_function(fid).0.get().args().iter().map(|(_, t)| t.clone()).collect_vec(); for (i, a) in arguments.iter().enumerate() { match a { @@ -79,7 +77,7 @@ pub fn call_function( // TODO: Check args length let mut args = Vec::new(); let mut size = ByteSize(0); - let signature_args = global_table.get_function(fid).0.args().iter().map(|(_, t)| t.clone()).collect_vec(); + let signature_args = global_table.get_function(fid).0.get().args().iter().map(|(_, t)| t.clone()).collect_vec(); for (i, a) in arguments.iter().enumerate() { match a { @@ -98,7 +96,7 @@ pub fn call_function( } // ? Let return value remain after stack up - let return_addr = if let Some(return_type) = global_table.get_function(fid).0.return_type().clone() { + let return_addr = if let Some(return_type) = global_table.get_function(fid).0.get().return_type().clone() { let s = global_table.get_size(&return_type); size += s; diff --git a/src/root/name_resolver/name_resolvers.rs b/src/root/name_resolver/name_resolvers.rs index c598591..ccef90c 100644 --- a/src/root/name_resolver/name_resolvers.rs +++ b/src/root/name_resolver/name_resolvers.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::collections::hash_map::{Iter, IterMut}; use std::collections::HashMap; use std::path::PathBuf; @@ -6,20 +7,23 @@ use derive_getters::Getters; use either::{Either, Left, Right}; use crate::root::builtin::{BuiltinInlineFunction, InlineFunctionGenerator}; use crate::root::compiler::compile_function_call::call_function; +use crate::root::compiler::global_tracker::GlobalTracker; use crate::root::compiler::local_variable_table::LocalVariableTable; use crate::root::errors::name_resolver_errors::NRErrors; use crate::root::errors::name_resolver_errors::NRErrors::IdentifierNotFound; use crate::root::errors::WErr; +use crate::root::name_resolver::name_resolvers::NameResult::Function; use crate::root::name_resolver::resolve_function_signatures::FunctionSignature; +use crate::root::ob::OB; use crate::root::parser::parse::Location; use crate::root::shared::types::Type; use crate::root::parser::parse_function::FunctionToken; use crate::root::parser::parse_function::parse_evaluable::{FullNameToken, FullNameTokens, FullNameWithIndirectionToken}; -use crate::root::parser::parse_function::parse_operator::{OperatorToken, PrefixOrInfixEx}; +use crate::root::parser::parse_function::parse_operator::{OperatorToken, OperatorTokens, PrefixOrInfixEx}; use crate::root::parser::parse_name::SimpleNameToken; use crate::root::parser::parse_struct::StructToken; use crate::root::POINTER_SIZE; -use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, LocalAddress, TypeID, TypeRef}; +use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, Indirection, LocalAddress, TypeID, TypeRef}; #[derive(Debug)] enum NameTreeEntry { @@ -77,10 +81,13 @@ pub enum NameResult { Variable(AddressedTypeRef) } +const REFERENCE_FUNCTION: FunctionID = FunctionID(1); + impl GlobalDefinitionTable { pub fn new() -> GlobalDefinitionTable { + GlobalDefinitionTable { - id_counter: 1, + id_counter: 2, type_definitions: Default::default(), impl_definitions: Default::default(), function_signatures: Default::default(), @@ -250,8 +257,8 @@ impl GlobalDefinitionTable { Ok(address) } - pub fn get_function_signature(&self, function_id: FunctionID) -> &FunctionSignature { - self.function_signatures.get(&function_id).as_ref().unwrap() + pub fn get_function_signature(&self, function_id: FunctionID) -> OB { + OB::b(self.function_signatures.get(&function_id).as_ref().unwrap()) } pub fn has_main(&self) -> bool { @@ -329,7 +336,7 @@ impl GlobalDefinitionTable { } } - pub fn get_function(&self, function: FunctionID) -> (&FunctionSignature, Option<&InlineFunctionGenerator>) { + pub fn get_function(&self, function: FunctionID) -> (OB, Option<&InlineFunctionGenerator>) { let signature = self.get_function_signature(function); let inline = self.inline_functions.get(&function); (signature, inline) diff --git a/src/root/name_resolver/resolve_function_signatures.rs b/src/root/name_resolver/resolve_function_signatures.rs index 02dd486..b4260a6 100644 --- a/src/root/name_resolver/resolve_function_signatures.rs +++ b/src/root/name_resolver/resolve_function_signatures.rs @@ -21,6 +21,14 @@ impl FunctionSignature { return_type } } + + pub fn new_custom(dynamic: bool, args: Vec<(SimpleNameToken, TypeRef)>, return_type: Option) -> FunctionSignature { + FunctionSignature { + dynamic, + args, + return_type + } + } } pub fn resolve_function_signature(function_token: &FunctionToken, global_table: &mut GlobalDefinitionTable) -> Result { diff --git a/src/root/ob.rs b/src/root/ob.rs new file mode 100644 index 0000000..2c0b5d7 --- /dev/null +++ b/src/root/ob.rs @@ -0,0 +1,22 @@ +pub enum OB<'a, T> { + Owned(T), + Borrowed(&'a T) +} + +impl<'a, T> OB<'a, T> { + pub fn o(o: T) -> OB<'a, T> { + OB::Owned(o) + } + + pub fn b(b: &'a T) -> OB<'a, T> { + OB::Borrowed(b) + } + + pub fn get(&self) -> &T { + match &self { + OB::Owned(o) => o, + OB::Borrowed(b) => *b + } + } +} + diff --git a/src/root/parser/parse_function/parse_assignment.rs b/src/root/parser/parse_function/parse_assignment.rs index 36ac626..96ca547 100644 --- a/src/root/parser/parse_function/parse_assignment.rs +++ b/src/root/parser/parse_function/parse_assignment.rs @@ -1,4 +1,4 @@ - +use derive_getters::Getters; use nom::sequence::Tuple; use nom_supreme::tag::complete::tag; use crate::root::parser::parse::{Location, ParseResult, Span}; @@ -9,7 +9,7 @@ use crate::root::parser::parse_function::parse_line::{LineTestFn, LineTokens}; use crate::root::parser::parse_name::SimpleNameToken; use crate::root::parser::parse_util::discard_ignored; -#[derive(Debug)] +#[derive(Debug, Getters)] pub struct AssignmentToken { location: Location, name: FullNameWithIndirectionToken, diff --git a/src/root/parser/parse_function/parse_evaluable.rs b/src/root/parser/parse_function/parse_evaluable.rs index 53ca3cd..214485d 100644 --- a/src/root/parser/parse_function/parse_evaluable.rs +++ b/src/root/parser/parse_function/parse_evaluable.rs @@ -215,7 +215,7 @@ pub fn parse_evaluable<'a, 'b>(s: Span<'a>, containing_class: Option<&SimpleName // Recursively parse bracketed sections let ns = if let Ok((ns, inner)) = default_section(s, '(') { let (_, evaluable) = parse_evaluable(inner, containing_class.clone(), false)?; - evaluables.push(TempEvaluableTokensOne::EvaluableToken(error_on_assignment(evaluable)?)); + evaluables.push(TempEvaluableTokensOne::EvaluableToken(evaluable)); ns } // Parse evaluable @@ -478,5 +478,5 @@ pub fn parse_evaluable<'a, 'b>(s: Span<'a>, containing_class: Option<&SimpleName let conv = recursively_convert_temp(base.unwrap(), &mut evaluables); - Ok((s, Left(conv))) + Ok((s, conv)) } diff --git a/src/root/parser/parse_function/parse_line.rs b/src/root/parser/parse_function/parse_line.rs index f33a40b..d9888d8 100644 --- a/src/root/parser/parse_function/parse_line.rs +++ b/src/root/parser/parse_function/parse_line.rs @@ -54,7 +54,7 @@ pub fn parse_line<'a, 'b>(s: Span<'a>, containing_class: Option<&'b SimpleNameTo test_parse_initialisation, test_parse_while, test_parse_if, - test_parse_assignment, + // test_parse_assignment, )) .parse(s) { diff --git a/src/root/parser/parse_function/parse_operator.rs b/src/root/parser/parse_function/parse_operator.rs index 1fdab52..8db6bd1 100644 --- a/src/root/parser/parse_function/parse_operator.rs +++ b/src/root/parser/parse_function/parse_operator.rs @@ -20,20 +20,21 @@ pub enum PrefixOrInfixEx { Infix } -const OPERATOR_MAPS: [(&str, OperatorTokens, PrefixOrInfix, &'static str); 5] = [ - ("+", OperatorTokens::Add, PrefixOrInfix::Both, "add"), - ("-", OperatorTokens::Subtract, PrefixOrInfix::Both, "sub"), - ("==", OperatorTokens::Equals, PrefixOrInfix::Infix, "eq"), - ("!", OperatorTokens::Not, PrefixOrInfix::Prefix, "not"), - ("+=", OperatorTokens::Not, PrefixOrInfix::Infix, "as_add"), -]; - #[derive(Debug, Clone, Getters)] pub struct OperatorToken { location: Location, operator: OperatorTokens, } +const OPERATOR_MAPS: [(&str, OperatorTokens, PrefixOrInfix, &'static str); 6] = [ + ("+=", OperatorTokens::Not, PrefixOrInfix::Infix, "as_add"), + ("&", OperatorTokens::Reference, PrefixOrInfix::Prefix, "ref"), + ("+", OperatorTokens::Add, PrefixOrInfix::Both, "add"), + ("-", OperatorTokens::Subtract, PrefixOrInfix::Both, "sub"), + ("==", OperatorTokens::Equals, PrefixOrInfix::Infix, "eq"), + ("!", OperatorTokens::Not, PrefixOrInfix::Prefix, "not"), +]; + impl OperatorToken { pub fn is_prefix_opt_t(&self) -> bool { self.operator.is_prefix_op() @@ -50,7 +51,8 @@ pub enum OperatorTokens { Subtract, Not, Equals, - AsAdd + AsAdd, + Reference } impl OperatorTokens { diff --git a/src/root/shared/common.rs b/src/root/shared/common.rs index 9ead72f..7f296cb 100644 --- a/src/root/shared/common.rs +++ b/src/root/shared/common.rs @@ -81,6 +81,13 @@ impl TypeRef { pub fn new(type_id: TypeID, indirection: Indirection) -> TypeRef { TypeRef { type_id, indirection } } + + pub fn plus_one_indirect(&self) -> TypeRef { + TypeRef { + type_id: self.type_id, + indirection: Indirection(self.indirection.0 + 1) + } + } } #[derive(Getters, Clone, Dissolve)] diff --git a/types.toml b/types.toml index 894a261..6661baf 100644 --- a/types.toml +++ b/types.toml @@ -7,3 +7,8 @@ IntType=5 PrintB=6 BoolType=7 ExitFunction=8 +IntasAdd=9 +IntaAdd=10 +IntAAdd=11 +IntASAdd=12 +IntAsAdd=13