diff --git a/.idea/workspace.xml b/.idea/workspace.xml index b7fb43d..2fe6de8 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -7,8 +7,17 @@ - + + + + + + + + + + @@ -687,7 +696,6 @@ - @@ -712,7 +720,8 @@ - diff --git a/main.why b/main.why index e50dc6d..72e959e 100644 --- a/main.why +++ b/main.why @@ -3,17 +3,15 @@ struct Test { } impl Test { - fn test(self) { - printi(*self.a); - self.a += 1; - printi(*self.a); + fn static() { + } } fn main() -> int { let x: Test = Test { a: 3 }; - x::test(); - printi(*x.a); + + + a + return 8; } \ No newline at end of file diff --git a/src/root/compiler/compile_function_call.rs b/src/root/compiler/compile_function_call.rs index 2da3fff..b14579f 100644 --- a/src/root/compiler/compile_function_call.rs +++ b/src/root/compiler/compile_function_call.rs @@ -34,7 +34,7 @@ pub fn call_function( let self_type = *global_table.get_function_signature(fid).self_type(); if uses_self && matches!(self_type, SelfType::None) { - todo!() + todo!() // ? } if let Some(inline) = global_table.get_function(fid).1 { @@ -107,9 +107,17 @@ pub fn call_function( global_tracker, )?; code.other(&c); - let Some(into) = into else { todo!() }; + let Some(into) = into else { + return WErr::ne(EvalErrs::ExpectedNotNone, eval.location().clone()); + }; if into.type_ref().type_id() != signature_args[i].type_id() { - todo!() + return WErr::ne( + EvalErrs::ExpectedDifferentType( + global_table.get_type_name(&into.type_ref().type_id().immediate()), + global_table.get_type_name(&signature_args[i].type_id().immediate()), + ), + location.clone(), + ); } into } else { @@ -205,9 +213,17 @@ pub fn call_function( global_tracker, )?; code.other(&c); - let Some(into) = into else { todo!() }; + let Some(into) = into else { + return WErr::ne(EvalErrs::ExpectedNotNone, eval.location().clone()); + }; if into.type_ref().type_id() != signature_args[i].type_id() { - todo!() + return WErr::ne( + EvalErrs::ExpectedDifferentType( + global_table.get_type_name(&into.type_ref().type_id().immediate()), + global_table.get_type_name(&signature_args[i].type_id().immediate()), + ), + location.clone(), + ); } into } else { diff --git a/src/root/compiler/evaluation/function_only.rs b/src/root/compiler/evaluation/function_only.rs index 0ff2f90..d482ae0 100644 --- a/src/root/compiler/evaluation/function_only.rs +++ b/src/root/compiler/evaluation/function_only.rs @@ -1,6 +1,7 @@ use crate::root::compiler::evaluation::type_only::compile_evaluable_type_only; use crate::root::compiler::global_tracker::GlobalTracker; use crate::root::compiler::local_variable_table::LocalVariableTable; +use crate::root::errors::evaluable_errors::EvalErrs; use crate::root::errors::evaluable_errors::EvalErrs::ExpectedFunctionName; use crate::root::errors::WErr; use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable, NameResult}; @@ -32,7 +33,12 @@ pub fn compile_evaluable_function_only<'a>( )?; let function = global_table.get_impl_function_by_name(*inner_type.type_id(), access.name()); - let Some(function) = function else { todo!() }; + let Some(function) = function else { + return WErr::ne(EvalErrs::TypeDoesntHaveMethod( + global_table.get_type_name(&inner_type.type_id().immediate()), + access.name().clone() + ), access.location().clone()); + }; (None, function, access.name().clone()) } @@ -46,7 +52,12 @@ pub fn compile_evaluable_function_only<'a>( )?; let function = global_table.get_impl_function_by_name(*inner_type.type_id(), access.name()); - let Some(function) = function else { todo!() }; + let Some(function) = function else { + return WErr::ne(EvalErrs::TypeDoesntHaveMethod( + global_table.get_type_name(&inner_type.type_id().immediate()), + access.name().clone() + ), access.location().clone()); + }; (Some(inner), function, access.name().clone()) } diff --git a/src/root/compiler/evaluation/into.rs b/src/root/compiler/evaluation/into.rs index ee0da2d..e916b10 100644 --- a/src/root/compiler/evaluation/into.rs +++ b/src/root/compiler/evaluation/into.rs @@ -22,6 +22,7 @@ use crate::root::shared::types::Type; use either::{Left, Right}; use itertools::Itertools; use std::any::Any; +use crate::root::errors::evaluable_errors::EvalErrs::WrongAttributeNameInInit; /// Evaluates `et` putting the result into `target` pub fn compile_evaluable_into( @@ -264,22 +265,26 @@ pub fn compile_evaluable_into( )?; c } - EvaluableTokens::DynamicAccess(inner, access) => { + EvaluableTokens::DynamicAccess(inner_eval, access) => { let mut ab = AssemblyBuilder::new(); let (c, inner) = compile_evaluable_reference( fid, - inner, + inner_eval, local_variables, global_table, global_tracker, )?; ab.other(&c); - let Some(inner) = inner else { todo!() }; + let Some(inner) = inner else { + return WErr::ne(EvalErrs::ExpectedNotNone, inner_eval.location().clone()) + }; - if inner.type_ref().indirection().0 > 1 { - todo!() - } + let inner = if inner.type_ref().indirection().0 > 1 { + let (c, inner) = coerce_self(inner, SelfType::RefSelf, global_table, local_variables)?; + ab.other(&c); + inner + } else { inner }; let t = global_table.get_type(*inner.type_ref().type_id()); let attribs = t.get_attributes(access.location())?; @@ -288,18 +293,26 @@ pub fn compile_evaluable_into( for (offset, name, t) in attribs { if name.name() == access.name() { if &t.plus_one_indirect() != target.type_ref() { - todo!() + return WErr::ne( + EvalErrs::ExpectedDifferentType( + global_table.get_type_name(target.type_ref()), + global_table.get_type_name(&t.plus_one_indirect()), + ), access.location().clone() + ) } found_offset = Some(*offset); } } let Some(found_offset) = found_offset else { - todo!() + return WErr::ne(EvalErrs::TypeDoesntHaveAttribute( + global_table.get_type_name(&t.id().immediate()), + access.name().clone() + ), access.location().clone()); }; if inner.type_ref().indirection().has_indirection() { - // TODO: Not 64 bit! + // TODO: This is not full 64 bit! ab.line(&format!("mov rax, {}", inner.local_address())); ab.line(&format!("add rax, {}", found_offset.0)); ab.line(&format!("mov qword {}, rax", target.local_address())); @@ -386,7 +399,13 @@ pub fn compile_evaluable_into( if *struct_init.heap_alloc() { if target.type_ref() != &t.plus_one_indirect() { - todo!() + return WErr::ne( + EvalErrs::ExpectedDifferentType( + global_table.get_type_name(target.type_ref()), + global_table.get_type_name(&t.plus_one_indirect()), + ), + struct_init.location().clone(), + ); } let mut ab = AssemblyBuilder::new(); let (c, sr) = @@ -403,10 +422,22 @@ pub fn compile_evaluable_into( debug_assert!(!t.indirection().has_indirection()); if *struct_init.heap_alloc() && &t.plus_one_indirect() != target.type_ref() { - todo!() + return WErr::ne( + EvalErrs::ExpectedDifferentType( + global_table.get_type_name(target.type_ref()), + global_table.get_type_name(&t.plus_one_indirect()), + ), + struct_init.location().clone(), + ); } if !struct_init.heap_alloc() && &t != target.type_ref() { - todo!(); + return WErr::ne( + EvalErrs::ExpectedDifferentType( + global_table.get_type_name(target.type_ref()), + global_table.get_type_name(&t), + ), + struct_init.location().clone(), + ); } let tt = global_table.get_type(t.type_id().clone()); @@ -424,7 +455,10 @@ pub fn compile_evaluable_into( let give_attrs = struct_init.contents(); if attributes.len() != give_attrs.len() { - todo!() + return WErr::ne(EvalErrs::WrongAttributeCount( + attributes.len(), + give_attrs.len() + ), struct_init.location().clone()); } let mut code = AssemblyBuilder::new(); @@ -433,7 +467,10 @@ pub fn compile_evaluable_into( for ((offset, t_name, t_type), (name, val)) in attributes.iter().zip(give_attrs.iter()) { if t_name.name() != name.name() { - todo!() + return WErr::ne( + WrongAttributeNameInInit(t_name.name().clone(), name.name().clone()), + name.location().clone() + ); } let new_addr = AddressedTypeRef::new( diff --git a/src/root/compiler/evaluation/mod.rs b/src/root/compiler/evaluation/mod.rs index 30ca3e5..c68f254 100644 --- a/src/root/compiler/evaluation/mod.rs +++ b/src/root/compiler/evaluation/mod.rs @@ -27,5 +27,5 @@ pub fn expect_addr( // // let et = et.token(); // -// todo!() +// // } diff --git a/src/root/compiler/evaluation/new.rs b/src/root/compiler/evaluation/new.rs index a08d9bd..833dce6 100644 --- a/src/root/compiler/evaluation/new.rs +++ b/src/root/compiler/evaluation/new.rs @@ -9,15 +9,18 @@ use crate::root::compiler::compile_function_call::call_function; use crate::root::compiler::compiler_errors::CompErrs; use crate::root::compiler::evaluation::reference::compile_evaluable_reference; use crate::root::compiler::evaluation::{function_only, into, reference, type_only}; +use crate::root::compiler::evaluation::coerce_self::coerce_self; use crate::root::compiler::global_tracker::GlobalTracker; use crate::root::compiler::local_variable_table::LocalVariableTable; use crate::root::errors::evaluable_errors::EvalErrs; +use crate::root::errors::evaluable_errors::EvalErrs::{ExpectedNotNone, WrongAttributeNameInInit}; use crate::root::errors::name_resolver_errors::NRErrs; use crate::root::errors::WErr; use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable, NameResult}; use crate::root::parser::parse::Location; use crate::root::parser::parse_function::parse_evaluable::{EvaluableToken, EvaluableTokens}; use crate::root::parser::parse_function::parse_operator::{OperatorTokens, PrefixOrInfixEx}; +use crate::root::parser::parse_parameters::SelfType; use crate::root::shared::common::{ AddressedTypeRef, FunctionID, Indirection, LocalAddress, TypeRef, }; @@ -284,22 +287,26 @@ pub fn compile_evaluable_new( )?; (c, return_into) } - EvaluableTokens::DynamicAccess(inner, access) => { + EvaluableTokens::DynamicAccess(inner_eval, access) => { let mut ab = AssemblyBuilder::new(); let (c, inner) = compile_evaluable_reference( fid, - inner, + inner_eval, local_variables, global_table, global_tracker, )?; ab.other(&c); - let Some(inner) = inner else { todo!() }; + let Some(inner) = inner else { + return WErr::ne(ExpectedNotNone, inner_eval.location().clone()); + }; - if inner.type_ref().indirection().0 > 1 { - todo!() - } + let inner = if inner.type_ref().indirection().0 > 1 { + let (c, inner) = coerce_self(inner, SelfType::RefSelf, global_table, local_variables)?; + ab.other(&c); + inner + } else { inner }; let t = global_table.get_type(*inner.type_ref().type_id()); let attribs = t.get_attributes(access.location())?; @@ -313,7 +320,10 @@ pub fn compile_evaluable_new( } let Some((found_offset, t)) = found else { - todo!() + return WErr::ne(EvalErrs::TypeDoesntHaveAttribute( + t.name().to_string(), + access.name().clone() + ), access.location().clone()) }; // let t = t.plus_one_indirect(); @@ -440,13 +450,19 @@ pub fn compile_evaluable_new( let give_attrs = struct_init.contents(); if attributes.len() != give_attrs.len() { - todo!() + return WErr::ne(EvalErrs::WrongAttributeCount( + attributes.len(), + give_attrs.len() + ), struct_init.location().clone()); } for ((offset, t_name, t_type), (name, val)) in attributes.iter().zip(give_attrs.iter()) { if t_name.name() != name.name() { - todo!() + return WErr::ne( + WrongAttributeNameInInit(t_name.name().clone(), name.name().clone()), + name.location().clone() + ); } let new_addr = AddressedTypeRef::new( diff --git a/src/root/compiler/evaluation/type_only.rs b/src/root/compiler/evaluation/type_only.rs index ac797cf..a5eb7dc 100644 --- a/src/root/compiler/evaluation/type_only.rs +++ b/src/root/compiler/evaluation/type_only.rs @@ -128,7 +128,10 @@ pub fn compile_evaluable_type_only( if let Some(out) = out { out.plus_one_indirect() } else { - todo!() + return WErr::ne(EvalErrs::TypeDoesntHaveAttribute( + global_table.get_type_name(&t.id().immediate()), + access.name().clone() + ), access.location().clone()); } } EvaluableTokens::StaticAccess(_, n) => { diff --git a/src/root/errors/evaluable_errors.rs b/src/root/errors/evaluable_errors.rs index 68c0111..776c76c 100644 --- a/src/root/errors/evaluable_errors.rs +++ b/src/root/errors/evaluable_errors.rs @@ -38,8 +38,16 @@ pub enum EvalErrs { BadFunctionArgCount(String, usize, usize), #[error("Type ({0}) does not have attributes")] TypeDoesntHaveAttributes(String), + #[error("Type ({0}) does not have attribute ({1})")] + TypeDoesntHaveAttribute(String, String), #[error("Type ({0}) cannot be initialised")] TypeCannotBeInitialised(String), #[error("Type ({0}) cannot be initialised from a literal")] - TypeCannotBeInitialisedByLiteral(String) + TypeCannotBeInitialisedByLiteral(String), + #[error("Type ({0}) doesn't have method ({1})")] + TypeDoesntHaveMethod(String, String), + #[error("Expected attribute ({0}) to be initialised next, not ({1})")] + WrongAttributeNameInInit(String, String), + #[error("Expected ({0}) attributes to be initialised - found ({1})")] + WrongAttributeCount(usize, usize) } diff --git a/src/root/parser/parse_function/parse_evaluable.rs b/src/root/parser/parse_function/parse_evaluable.rs index 06cf88e..05f3a86 100644 --- a/src/root/parser/parse_function/parse_evaluable.rs +++ b/src/root/parser/parse_function/parse_evaluable.rs @@ -15,6 +15,7 @@ use derive_getters::Getters; use nom::branch::alt; use nom::bytes::complete::tag; use nom::character::complete::char; +use crate::root::errors::parser_errors::create_custom_error; #[derive(Debug, Getters)] pub struct EvaluableToken { @@ -212,7 +213,7 @@ pub fn parse_full_name<'a>( // match either { // Left(val) => {Ok(val)} // Right(_) => { -// todo!() +// // } // } // } @@ -485,8 +486,12 @@ pub fn parse_evaluable<'a, 'b>( enumerated_slice = &enumerated_slice[1..]; Some(op.clone()) } - (_, TempEvaluableTokensTwo::EvaluableToken(_)) => { + (_, TempEvaluableTokensTwo::EvaluableToken(e)) => { // ? Expected infix connecting operator + // return Err(create_custom_error( + // + // e.location + // )); todo!() } }