diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_05_06_2024,_13_36_[Changes]/shelved.patch b/.idea/shelf/Uncommitted_changes_before_Update_at_05_06_2024,_13_36_[Changes]/shelved.patch new file mode 100644 index 0000000..6d9f839 --- /dev/null +++ b/.idea/shelf/Uncommitted_changes_before_Update_at_05_06_2024,_13_36_[Changes]/shelved.patch @@ -0,0 +1,153 @@ +Index: src/root/compiler/compile_evaluable.rs +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP +<+>use std::collections::HashSet;\nuse crate::root::compiler::local_variable_table::LocalVariableTable;\nuse crate::root::name_resolver::name_resolvers::GlobalDefinitionTable;\nuse crate::root::parser::parse_function::parse_evaluable::{EvaluableToken, EvaluableTokens};\nuse crate::root::shared::common::{FunctionID, TypeRef};\nuse crate::root::shared::common::AddressedTypeRef;\n\npub fn compile_evaluable(fid: FunctionID, et: &EvaluableToken, target: Option, local_variables: &mut LocalVariableTable, global_table: &GlobalDefinitionTable, function_calls: &mut HashSet) -> (String, Option) {\n let et = et.token();\n\n match et {\n EvaluableTokens::Name(_, _) => todo!(),\n EvaluableTokens::Literal(literal) => {\n let (address, t, tid) = if let Some(target) = target {\n let (address, tid) = target.dissolve();\n if tid.indirection().has_indirection() {\n todo!()\n }\n let t = global_table.type_definitions().get(tid.type_id()).unwrap();\n (address, t, tid)\n }\n else {\n let tid = literal.literal().default_type();\n if tid.indirection().has_indirection() {\n todo!()\n }\n let t = global_table.type_definitions().get(tid.type_id()).unwrap();\n let address = local_variables.add_new_unnamed(t.size());\n (address, t, tid)\n };\n\n (t.instantiate_from_literal(&address, literal), Some(AddressedTypeRef::new(address, tid)))\n }\n EvaluableTokens::InfixOperator(_, _, _) => todo!(),\n EvaluableTokens::PrefixOperator(_, _) => todo!(),\n EvaluableTokens::DynamicAccess(_, _) => todo!(),\n EvaluableTokens::StaticAccess(_, _) => todo!(),\n EvaluableTokens::FunctionCall(_, _, _) => todo!()\n }\n} +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/root/compiler/compile_evaluable.rs b/src/root/compiler/compile_evaluable.rs +--- a/src/root/compiler/compile_evaluable.rs (revision 2faf4af5e5473a64a986ce274d5ce52ff3cc43f7) ++++ b/src/root/compiler/compile_evaluable.rs (date 1717590981611) +@@ -5,7 +5,15 @@ + 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: &GlobalDefinitionTable, ++ function_calls: &mut HashSet ++) -> (String, Option) { ++ + let et = et.token(); + + match et { +@@ -21,10 +29,7 @@ + } + 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 t = global_table.type_definitions().get(&tid).unwrap(); + let address = local_variables.add_new_unnamed(t.size()); + (address, t, tid) + }; +Index: src/root/parser/parse_function/parse_literal.rs +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP +<+>use derive_getters::{Dissolve, Getters};\nuse crate::root::parser::parse::{Location, ParseResult, Span};\nuse nom::branch::alt;\nuse nom::bytes::complete::tag;\nuse crate::root::builtin::int::IntType;\nuse crate::root::parser::parse_util::discard_ignored;\nuse crate::root::shared::common::{Indirection, TypeID, TypeRef};\nuse crate::root::shared::types::Type;\n\n#[derive(Debug, Dissolve, Getters)]\npub struct LiteralToken {\n location: Location,\n literal: LiteralTokens,\n}\n\n#[derive(Debug)]\npub enum LiteralTokens {\n Bool(bool),\n Int(i64),\n}\n\nimpl LiteralTokens {\n pub fn default_type(&self) -> TypeRef {\n match self {\n LiteralTokens::Bool(_) => {\n todo!()\n }\n LiteralTokens::Int(_) => {\n TypeRef::new(IntType{}.id(), Indirection(0))\n }\n }\n }\n}\n\npub fn parse_literal(s: Span) -> ParseResult {\n let (s, _) = discard_ignored(s)?;\n\n let (ns, l) = alt((\n |x| tag(\"true\")(x).map(|(s, _)| (s, LiteralTokens::Bool(true))),\n |x| tag(\"false\")(x).map(|(s, _)| (s, LiteralTokens::Bool(false))),\n |x| nom::character::complete::i64(x).map(|(s, i)| (s, LiteralTokens::Int(i))),\n ))(s)?;\n\n let l = LiteralToken {\n location: Location::from_span(&s),\n literal: l,\n };\n\n Ok((ns, l))\n}\n +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/root/parser/parse_function/parse_literal.rs b/src/root/parser/parse_function/parse_literal.rs +--- a/src/root/parser/parse_function/parse_literal.rs (revision 2faf4af5e5473a64a986ce274d5ce52ff3cc43f7) ++++ b/src/root/parser/parse_function/parse_literal.rs (date 1717590906072) +@@ -20,13 +20,13 @@ + } + + impl LiteralTokens { +- pub fn default_type(&self) -> TypeRef { ++ pub fn default_type(&self) -> TypeID { + match self { + LiteralTokens::Bool(_) => { + todo!() + } + LiteralTokens::Int(_) => { +- TypeRef::new(IntType{}.id(), Indirection(0)) ++ IntType{}.id() + } + } + } +Index: src/root/errors/evaluable_errors.rs +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/root/errors/evaluable_errors.rs b/src/root/errors/evaluable_errors.rs +new file mode 100644 +--- /dev/null (date 1717590981605) ++++ b/src/root/errors/evaluable_errors.rs (date 1717590981605) +@@ -0,0 +1,7 @@ ++use thiserror::Error; ++ ++#[derive(Error, Debug)] ++pub enum EvaluableErrors { ++ #[error("Names cannot contain character '{0}' (UTF-8 Code: {1:?})")] ++ BadName(char, Vec), ++} +Index: src/root/errors/mod.rs +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP +<+>use std::fmt::{Display, Formatter};\nuse color_print::cformat;\nuse crate::root::parser::parse::Location;\n\npub mod parser_errors;\npub mod name_resolver_errors;\n\npub struct WError {\n error: String,\n location: Option // ! Important, don't do file reads unless necessary (i.e. Display)\n}\n\nimpl WError {\n pub fn n(error: impl Display, location: Location) -> WError {\n WError {\n error: format!(\"{error}\"),\n location: Some(location)\n }\n }\n\n pub fn locationless(error: impl Display) -> WError {\n WError {\n error: format!(\"{error}\"),\n location: None\n }\n }\n}\n\nimpl Display for WError {\n fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {\n let text = if let Some(location) = &self.location {\n cformat!(\"Error:\\n {}\\n{}\\n\", self.error, location)\n }\n else {\n cformat!(\"Error:\\n {}\", self.error)\n };\n f.write_str(&text)\n }\n} +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/root/errors/mod.rs b/src/root/errors/mod.rs +--- a/src/root/errors/mod.rs (revision 2faf4af5e5473a64a986ce274d5ce52ff3cc43f7) ++++ b/src/root/errors/mod.rs (date 1717590981609) +@@ -4,6 +4,7 @@ + + pub mod parser_errors; + pub mod name_resolver_errors; ++mod evaluable_errors; + + pub struct WError { + error: String, +Index: .idea/workspace.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP +<+>\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n "lastFilter": {\n "state": "OPEN",\n "assignee": "Robert-M-Lucas"\n }\n}\n \n \n {\n "selectedUrlAndAccountId": {\n "url": "https://github.com/Robert-M-Lucas/whython-8.git",\n "accountId": "dcb8df19-0b39-47e1-9073-4a54f7034be8"\n }\n}\n \n \n \n \n {\n "customColor": "",\n "associatedIndex": 4\n}\n \n \n \n {\n "keyToString": {\n "Cargo.Run whython-8.executor": "Run",\n "RunOnceActivity.OpenProjectViewOnStart": "true",\n "RunOnceActivity.ShowReadmeOnStart": "true",\n "RunOnceActivity.rust.reset.selective.auto.import": "true",\n "git-widget-placeholder": "master",\n "ignore.virus.scanning.warn.message": "true",\n "node.js.detected.package.eslint": "true",\n "node.js.detected.package.tslint": "true",\n "node.js.selected.package.eslint": "(autodetect)",\n "node.js.selected.package.tslint": "(autodetect)",\n "nodejs_package_manager_path": "npm",\n "org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",\n "org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",\n "org.rust.first.attach.projects": "true",\n "settings.editor.selected.configurable": "reference.settingsdialog.IDE.editor.colors.Rust",\n "vue.rearranger.settings.migration": "true"\n }\n}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 1714088144106\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/.idea/workspace.xml b/.idea/workspace.xml +--- a/.idea/workspace.xml (revision 2faf4af5e5473a64a986ce274d5ce52ff3cc43f7) ++++ b/.idea/workspace.xml (date 1717590906506) +@@ -7,15 +7,7 @@ + + + +- +- +- +- +- +- +- +- +- ++ + + diff --git a/src/root/compiler/compile_evaluable.rs b/src/root/compiler/compile_evaluable.rs index 53cfb66..15ad3e8 100644 --- a/src/root/compiler/compile_evaluable.rs +++ b/src/root/compiler/compile_evaluable.rs @@ -8,14 +8,198 @@ use crate::root::parser::parse_function::parse_evaluable::{EvaluableToken, Evalu use crate::root::shared::common::{FunctionID, Indirection, TypeRef}; use crate::root::shared::common::AddressedTypeRef; +/// Will always evaluate into new address pub fn compile_evaluable( + fid: FunctionID, + et: &EvaluableToken, + local_variables: &mut LocalVariableTable, + global_table: &mut GlobalDefinitionTable, + function_calls: &mut HashSet +) -> Result<(String, AddressedTypeRef), WError> { + + let et = et.token(); + + Ok(match et { + EvaluableTokens::Name(name, containing_class) => { + match global_table.resolve_name(name.name(), local_variables, containing_class.as_ref().map(|x| x.name()))? { + NameResult::Function(_) => todo!(), // Cannot use a function without a call + NameResult::Type(_) => todo!(), // Cannot evaluate a type + NameResult::Variable(address) => { + let target = global_table.add_local_variable_unnamed_base(address.type_ref().clone(), local_variables); + (copy(*address.local_address(), *target.local_address(), global_table.get_size(target.type_ref())), Some(target)) + } + } + }, + EvaluableTokens::Literal(literal) => { + let tid = literal.literal().default_type(); + let address = global_table.add_local_variable_unnamed_base(TypeRef::new(tid.clone(), Indirection(0)), local_variables); + let t = global_table.get_type(tid); + + (t.instantiate_from_literal(address.local_address(), literal), Some(address)) + } + EvaluableTokens::InfixOperator(_, _, _) => todo!(), + EvaluableTokens::PrefixOperator(_, _) => todo!(), + EvaluableTokens::DynamicAccess(_, _) => todo!(), // Accessed methods must be called + EvaluableTokens::StaticAccess(_, _) => todo!(), // Accessed methods must be called + EvaluableTokens::FunctionCall(_, _) => todo!() + }) +} + + +/// Will always put result into target +pub fn compile_evaluable_into( + fid: FunctionID, + et: &EvaluableToken, + target: AddressedTypeRef, + local_variables: &mut LocalVariableTable, + global_table: &mut GlobalDefinitionTable, + function_calls: &mut HashSet +) -> Result { + + let et = et.token(); + + Ok(match et { + EvaluableTokens::Name(name, containing_class) => { + match global_table.resolve_name(name.name(), local_variables, containing_class.as_ref().map(|x| x.name()))? { + NameResult::Function(_) => todo!(), // Cannot use a function without a call + NameResult::Type(_) => todo!(), // Cannot evaluate a type + NameResult::Variable(address) => { + if address.type_ref() != target.type_ref() { + todo!() // Mismatched types + } + copy(*address.local_address(), *target.local_address(), global_table.get_size(target.type_ref())) + } + } + }, + EvaluableTokens::Literal(literal) => { + if target.type_ref().indirection().has_indirection() { + return Err(WError::n(EvaluableErrors::BadIndirection(target.type_ref().indirection().0, 0), literal.location().clone())); + } + let t = global_table.get_type(*target.type_ref().type_id()); + + t.instantiate_from_literal(target.local_address(), literal) + } + EvaluableTokens::InfixOperator(_, _, _) => todo!(), + EvaluableTokens::PrefixOperator(_, _) => todo!(), + EvaluableTokens::DynamicAccess(_, _) => todo!(), // Accessed methods must be called + EvaluableTokens::StaticAccess(_, _) => todo!(), // Accessed methods must be called + EvaluableTokens::FunctionCall(inner, args) => { + + } + }) +} + +/// Will try to return a reference i.e. not allocate stack +pub fn compile_evaluable_reference( + fid: FunctionID, + et: &EvaluableToken, + local_variables: &mut LocalVariableTable, + global_table: &mut GlobalDefinitionTable, + function_calls: &mut HashSet +) -> Result<(String, AddressedTypeRef), WError> { + + let et = et.token(); + + Ok(match et { + EvaluableTokens::Name(name, containing_class) => { + match global_table.resolve_name(name.name(), local_variables, containing_class.as_ref().map(|x| x.name()))? { + NameResult::Function(_) => todo!(), + NameResult::Type(_) => todo!(), + NameResult::Variable(address) => { + ("".to_string(), address) + } + } + }, + EvaluableTokens::Literal(literal) => { + let (address, t) = if let Some(target) = target { + if target.type_ref().indirection().has_indirection() { + return Err(WError::n(EvaluableErrors::BadIndirection(target.type_ref().indirection().0, 0), literal.location().clone())); + } + let t = global_table.get_type(*target.type_ref().type_id()); + (target, t) + } + else { + let tid = literal.literal().default_type(); + let address = global_table.add_local_variable_unnamed_base(TypeRef::new(tid.clone(), Indirection(0)), local_variables); + let t = global_table.get_type(tid); + (address, t) + }; + + (t.instantiate_from_literal(address.local_address(), literal), Some(address)) + } + EvaluableTokens::InfixOperator(_, _, _) => todo!(), + EvaluableTokens::PrefixOperator(_, _) => todo!(), + EvaluableTokens::DynamicAccess(_, _) => todo!(), + EvaluableTokens::StaticAccess(_, _) => todo!(), + EvaluableTokens::FunctionCall(_, _) => todo!() + }) +} + +/// Will always return a function pointer (and self) +pub fn compile_evaluable_function_only( fid: FunctionID, et: &EvaluableToken, target: Option, local_variables: &mut LocalVariableTable, global_table: &mut GlobalDefinitionTable, function_calls: &mut HashSet -) -> Result<(String, Option), WError> { +) -> Result<(String, Option, FunctionID), WError> { + + let et = et.token(); + + Ok(match et { + EvaluableTokens::Name(name, containing_class) => { + match global_table.resolve_name(name.name(), local_variables)? { + NameResult::Function(_) => todo!(), + NameResult::Type(_) => todo!(), + NameResult::Variable(address) => { + if let Some(target) = target { + if target.type_ref() != address.type_ref() { + todo!() + } + + (copy(*address.local_address(), *target.local_address(), global_table.get_size(target.type_ref())), Some(target)) + } + else { + let target = global_table.add_local_variable_unnamed_base(address.type_ref().clone(), local_variables); + (copy(*address.local_address(), *target.local_address(), global_table.get_size(target.type_ref())), Some(target)) + } + } + } + }, + EvaluableTokens::Literal(literal) => { + let (address, t) = if let Some(target) = target { + if target.type_ref().indirection().has_indirection() { + return Err(WError::n(EvaluableErrors::BadIndirection(target.type_ref().indirection().0, 0), literal.location().clone())); + } + let t = global_table.get_type(*target.type_ref().type_id()); + (target, t) + } + else { + let tid = literal.literal().default_type(); + let address = global_table.add_local_variable_unnamed_base(TypeRef::new(tid.clone(), Indirection(0)), local_variables); + let t = global_table.get_type(tid); + (address, t) + }; + + (t.instantiate_from_literal(address.local_address(), literal), Some(address)) + } + EvaluableTokens::InfixOperator(_, _, _) => todo!(), + EvaluableTokens::PrefixOperator(_, _) => todo!(), + EvaluableTokens::DynamicAccess(_, _) => todo!(), + EvaluableTokens::StaticAccess(_, _) => todo!(), + EvaluableTokens::FunctionCall(_, _) => todo!() + }) +} + +/// Will ignore everything other than type +pub fn compile_evaluable_type_only( + fid: FunctionID, + et: &EvaluableToken, + local_variables: &mut LocalVariableTable, + global_table: &mut GlobalDefinitionTable, + function_calls: &mut HashSet +) -> Result<(String, TypeRef), WError> { let et = et.token(); @@ -60,6 +244,6 @@ pub fn compile_evaluable( EvaluableTokens::PrefixOperator(_, _) => todo!(), EvaluableTokens::DynamicAccess(_, _) => todo!(), EvaluableTokens::StaticAccess(_, _) => todo!(), - EvaluableTokens::FunctionCall(_, _, _) => todo!() + EvaluableTokens::FunctionCall(_, _) => todo!() }) } \ 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 21ba9d3..e582dc2 100644 --- a/src/root/name_resolver/name_resolvers.rs +++ b/src/root/name_resolver/name_resolvers.rs @@ -231,7 +231,7 @@ impl GlobalDefinitionTable { self.type_definitions.get(&type_id).as_ref().unwrap() } - pub fn resolve_name(&mut self, name: &String, local_variable_table: &LocalVariableTable) -> Result { + pub fn resolve_name(&mut self, name: &String, containing_class: Option<&String>, local_variable_table: &LocalVariableTable) -> Result { if let Some(variable) = local_variable_table.get_name(name) { return Ok(NameResult::Variable(variable)) } diff --git a/src/root/parser/parse_function/parse_evaluable.rs b/src/root/parser/parse_function/parse_evaluable.rs index abaf72e..7d109ba 100644 --- a/src/root/parser/parse_function/parse_evaluable.rs +++ b/src/root/parser/parse_function/parse_evaluable.rs @@ -33,7 +33,7 @@ pub enum EvaluableTokens { Name(SimpleNameToken, Option), StaticAccess(Box, SimpleNameToken), DynamicAccess(Box, SimpleNameToken), - FunctionCall(Box, SimpleNameToken, Vec), + FunctionCall(Box, Vec), Literal(LiteralToken), InfixOperator(Box, OperatorToken, Box), PrefixOperator(OperatorToken, Box), @@ -111,7 +111,9 @@ enum TempEvaluableTokensOne { Operator(OperatorToken), StaticAccess(SimpleNameToken), DynamicAccess(SimpleNameToken), - FunctionCall(SimpleNameToken, Vec), + FunctionCall(SimpleNameToken, Option, Vec), + StaticFunctionCall(SimpleNameToken, Vec), + DynamicFunctionCall(SimpleNameToken, Vec), } #[derive(Debug)] @@ -230,7 +232,11 @@ pub fn parse_evaluable<'a, 'b>(s: Span<'a>, containing_class: Option<&SimpleName Ok(if char::('(')(x).is_ok() { let (x, arguments) = default_section(x, '(')?; let (_, arguments) = parse_arguments(arguments, containing_class)?; - (x, TempEvaluableTokensOne::FunctionCall(section, arguments)) + (x, match kind { + Kind::Static => TempEvaluableTokensOne::StaticFunctionCall(section, arguments), + Kind::Dynamic => TempEvaluableTokensOne::DynamicFunctionCall(section, arguments), + Kind::None => TempEvaluableTokensOne::FunctionCall(section, containing_class.and_then(|x| Some(x.clone())), arguments) + }) } else { match kind { @@ -279,13 +285,31 @@ pub fn parse_evaluable<'a, 'b>(s: Span<'a>, containing_class: Option<&SimpleName None => todo!(), // Must have previous } } - TempEvaluableTokensOne::FunctionCall(n, a) => { + TempEvaluableTokensOne::FunctionCall(n, c, a) => { + new_evaluables.push(TempEvaluableTokensTwo::EvaluableToken(EvaluableToken { + location: n.location().clone(), + token: EvaluableTokens::FunctionCall(b!(EvaluableToken { location: n.location().clone(), token: EvaluableTokens::Name(n, c) }), a), + })) + } + TempEvaluableTokensOne::DynamicFunctionCall(n, a) => { + match new_evaluables.pop() { + Some(TempEvaluableTokensTwo::Operator(_)) => todo!(), // Can't be operator + Some(TempEvaluableTokensTwo::EvaluableToken(e)) => { + new_evaluables.push(TempEvaluableTokensTwo::EvaluableToken(EvaluableToken { + location: e.location.clone(), + token: EvaluableTokens::FunctionCall(b!(EvaluableToken { location: n.location().clone(), token: EvaluableTokens::DynamicAccess(b!(e), n) }), a), + })) + }, + None => todo!(), // Must have previous + } + } + TempEvaluableTokensOne::StaticFunctionCall(n, a) => { match new_evaluables.pop() { Some(TempEvaluableTokensTwo::Operator(_)) => todo!(), // Can't be operator Some(TempEvaluableTokensTwo::EvaluableToken(e)) => { new_evaluables.push(TempEvaluableTokensTwo::EvaluableToken(EvaluableToken { location: e.location.clone(), - token: EvaluableTokens::FunctionCall(b!(e), n, a), + token: EvaluableTokens::FunctionCall(b!(EvaluableToken { location: n.location().clone(), token: EvaluableTokens::StaticAccess(b!(e), n) }), a), })) }, None => todo!(), // Must have previous diff --git a/src/root/shared/types.rs b/src/root/shared/types.rs index a11e646..451da27 100644 --- a/src/root/shared/types.rs +++ b/src/root/shared/types.rs @@ -1,3 +1,4 @@ +use crate::root::errors::WError; use crate::root::parser::parse_function::parse_literal::LiteralToken; use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, LocalAddress, TypeID}; @@ -6,5 +7,5 @@ pub trait Type { fn size(&self) -> ByteSize; - fn instantiate_from_literal(&self, location: &LocalAddress, literal: &LiteralToken) -> String; + fn instantiate_from_literal(&self, location: &LocalAddress, literal: &LiteralToken) -> Result; }