From fdf17405c5e5de05f61f48158769c66949ded5d9 Mon Sep 17 00:00:00 2001 From: Robert Lucas Date: Wed, 5 Jun 2024 13:02:05 +0100 Subject: [PATCH] Began adding assignment --- build/out.asm | 4 +- build/out.o | Bin 592 -> 592 bytes build/out.out | Bin 16480 -> 16480 bytes main.why | 3 +- src/root/builtin/int.rs | 8 +++- src/root/compiler/compile_evaluable.rs | 23 ++++----- src/root/compiler/compile_function.rs | 20 ++++---- src/root/compiler/local_variable_table.rs | 14 +----- src/root/name_resolver/name_resolvers.rs | 45 +++++++++++++++++- src/root/name_resolver/resolve.rs | 2 +- src/root/name_resolver/resolve_names.rs | 38 --------------- src/root/name_resolver/resolve_type_sizes.rs | 7 +-- .../parse_function/parse_initialisation.rs | 3 +- .../parser/parse_function/parse_literal.rs | 2 +- 14 files changed, 80 insertions(+), 89 deletions(-) diff --git a/build/out.asm b/build/out.asm index 7176b00..b7dafd8 100644 --- a/build/out.asm +++ b/build/out.asm @@ -7,7 +7,7 @@ main: mov rbp, rsp sub rsp, 16 - mov qword [rbp-8], 12 - mov rax, qword [rbp-8] + mov qword [rbp-16], 12 + mov rax, qword [rbp-16] leave ret \ No newline at end of file diff --git a/build/out.o b/build/out.o index 15a9a0fafd48e59f519b616f9c27bf980143203d..c3b9c575e80cd1f12f63e02dde29835ef8272425 100644 GIT binary patch delta 21 dcmcb>a)D(-HzVf<9tH*mk8alwlczB50RU6`2i5=p delta 21 dcmcb>a)D(-HzVf{9tH*mk8al=lczB50RU8s2j&0( diff --git a/build/out.out b/build/out.out index 42652b22db0369402a23fb69f1e7b149dac56606..3213d3cca9640afc44c5c3ded83e8782c571f837 100755 GIT binary patch delta 50 zcmV-20L}m4fC1ou0kCKT6px;g9v3hZrqS}uiG>p~pb_?$inDwJpA8A{3;+NCNQ*`A Ivm_BbFB=IHw*UYD delta 50 zcmaFR!1$nnaYF{Pi0& int { - return 12; + let a: int = 13; + return a; } diff --git a/src/root/builtin/int.rs b/src/root/builtin/int.rs index 39f2894..c6c196a 100644 --- a/src/root/builtin/int.rs +++ b/src/root/builtin/int.rs @@ -8,10 +8,14 @@ use crate::root::shared::types::Type; #[UniqueTypeIdType = "u16"] pub struct IntType {} -impl Type for IntType { - fn id(&self) -> TypeID { +impl IntType { + pub const fn id() -> TypeID { TypeID(-(IntType::unique_type_id().0 as isize) - 1) } +} + +impl Type for IntType { + fn id(&self) -> TypeID { Self::id() } fn size(&self) -> ByteSize { ByteSize(8) diff --git a/src/root/compiler/compile_evaluable.rs b/src/root/compiler/compile_evaluable.rs index e8da345..6248860 100644 --- a/src/root/compiler/compile_evaluable.rs +++ b/src/root/compiler/compile_evaluable.rs @@ -1,3 +1,4 @@ +use std::any::Any; use std::collections::HashSet; use crate::root::compiler::local_variable_table::LocalVariableTable; use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable; @@ -5,31 +6,27 @@ use crate::root::parser::parse_function::parse_evaluable::{EvaluableToken, Evalu use crate::root::shared::common::{FunctionID, TypeRef}; use crate::root::shared::common::AddressedTypeRef; -pub fn compile_evaluable(fid: FunctionID, et: &EvaluableToken, target: Option, local_variables: &mut LocalVariableTable, global_table: &GlobalDefinitionTable, function_calls: &mut HashSet) -> (String, Option) { +pub fn compile_evaluable(fid: FunctionID, et: &EvaluableToken, target: Option, local_variables: &mut LocalVariableTable, global_table: &mut GlobalDefinitionTable, function_calls: &mut HashSet) -> (String, Option) { let et = et.token(); match et { EvaluableTokens::Name(_, _) => todo!(), EvaluableTokens::Literal(literal) => { - let (address, t, tid) = if let Some(target) = target { - let (address, tid) = target.dissolve(); - if tid.indirection().has_indirection() { + let (address, t) = if let Some(target) = target { + if target.type_ref().indirection().has_indirection() { todo!() } - let t = global_table.type_definitions().get(tid.type_id()).unwrap(); - (address, t, tid) + let t = global_table.get_type(*target.type_ref().type_id()); + (target, t) } else { let tid = literal.literal().default_type(); - if tid.indirection().has_indirection() { - todo!() - } - let t = global_table.type_definitions().get(tid.type_id()).unwrap(); - let address = local_variables.add_new_unnamed(t.size()); - (address, t, tid) + let address = global_table.add_local_variable_unnamed_base(tid.clone(), local_variables); + let t = global_table.get_type(*tid.type_id()); + (address, t) }; - (t.instantiate_from_literal(&address, literal), Some(AddressedTypeRef::new(address, tid))) + (t.instantiate_from_literal(address.local_address(), literal), Some(address)) } EvaluableTokens::InfixOperator(_, _, _) => todo!(), EvaluableTokens::PrefixOperator(_, _) => todo!(), diff --git a/src/root/compiler/compile_function.rs b/src/root/compiler/compile_function.rs index 58cd5fd..4e9e4bc 100644 --- a/src/root/compiler/compile_function.rs +++ b/src/root/compiler/compile_function.rs @@ -26,12 +26,10 @@ pub fn compile_function(fid: FunctionID, function: FunctionToken, global_table: let mut param_address = LocalAddress(8); for (param_name, param_type) in parameters { - let type_ref = global_table.resolve_to_type_ref(¶m_type)?; + let t = global_table.resolve_to_type_ref(¶m_type)?; + global_table.add_local_variable_named(param_name.name().clone(), ¶m_type, &mut local_variables)?; - let size = global_table.type_definitions().get(type_ref.type_id()).unwrap().size(); - local_variables.add_existing(param_name.name().clone(), AddressedTypeRef::new(param_address, type_ref)); - - param_address += LocalAddress(size.0 as isize); + param_address += LocalAddress(global_table.get_size(&t).0 as isize); } let return_variable = return_type.and_then( @@ -42,7 +40,7 @@ pub fn compile_function(fid: FunctionID, function: FunctionToken, global_table: ); let mut function_calls = HashSet::new(); - let (full_contents, local_variables) = recursively_compile_lines(fid, &lines, &return_variable, local_variables, global_table, &mut function_calls); + let (full_contents, local_variables) = recursively_compile_lines(fid, &lines, &return_variable, local_variables, global_table, &mut function_calls)?; let stack_size = local_variables.stack_size(); @@ -66,13 +64,17 @@ pub fn compile_function(fid: FunctionID, function: FunctionToken, global_table: Ok((final_contents, function_calls)) } -fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_variable: &Option, local_variables: Box, global_table: &GlobalDefinitionTable, function_calls: &mut HashSet) -> (String, Box) { +fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_variable: &Option, local_variables: Box, global_table: &mut GlobalDefinitionTable, function_calls: &mut HashSet) -> Result<(String, Box), WError> { let mut local_variables = local_variables.enter_block(); let mut contents = String::new(); for line in lines { match line { - LineTokens::Initialisation(_) => todo!(), + LineTokens::Initialisation(it) => { + let (name, type_name, value) = (it.name(), it.type_name(), it.value()); + let address = global_table.add_local_variable_named(name.name().clone(), type_name, &mut local_variables)?; + compile_evaluable(fid, value, Some(address), &mut local_variables, global_table, function_calls); + }, LineTokens::Assignment(_) => todo!(), LineTokens::If(_) => todo!(), LineTokens::While(_) => todo!(), @@ -96,5 +98,5 @@ fn recursively_compile_lines(fid: FunctionID, lines: &[LineTokens], return_varia } } - (contents, local_variables.leave_block()) + Ok((contents, local_variables.leave_block())) } \ No newline at end of file diff --git a/src/root/compiler/local_variable_table.rs b/src/root/compiler/local_variable_table.rs index c650466..7f1cb15 100644 --- a/src/root/compiler/local_variable_table.rs +++ b/src/root/compiler/local_variable_table.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use crate::root::shared::common::{AddressedTypeRef, ByteSize, LocalAddress, TypeID}; +use crate::root::shared::common::{AddressedTypeRef, ByteSize, LocalAddress, TypeID, TypeRef}; use crate::root::shared::types::Type; /// Function-local table of defined variables. Only used within function processing @@ -48,16 +48,4 @@ impl LocalVariableTable { None } } - - pub fn get_ref_and_type<'a>(&self, name: &str, type_defs: &'a HashMap>) -> Option<(AddressedTypeRef, &'a dyn Type)> { - if let Some(r) = self.table.get(name) { - if let Some(t) = type_defs.get(r.type_ref().type_id()) { - return Some((r.clone(), t.as_ref())); - } - panic!("Type in VariableTable but no corresponding definition found!"); - } - else { - None - } - } } \ No newline at end of file diff --git a/src/root/name_resolver/name_resolvers.rs b/src/root/name_resolver/name_resolvers.rs index f99466f..a170ce7 100644 --- a/src/root/name_resolver/name_resolvers.rs +++ b/src/root/name_resolver/name_resolvers.rs @@ -15,7 +15,8 @@ use crate::root::parser::parse_function::FunctionToken; use crate::root::parser::parse_function::parse_evaluable::{FullNameToken, FullNameTokens, FullNameWithIndirectionToken}; use crate::root::parser::parse_name::SimpleNameToken; use crate::root::parser::parse_struct::StructToken; -use crate::root::shared::common::{AddressedTypeRef, FunctionID, TypeID, TypeRef}; +use crate::root::POINTER_SIZE; +use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, TypeID, TypeRef}; #[derive(Debug)] enum NameTreeEntry { @@ -54,7 +55,6 @@ impl TopLevelNameTree { } } -#[derive(Getters)] pub struct GlobalDefinitionTable { id_counter: isize, type_definitions: HashMap>, @@ -190,4 +190,45 @@ impl GlobalDefinitionTable { Err(WError::n(NRErrors::TypeNotFound(name.name().clone()), full_name.location().clone())) } + + pub fn get_size(&mut self, t: &TypeRef) -> ByteSize { + if t.indirection().has_indirection() { + POINTER_SIZE + } + else { + self.type_definitions.get(t.type_id()).unwrap().size() + } + } + + pub fn add_local_variable_unnamed_base(&mut self, t: TypeRef, local_variable_table: &mut LocalVariableTable) -> AddressedTypeRef { + let size = self.get_size(&t); + let address = local_variable_table.add_new_unnamed(size); + AddressedTypeRef::new(address, t) + } + + pub fn add_local_variable_unnamed(&mut self, t: &FullNameWithIndirectionToken, local_variable_table: &mut LocalVariableTable) -> Result { + let t = self.resolve_to_type_ref(t)?; + Ok(self.add_local_variable_unnamed_base(t, local_variable_table)) + } + + pub fn add_local_variable_named(&mut self, name: String, t: &FullNameWithIndirectionToken, local_variable_table: &mut LocalVariableTable) -> Result { + let t = self.resolve_to_type_ref(t)?; + let size = self.get_size(&t); + let address = local_variable_table.add_new_unnamed(size); + let address = AddressedTypeRef::new(address, t); + local_variable_table.add_existing(name, address.clone()); + Ok(address) + } + + pub fn get_function_signature(&self, function_id: FunctionID) -> &FunctionSignature { + self.function_signatures.get(&function_id).as_ref().unwrap() + } + + pub fn has_main(&self) -> bool { + self.function_signatures.contains_key(&FunctionID(0)) + } + + pub fn get_type(&self, type_id: TypeID) -> &Box { + self.type_definitions.get(&type_id).as_ref().unwrap() + } } diff --git a/src/root/name_resolver/resolve.rs b/src/root/name_resolver/resolve.rs index 74a7d27..e6e134b 100644 --- a/src/root/name_resolver/resolve.rs +++ b/src/root/name_resolver/resolve.rs @@ -13,7 +13,7 @@ pub fn resolve(ast: Vec) -> Result<(GlobalDefinitionTable, HashM register_builtin(&mut global_table); let unprocessed_functions = resolve_names(ast, &mut global_table)?; - if !global_table.function_signatures().contains_key(&FunctionID(0)) { + if !global_table.has_main() { return Err(WError::locationless(NRErrors::NoMain)) } diff --git a/src/root/name_resolver/resolve_names.rs b/src/root/name_resolver/resolve_names.rs index 7d0cd61..5f59f10 100644 --- a/src/root/name_resolver/resolve_names.rs +++ b/src/root/name_resolver/resolve_names.rs @@ -19,44 +19,6 @@ use crate::root::shared::common::{LocalAddress, TypeRef}; use crate::root::shared::common::{ByteSize, FunctionID, TypeID}; use crate::root::shared::types::Type; -// #[derive(Hash)] -// pub struct TypeName { -// name: String, -// location: Location, -// } -// -// impl TypeName { -// pub fn from_struct_token(st: &StructToken) -> TypeName { -// TypeName { -// name: st.name().clone(), -// location: st.location().clone(), -// } -// } -// -// pub fn from_impl_token(it: &ImplToken) -> TypeName { -// TypeName { -// name: it.name().clone(), -// location: it.location().clone(), -// } -// } - - // pub fn from_name_token(name: UnresolvedNameToken) -> TypeName { - // let name: (Location, Rc, Option, usize, String, Vec<(NameConnectors, String)>, Option>) = name.dissolve(); - // TypeName { - // name: name.4, - // location: name.0, - // } - // } -// } - -// impl PartialEq for TypeName { -// fn eq(&self, other: &Self) -> bool { -// self.name == other.name -// } -// } -// -// impl Eq for TypeName {} - /// A whython-code-defined type #[derive(Getters)] diff --git a/src/root/name_resolver/resolve_type_sizes.rs b/src/root/name_resolver/resolve_type_sizes.rs index 914e840..14b728d 100644 --- a/src/root/name_resolver/resolve_type_sizes.rs +++ b/src/root/name_resolver/resolve_type_sizes.rs @@ -53,12 +53,7 @@ pub fn resolve_type_sizes( size += resolve_type_sizes(unsized_type, final_types, unsized_types, global_table, path); } else { - if let Some(builtin_type) = global_table.type_definitions().get(&attribute_type.type_id()) { - size += builtin_type.size(); - } - else { - todo!() - } + size += global_table.get_type(*attribute_type.type_id()).size(); } } diff --git a/src/root/parser/parse_function/parse_initialisation.rs b/src/root/parser/parse_function/parse_initialisation.rs index 258bb6d..62ad233 100644 --- a/src/root/parser/parse_function/parse_initialisation.rs +++ b/src/root/parser/parse_function/parse_initialisation.rs @@ -1,3 +1,4 @@ +use derive_getters::Getters; use crate::root::parser::parse::{Location, ParseResult, Span}; use crate::root::parser::parse_function::parse_evaluable::{EvaluableToken, FullNameWithIndirectionToken, parse_evaluable, parse_full_name}; use crate::root::parser::parse_function::parse_line::{LineTestFn, LineTokens}; @@ -7,7 +8,7 @@ use nom_supreme::tag::complete::tag; use crate::root::parser::parse_name::{SimpleNameToken, parse_simple_name}; use crate::root::parser::parse_util::{discard_ignored, require_ignored}; -#[derive(Debug)] +#[derive(Debug, Getters)] pub struct InitialisationToken { location: Location, name: SimpleNameToken, diff --git a/src/root/parser/parse_function/parse_literal.rs b/src/root/parser/parse_function/parse_literal.rs index a29c8f5..2e65172 100644 --- a/src/root/parser/parse_function/parse_literal.rs +++ b/src/root/parser/parse_function/parse_literal.rs @@ -26,7 +26,7 @@ impl LiteralTokens { todo!() } LiteralTokens::Int(_) => { - TypeRef::new(IntType{}.id(), Indirection(0)) + TypeRef::new(IntType::id(), Indirection(0)) } } }