From d25df42a65d3fe44c722d5a1a80686cbd7e6d175 2021-03-08 09:55:18 From: MH Date: 2021-03-08 09:55:18 Subject: [PATCH] remove concept of declaration AST nodes --- diff --git a/src/protocol/ast.rs b/src/protocol/ast.rs index 0301c6def68c4e66c022f36102e4b3c9e2ebaccd..beb2f578d53544d1fa9d9847cdc9efae0ef510b5 100644 --- a/src/protocol/ast.rs +++ b/src/protocol/ast.rs @@ -81,10 +81,6 @@ define_new_ast_id!(ConstantExpressionId, ExpressionId); define_new_ast_id!(CallExpressionId, ExpressionId); define_new_ast_id!(VariableExpressionId, ExpressionId); -define_aliased_ast_id!(DeclarationId, Id); // TODO: @cleanup -define_new_ast_id!(DefinedDeclarationId, DeclarationId); -define_new_ast_id!(ImportedDeclarationId, DeclarationId); - // TODO: @cleanup - pub qualifiers can be removed once done #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct Heap { @@ -102,7 +98,6 @@ pub struct Heap { pub(crate) definitions: Arena, pub(crate) statements: Arena, pub(crate) expressions: Arena, - declarations: Arena, } impl Heap { @@ -118,7 +113,6 @@ impl Heap { definitions: Arena::new(), statements: Arena::new(), expressions: Arena::new(), - declarations: Arena::new(), } } pub fn alloc_type_annotation( @@ -440,24 +434,6 @@ impl Heap { pub fn alloc_protocol_description(&mut self, f: impl FnOnce(RootId) -> Root) -> RootId { self.protocol_descriptions.alloc_with_id(|id| f(id)) } - pub fn alloc_imported_declaration( - &mut self, - f: impl FnOnce(ImportedDeclarationId) -> ImportedDeclaration, - ) -> ImportedDeclarationId { - ImportedDeclarationId(self.declarations.alloc_with_id(|id| { - Declaration::Imported(f(ImportedDeclarationId(id))) - })) - } - pub fn alloc_defined_declaration( - &mut self, - f: impl FnOnce(DefinedDeclarationId) -> DefinedDeclaration, - ) -> DefinedDeclarationId { - DefinedDeclarationId( - self.declarations.alloc_with_id(|id| { - Declaration::Defined(f(DefinedDeclarationId(id))) - }), - ) - } } impl Index for Heap { @@ -838,13 +814,6 @@ impl IndexMut for Heap { } } -impl Index for Heap { - type Output = Declaration; - fn index(&self, index: DeclarationId) -> &Self::Output { - &self.declarations[index] - } -} - #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct Root { pub this: RootId, @@ -853,8 +822,6 @@ pub struct Root { pub pragmas: Vec, pub imports: Vec, pub definitions: Vec, - // Pase 2: linker - pub declarations: Vec, } impl Root { @@ -866,25 +833,6 @@ impl Root { } None } - 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 - } - pub fn get_declaration_namespaced(&self, h: &Heap, id: &NamespacedIdentifier) -> Option { - for declaration_id in self.declarations.iter() { - let declaration = &h[*declaration_id]; - // TODO: @fixme - if declaration.identifier().value == id.value { - return Some(*declaration_id); - } - } - None - } } impl SyntaxElement for Root { @@ -1555,52 +1503,6 @@ impl SyntaxElement for Function { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub enum Declaration { - Defined(DefinedDeclaration), - Imported(ImportedDeclaration), -} - -impl Declaration { - pub fn signature(&self) -> &Signature { - match self { - Declaration::Defined(decl) => &decl.signature, - Declaration::Imported(decl) => &decl.signature, - } - } - pub fn identifier(&self) -> &Identifier { - self.signature().identifier() - } - pub fn is_component(&self) -> bool { - self.signature().is_component() - } - pub fn is_function(&self) -> bool { - self.signature().is_function() - } - pub fn as_defined(&self) -> &DefinedDeclaration { - match self { - Declaration::Defined(result) => result, - _ => panic!("Unable to cast `Declaration` to `DefinedDeclaration`"), - } - } -} - -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct DefinedDeclaration { - pub this: DefinedDeclarationId, - // Phase 2: linker - pub definition: DefinitionId, - pub signature: Signature, -} - -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct ImportedDeclaration { - pub this: ImportedDeclarationId, - // Phase 2: linker - pub import: ImportId, - pub signature: Signature, -} - #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum Signature { Component(ComponentSignature), diff --git a/src/protocol/ast_printer.rs b/src/protocol/ast_printer.rs index 84ca2c509b5c34e2a88e560859b7b9e403161cd9..2bd329753b8eb5b381484b4f8d1a6948f0b739d4 100644 --- a/src/protocol/ast_printer.rs +++ b/src/protocol/ast_printer.rs @@ -2,7 +2,6 @@ use std::fmt::{Debug, Display, Write}; use std::io::Write as IOWrite; use super::ast::*; -use std::borrow::Borrow; const INDENT: usize = 2; diff --git a/src/protocol/lexer.rs b/src/protocol/lexer.rs index 00407f726ef22a859e6df437db94fe793f7243f3..dd4cf28037a2be43a03cfdab7ab94740b8170131 100644 --- a/src/protocol/lexer.rs +++ b/src/protocol/lexer.rs @@ -2050,7 +2050,6 @@ impl Lexer<'_> { pragmas, imports, definitions, - declarations: Vec::new(), })) } } @@ -2058,7 +2057,7 @@ impl Lexer<'_> { #[cfg(test)] mod tests { use crate::protocol::ast::*; - use crate::protocol::{ast, lexer::*}; + use crate::protocol::lexer::*; use crate::protocol::inputsource::*; #[test] diff --git a/src/protocol/library.rs b/src/protocol/library.rs deleted file mode 100644 index 76a4f52d86cef48b13ff687ee7e385c6e2f258e5..0000000000000000000000000000000000000000 --- a/src/protocol/library.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::protocol::ast::*; -use crate::protocol::inputsource::*; - -// TABBED OUT FOR NOW - -pub fn get_declarations(_h: &mut Heap, _i: ImportId) -> Result, ParseError2> { - todo!("implement me"); - // if h[i].value == b"std.reo" { - // let mut vec = Vec::new(); - // vec.push(cd(h, i, b"sync", &[Type::INPUT, Type::OUTPUT])); - // vec.push(cd(h, i, b"syncdrain", &[Type::INPUT, Type::INPUT])); - // vec.push(cd(h, i, b"syncspout", &[Type::OUTPUT, Type::OUTPUT])); - // vec.push(cd(h, i, b"asyncdrain", &[Type::INPUT, Type::INPUT])); - // vec.push(cd(h, i, b"asyncspout", &[Type::OUTPUT, Type::OUTPUT])); - // vec.push(cd(h, i, b"merger", &[Type::INPUT_ARRAY, Type::OUTPUT])); - // vec.push(cd(h, i, b"router", &[Type::INPUT, Type::OUTPUT_ARRAY])); - // vec.push(cd(h, i, b"consensus", &[Type::INPUT_ARRAY, Type::OUTPUT])); - // vec.push(cd(h, i, b"replicator", &[Type::INPUT, Type::OUTPUT_ARRAY])); - // vec.push(cd(h, i, b"alternator", &[Type::INPUT_ARRAY, Type::OUTPUT])); - // vec.push(cd(h, i, b"roundrobin", &[Type::INPUT, Type::OUTPUT_ARRAY])); - // vec.push(cd(h, i, b"node", &[Type::INPUT_ARRAY, Type::OUTPUT_ARRAY])); - // vec.push(cd(h, i, b"fifo", &[Type::INPUT, Type::OUTPUT])); - // vec.push(cd(h, i, b"xfifo", &[Type::INPUT, Type::OUTPUT, Type::MESSAGE])); - // vec.push(cd(h, i, b"nfifo", &[Type::INPUT, Type::OUTPUT, Type::INT])); - // vec.push(cd(h, i, b"ufifo", &[Type::INPUT, Type::OUTPUT])); - // Ok(vec) - // } else if h[i].value == b"std.buf" { - // let mut vec = Vec::new(); - // vec.push(fd(h, i, b"writeByte", Type::BYTE, &[Type::MESSAGE, Type::INT, Type::BYTE])); - // vec.push(fd(h, i, b"writeShort", Type::SHORT, &[Type::MESSAGE, Type::INT, Type::SHORT])); - // vec.push(fd(h, i, b"writeInt", Type::INT, &[Type::MESSAGE, Type::INT, Type::INT])); - // vec.push(fd(h, i, b"writeLong", Type::LONG, &[Type::MESSAGE, Type::INT, Type::LONG])); - // vec.push(fd(h, i, b"readByte", Type::BYTE, &[Type::MESSAGE, Type::INT])); - // vec.push(fd(h, i, b"readShort", Type::SHORT, &[Type::MESSAGE, Type::INT])); - // vec.push(fd(h, i, b"readInt", Type::INT, &[Type::MESSAGE, Type::INT])); - // vec.push(fd(h, i, b"readLong", Type::LONG, &[Type::MESSAGE, Type::INT])); - // Ok(vec) - // } else { - // Err(ParseError::new(h[i].position, "Unknown import")) - // } -} -// -// fn cd(h: &mut Heap, import: ImportId, ident: &[u8], sig: &[Type]) -> DeclarationId { -// let identifier = h.get_external_identifier(ident).upcast(); -// h.alloc_imported_declaration(|this| ImportedDeclaration { -// this, -// import, -// signature: Signature::Component(ComponentSignature { identifier, arity: sig.to_vec() }), -// }) -// .upcast() -// } -// -// fn fd(h: &mut Heap, import: ImportId, ident: &[u8], ret: Type, sig: &[Type]) -> DeclarationId { -// let identifier = h.get_external_identifier(ident).upcast(); -// h.alloc_imported_declaration(|this| ImportedDeclaration { -// this, -// import, -// signature: Signature::Function(FunctionSignature { -// return_type: ret, -// identifier, -// arity: sig.to_vec(), -// }), -// }) -// .upcast() -// } diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index b924e736d9117e819a062c566db23a2499297351..4035bfc1246afdca8ccc6ba33705861876524214 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -3,7 +3,6 @@ mod arena; mod eval; pub(crate) mod inputsource; // mod lexer; -mod library; mod parser; // TODO: Remove when not benchmarking diff --git a/src/protocol/parser/depth_visitor.rs b/src/protocol/parser/depth_visitor.rs index b3792213d2fdb11780d8eafe99aca7284fde1626..e344609f72ad651c643aba0b48b9652c3f08a4ae 100644 --- a/src/protocol/parser/depth_visitor.rs +++ b/src/protocol/parser/depth_visitor.rs @@ -1,6 +1,5 @@ use crate::protocol::ast::*; use crate::protocol::inputsource::*; -use crate::protocol::library; // The following indirection is needed due to a bug in the cbindgen tool. type Unit = (); @@ -780,142 +779,6 @@ impl Visitor for CheckBuiltinOccurrences { } } -pub(crate) struct BuildSymbolDeclarations { - declarations: Vec, -} - -impl BuildSymbolDeclarations { - pub(crate) fn new() -> Self { - BuildSymbolDeclarations { declarations: Vec::new() } - } - fn checked_add(&mut self, h: &mut Heap, decl: DeclarationId) -> VisitorResult { - for &old in self.declarations.iter() { - let id = h[decl].identifier(); - if id.value == h[old].identifier().value { - return match h[decl].clone() { - Declaration::Defined(defined) => Err(( - h[defined.definition].position(), - format!("Defined symbol clash: {}", String::from_utf8_lossy(&id.value)), - )), - Declaration::Imported(imported) => Err(( - h[imported.import].position(), - format!("Imported symbol clash: {}", String::from_utf8_lossy(&id.value)), - )), - }; - } - } - self.declarations.push(decl); - Ok(()) - } -} - -impl Visitor for BuildSymbolDeclarations { - fn visit_protocol_description(&mut self, h: &mut Heap, pd: RootId) -> VisitorResult { - recursive_protocol_description(self, h, pd)?; - // Move all collected declarations to the protocol description - h[pd].declarations.append(&mut self.declarations); - Ok(()) - } - fn visit_import(&mut self, h: &mut Heap, import: ImportId) -> VisitorResult { - // println!("DEBUG: Warning (at {}:{}), import actually not yet implemented", file!(), line!()); - // TODO: Implement - let vec = library::get_declarations(h, import); - if let Err(_err)= vec { - return Err((h[import].position(), "Failed to perform import".to_string())) - } - - // Destructively iterate over the vector - for decl in vec.unwrap() { - self.checked_add(h, decl)?; - } - Ok(()) - } - fn visit_symbol_definition(&mut self, h: &mut Heap, definition: DefinitionId) -> VisitorResult { - let signature = Signature::from_definition(h, definition); - let decl = h - .alloc_defined_declaration(|this| DefinedDeclaration { this, definition, signature }) - .upcast(); - self.checked_add(h, decl)?; - Ok(()) - } -} - -pub(crate) struct LinkCallExpressions { - pd: Option, - composite: bool, - new_statement: bool, -} - -impl LinkCallExpressions { - pub(crate) fn new() -> Self { - LinkCallExpressions { pd: None, composite: false, new_statement: false } - } - fn get_declaration( - &self, - h: &Heap, - id: &Identifier, - ) -> Result { - match h[self.pd.unwrap()].get_declaration(h, &id) { - Some(id) => Ok(id), - None => Err((id.position, "Unresolved method".to_string())), - } - } - fn get_declaration_namespaced( - &self, h: &Heap, id: &NamespacedIdentifier - ) -> Result { - // TODO: @fixme - match h[self.pd.unwrap()].get_declaration_namespaced(h, id) { - Some(id) => Ok(id), - None => Err((id.position, "Unresolved method".to_string())) - } - } -} - -impl Visitor for LinkCallExpressions { - fn visit_protocol_description(&mut self, h: &mut Heap, pd: RootId) -> VisitorResult { - self.pd = Some(pd); - recursive_protocol_description(self, h, pd)?; - self.pd = None; - Ok(()) - } - fn visit_composite_definition(&mut self, h: &mut Heap, def: ComponentId) -> VisitorResult { - assert!(!self.composite); - self.composite = true; - recursive_composite_definition(self, h, def)?; - self.composite = false; - Ok(()) - } - fn visit_new_statement(&mut self, h: &mut Heap, stmt: NewStatementId) -> VisitorResult { - assert!(self.composite); - assert!(!self.new_statement); - self.new_statement = true; - recursive_new_statement(self, h, stmt)?; - self.new_statement = false; - Ok(()) - } - fn visit_call_expression(&mut self, h: &mut Heap, expr: CallExpressionId) -> VisitorResult { - if let Method::Symbolic(id) = &h[expr].method { - // TODO: @symbol_table - let decl = self.get_declaration_namespaced(h, &id.identifier)?; - if self.new_statement && h[decl].is_function() { - return Err((id.identifier.position, "Illegal call expression".to_string())); - } - if !self.new_statement && h[decl].is_component() { - return Err((id.identifier.position, "Illegal call expression".to_string())); - } - // Set the corresponding declaration of the call - // TODO: This should not be necessary anymore once parser is rewritten - // h[expr]. = Some(decl); - } - // A new statement's call expression may have as arguments function calls - let old = self.new_statement; - self.new_statement = false; - recursive_call_expression(self, h, expr)?; - self.new_statement = old; - Ok(()) - } -} - pub(crate) struct BuildScope { scope: Option, } @@ -968,145 +831,6 @@ impl Visitor for BuildScope { } } -pub(crate) struct ResolveVariables { - scope: Option, -} - -impl ResolveVariables { - pub(crate) fn new() -> Self { - ResolveVariables { scope: None } - } - fn get_variable(&self, h: &Heap, id: &Identifier) -> Result { - if let Some(var) = self.find_variable(h, id) { - Ok(var) - } else { - Err((id.position, "Unresolved variable".to_string())) - } - } - fn find_variable(&self, h: &Heap, id: &Identifier) -> Option { - ResolveVariables::find_variable_impl(h, self.scope, id) - } - fn find_variable_impl( - h: &Heap, - scope: Option, - id: &Identifier, - ) -> Option { - if let Some(scope) = scope { - // The order in which we check for variables is important: - // otherwise, two variables with the same name are shadowed. - if let Some(var) = ResolveVariables::find_variable_impl(h, scope.parent_scope(h), id) { - Some(var) - } else { - scope.get_variable(h, id) - } - } else { - None - } - } -} - -impl Visitor for ResolveVariables { - fn visit_symbol_definition(&mut self, h: &mut Heap, def: DefinitionId) -> VisitorResult { - assert!(self.scope.is_none()); - self.scope = Some(Scope::Definition(def)); - recursive_symbol_definition(self, h, def)?; - self.scope = None; - Ok(()) - } - fn visit_variable_declaration(&mut self, h: &mut Heap, decl: VariableId) -> VisitorResult { - // This is only called for parameters of definitions and synchronous statements, - // since the local variables of block statements are still empty - // the moment it is traversed. After resolving variables, this - // function is also called for every local variable declaration. - - // We want to make sure that the resolved variable is the variable declared itself; - // otherwise, there is some variable defined in the parent scope. This check - // imposes that the order in which find_variable looks is significant! - let id = h[decl].identifier(); - let check_same = self.find_variable(h, id); - if let Some(check_same) = check_same { - if check_same != decl { - return Err((id.position, "Declared variable clash".to_string())); - } - } - recursive_variable_declaration(self, h, decl) - } - fn visit_memory_statement(&mut self, h: &mut Heap, stmt: MemoryStatementId) -> VisitorResult { - assert!(!self.scope.is_none()); - let var = h[stmt].variable; - let id = &h[var].identifier; - // First check whether variable with same identifier is in scope - let check_duplicate = self.find_variable(h, id); - if check_duplicate.is_some() { - return Err((id.position, "Declared variable clash".to_string())); - } - // Then check the expression's variables (this should not refer to own variable) - recursive_memory_statement(self, h, stmt)?; - // Finally, we may add the variable to the scope, which is guaranteed to be a block - { - let block = &mut h[self.scope.unwrap().to_block()]; - block.locals.push(var); - } - Ok(()) - } - fn visit_channel_statement(&mut self, h: &mut Heap, stmt: ChannelStatementId) -> VisitorResult { - assert!(!self.scope.is_none()); - // First handle the from variable - { - let var = h[stmt].from; - let id = &h[var].identifier; - let check_duplicate = self.find_variable(h, id); - if check_duplicate.is_some() { - return Err((id.position, "Declared variable clash".to_string())); - } - let block = &mut h[self.scope.unwrap().to_block()]; - block.locals.push(var); - } - // Then handle the to variable (which may not be the same as the from) - { - let var = h[stmt].to; - let id = &h[var].identifier; - let check_duplicate = self.find_variable(h, id); - if check_duplicate.is_some() { - return Err((id.position, "Declared variable clash".to_string())); - } - let block = &mut h[self.scope.unwrap().to_block()]; - block.locals.push(var); - } - Ok(()) - } - fn visit_block_statement(&mut self, h: &mut Heap, stmt: BlockStatementId) -> VisitorResult { - assert!(!self.scope.is_none()); - let old = self.scope; - self.scope = Some(Scope::Regular(stmt)); - recursive_block_statement(self, h, stmt)?; - self.scope = old; - Ok(()) - } - fn visit_synchronous_statement( - &mut self, - h: &mut Heap, - stmt: SynchronousStatementId, - ) -> VisitorResult { - assert!(!self.scope.is_none()); - let old = self.scope; - self.scope = Some(Scope::Synchronous((stmt, BlockStatementId(stmt.upcast())))); // TODO: WRONG! - recursive_synchronous_statement(self, h, stmt)?; - self.scope = old; - Ok(()) - } - fn visit_variable_expression( - &mut self, - h: &mut Heap, - expr: VariableExpressionId, - ) -> VisitorResult { - let ident = Identifier{ position: Default::default(), value: h[expr].identifier.value.clone() }; - let var = self.get_variable(h, &ident)?; - h[expr].declaration = Some(var); - Ok(()) - } -} - pub(crate) struct UniqueStatementId(StatementId); pub(crate) struct LinkStatements { diff --git a/src/protocol/parser/mod.rs b/src/protocol/parser/mod.rs index a16c39a9b30955d01c309822c3f29022194dc703..96f187554c6f63d8e39d92ce52b4444891d61ac9 100644 --- a/src/protocol/parser/mod.rs +++ b/src/protocol/parser/mod.rs @@ -16,7 +16,6 @@ use crate::protocol::inputsource::*; use crate::protocol::lexer::*; use std::collections::HashMap; -use crate::protocol::parser::visitor::Ctx; use crate::protocol::ast_printer::ASTWriter; // TODO: @fixme, pub qualifier