diff --git a/src/protocol/ast.rs b/src/protocol/ast.rs index e28067b5849b6d42322ef7524386c96b9a5aff3e..f7a570318056ec6c02182e5188fc14bb97974fda 100644 --- a/src/protocol/ast.rs +++ b/src/protocol/ast.rs @@ -3,11 +3,12 @@ use std::fmt::{Debug, Display, Formatter}; use std::ops::{Index, IndexMut}; use super::arena::{Arena, Id}; +// use super::containers::StringAllocator; use crate::protocol::inputsource::*; -#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct RootId(Id); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct RootId(pub(crate) Id); #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] pub struct PragmaId(Id); @@ -15,27 +16,6 @@ pub struct PragmaId(Id); #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ImportId(Id); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct IdentifierId(Id); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct SourceIdentifierId(IdentifierId); - -impl SourceIdentifierId { - pub fn upcast(self) -> IdentifierId { - self.0 - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct ExternalIdentifierId(IdentifierId); - -impl ExternalIdentifierId { - pub fn upcast(self) -> IdentifierId { - self.0 - } -} - #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] pub struct TypeAnnotationId(Id); @@ -63,6 +43,24 @@ impl LocalId { #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] pub struct DefinitionId(Id); +#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct StructId(DefinitionId); + +impl StructId { + pub fn upcast(self) -> DefinitionId{ + self.0 + } +} + +#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EnumId(DefinitionId); + +impl EnumId { + pub fn upcast(self) -> DefinitionId{ + self.0 + } +} + #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ComponentId(DefinitionId); @@ -407,14 +405,18 @@ impl ImportedDeclarationId { #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct Heap { - // Phase 0: allocation + // Allocators + // #[serde[skip]] string_alloc: StringAllocator, + // Root arena, contains the entry point for different modules. Each root + // contains lists of IDs that correspond to the other arenas. protocol_descriptions: Arena, + // Contents of a file, these are the elements the `Root` elements refer to pragmas: Arena, - imports: Arena, + pub(crate) imports: Arena, identifiers: Arena, type_annotations: Arena, variables: Arena, - definitions: Arena, + pub(crate) definitions: Arena, statements: Arena, expressions: Arena, declarations: Arena, @@ -423,6 +425,7 @@ pub struct Heap { impl Heap { pub fn new() -> Heap { Heap { + // string_alloc: StringAllocator::new(), protocol_descriptions: Arena::new(), pragmas: Arena::new(), imports: Arena::new(), @@ -435,25 +438,6 @@ impl Heap { declarations: Arena::new(), } } - pub fn alloc_source_identifier( - &mut self, - f: impl FnOnce(SourceIdentifierId) -> SourceIdentifier, - ) -> SourceIdentifierId { - SourceIdentifierId(IdentifierId( - self.identifiers - .alloc_with_id(|id| Identifier::Source(f(SourceIdentifierId(IdentifierId(id))))), - )) - } - pub fn alloc_external_identifier( - &mut self, - f: impl FnOnce(ExternalIdentifierId) -> ExternalIdentifier, - ) -> ExternalIdentifierId { - ExternalIdentifierId(IdentifierId( - self.identifiers.alloc_with_id(|id| { - Identifier::External(f(ExternalIdentifierId(IdentifierId(id)))) - }), - )) - } pub fn alloc_type_annotation( &mut self, f: impl FnOnce(TypeAnnotationId) -> TypeAnnotation, @@ -739,6 +723,16 @@ impl Heap { }), )) } + pub fn alloc_struct_definition(&mut self, f: impl FnOnce(StructId) -> StructDefinition) -> StructId { + StructId(DefinitionId(self.definitions.alloc_with_id(|id| { + Definition::Struct(f(StructId(DefinitionId(id)))) + }))) + } + pub fn alloc_enum_definition(&mut self, f: impl FnOnce(EnumId) -> EnumDefinition) -> EnumId { + EnumId(DefinitionId(self.definitions.alloc_with_id(|id| { + Definition::Enum(f(EnumId(DefinitionId(id)))) + }))) + } pub fn alloc_composite(&mut self, f: impl FnOnce(CompositeId) -> Composite) -> CompositeId { CompositeId(ComponentId(DefinitionId(self.definitions.alloc_with_id(|id| { Definition::Component(Component::Composite(f(CompositeId(ComponentId(DefinitionId( @@ -786,16 +780,6 @@ impl Heap { }), )) } - - pub fn get_external_identifier(&mut self, ident: &[u8]) -> ExternalIdentifierId { - for (_, id) in self.identifiers.iter() { - if id.is_external() && id.ident() == ident { - return id.as_external().this; - } - } - // Not found - self.alloc_external_identifier(|this| ExternalIdentifier { this, value: ident.to_vec() }) - } } impl Index for Heap { @@ -825,24 +809,9 @@ impl Index for Heap { } } -impl Index for Heap { - type Output = Identifier; - fn index(&self, index: IdentifierId) -> &Self::Output { - &self.identifiers[index.0] - } -} - -impl Index for Heap { - type Output = SourceIdentifier; - fn index(&self, index: SourceIdentifierId) -> &Self::Output { - &self.identifiers[(index.0).0].as_source() - } -} - -impl Index for Heap { - type Output = ExternalIdentifier; - fn index(&self, index: ExternalIdentifierId) -> &Self::Output { - &self.identifiers[(index.0).0].as_external() +impl IndexMut for Heap { + fn index_mut(&mut self, index: ImportId) -> &mut Self::Output { + &mut self.imports[index.0] } } @@ -1213,26 +1182,19 @@ pub struct Root { } impl Root { - pub fn get_definition(&self, h: &Heap, id: IdentifierId) -> Option { - for &def in self.definitions.iter() { - if h[h[def].identifier()] == h[id] { - return Some(def); - } - } - None - } pub fn get_definition_ident(&self, h: &Heap, id: &[u8]) -> Option { for &def in self.definitions.iter() { - if h[h[def].identifier()].ident() == id { + if h[def].identifier().value == id { return Some(def); } } None } - pub fn get_declaration(&self, h: &Heap, id: IdentifierId) -> Option { - for &decl in self.declarations.iter() { - if h[h[decl].identifier()] == h[id] { - return Some(decl); + pub fn get_declaration(&self, h: &Heap, id: &Identifier) -> Option { + for declaration_id in self.declarations.iter() { + let declaration = &h[*declaration_id]; + if declaration.identifier().value == id.value { + return Some(*declaration_id); } } None @@ -1282,127 +1244,136 @@ impl SyntaxElement for PragmaOld { } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct Import { - pub this: ImportId, - // Phase 1: parser - pub position: InputPosition, - pub value: Vec, -} - -impl SyntaxElement for Import { - fn position(&self) -> InputPosition { - self.position - } -} - -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub enum Identifier { - External(ExternalIdentifier), - Source(SourceIdentifier), +pub enum Import { + Module(ImportModule), + Symbols(ImportSymbols) } -impl Identifier { - pub fn as_source(&self) -> &SourceIdentifier { +impl Import { + pub(crate) fn as_module(&self) -> &ImportModule { match self { - Identifier::Source(result) => result, - _ => panic!("Unable to cast `Identifier` to `SourceIdentifier`"), + Import::Module(m) => m, + _ => panic!("Unable to cast 'Import' to 'ImportModule'") } } - pub fn is_external(&self) -> bool { + pub(crate) fn as_symbols(&self) -> &ImportSymbols { match self { - Identifier::External(_) => true, - _ => false, - } - } - pub fn as_external(&self) -> &ExternalIdentifier { - match self { - Identifier::External(result) => result, - _ => panic!("Unable to cast `Identifier` to `ExternalIdentifier`"), - } - } - fn ident(&self) -> &[u8] { - match self { - Identifier::External(eid) => eid.ident(), - Identifier::Source(sid) => sid.ident(), + Import::Symbols(m) => m, + _ => panic!("Unable to cast 'Import' to 'ImportSymbols'") } } } -impl Display for Identifier { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - // A source identifier is in ASCII range. - write!(f, "{}", String::from_utf8_lossy(self.ident())) - } -} - -impl PartialEq for Identifier { - fn eq(&self, rhs: &Identifier) -> bool { - self.ident() == rhs.ident() +impl SyntaxElement for Import { + fn position(&self) -> InputPosition { + match self { + Import::Module(m) => m.position, + Import::Symbols(m) => m.position + } } } -impl PartialEq for Identifier { - fn eq(&self, rhs: &SourceIdentifier) -> bool { - self.ident() == rhs.ident() - } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct ImportModule { + pub this: ImportId, + // Phase 1: parser + pub position: InputPosition, + pub module_name: Vec, + pub alias: Vec, + // Phase 2: module resolving + pub module_id: Option, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct ExternalIdentifier { - pub this: ExternalIdentifierId, +pub struct AliasedSymbol { // Phase 1: parser - pub value: Vec, + pub position: InputPosition, + pub name: Vec, + pub alias: Vec, + // Phase 2: symbol resolving + pub definition_id: Option, } -impl ExternalIdentifier { - fn ident(&self) -> &[u8] { - &self.value - } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct ImportSymbols { + pub this: ImportId, + // Phase 1: parser + pub position: InputPosition, + pub module_name: Vec, + // Phase 2: module resolving + pub module_id: Option, + // Phase 1&2 + // if symbols is empty, then we implicitly import all symbols without any + // aliases for them. If it is not empty, then symbols are explicitly + // specified, and optionally given an alias. + pub symbols: Vec, } -impl Display for ExternalIdentifier { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - // A source identifier is in ASCII range. - write!(f, "{}", String::from_utf8_lossy(&self.value)) - } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct Identifier { + pub position: InputPosition, + pub value: Vec } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct SourceIdentifier { - pub this: SourceIdentifierId, - // Phase 1: parser +pub struct NamespacedIdentifier { pub position: InputPosition, + pub num_namespaces: u8, pub value: Vec, } -impl SourceIdentifier { - pub fn ident(&self) -> &[u8] { - &self.value +impl NamespacedIdentifier { + fn iter(&self) -> NamespacedIdentifierIter { + NamespacedIdentifierIter{ + value: &self.value, + cur_offset: 0, + num_returned: 0, + num_total: self.num_namespaces + } } } -impl SyntaxElement for SourceIdentifier { - fn position(&self) -> InputPosition { - self.position - } +struct NamespacedIdentifierIter<'a> { + value: &'a Vec, + cur_offset: usize, + num_returned: u8, + num_total: u8, } -impl Display for SourceIdentifier { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - // A source identifier is in ASCII range. - write!(f, "{}", String::from_utf8_lossy(&self.value)) - } -} +impl<'a> Iterator for NamespacedIdentifierIter<'a> { + type Item = &'a [u8]; + fn next(&mut self) -> Option { + if self.cur_offset >= self.value.len() { + debug_assert_eq!(self.num_returned, self.num_total); + None + } else { + debug_assert!(self.num_returned < self.num_total); + let start = self.cur_offset; + let mut end = start; + while end < self.value.len() - 1 { + if self.value[end] == b':' && self.value[end + 1] == b':' { + self.cur_offset = end + 2; + self.num_returned += 1; + return Some(&self.value[start..end]); + } + end += 1; + } -impl PartialEq for SourceIdentifier { - fn eq(&self, rhs: &Identifier) -> bool { - self.ident() == rhs.ident() + // If NamespacedIdentifier is constructed properly, then we cannot + // end with "::" in the value, so + debug_assert!(end == 0 || (self.value[end - 1] != b':' && self.value[end] != b':')); + debug_assert_eq!(self.num_returned + 1, self.num_total); + self.cur_offset = self.value.len(); + self.num_returned += 1; + return Some(&self.value[start..]); + } } } -impl PartialEq for SourceIdentifier { - fn eq(&self, rhs: &SourceIdentifier) -> bool { - self.ident() == rhs.ident() +impl Display for Identifier { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + // A source identifier is in ASCII range. + write!(f, "{}", String::from_utf8_lossy(&self.value)) } } @@ -1519,13 +1490,13 @@ pub enum Method { Get, Fires, Create, - Symbolic(SourceIdentifierId), + Symbolic(Identifier), } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum Field { Length, - Symbolic(SourceIdentifierId), + Symbolic(Identifier), } impl Field { pub fn is_length(&self) -> bool { @@ -1554,7 +1525,7 @@ impl Scope { pub trait VariableScope { fn parent_scope(&self, h: &Heap) -> Option; - fn get_variable(&self, h: &Heap, id: SourceIdentifierId) -> Option; + fn get_variable(&self, h: &Heap, id: &Identifier) -> Option; } impl VariableScope for Scope { @@ -1565,7 +1536,7 @@ impl VariableScope for Scope { Scope::Synchronous(stmt) => h[*stmt].parent_scope(h), } } - fn get_variable(&self, h: &Heap, id: SourceIdentifierId) -> Option { + fn get_variable(&self, h: &Heap, id: &Identifier) -> Option { match self { Scope::Definition(def) => h[*def].get_variable(h, id), Scope::Block(stmt) => h[*stmt].get_variable(h, id), @@ -1581,10 +1552,10 @@ pub enum Variable { } impl Variable { - pub fn identifier(&self) -> SourceIdentifierId { + pub fn identifier(&self) -> &Identifier { match self { - Variable::Parameter(var) => var.identifier, - Variable::Local(var) => var.identifier, + Variable::Parameter(var) => &var.identifier, + Variable::Local(var) => &var.identifier, } } pub fn is_parameter(&self) -> bool { @@ -1628,7 +1599,7 @@ pub struct Parameter { // Phase 1: parser pub position: InputPosition, pub type_annotation: TypeAnnotationId, - pub identifier: SourceIdentifierId, + pub identifier: Identifier, } impl SyntaxElement for Parameter { @@ -1643,7 +1614,7 @@ pub struct Local { // Phase 1: parser pub position: InputPosition, pub type_annotation: TypeAnnotationId, - pub identifier: SourceIdentifierId, + pub identifier: Identifier, } impl SyntaxElement for Local { fn position(&self) -> InputPosition { @@ -1653,11 +1624,37 @@ impl SyntaxElement for Local { #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum Definition { + Struct(StructDefinition), + Enum(EnumDefinition), Component(Component), Function(Function), } impl Definition { + pub fn is_struct(&self) -> bool { + match self { + Definition::Struct(_) => true, + _ => false + } + } + pub fn as_struct(&self) -> &StructDefinition { + match self { + Definition::Struct(result) => result, + _ => panic!("Unable to cast 'Definition' to 'StructDefinition'"), + } + } + pub fn is_enum(&self) -> bool { + match self { + Definition::Enum(_) => true, + _ => false, + } + } + pub fn as_enum(&self) -> &EnumDefinition { + match self { + Definition::Enum(result) => result, + _ => panic!("Unable to cast 'Definition' to 'EnumDefinition'"), + } + } pub fn is_component(&self) -> bool { match self { Definition::Component(_) => true, @@ -1682,22 +1679,29 @@ impl Definition { pub fn as_primitive(&self) -> &Primitive { self.as_component().as_primitive() } - pub fn identifier(&self) -> SourceIdentifierId { + pub fn identifier(&self) -> &Identifier { match self { + Definition::Struct(def) => &def.identifier, + Definition::Enum(def) => &def.identifier, Definition::Component(com) => com.identifier(), - Definition::Function(fun) => fun.identifier, + Definition::Function(fun) => &fun.identifier, } } pub fn parameters(&self) -> &Vec { + // TODO: Fix this + static EMPTY_VEC: Vec = Vec::new(); match self { Definition::Component(com) => com.parameters(), Definition::Function(fun) => &fun.parameters, + _ => &EMPTY_VEC, } } pub fn body(&self) -> StatementId { + // TODO: Fix this match self { Definition::Component(com) => com.body(), Definition::Function(fun) => fun.body, + _ => panic!("cannot retrieve body (for EnumDefinition or StructDefinition)") } } } @@ -1705,6 +1709,8 @@ impl Definition { impl SyntaxElement for Definition { fn position(&self) -> InputPosition { match self { + Definition::Struct(def) => def.position, + Definition::Enum(def) => def.position, Definition::Component(def) => def.position(), Definition::Function(def) => def.position(), } @@ -1715,16 +1721,56 @@ impl VariableScope for Definition { fn parent_scope(&self, _h: &Heap) -> Option { None } - fn get_variable(&self, h: &Heap, id: SourceIdentifierId) -> Option { - for ¶m in self.parameters().iter() { - if h[h[param].identifier] == h[id] { - return Some(param.0); + fn get_variable(&self, h: &Heap, id: &Identifier) -> Option { + for ¶meter_id in self.parameters().iter() { + let parameter = &h[parameter_id]; + if parameter.identifier.value == id.value { + return Some(parameter_id.0); } } None } } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct StructFieldDefinition { + pub position: InputPosition, + pub field: Identifier, + pub the_type: TypeAnnotationId, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct StructDefinition { + pub this: StructId, + // Phase 1: parser + pub position: InputPosition, + pub identifier: Identifier, + pub fields: Vec +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)] +pub enum EnumVariantValue { + None, + Integer(i64), + Type(TypeAnnotationId), +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct EnumVariantDefinition { + pub position: InputPosition, + pub identifier: Identifier, + pub value: EnumVariantValue, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct EnumDefinition { + pub this: EnumId, + // Phase 1: parser + pub position: InputPosition, + pub identifier: Identifier, + pub variants: Vec, +} + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum Component { Composite(Composite), @@ -1750,10 +1796,10 @@ impl Component { _ => panic!("Unable to cast `Component` to `Primitive`"), } } - fn identifier(&self) -> SourceIdentifierId { + fn identifier(&self) -> &Identifier { match self { - Component::Composite(com) => com.identifier, - Component::Primitive(prim) => prim.identifier, + Component::Composite(com) => &com.identifier, + Component::Primitive(prim) => &prim.identifier, } } pub fn parameters(&self) -> &Vec { @@ -1784,7 +1830,7 @@ pub struct Composite { pub this: CompositeId, // Phase 1: parser pub position: InputPosition, - pub identifier: SourceIdentifierId, + pub identifier: Identifier, pub parameters: Vec, pub body: StatementId, } @@ -1800,7 +1846,7 @@ pub struct Primitive { pub this: PrimitiveId, // Phase 1: parser pub position: InputPosition, - pub identifier: SourceIdentifierId, + pub identifier: Identifier, pub parameters: Vec, pub body: StatementId, } @@ -1817,7 +1863,7 @@ pub struct Function { // Phase 1: parser pub position: InputPosition, pub return_type: TypeAnnotationId, - pub identifier: SourceIdentifierId, + pub identifier: Identifier, pub parameters: Vec, pub body: StatementId, } @@ -1841,7 +1887,7 @@ impl Declaration { Declaration::Imported(decl) => &decl.signature, } } - pub fn identifier(&self) -> IdentifierId { + pub fn identifier(&self) -> &Identifier { self.signature().identifier() } pub fn is_component(&self) -> bool { @@ -1882,16 +1928,18 @@ pub enum Signature { impl Signature { pub fn from_definition(h: &Heap, def: DefinitionId) -> Signature { + // TODO: Fix this match &h[def] { Definition::Component(com) => Signature::Component(ComponentSignature { - identifier: com.identifier().0, + identifier: com.identifier().clone(), // TODO: @fix arity: Signature::convert_parameters(h, com.parameters()), }), Definition::Function(fun) => Signature::Function(FunctionSignature { return_type: h[fun.return_type].the_type.clone(), - identifier: fun.identifier.0, + identifier: fun.identifier.clone(), // TODO: @fix arity: Signature::convert_parameters(h, &fun.parameters), }), + _ => panic!("cannot retrieve signature (for StructDefinition or EnumDefinition)") } } fn convert_parameters(h: &Heap, params: &Vec) -> Vec { @@ -1901,10 +1949,10 @@ impl Signature { } result } - fn identifier(&self) -> IdentifierId { + fn identifier(&self) -> &Identifier { match self { - Signature::Component(com) => com.identifier, - Signature::Function(fun) => fun.identifier, + Signature::Component(com) => &com.identifier, + Signature::Function(fun) => &fun.identifier, } } pub fn is_component(&self) -> bool { @@ -1923,14 +1971,14 @@ impl Signature { #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct ComponentSignature { - pub identifier: IdentifierId, + pub identifier: Identifier, pub arity: Vec, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct FunctionSignature { pub return_type: Type, - pub identifier: IdentifierId, + pub identifier: Identifier, pub arity: Vec, } @@ -2222,10 +2270,11 @@ impl VariableScope for BlockStatement { fn parent_scope(&self, _h: &Heap) -> Option { self.parent_scope } - fn get_variable(&self, h: &Heap, id: SourceIdentifierId) -> Option { - for &local in self.locals.iter() { - if h[h[local].identifier] == h[id] { - return Some(local.0); + fn get_variable(&self, h: &Heap, id: &Identifier) -> Option { + for local_id in self.locals.iter() { + let local = &h[*local_id]; + if local.identifier.value == id.value { + return Some(local_id.0); } } None @@ -2328,7 +2377,7 @@ pub struct LabeledStatement { pub this: LabeledStatementId, // Phase 1: parser pub position: InputPosition, - pub label: SourceIdentifierId, + pub label: Identifier, pub body: StatementId, // Phase 2: linker pub in_sync: Option, @@ -2407,7 +2456,7 @@ pub struct BreakStatement { pub this: BreakStatementId, // Phase 1: parser pub position: InputPosition, - pub label: Option, + pub label: Option, // Phase 2: linker pub target: Option, } @@ -2423,7 +2472,7 @@ pub struct ContinueStatement { pub this: ContinueStatementId, // Phase 1: parser pub position: InputPosition, - pub label: Option, + pub label: Option, // Phase 2: linker pub target: Option, } @@ -2455,10 +2504,11 @@ impl VariableScope for SynchronousStatement { fn parent_scope(&self, _h: &Heap) -> Option { self.parent_scope } - fn get_variable(&self, h: &Heap, id: SourceIdentifierId) -> Option { - for ¶m in self.parameters.iter() { - if h[h[param].identifier] == h[id] { - return Some(param.0); + fn get_variable(&self, h: &Heap, id: &Identifier) -> Option { + for parameter_id in self.parameters.iter() { + let parameter = &h[*parameter_id]; + if parameter.identifier.value == id.value { + return Some(parameter_id.0); } } None @@ -2514,7 +2564,7 @@ pub struct GotoStatement { pub this: GotoStatementId, // Phase 1: parser pub position: InputPosition, - pub label: SourceIdentifierId, + pub label: Identifier, // Phase 2: linker pub target: Option, } @@ -2897,7 +2947,7 @@ pub struct VariableExpression { pub this: VariableExpressionId, // Phase 1: parser pub position: InputPosition, - pub identifier: SourceIdentifierId, + pub identifier: Identifier, // Phase 2: linker pub declaration: Option, }