From 811e0bec1c0f1cfe706cad0b4415f262c4dafad3 2022-02-03 15:38:40 From: MH Date: 2022-02-03 15:38:40 Subject: [PATCH] Initial setup of tree rewriting --- diff --git a/src/protocol/ast.rs b/src/protocol/ast.rs index da5ba6db6c6a05dde8bafa165679eda350dd7256..1a8b15815835a0aa5b320791193ad9cfa98942d1 100644 --- a/src/protocol/ast.rs +++ b/src/protocol/ast.rs @@ -1747,7 +1747,7 @@ pub struct CallExpression { #[derive(Debug, Clone, PartialEq, Eq)] pub enum Method { - // Builtin + // Builtin, accessible by programmer Get, Put, Fires, @@ -1755,6 +1755,11 @@ pub enum Method { Length, Assert, Print, + // Builtin, not accessible by programmer + SelectStart, // SelectStart(total_num_cases, total_num_ports) + SelectRegisterCasePort, // SelectRegisterCasePort(case_index, port_index, port_id) + SelectWait, // SelectWait() -> u32 + // User-defined UserFunction, UserComponent, } diff --git a/src/protocol/eval/executor.rs b/src/protocol/eval/executor.rs index 00e18b174b087d514ebe4b29e8760a104de3c0bc..78ab516f15000eec257786982eaa2250d7c3cb02 100644 --- a/src/protocol/eval/executor.rs +++ b/src/protocol/eval/executor.rs @@ -734,6 +734,15 @@ impl Prompt { self.store.drop_heap_pos(value_heap_pos); println!("{}", message); }, + Method::SelectStart => { + todo!("select start"); + }, + Method::SelectRegisterCasePort => { + todo!("select register"); + }, + Method::SelectWait => { + todo!("select wait"); + }, Method::UserComponent => { // This is actually handled by the evaluation // of the statement. @@ -842,7 +851,7 @@ impl Prompt { match ctx.created_channel() { None => { // No channel is pending. So request one - Ok(EvalContinuation::NewChannel) + Ok(EvalContinuation::NewChannel) }, Some((put_port, get_port)) => { self.store.write(ValueId::Stack(heap[stmt.from].unique_id_in_scope as u32), put_port); diff --git a/src/protocol/parser/mod.rs b/src/protocol/parser/mod.rs index 935ccdcc7d7b7b3e50bc31fbeb2cef2f96d7faff..4688c9fe5e963e7877606b9384ae685762c2521c 100644 --- a/src/protocol/parser/mod.rs +++ b/src/protocol/parser/mod.rs @@ -8,6 +8,7 @@ pub(crate) mod pass_imports; pub(crate) mod pass_definitions; pub(crate) mod pass_definitions_types; pub(crate) mod pass_validation_linking; +pub(crate) mod pass_rewriting; pub(crate) mod pass_typing; mod visitor; @@ -36,6 +37,7 @@ pub enum ModuleCompilationPhase { DefinitionsParsed, // produced the AST for the entire module TypesAddedToTable, // added all definitions to the type table ValidatedAndLinked, // AST is traversed and has linked the required AST nodes + Rewritten, // Special AST nodes are rewritten into regular AST nodes // When we continue with the compiler: // Typed, // Type inference and checking has been performed } diff --git a/src/protocol/parser/pass_rewriting.rs b/src/protocol/parser/pass_rewriting.rs new file mode 100644 index 0000000000000000000000000000000000000000..3e3a117ed71dae830de1af1d9180ac5d5eb72818 --- /dev/null +++ b/src/protocol/parser/pass_rewriting.rs @@ -0,0 +1,80 @@ +use crate::collections::*; +use crate::protocol::*; + +use super::visitor::*; + +pub(crate) struct PassRewriting { + statement_buffer: ScopedBuffer, +} + +impl PassRewriting { + pub(crate) fn new() -> Self { + Self{ + statement_buffer: ScopedBuffer::with_capacity(16), + } + } +} + +impl Visitor for PassRewriting { + // --- Visiting procedures + + fn visit_component_definition(&mut self, ctx: &mut Ctx, id: ComponentDefinitionId) -> VisitorResult { + let def = &ctx.heap[id]; + let body_id = def.body; + return self.visit_block_stmt(ctx, body_id); + } + + fn visit_function_definition(&mut self, ctx: &mut Ctx, id: FunctionDefinitionId) -> VisitorResult { + let def = &ctx.heap[id]; + let body_id = def.body; + return self.visit_block_stmt(ctx, body_id); + } + + // --- Visiting statements (that are not the select statement) + + fn visit_block_stmt(&mut self, ctx: &mut Ctx, id: BlockStatementId) -> VisitorResult { + let block_stmt = &ctx.heap[id]; + let stmt_section = self.statement_buffer.start_section_initialized(&block_stmt.statements); + + for stmt_idx in 0..stmt_section.len() { + self.visit_stmt(ctx, stmt_section[stmt_idx])?; + } + + stmt_section.forget(); + return Ok(()) + } + + fn visit_labeled_stmt(&mut self, ctx: &mut Ctx, id: LabeledStatementId) -> VisitorResult { + let labeled_stmt = &ctx.heap[id]; + let body_id = labeled_stmt.body; + return self.visit_stmt(ctx, body_id); + } + + fn visit_if_stmt(&mut self, ctx: &mut Ctx, id: IfStatementId) -> VisitorResult { + let if_stmt = &ctx.heap[id]; + let true_body_id = if_stmt.true_body; + let false_body_id = if_stmt.false_body; + + self.visit_block_stmt(ctx, true_body_id)?; + if let Some(false_body_id) = false_body_id { + self.visit_block_stmt(ctx, false_body_id)?; + } + + return Ok(()) + } + + fn visit_while_stmt(&mut self, ctx: &mut Ctx, id: WhileStatementId) -> VisitorResult { + let while_stmt = &ctx.heap[id]; + let body_id = while_stmt.body; + return self.visit_block_stmt(ctx, body_id); + } + + // --- Visiting the select statement + + fn visit_select_stmt(&mut self, ctx: &mut Ctx, id: SelectStatementId) -> VisitorResult { + let stmt = &ctx.heap[id]; + + + return Ok(()) + } +} \ No newline at end of file diff --git a/src/protocol/parser/pass_validation_linking.rs b/src/protocol/parser/pass_validation_linking.rs index dd755059ac902761a6752d00a6b036909d572d6a..2d3292c0b00cbd158c35f10c0cbcd4211c2beea9 100644 --- a/src/protocol/parser/pass_validation_linking.rs +++ b/src/protocol/parser/pass_validation_linking.rs @@ -278,8 +278,6 @@ impl Visitor for PassValidationLinking { let block_stmt = &ctx.heap[id]; let end_block_id = block_stmt.end_block; - // Copy statement IDs into buffer - // Traverse statements in block let statement_section = self.statement_buffer.start_section_initialized(&block_stmt.statements); assign_and_replace_next_stmt!(self, ctx, id.upcast()); @@ -1212,6 +1210,9 @@ impl Visitor for PassValidationLinking { } }, Method::Print => {}, + Method::SelectStart + | Method::SelectRegisterCasePort + | Method::SelectWait => unreachable!(), // not usable by programmer directly Method::UserFunction => {}, Method::UserComponent => { expecting_wrapping_new_stmt = true;