diff --git a/src/protocol/ast.rs b/src/protocol/ast.rs index 95195aef473b46c535fb2b034a712da10bf953ca..a8b18a801eef40f745879bd48630af59c8159dc3 100644 --- a/src/protocol/ast.rs +++ b/src/protocol/ast.rs @@ -137,6 +137,8 @@ define_new_ast_id!(SynchronousStatementId, StatementId, index(SynchronousStateme define_new_ast_id!(EndSynchronousStatementId, StatementId, index(EndSynchronousStatement, Statement::EndSynchronous, statements), alloc(alloc_end_synchronous_statement)); define_new_ast_id!(ForkStatementId, StatementId, index(ForkStatement, Statement::Fork, statements), alloc(alloc_fork_statement)); define_new_ast_id!(EndForkStatementId, StatementId, index(EndForkStatement, Statement::EndFork, statements), alloc(alloc_end_fork_statement)); +define_new_ast_id!(SelectStatementId, StatementId, index(SelectStatement, Statement::Select, statements), alloc(alloc_select_statement)); +define_new_ast_id!(EndSelectStatementId, StatementId, index(EndSelectStatement, Statement::EndSelect, statements), alloc(alloc_end_select_statement)); define_new_ast_id!(ReturnStatementId, StatementId, index(ReturnStatement, Statement::Return, statements), alloc(alloc_return_statement)); define_new_ast_id!(GotoStatementId, StatementId, index(GotoStatement, Statement::Goto, statements), alloc(alloc_goto_statement)); define_new_ast_id!(NewStatementId, StatementId, index(NewStatement, Statement::New, statements), alloc(alloc_new_statement)); @@ -1068,6 +1070,8 @@ pub enum Statement { EndSynchronous(EndSynchronousStatement), Fork(ForkStatement), EndFork(EndForkStatement), + Select(SelectStatement), + EndSelect(EndSelectStatement), Return(ReturnStatement), Goto(GotoStatement), New(NewStatement), @@ -1112,11 +1116,17 @@ impl Statement { Statement::Continue(v) => v.span, Statement::Synchronous(v) => v.span, Statement::Fork(v) => v.span, + Statement::Select(v) => v.span, Statement::Return(v) => v.span, Statement::Goto(v) => v.span, Statement::New(v) => v.span, Statement::Expression(v) => v.span, - Statement::EndBlock(_) | Statement::EndIf(_) | Statement::EndWhile(_) | Statement::EndSynchronous(_) | Statement::EndFork(_) => unreachable!(), + Statement::EndBlock(_) + | Statement::EndIf(_) + | Statement::EndWhile(_) + | Statement::EndSynchronous(_) + | Statement::EndFork(_) + | Statement::EndSelect(_) => unreachable!(), } } pub fn link_next(&mut self, next: StatementId) { @@ -1131,6 +1141,7 @@ impl Statement { Statement::EndWhile(stmt) => stmt.next = next, Statement::EndSynchronous(stmt) => stmt.next = next, Statement::EndFork(stmt) => stmt.next = next, + Statement::EndSelect(stmt) => stmt.next = next, Statement::New(stmt) => stmt.next = next, Statement::Expression(stmt) => stmt.next = next, Statement::Return(_) @@ -1138,6 +1149,7 @@ impl Statement { | Statement::Continue(_) | Statement::Synchronous(_) | Statement::Fork(_) + | Statement::Select(_) | Statement::Goto(_) | Statement::While(_) | Statement::Labeled(_) @@ -1335,6 +1347,28 @@ pub struct EndForkStatement { pub next: StatementId, } +#[derive(Debug, Clone)] +pub struct SelectStatement { + pub this: SelectStatementId, + pub span: InputSpan, // of the "select" keyword + pub cases: Vec, + pub end_select: EndSelectStatementId, +} + +#[derive(Debug, Clone)] +pub struct SelectCase { + pub guard_var: Option, // optional memory declaration + pub guard_expr: ExpressionStatementId, // if `guard_var.is_some()`, then always assignment expression + pub block: BlockStatementId, +} + +#[derive(Debug, Clone)] +pub struct EndSelectStatement { + pub this: EndSelectStatementId, + pub start_select: SelectStatementId, + pub next: StatementId, +} + #[derive(Debug, Clone)] pub struct ReturnStatement { pub this: ReturnStatementId,