diff --git a/src/protocol/ast.rs b/src/protocol/ast.rs index 2cf4fc0e434bc25cf1a4035461e4854d9bc90739..262007e63b782f2f69c37715b75092771cd0388a 100644 --- a/src/protocol/ast.rs +++ b/src/protocol/ast.rs @@ -83,7 +83,8 @@ impl FunctionId { pub struct StatementId(Id); #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BlockStatementId(StatementId); +// TODO: Remove pub +pub struct BlockStatementId(pub StatementId); impl BlockStatementId { pub fn upcast(self) -> StatementId { @@ -818,6 +819,12 @@ impl Index for Heap { } } +impl IndexMut for Heap { + fn index_mut(&mut self, index: LocalId) -> &mut Self::Output { + self.variables[index.0.0].as_local_mut() + } +} + impl Index for Heap { type Output = Definition; fn index(&self, index: DefinitionId) -> &Self::Output { @@ -913,6 +920,12 @@ impl Index for Heap { } } +impl IndexMut for Heap { + fn index_mut(&mut self, index: IfStatementId) -> &mut Self::Output { + self.statements[(index.0).0].as_if_mut() + } +} + impl Index for Heap { type Output = EndIfStatement; fn index(&self, index: EndIfStatementId) -> &Self::Output { @@ -1527,30 +1540,24 @@ impl Field { } #[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)] -pub enum ScopeVariant { +pub enum Scope { Definition(DefinitionId), Regular(BlockStatementId), Synchronous((SynchronousStatementId, BlockStatementId)), } -// TODO: Cleanup -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct Scope { - pub variant: ScopeVariant -} - impl Scope { pub fn is_block(&self) -> bool { - match &self.variant { - ScopeVariant::Definition(_) => false, - ScopeVariant::Regular(_) => true, - ScopeVariant::Synchronous(_) => true, + match &self { + Scope::Definition(_) => false, + Scope::Regular(_) => true, + Scope::Synchronous(_) => true, } } pub fn to_block(&self) -> BlockStatementId { - match &self.variant { - ScopeVariant::Regular(id) => *id, - ScopeVariant::Synchronous((_, id)) => *id, + match &self { + Scope::Regular(id) => *id, + Scope::Synchronous((_, id)) => *id, _ => panic!("unable to get BlockStatement from Scope") } } @@ -1565,15 +1572,15 @@ impl VariableScope for Scope { fn parent_scope(&self, h: &Heap) -> Option { match self { Scope::Definition(def) => h[*def].parent_scope(h), - Scope::Block(stmt) => h[*stmt].parent_scope(h), - Scope::Synchronous(stmt) => h[*stmt].parent_scope(h), + Scope::Regular(stmt) => h[*stmt].parent_scope(h), + Scope::Synchronous((stmt, _)) => h[*stmt].parent_scope(h), } } 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), - Scope::Synchronous(stmt) => h[*stmt].get_variable(h, id), + Scope::Regular(stmt) => h[*stmt].get_variable(h, id), + Scope::Synchronous((stmt, _)) => h[*stmt].get_variable(h, id), } } } @@ -1609,6 +1616,12 @@ impl Variable { _ => panic!("Unable to cast `Variable` to `Local`"), } } + pub fn as_local_mut(&mut self) -> &mut Local { + match self { + Variable::Local(result) => result, + _ => panic!("Unable to cast 'Variable' to 'Local'"), + } + } pub fn the_type<'b>(&self, h: &'b Heap) -> &'b Type { match self { Variable::Parameter(param) => &h[param.type_annotation].the_type, @@ -2019,6 +2032,12 @@ impl Statement { _ => panic!("Unable to cast `Statement` to `IfStatement`"), } } + pub fn as_if_mut(&mut self) -> &mut IfStatement { + match self { + Statement::If(result) => result, + _ => panic!("Unable to cast 'Statement' to 'IfStatement'"), + } + } pub fn as_end_if(&self) -> &EndIfStatement { match self { Statement::EndIf(result) => result, @@ -2207,7 +2226,7 @@ impl BlockStatement { // parent block. None } - Scope::Synchronous(parent) => { + Scope::Synchronous((parent, _)) => { // It is always the case that when this function is called, // the parent of a synchronous statement is a block statement: // nested synchronous statements are flagged illegal, @@ -2215,7 +2234,7 @@ impl BlockStatement { // creates the parent_scope references in the first place. Some(h[parent].parent_scope(h).unwrap().to_block()) } - Scope::Block(parent) => { + Scope::Regular(parent) => { // A variable scope is either a definition, sync, or block. Some(parent) } @@ -2413,7 +2432,7 @@ impl SyntaxElement for WhileStatement { pub struct EndWhileStatement { pub this: EndWhileStatementId, // Phase 2: linker - pub start_while: Option, + pub start_while: WhileStatementId, pub position: InputPosition, // of corresponding while pub next: Option, } @@ -2478,13 +2497,14 @@ impl VariableScope for SynchronousStatement { fn parent_scope(&self, _h: &Heap) -> Option { self.parent_scope.clone() } - 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); - } - } + fn get_variable(&self, _h: &Heap, _id: &Identifier) -> Option { + // TODO: Another case of "where was this used for?" + // for parameter_id in self.parameters.iter() { + // let parameter = &h[*parameter_id]; + // if parameter.identifier.value == id.value { + // return Some(parameter_id.0); + // } + // } None } }