diff --git a/src/protocol/parser/pass_definitions.rs b/src/protocol/parser/pass_definitions.rs index 66ed638cc16da38f731d12225efd5d7c0a7da217..8ce576bcfa720aef0e2e4d9701150fb216f14b7a 100644 --- a/src/protocol/parser/pass_definitions.rs +++ b/src/protocol/parser/pass_definitions.rs @@ -273,35 +273,22 @@ impl PassDefinitions { // Consume return types consume_token(&module.source, iter, TokenKind::ArrowRight)?; - let mut return_types = self.parser_types.start_section(); - let mut open_curly_pos = iter.last_valid_pos(); // bogus value - consume_comma_separated_until( - TokenKind::OpenCurly, &module.source, iter, ctx, - |source, iter, ctx| { - let poly_vars = ctx.heap[definition_id].poly_vars(); - self.type_parser.consume_parser_type( - iter, &ctx.heap, source, &ctx.symbols, poly_vars, definition_id, - module_scope, false, None - ) - }, - &mut return_types, "a return type", Some(&mut open_curly_pos) + let poly_vars = ctx.heap[definition_id].poly_vars(); + let parser_type = self.type_parser.consume_parser_type( + iter, &ctx.heap, &module.source, &ctx.symbols, poly_vars, definition_id, + module_scope, false, None )?; - let return_types = return_types.into_vec(); - - match return_types.len() { - 0 => return Err(ParseError::new_error_str_at_pos(&module.source, open_curly_pos, "expected a return type")), - 1 => {}, - _ => return Err(ParseError::new_error_str_at_pos(&module.source, open_curly_pos, "multiple return types are not (yet) allowed")), - } - // Consume block - let body = self.consume_block_statement_without_leading_curly(module, iter, ctx, open_curly_pos)?; + // Consume block and the definition's scope + let body_id = self.consume_block_statement(module, iter, ctx)?; + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Definition(definition_id))); // Assign everything in the preallocated AST node - let function = ctx.heap[definition_id].as_function_mut(); - function.return_types = return_types; + let function = ctx.heap[definition_id].as_procedure_mut(); + function.return_type = Some(parser_type); function.parameters = parameters; - function.body = body; + function.scope = scope_id; + function.body = body_id; Ok(()) } @@ -330,197 +317,109 @@ impl PassDefinitions { let parameters = parameter_section.into_vec(); // Consume block - let body = self.consume_block_statement(module, iter, ctx)?; + let body_id = self.consume_block_statement(module, iter, ctx)?; + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Definition(definition_id))); // Assign everything in the AST node - let component = ctx.heap[definition_id].as_component_mut(); + let component = ctx.heap[definition_id].as_procedure_mut(); + debug_assert!(component.return_type.is_none()); component.parameters = parameters; - component.body = body; + component.scope = scope_id; + component.body = body_id; Ok(()) } - /// Consumes a block statement. If the resulting statement is not a block - /// (e.g. for a shorthand "if (expr) single_statement") then it will be - /// wrapped in one - fn consume_block_or_wrapped_statement( - &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx - ) -> Result { - if Some(TokenKind::OpenCurly) == iter.next() { - // This is a block statement - self.consume_block_statement(module, iter, ctx) - } else { - // Not a block statement, so wrap it in one - let mut statements = self.statements.start_section(); - let wrap_begin_pos = iter.last_valid_pos(); - self.consume_statement(module, iter, ctx, &mut statements)?; - let wrap_end_pos = iter.last_valid_pos(); - - let statements = statements.into_vec(); - - let id = ctx.heap.alloc_block_statement(|this| BlockStatement{ - this, - is_implicit: true, - span: InputSpan::from_positions(wrap_begin_pos, wrap_end_pos), - statements, - end_block: EndBlockStatementId::new_invalid(), - scope_node: ScopeNode::new_invalid(), - first_unique_id_in_scope: -1, - next_unique_id_in_scope: -1, - locals: Vec::new(), - labels: Vec::new(), - next: StatementId::new_invalid(), - }); - - let end_block = ctx.heap.alloc_end_block_statement(|this| EndBlockStatement{ - this, start_block: id, next: StatementId::new_invalid() - }); - - let block_stmt = &mut ctx.heap[id]; - block_stmt.end_block = end_block; - - Ok(id) - } - } - /// Consumes a statement and returns a boolean indicating whether it was a /// block or not. - fn consume_statement( - &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx, section: &mut ScopedSection - ) -> Result<(), ParseError> { + fn consume_statement(&mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx) -> Result { let next = iter.next().expect("consume_statement has a next token"); if next == TokenKind::OpenCurly { let id = self.consume_block_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } else if next == TokenKind::Ident { let ident = peek_ident(&module.source, iter).unwrap(); if ident == KW_STMT_IF { // Consume if statement and place end-if statement directly // after it. let id = self.consume_if_statement(module, iter, ctx)?; - section.push(id.upcast()); - - let end_if = ctx.heap.alloc_end_if_statement(|this| EndIfStatement { - this, - start_if: id, - next: StatementId::new_invalid() - }); - section.push(end_if.upcast()); - - let if_stmt = &mut ctx.heap[id]; - if_stmt.end_if = end_if; + return Ok(id.upcast()); } else if ident == KW_STMT_WHILE { let id = self.consume_while_statement(module, iter, ctx)?; - section.push(id.upcast()); - - let end_while = ctx.heap.alloc_end_while_statement(|this| EndWhileStatement { - this, - start_while: id, - next: StatementId::new_invalid() - }); - section.push(end_while.upcast()); - - let while_stmt = &mut ctx.heap[id]; - while_stmt.end_while = end_while; + return Ok(id.upcast()); } else if ident == KW_STMT_BREAK { let id = self.consume_break_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } else if ident == KW_STMT_CONTINUE { let id = self.consume_continue_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } else if ident == KW_STMT_SYNC { let id = self.consume_synchronous_statement(module, iter, ctx)?; - section.push(id.upcast()); - - let end_sync = ctx.heap.alloc_end_synchronous_statement(|this| EndSynchronousStatement { - this, - start_sync: id, - next: StatementId::new_invalid() - }); - section.push(end_sync.upcast()); - - let sync_stmt = &mut ctx.heap[id]; - sync_stmt.end_sync = end_sync; + return Ok(id.upcast()); } else if ident == KW_STMT_FORK { let id = self.consume_fork_statement(module, iter, ctx)?; - section.push(id.upcast()); let end_fork = ctx.heap.alloc_end_fork_statement(|this| EndForkStatement { this, start_fork: id, next: StatementId::new_invalid(), }); - section.push(end_fork.upcast()); let fork_stmt = &mut ctx.heap[id]; fork_stmt.end_fork = end_fork; + + return Ok(id.upcast()); } else if ident == KW_STMT_SELECT { let id = self.consume_select_statement(module, iter, ctx)?; - section.push(id.upcast()); - - let end_select = ctx.heap.alloc_end_select_statement(|this| EndSelectStatement{ - this, - start_select: id, - next: StatementId::new_invalid(), - }); - section.push(end_select.upcast()); - - let select_stmt = &mut ctx.heap[id]; - select_stmt.end_select = end_select; + return Ok(id.upcast()); } else if ident == KW_STMT_RETURN { let id = self.consume_return_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } else if ident == KW_STMT_GOTO { let id = self.consume_goto_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } else if ident == KW_STMT_NEW { let id = self.consume_new_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } else if ident == KW_STMT_CHANNEL { let id = self.consume_channel_statement(module, iter, ctx)?; - section.push(id.upcast().upcast()); + return Ok(id.upcast().upcast()); } else if iter.peek() == Some(TokenKind::Colon) { - self.consume_labeled_statement(module, iter, ctx, section)?; + let id = self.consume_labeled_statement(module, iter, ctx)?; + return Ok(id.upcast()); } else { // Two fallback possibilities: the first one is a memory // declaration, the other one is to parse it as a normal // expression. This is a bit ugly. if let Some(memory_stmt_id) = self.maybe_consume_memory_statement_without_semicolon(module, iter, ctx)? { consume_token(&module.source, iter, TokenKind::SemiColon)?; - section.push(memory_stmt_id.upcast().upcast()); + return Ok(memory_stmt_id.upcast().upcast()); } else { let id = self.consume_expression_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } } } else if next == TokenKind::OpenParen { // Same as above: memory statement or normal expression if let Some(memory_stmt_id) = self.maybe_consume_memory_statement_without_semicolon(module, iter, ctx)? { consume_token(&module.source, iter, TokenKind::SemiColon)?; - section.push(memory_stmt_id.upcast().upcast()); + return Ok(memory_stmt_id.upcast().upcast()); } else { let id = self.consume_expression_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } } else { let id = self.consume_expression_statement(module, iter, ctx)?; - section.push(id.upcast()); + return Ok(id.upcast()); } - - return Ok(()); } fn consume_block_statement( &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx ) -> Result { - let open_span = consume_token(&module.source, iter, TokenKind::OpenCurly)?; - self.consume_block_statement_without_leading_curly(module, iter, ctx, open_span.begin) - } + let open_curly_span = consume_token(&module.source, iter, TokenKind::OpenCurly)?; - fn consume_block_statement_without_leading_curly( - &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx, open_curly_pos: InputPosition - ) -> Result { let mut stmt_section = self.statements.start_section(); let mut next = iter.next(); while next != Some(TokenKind::CloseCurly) { @@ -529,36 +428,34 @@ impl PassDefinitions { &module.source, iter.last_valid_pos(), "expected a statement or '}'" )); } - self.consume_statement(module, iter, ctx, &mut stmt_section)?; + let stmt_id = self.consume_statement(module, iter, ctx)?; + stmt_section.push(stmt_id); next = iter.next(); } let statements = stmt_section.into_vec(); let mut block_span = consume_token(&module.source, iter, TokenKind::CloseCurly)?; - block_span.begin = open_curly_pos; + block_span.begin = open_curly_span.begin; - let id = ctx.heap.alloc_block_statement(|this| BlockStatement{ + let block_id = ctx.heap.alloc_block_statement(|this| BlockStatement{ this, - is_implicit: false, span: block_span, statements, end_block: EndBlockStatementId::new_invalid(), - scope_node: ScopeNode::new_invalid(), - first_unique_id_in_scope: -1, - next_unique_id_in_scope: -1, - locals: Vec::new(), - labels: Vec::new(), + scope: ScopeId::new_invalid(), next: StatementId::new_invalid(), }); + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Block(block_id))); - let end_block = ctx.heap.alloc_end_block_statement(|this| EndBlockStatement{ - this, start_block: id, next: StatementId::new_invalid() + let end_block_id = ctx.heap.alloc_end_block_statement(|this| EndBlockStatement{ + this, start_block: block_id, next: StatementId::new_invalid() }); - let block_stmt = &mut ctx.heap[id]; - block_stmt.end_block = end_block; + let block_stmt = &mut ctx.heap[block_id]; + block_stmt.end_block = end_block_id; + block_stmt.scope = scope_id; - Ok(id) + Ok(block_id) } fn consume_if_statement( @@ -568,24 +465,54 @@ impl PassDefinitions { consume_token(&module.source, iter, TokenKind::OpenParen)?; let test = self.consume_expression(module, iter, ctx)?; consume_token(&module.source, iter, TokenKind::CloseParen)?; - let true_body = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + + // Consume bodies of if-statement + let true_body = IfStatementCase{ + body: self.consume_statement(module, iter, ctx)?, + scope: ScopeId::new_invalid(), + }; let false_body = if has_ident(&module.source, iter, KW_STMT_ELSE) { iter.consume(); - let false_body = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + let false_body = IfStatementCase{ + body: self.consume_statement(module, iter, ctx)?, + scope: ScopeId::new_invalid(), + }; + Some(false_body) } else { None }; - Ok(ctx.heap.alloc_if_statement(|this| IfStatement{ + // Construct AST elements + let if_stmt_id = ctx.heap.alloc_if_statement(|this| IfStatement{ this, span: if_span, test, - true_body, - false_body, + true_case: true_body, + false_case: false_body, end_if: EndIfStatementId::new_invalid(), - })) + }); + let end_if_stmt_id = ctx.heap.alloc_end_if_statement(|this| EndIfStatement{ + this, + start_if: if_stmt_id, + next: StatementId::new_invalid(), + }); + let true_scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::If(if_stmt_id, true))); + let false_scope_id = if false_body.is_some() { + Some(ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::If(if_stmt_id, false)))) + } else { + None + }; + + let if_stmt = &mut ctx.heap[if_stmt_id]; + if_stmt.end_if = end_if_stmt_id; + if_stmt.true_case.scope = true_scope_id; + if let Some(false_case) = &mut if_stmt.false_case { + false_case.scope = false_scope_id.unwrap(); + } + + return Ok(if_stmt_id); } fn consume_while_statement( @@ -595,16 +522,29 @@ impl PassDefinitions { consume_token(&module.source, iter, TokenKind::OpenParen)?; let test = self.consume_expression(module, iter, ctx)?; consume_token(&module.source, iter, TokenKind::CloseParen)?; - let body = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + let body = self.consume_statement(module, iter, ctx)?; - Ok(ctx.heap.alloc_while_statement(|this| WhileStatement{ + let while_stmt_id = ctx.heap.alloc_while_statement(|this| WhileStatement{ this, span: while_span, test, + scope: ScopeId::new_invalid(), body, end_while: EndWhileStatementId::new_invalid(), in_sync: SynchronousStatementId::new_invalid(), - })) + }); + let end_while_stmt_id = ctx.heap.alloc_end_while_statement(|this| EndWhileStatement{ + this, + start_while: while_stmt_id, + next: StatementId::new_invalid(), + }); + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::While(while_stmt_id))); + + let while_stmt = &mut ctx.heap[while_stmt_id]; + while_stmt.scope = scope_id; + while_stmt.end_while = end_while_stmt_id; + + Ok(while_stmt_id) } fn consume_break_statement( @@ -649,25 +589,38 @@ impl PassDefinitions { &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx ) -> Result { let synchronous_span = consume_exact_ident(&module.source, iter, KW_STMT_SYNC)?; - let body = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + let body = self.consume_statement(module, iter, ctx)?; - Ok(ctx.heap.alloc_synchronous_statement(|this| SynchronousStatement{ + let sync_stmt_id = ctx.heap.alloc_synchronous_statement(|this| SynchronousStatement{ this, span: synchronous_span, + scope: ScopeId::new_invalid(), body, end_sync: EndSynchronousStatementId::new_invalid(), - })) + }); + let end_sync_stmt_id = ctx.heap.alloc_end_synchronous_statement(|this| EndSynchronousStatement{ + this, + start_sync: sync_stmt_id, + next: StatementId::new_invalid(), + }); + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Synchronous(sync_stmt_id))); + + let sync_stmt = &mut ctx.heap[sync_stmt_id]; + sync_stmt.scope = scope_id; + sync_stmt.end_sync = end_sync_stmt_id; + + return Ok(sync_stmt_id); } fn consume_fork_statement( &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx ) -> Result { let fork_span = consume_exact_ident(&module.source, iter, KW_STMT_FORK)?; - let left_body = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + let left_body = self.consume_statement(module, iter, ctx)?; let right_body = if has_ident(&module.source, iter, KW_STMT_OR) { iter.consume(); - let right_body = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + let right_body = self.consume_statement(module, iter, ctx)?; Some(right_body) } else { None @@ -710,9 +663,11 @@ impl PassDefinitions { }, }; consume_token(&module.source, iter, TokenKind::ArrowRight)?; - let block = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + let block = self.consume_statement(module, iter, ctx)?; cases.push(SelectCase{ - guard, block, + guard, + body: block, + scope: ScopeId::new_invalid(), involved_ports: Vec::with_capacity(1) }); @@ -721,12 +676,33 @@ impl PassDefinitions { consume_token(&module.source, iter, TokenKind::CloseCurly)?; - Ok(ctx.heap.alloc_select_statement(|this| SelectStatement{ + let num_cases = cases.len(); + let select_stmt_id = ctx.heap.alloc_select_statement(|this| SelectStatement{ this, span: select_span, cases, end_select: EndSelectStatementId::new_invalid(), - })) + relative_pos_in_parent: -1, + next: StatementId::new_invalid(), + }); + + let end_select_stmt_id = ctx.heap.alloc_end_select_statement(|this| EndSelectStatement{ + this, + start_select: select_stmt_id, + next: StatementId::new_invalid(), + }); + + let select_stmt = &mut ctx.heap[select_stmt_id]; + select_stmt.end_select = end_select_stmt_id; + + for case_index in 0..num_cases { + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::SelectCase(select_stmt_id, case_index as u32))); + let select_stmt = &mut ctx.heap[select_stmt_id]; + let select_case = &mut select_stmt.cases[case_index]; + select_case.scope = scope_id; + } + + return Ok(select_stmt_id) } fn consume_return_statement( @@ -855,7 +831,7 @@ impl PassDefinitions { kind: VariableKind::Local, identifier: from_identifier, parser_type: from_port_type, - relative_pos_in_block: 0, + relative_pos_in_parent: 0, unique_id_in_scope: -1, }); @@ -870,7 +846,7 @@ impl PassDefinitions { kind: VariableKind::Local, identifier: to_identifier, parser_type: to_port_type, - relative_pos_in_block: 0, + relative_pos_in_parent: 0, unique_id_in_scope: -1, }); @@ -879,49 +855,25 @@ impl PassDefinitions { this, span: channel_span, from, to, - relative_pos_in_block: 0, + relative_pos_in_parent: 0, next: StatementId::new_invalid(), })) } - fn consume_labeled_statement( - &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx, section: &mut ScopedSection - ) -> Result<(), ParseError> { + fn consume_labeled_statement(&mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx) -> Result { let label = consume_ident_interned(&module.source, iter, ctx)?; consume_token(&module.source, iter, TokenKind::Colon)?; - // Not pretty: consume_statement may produce more than one statement. - // The values in the section need to be in the correct order if some - // kind of outer block is consumed, so we take another section, push - // the expressions in that one, and then allocate the labeled statement. - let mut inner_section = self.statements.start_section(); - self.consume_statement(module, iter, ctx, &mut inner_section)?; - debug_assert!(inner_section.len() >= 1); - + let inner_stmt_id = self.consume_statement(module, iter, ctx)?; let stmt_id = ctx.heap.alloc_labeled_statement(|this| LabeledStatement { this, label, - body: inner_section[0], - relative_pos_in_block: 0, + body: inner_stmt_id, + relative_pos_in_parent: 0, in_sync: SynchronousStatementId::new_invalid(), }); - if inner_section.len() == 1 { - // Produce the labeled statement pointing to the first statement. - // This is by far the most common case. - inner_section.forget(); - section.push(stmt_id.upcast()); - } else { - // Produce the labeled statement using the first statement, and push - // the remaining ones at the end. - let inner_statements = inner_section.into_vec(); - section.push(stmt_id.upcast()); - for idx in 1..inner_statements.len() { - section.push(inner_statements[idx]) - } - } - - Ok(()) + return Ok(stmt_id); } /// Attempts to consume a memory statement (a statement along the lines of @@ -960,7 +912,7 @@ impl PassDefinitions { kind: VariableKind::Local, identifier: identifier.clone(), parser_type, - relative_pos_in_block: 0, + relative_pos_in_parent: 0, unique_id_in_scope: -1, }); @@ -972,7 +924,7 @@ impl PassDefinitions { declaration: Some(local_id), used_as_binding_target: false, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }); let assignment_expr_id = ctx.heap.alloc_assignment_expression(|this| AssignmentExpression{ this, @@ -982,7 +934,7 @@ impl PassDefinitions { operation: AssignmentOperator::Set, right: initial_expr_id, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }); // Put both together in the memory statement @@ -1077,7 +1029,7 @@ impl PassDefinitions { Ok(ctx.heap.alloc_assignment_expression(|this| AssignmentExpression{ this, operator_span, full_span, left, operation, right, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast()) } else { Ok(expr) @@ -1105,7 +1057,7 @@ impl PassDefinitions { Ok(ctx.heap.alloc_conditional_expression(|this| ConditionalExpression{ this, operator_span, full_span, test, true_expression, false_expression, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast()) } else { Ok(result) @@ -1290,7 +1242,7 @@ impl PassDefinitions { Ok(ctx.heap.alloc_unary_expression(|this| UnaryExpression { this, operator_span, full_span, operation, expression, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast()) } else if next == Some(TokenKind::PlusPlus) { return Err(ParseError::new_error_str_at_span( @@ -1354,7 +1306,7 @@ impl PassDefinitions { slicing_span: operator_span, full_span, subject, from_index, to_index, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast(); } else if Some(TokenKind::CloseSquare) == next { let end_span = consume_token(&module.source, iter, TokenKind::CloseSquare)?; @@ -1368,7 +1320,7 @@ impl PassDefinitions { this, operator_span, full_span, subject, index: from_index, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast(); } else { return Err(ParseError::new_error_str_at_pos( @@ -1409,7 +1361,7 @@ impl PassDefinitions { this, operator_span, full_span, subject, kind: select_kind, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast(); } @@ -1445,7 +1397,7 @@ impl PassDefinitions { span: InputSpan::from_positions(open_paren_pos, close_paren_pos), value: Literal::Tuple(Vec::new()), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }); literal_id.upcast() @@ -1471,7 +1423,7 @@ impl PassDefinitions { span: InputSpan::from_positions(open_paren_pos, close_paren_pos), value: Literal::Tuple(scoped_section.into_vec()), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }); literal_id.upcast() @@ -1499,7 +1451,7 @@ impl PassDefinitions { span: InputSpan::from_positions(start_pos, end_pos), value: Literal::Array(scoped_section.into_vec()), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } else if next == Some(TokenKind::Integer) { let (literal, span) = consume_integer_literal(&module.source, iter, &mut self.buffer)?; @@ -1508,7 +1460,7 @@ impl PassDefinitions { this, span, value: Literal::Integer(LiteralInteger{ unsigned_value: literal, negated: false }), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } else if next == Some(TokenKind::String) { let span = consume_string_literal(&module.source, iter, &mut self.buffer)?; @@ -1518,7 +1470,7 @@ impl PassDefinitions { this, span, value: Literal::String(interned), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } else if next == Some(TokenKind::Character) { let (character, span) = consume_character_literal(&module.source, iter)?; @@ -1527,7 +1479,7 @@ impl PassDefinitions { this, span, value: Literal::Character(character), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } else if next == Some(TokenKind::Ident) { // May be a variable, a type instantiation or a function call. If we @@ -1579,7 +1531,7 @@ impl PassDefinitions { definition: target_definition_id, }), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() }, Definition::Enum(_) => { @@ -1597,7 +1549,7 @@ impl PassDefinitions { variant_idx: 0 }), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() }, Definition::Union(_) => { @@ -1622,31 +1574,14 @@ impl PassDefinitions { variant_idx: 0, }), parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() }, - Definition::Component(_) => { - // Component instantiation - let func_span = parser_type.full_span; - let mut full_span = func_span; - let arguments = self.consume_expression_list( - module, iter, ctx, Some(&mut full_span.end) - )?; - - ctx.heap.alloc_call_expression(|this| CallExpression{ - this, func_span, full_span, - parser_type, - method: Method::UserComponent, - arguments, - definition: target_definition_id, - parent: ExpressionParent::None, - unique_id_in_definition: -1, - }).upcast() - }, - Definition::Function(function_definition) => { + Definition::Procedure(proc_def) => { // Check whether it is a builtin function - let method = if function_definition.builtin { - match function_definition.identifier.value.as_bytes() { + let procedure_id = proc_def.this; + let method = if proc_def.builtin { + match proc_def.identifier.value.as_bytes() { KW_FUNC_GET => Method::Get, KW_FUNC_PUT => Method::Put, KW_FUNC_FIRES => Method::Fires, @@ -1656,8 +1591,10 @@ impl PassDefinitions { KW_FUNC_PRINT => Method::Print, _ => unreachable!(), } - } else { + } else if proc_def.kind == ProcedureKind::Function { Method::UserFunction + } else { + Method::UserComponent }; // Function call: consume the arguments @@ -1669,9 +1606,9 @@ impl PassDefinitions { ctx.heap.alloc_call_expression(|this| CallExpression{ this, func_span, full_span, parser_type, method, arguments, - definition: target_definition_id, + procedure: procedure_id, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } } @@ -1700,7 +1637,7 @@ impl PassDefinitions { span: ident_span, value, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } else if ident_text == KW_LET { // Binding expression @@ -1718,7 +1655,7 @@ impl PassDefinitions { ctx.heap.alloc_binding_expression(|this| BindingExpression{ this, operator_span, full_span, bound_to, bound_from, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } else if ident_text == KW_CAST { // Casting expression @@ -1755,7 +1692,7 @@ impl PassDefinitions { cast_span: to_type.full_span, full_span, to_type, subject, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } else { // Not a builtin literal, but also not a known type. So we @@ -1790,7 +1727,7 @@ impl PassDefinitions { declaration: None, used_as_binding_target: false, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast() } } @@ -1830,7 +1767,7 @@ impl PassDefinitions { result = ctx.heap.alloc_binary_expression(|this| BinaryExpression{ this, operator_span, full_span, left, operation, right, parent: ExpressionParent::None, - unique_id_in_definition: -1, + type_index: -1, }).upcast(); } @@ -1883,7 +1820,7 @@ fn consume_parameter_list( kind: VariableKind::Parameter, parser_type, identifier, - relative_pos_in_block: 0, + relative_pos_in_parent: 0, unique_id_in_scope: -1, }); Ok(parameter_id)