diff --git a/src/protocol/ast.rs b/src/protocol/ast.rs index 262007e63b782f2f69c37715b75092771cd0388a..504ab1513d281316bd0e88d13b3d33ece5393364 100644 --- a/src/protocol/ast.rs +++ b/src/protocol/ast.rs @@ -5,25 +5,26 @@ use std::ops::{Index, IndexMut}; use super::arena::{Arena, Id}; // use super::containers::StringAllocator; +// TODO: @cleanup, transform wrapping types into type aliases where possible use crate::protocol::inputsource::*; #[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); +pub struct PragmaId(pub(crate) Id); #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ImportId(Id); +pub struct ImportId(pub(crate) Id); #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct TypeAnnotationId(Id); +pub struct TypeAnnotationId(pub(crate) Id); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct VariableId(Id); +pub struct VariableId(pub(crate) Id); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct ParameterId(VariableId); +pub struct ParameterId(pub(crate) VariableId); impl ParameterId { pub fn upcast(self) -> VariableId { @@ -32,7 +33,7 @@ impl ParameterId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct LocalId(VariableId); +pub struct LocalId(pub(crate) VariableId); impl LocalId { pub fn upcast(self) -> VariableId { @@ -41,10 +42,10 @@ impl LocalId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct DefinitionId(Id); +pub struct DefinitionId(pub(crate) Id); #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct StructId(DefinitionId); +pub struct StructId(pub(crate) DefinitionId); impl StructId { pub fn upcast(self) -> DefinitionId{ @@ -53,7 +54,7 @@ impl StructId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct EnumId(DefinitionId); +pub struct EnumId(pub(crate) DefinitionId); impl EnumId { pub fn upcast(self) -> DefinitionId{ @@ -62,7 +63,7 @@ impl EnumId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ComponentId(DefinitionId); +pub struct ComponentId(pub(crate) DefinitionId); impl ComponentId { pub fn upcast(self) -> DefinitionId { @@ -71,7 +72,7 @@ impl ComponentId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct FunctionId(DefinitionId); +pub struct FunctionId(pub(crate) DefinitionId); impl FunctionId { pub fn upcast(self) -> DefinitionId { @@ -80,7 +81,7 @@ impl FunctionId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct StatementId(Id); +pub struct StatementId(pub(crate) Id); #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] // TODO: Remove pub @@ -93,7 +94,7 @@ impl BlockStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct LocalStatementId(StatementId); +pub struct LocalStatementId(pub(crate) StatementId); impl LocalStatementId { pub fn upcast(self) -> StatementId { @@ -102,7 +103,7 @@ impl LocalStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct MemoryStatementId(LocalStatementId); +pub struct MemoryStatementId(pub(crate) LocalStatementId); impl MemoryStatementId { pub fn upcast(self) -> LocalStatementId { @@ -111,7 +112,7 @@ impl MemoryStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ChannelStatementId(LocalStatementId); +pub struct ChannelStatementId(pub(crate) LocalStatementId); impl ChannelStatementId { pub fn upcast(self) -> LocalStatementId { @@ -120,7 +121,7 @@ impl ChannelStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct SkipStatementId(StatementId); +pub struct SkipStatementId(pub(crate) StatementId); impl SkipStatementId { pub fn upcast(self) -> StatementId { @@ -129,7 +130,7 @@ impl SkipStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct LabeledStatementId(StatementId); +pub struct LabeledStatementId(pub(crate) StatementId); impl LabeledStatementId { pub fn upcast(self) -> StatementId { @@ -138,7 +139,7 @@ impl LabeledStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct IfStatementId(StatementId); +pub struct IfStatementId(pub(crate) StatementId); impl IfStatementId { pub fn upcast(self) -> StatementId { @@ -147,7 +148,7 @@ impl IfStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct EndIfStatementId(StatementId); +pub struct EndIfStatementId(pub(crate) StatementId); impl EndIfStatementId { pub fn upcast(self) -> StatementId { @@ -156,7 +157,7 @@ impl EndIfStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct WhileStatementId(StatementId); +pub struct WhileStatementId(pub(crate) StatementId); impl WhileStatementId { pub fn upcast(self) -> StatementId { @@ -165,7 +166,7 @@ impl WhileStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct EndWhileStatementId(StatementId); +pub struct EndWhileStatementId(pub(crate) StatementId); impl EndWhileStatementId { pub fn upcast(self) -> StatementId { @@ -174,7 +175,7 @@ impl EndWhileStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BreakStatementId(StatementId); +pub struct BreakStatementId(pub(crate) StatementId); impl BreakStatementId { pub fn upcast(self) -> StatementId { @@ -183,7 +184,7 @@ impl BreakStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ContinueStatementId(StatementId); +pub struct ContinueStatementId(pub(crate) StatementId); impl ContinueStatementId { pub fn upcast(self) -> StatementId { @@ -192,7 +193,7 @@ impl ContinueStatementId { } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct SynchronousStatementId(StatementId); +pub struct SynchronousStatementId(pub(crate) StatementId); impl SynchronousStatementId { pub fn upcast(self) -> StatementId { @@ -386,13 +387,14 @@ impl ImportedDeclarationId { } } +// TODO: @cleanup - pub qualifiers can be removed once done #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct Heap { // 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, + pub(crate) protocol_descriptions: Arena, // Contents of a file, these are the elements the `Root` elements refer to pragmas: Arena, pub(crate) imports: Arena, diff --git a/src/protocol/ast_printer.rs b/src/protocol/ast_printer.rs new file mode 100644 index 0000000000000000000000000000000000000000..3b3bed69397c541960531b11c2ebae411f07155b --- /dev/null +++ b/src/protocol/ast_printer.rs @@ -0,0 +1,353 @@ +use std::fmt::{Display, Write}; +use std::io::Write as IOWrite; + +use super::ast::*; +use std::borrow::Borrow; + +const INDENT: usize = 2; + +const PREFIX_EMPTY: &'static str = " "; +const PREFIX_ROOT_ID: &'static str = "Root"; +const PREFIX_PRAGMA_ID: &'static str = "Prag"; +const PREFIX_IMPORT_ID: &'static str = "Imp "; +const PREFIX_TYPE_ANNOT_ID: &'static str = "TyAn"; +const PREFIX_VARIABLE_ID: &'static str = "Var "; +const PREFIX_PARAMETER_ID: &'static str = "Par "; +const PREFIX_LOCAL_ID: &'static str = "Loc "; +const PREFIX_DEFINITION_ID: &'static str = "Def "; +const PREFIX_STRUCT_ID: &'static str = "DefS"; +const PREFIX_ENUM_ID: &'static str = "DefE"; +const PREFIX_COMPONENT_ID: &'static str = "DefC"; +const PREFIX_FUNCTION_ID: &'static str = "DefF"; +const PREFIX_STMT_ID: &'static str = "Stmt"; +const PREFIX_BLOCK_STMT_ID: &'static str = "SBl "; +const PREFIX_LOCAL_STMT_ID: &'static str = "SLoc"; +const PREFIX_MEM_STMT_ID: &'static str = "SMem"; +const PREFIX_CHANNEL_STMT_ID: &'static str = "SCha"; +const PREFIX_SKIP_STMT_ID: &'static str = "SSki"; +const PREFIX_LABELED_STMT_ID: &'static str = "SLab"; +const PREFIX_IF_STMT_ID: &'static str = "SIf "; +const PREFIX_ENDIF_STMT_ID: &'static str = "SEIf"; +const PREFIX_WHILE_STMT_ID: &'static str = "SWhi"; +const PREFIX_ENDWHILE_STMT_ID: &'static str = "SEWh"; +const PREFIX_BREAK_STMT_ID: &'static str = "SBre"; +const PREFIX_CONTINUE_STMT_ID: &'static str = "SCon"; +const PREFIX_SYNC_STMT_ID: &'static str = "SSyn"; +const PREFIX_ENDSYNC_STMT_ID: &'static str = "SESy"; +const PREFIX_RETURN_STMT_ID: &'static str = "SRet"; +const PREFIX_ASSERT_STMT_ID: &'static str = "SAsr"; +const PREFIX_GOTO_STMT_ID: &'static str = "SGot"; +const PREFIX_NEW_STMT_ID: &'static str = "SNew"; +const PREFIX_PUT_STMT_ID: &'static str = "SPut"; +const PREFIX_EXPR_STMT_ID: &'static str = "SExp"; +const PREFIX_ASSIGNMENT_EXPR_ID: &'static str = "EAsi"; +const PREFIX_CONDITIONAL_EXPR_ID: &'static str = "ECnd"; +const PREFIX_BINARY_EXPR_ID: &'static str = "EBin"; +const PREFIX_UNARY_EXPR_ID: &'static str = "EUna"; +const PREFIX_INDEXING_EXPR_ID: &'static str = "EIdx"; +const PREFIX_SLICING_EXPR_ID: &'static str = "ESli"; +const PREFIX_SELECT_EXPR_ID: &'static str = "ESel"; +const PREFIX_ARRAY_EXPR_ID: &'static str = "EArr"; +const PREFIX_CONST_EXPR_ID: &'static str = "ECns"; +const PREFIX_CALL_EXPR_ID: &'static str = "ECll"; +const PREFIX_VARIABLE_EXPR_ID: &'static str = "EVar"; + +pub(crate) struct ASTWriter { + buffer: String, + temp: String, +} + +impl ASTWriter { + pub(crate) fn new() -> Self { + Self{ buffer: String::with_capacity(4096), temp: String::with_capacity(256) } + } + pub(crate) fn write_ast(&mut self, w: &mut W, heap: &Heap) { + for root_id in heap.protocol_descriptions.iter().map(|v| v.this) { + self.write_module(heap, root_id); + w.write_all(self.buffer.as_bytes()).expect("flush buffer"); + self.buffer.clear(); + } + } + + //-------------------------------------------------------------------------- + // Top-level module writing + //-------------------------------------------------------------------------- + + fn write_module(&mut self, heap: &Heap, root_id: RootId) { + self.write_id_and_indent(PREFIX_ROOT_ID, root_id.0.index, 0); + self.buffer.write_str("Module:\n"); + + let root = &heap[root_id]; + + self.write_indent(0); + write!(&mut self.buffer, "- ID: {}\n", root.this.0.index); + + self.write_indent(0); + self.buffer.write_str("- Pragmas:\n"); + + for pragma_id in &root.pragmas { + self.write_pragma(&heap[*pragma_id], 1); + } + + self.write_indent(0); + self.buffer.write_str("- Imports:\n"); + + for import_id in &root.imports { + self.write_import(&heap[*import_id], 1); + } + + self.write_indent(0); + self.buffer.write_str("- Definitions:\n"); + + for definition_id in &root.definitions { + self.write_definition(heap, &heap[*definition_id], 1); + } + } + + fn write_pragma(&mut self, pragma: &Pragma, indent: usize) { + match pragma { + Pragma::Version(pragma) => { + self.write_id_and_indent(PREFIX_PRAGMA_ID, pragma.this.0.index, indent); + write!(&mut self.buffer, "- Version: {}\n", pragma.version); + }, + Pragma::Module(pragma) => { + self.write_id_and_indent(PREFIX_PRAGMA_ID, pragma.this.0.index, indent); + write!(&mut self.buffer, "- Module: {}\n", String::from_utf8_lossy(&pragma.value)); + } + } + } + + fn write_import(&mut self, import: &Import, indent: usize) { + let indent2 = indent + 1; + match import { + Import::Module(import) => { + self.write_id_and_indent(PREFIX_IMPORT_ID, import.this.0.index, indent); + write!(&mut self.buffer, "- ModuleImport:\n"); + + self.write_indent(indent2); + write!(&mut self.buffer, "- Name: {}\n", String::from_utf8_lossy(&import.module_name)); + self.write_indent(indent2); + write!(&mut self.buffer, "- Alias: {}\n", String::from_utf8_lossy(&import.alias)); + self.write_indent(indent2); + write_option(&mut self.temp, import.module_id.map(|v| v.0.index)); + write!(&mut self.buffer, "- Target: {}\n", &self.temp); + }, + Import::Symbols(import) => { + self.write_id_and_indent(PREFIX_IMPORT_ID, import.this.0.index, indent); + write!(&mut self.buffer, "- SymbolImport:\n"); + + self.write_indent(indent2); + write!(&mut self.buffer, "- Name: {}\n", String::from_utf8_lossy(&import.module_name)); + self.write_indent(indent2); + write_option(&mut self.temp, import.module_id.map(|v| v.0.index)); + write!(&mut self.buffer, "- Target: {}\n", &self.temp); + + self.write_indent(indent2); + write!(&mut self.buffer, "- Symbols:\n"); + + let indent3 = indent2 + 1; + let indent4 = indent3 + 1; + for symbol in &import.symbols { + self.write_indent(indent3); + write!(&mut self.buffer, "- AliasedSymbol:\n"); + self.write_indent(indent4); + write!(&mut self.buffer, "- Name: {}\n", String::from_utf8_lossy(&symbol.name)); + self.write_indent(indent4); + write!(&mut self.buffer, "- Alias: {}\n", String::from_utf8_lossy(&symbol.alias)); + self.write_indent(indent4); + write_option(&mut self.temp, symbol.definition_id.map(|v| v.0.index)); + write!(&mut self.buffer, "- Definition: {}\n", &self.temp); + } + } + } + } + + //-------------------------------------------------------------------------- + // Top-level definition writing + //-------------------------------------------------------------------------- + + fn write_definition(&mut self, heap: &Heap, def: &Definition, indent: usize) { + match def { + Definition::Struct(_) => todo!("implement Definition::Struct"), + Definition::Enum(_) => todo!("implement Definition::Enum"), + Definition::Function(_) => todo!("implement Definition::Function"), + Definition::Component(def) => { + self.write_id_and_indent(PREFIX_COMPONENT_ID, def.this.0.0.index, indent); + write!(&mut self.buffer, "- Component:\n"); + + let indent2 = indent + 1; + let indent3 = indent2 + 1; + let indent4 = indent3 + 1; + self.write_indent(indent2); + write!(&mut self.buffer, "- Name: {}\n", String::from_utf8_lossy(&def.identifier.value)); + self.write_indent(indent2); + write!(&mut self.buffer, "- Variant: {:?}\n", &def.variant); + self.write_indent(indent2); + write!(&mut self.buffer, "- Parameters:\n"); + + for parameter_id in &def.parameters { + let param = &heap[*parameter_id]; + self.write_indent(indent3); + write!(&mut self.buffer, "- Parameter\n"); + + self.write_indent(indent4); + write!(&mut self.buffer, "- Name: {}\n", String::from_utf8_lossy(¶m.identifier.value)); + self.write_indent(indent4); + write!(&mut self.buffer, "- Type: "); + write_type(&mut self.buffer, &heap[param.type_annotation]); + self.buffer.push('\n'); + } + + self.write_indent(indent2); + write!(&mut self.buffer, "- Body:\n"); + + self.write_stmt(heap, def.body, indent3); + } + } + } + + fn write_stmt(&mut self, heap: &Heap, stmt_id: StatementId, indent: usize) { + let stmt = &heap[stmt_id]; + + match stmt { + Statement::Block(stmt) => { + self.write_id_and_indent(PREFIX_BLOCK_STMT_ID, stmt.this.0.0.index, indent); + write!(&mut self.buffer, "- Block:\n"); + for stmt_id in &stmt.statements { + self.write_stmt(heap, *stmt_id, indent + 1); + } + }, + Statement::Local(stmt) => { + match stmt { + LocalStatement::Channel(stmt) => { + self.write_id_and_indent(PREFIX_CHANNEL_STMT_ID, stmt.this.0.0.0.index, indent); + write!(&mut self.buffer, "- Channel:\n"); + + let indent2 = indent + 1; + let indent3 = indent2 + 1; + let from = &heap[stmt.from]; + self.write_id_and_indent(PREFIX_LOCAL_ID, stmt.from.0.0.index, indent2); + }, + LocalStatement::Memory(stmt) => { + + } + } + }, + Statement::Skip(stmt) => { + self.write_id_and_indent(PREFIX_SKIP_STMT_ID, stmt.this.0.0.index, indent); + write!(&mut self.buffer, "- Skip\n"); + }, + Statement::Labeled(stmt) => { + self.write_id_and_indent(PREFIX_LABELED_STMT_ID, stmt.this.0.0.index, indent); + write!(&mut self.buffer, "- LabeledStatement\n"); + + let indent1 = indent + 1; + let indent2 = indent + 2; + self.write_indent(indent1); + write!(&mut self.buffer, "- Label: {}\n", String::from_utf8_lossy(&stmt.label.value)); + self.write_indent(indent1); + write!(&mut self.buffer, "- Statement:\n"); + self.write_stmt(heap, stmt.body, indent2); + }, + Statement::If(stmt) => { + + }, + Statement::EndIf(stmt) => { + + }, + Statement::While(stmt) => { + + }, + Statement::EndWhile(stmt) => { + + }, + Statement::Break(stmt) => { + + }, + Statement::Continue(stmt) => { + + }, + Statement::Synchronous(stmt) => { + + }, + Statement::EndSynchronous(stmt) => { + + }, + Statement::Return(stmt) => { + + }, + Statement::Assert(stmt) => { + + }, + Statement::Goto(stmt) => { + + }, + Statement::New(stmt) => { + + }, + Statement::Put(stmt) => { + + }, + Statement::Expression(stmt) => { + + } + } + } + + fn write_local(&mut self, heap: &Heap, local_id: LocalId, indent: usize) { + o + } + + //-------------------------------------------------------------------------- + // Printing Utilities + //-------------------------------------------------------------------------- + + fn write_id_and_indent(&mut self, prefix: &'static str, id: u32, indent: usize) { + write!(&mut self.buffer, "{}[{:04}] ", prefix, id); + for _ in 0..indent*INDENT { + self.buffer.push(' '); + } + } + + fn write_indent(&mut self, indent: usize) { + write!(&mut self.buffer, "{} ", PREFIX_EMPTY); + for _ in 0..indent*INDENT { + self.buffer.push(' '); + } + } + + fn flush(&mut self, w: &mut W) { + w.write(self.buffer.as_bytes()).unwrap(); + self.buffer.clear() + } +} + +fn write_option(target: &mut String, value: Option) { + target.clear(); + match &value { + Some(v) => write!(target, "Some({})", v), + None => target.write_str("None") + }; +} + +fn write_type(target: &mut String, t: &TypeAnnotation) { + match &t.the_type.primitive { + PrimitiveType::Input => target.write_str("in"), + PrimitiveType::Output => target.write_str("out"), + PrimitiveType::Message => target.write_str("msg"), + PrimitiveType::Boolean => target.write_str("bool"), + PrimitiveType::Byte => target.write_str("byte"), + PrimitiveType::Short => target.write_str("short"), + PrimitiveType::Int => target.write_str("int"), + PrimitiveType::Long => target.write_str("long"), + PrimitiveType::Symbolic(symbolic) => { + let mut temp = String::new(); + write_option(&mut temp, symbolic.definition.map(|v| v.0.index)); + write!(target, "Symbolic(name: {}, target: {})", String::from_utf8_lossy(&symbolic.identifier.value), &temp); + } + }; + + if t.the_type.array { + target.push_str("[]"); + } +} \ No newline at end of file diff --git a/src/protocol/inputsource.rs b/src/protocol/inputsource.rs index 60fa628ebe50cf27f3e786243d29465c3f0359f0..8e25f7d6e655d53d4d8926da1dc864e07a52160a 100644 --- a/src/protocol/inputsource.rs +++ b/src/protocol/inputsource.rs @@ -212,8 +212,6 @@ pub struct ParseErrorStatement { impl ParseErrorStatement { fn from_source(error_type: ParseErrorType, source: &InputSource, position: InputPosition, msg: &str) -> Self { // Seek line start and end - println!("DEBUG[1]:\nPos {}, msg: {},\nDEBUG[2]: In source:\n{}", - position, msg, String::from_utf8_lossy(&source.input)); debug_assert!(position.column < position.offset); let line_start = position.offset - (position.column - 1); let mut line_end = position.offset; diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 23199e60e19c0e195d3ee1f26a3f2255cbf3db7a..b924e736d9117e819a062c566db23a2499297351 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -8,6 +8,7 @@ mod parser; // TODO: Remove when not benchmarking pub(crate) mod ast; +pub(crate) mod ast_printer; pub(crate) mod lexer; lazy_static::lazy_static! { @@ -61,6 +62,7 @@ impl ProtocolDescription { return Ok(ProtocolDescription { heap: parser.heap, source: parser.modules[0].source.clone(), root }); } Err(err) => { + println!("ERROR:\n{}", err); Err(format!("{}", err)) } } diff --git a/src/protocol/parser/depth_visitor.rs b/src/protocol/parser/depth_visitor.rs index 0f48122a628aa8184bcaaf15a2efc675910acddd..cacb73667ea698069aad629d4cbce42b7fd6693d 100644 --- a/src/protocol/parser/depth_visitor.rs +++ b/src/protocol/parser/depth_visitor.rs @@ -315,7 +315,8 @@ fn recursive_statement(this: &mut T, h: &mut Heap, stmt: StatementId Statement::Put(stmt) => this.visit_put_statement(h, stmt.this), Statement::Expression(stmt) => this.visit_expression_statement(h, stmt.this), Statement::EndSynchronous(_) | Statement::EndWhile(_) | Statement::EndIf(_) => { - unreachable!() // pseudo-statement + // unreachable!() // pseudo-statement + Ok(()) } } } diff --git a/src/protocol/parser/mod.rs b/src/protocol/parser/mod.rs index 564e441db1612c0543020e12cb1c093dc00dceec..844cd3f795a1d968dc7ef501134d448d0a465337 100644 --- a/src/protocol/parser/mod.rs +++ b/src/protocol/parser/mod.rs @@ -15,6 +15,7 @@ use crate::protocol::lexer::*; use std::collections::HashMap; use crate::protocol::parser::visitor::Ctx; +use crate::protocol::ast_printer::ASTWriter; // TODO: @fixme, pub qualifier pub(crate) struct LexedModule { @@ -210,6 +211,10 @@ impl Parser { return Err(err) } + let mut writer = ASTWriter::new(); + let mut file = std::fs::File::create(std::path::Path::new("ast.txt")).unwrap(); + writer.write_ast(&mut file, &self.heap); + if let Err((position, message)) = Self::parse_inner(&mut self.heap, root_id) { return Err(ParseError2::new_error(&self.modules[0].source, position, &message)) } @@ -219,15 +224,15 @@ impl Parser { pub fn parse_inner(h: &mut Heap, pd: RootId) -> VisitorResult { // TODO: @cleanup, slowly phasing out old compiler - NestedSynchronousStatements::new().visit_protocol_description(h, pd)?; - ChannelStatementOccurrences::new().visit_protocol_description(h, pd)?; - FunctionStatementReturns::new().visit_protocol_description(h, pd)?; - ComponentStatementReturnNew::new().visit_protocol_description(h, pd)?; - CheckBuiltinOccurrences::new().visit_protocol_description(h, pd)?; - BuildSymbolDeclarations::new().visit_protocol_description(h, pd)?; + // NestedSynchronousStatements::new().visit_protocol_description(h, pd)?; + // ChannelStatementOccurrences::new().visit_protocol_description(h, pd)?; + // FunctionStatementReturns::new().visit_protocol_description(h, pd)?; + // ComponentStatementReturnNew::new().visit_protocol_description(h, pd)?; + // CheckBuiltinOccurrences::new().visit_protocol_description(h, pd)?; + // BuildSymbolDeclarations::new().visit_protocol_description(h, pd)?; LinkCallExpressions::new().visit_protocol_description(h, pd)?; - BuildScope::new().visit_protocol_description(h, pd)?; - ResolveVariables::new().visit_protocol_description(h, pd)?; + // BuildScope::new().visit_protocol_description(h, pd)?; + // ResolveVariables::new().visit_protocol_description(h, pd)?; LinkStatements::new().visit_protocol_description(h, pd)?; // BuildLabels::new().visit_protocol_description(h, pd)?; // ResolveLabels::new().visit_protocol_description(h, pd)?; diff --git a/src/protocol/parser/visitor.rs b/src/protocol/parser/visitor.rs index a022f728e9aaf7ec1aafc48079a3bf17f6f3c045..b8c169565291bf0b003447df394092a99e4359b8 100644 --- a/src/protocol/parser/visitor.rs +++ b/src/protocol/parser/visitor.rs @@ -867,15 +867,15 @@ impl ValidityAndLinkerVisitor { fn visit_block_stmt_with_hint(&mut self, ctx: &mut Ctx, id: BlockStatementId, hint: Option) -> VisitorResult { if self.performing_breadth_pass { - // Our parent is performing a breadth-pass. We do this simple stuff - // here - let body = &mut ctx.heap[id]; - body.parent_scope = self.cur_scope.clone(); - body.relative_pos_in_parent = self.relative_pos_in_block; - + // Performing a breadth pass, so don't traverse into the statements + // of the block. return Ok(()) } + let body = &mut ctx.heap[id]; + body.parent_scope = self.cur_scope.clone(); + body.relative_pos_in_parent = self.relative_pos_in_block; + // We may descend into children of this block. However, this is // where we first perform a breadth-first pass // TODO: This is where crap goes wrong! If we are performing the first @@ -963,7 +963,9 @@ impl ValidityAndLinkerVisitor { // Position check in case another variable with the same name // is defined in a higher-level scope, but later than the scope // in which the current variable resides. - if local_relative_pos > other_local.relative_pos_in_block && local.identifier.value == other_local.identifier.value { + if local.this != *other_local_id && + local_relative_pos >= other_local.relative_pos_in_block && + local.identifier.value == other_local.identifier.value { // Collision within this scope return Err( ParseError2::new_error(&ctx.module.source, local.position, "Local variable name conflicts with another variable") @@ -1017,12 +1019,10 @@ impl ValidityAndLinkerVisitor { // No need to use iterator over namespaces if here let mut scope = self.cur_scope.as_ref().unwrap(); loop { - println!("DEBUG: Looking at block {}...", scope.); debug_assert!(scope.is_block()); let block = &ctx.heap[scope.to_block()]; for local_id in &block.locals { let local = &ctx.heap[*local_id]; - println!("DEBUG: With local {}", String::from_utf8_lossy(&local.identifier.value)); if local.relative_pos_in_block < relative_pos && local.identifier.value == identifier.value { return Ok(local_id.upcast()); }