diff options
Diffstat (limited to 'src/stages/semantic.rs')
-rw-r--r-- | src/stages/semantic.rs | 72 |
1 files changed, 34 insertions, 38 deletions
diff --git a/src/stages/semantic.rs b/src/stages/semantic.rs index fdd1766..96cf7af 100644 --- a/src/stages/semantic.rs +++ b/src/stages/semantic.rs @@ -306,22 +306,44 @@ impl SemanticParser { } } - /// Parse the remaining syntactic tokens as the contents of a block. - fn parse_block(&mut self) -> Vec<Tracked<BlockToken>> { - let mut tokens = Vec::new(); - while !self.syntactic.is_empty() { - if let Some(token) = self.pull_block_token(SemanticLocation::BlockLiteral) { - tokens.push(token); + /// Attempt to pull a token that can be used in an expression. + fn pull_expression_token(&mut self) -> Option<Tracked<ExpressionToken>> { + match self.pull_macro_definition_body_token()? { + MacroDefinitionBody::Block(mut tokens) => { + assert_eq!(tokens.len(), 1); + let token = tokens.pop().unwrap(); + let error = SemanticError::InvalidBlockInExpression; + self.errors.push(Tracked::from(error, token.source)); + None + } + MacroDefinitionBody::Invocation(invocation) => { + // Attempt to parse the invocation as an operator. + if invocation.arguments.is_empty() { + if let Some(operator) = Operator::from_str(&invocation.name) { + let expr = ExpressionToken::Operator(operator); + return Some(Tracked::from(expr, invocation.source)) + } + } + // Parse invocation as an invocation. + let expr = ExpressionToken::Invocation(invocation.value); + Some(Tracked::from(expr, invocation.source)) + } + MacroDefinitionBody::Integer(integer) => { + let expr = ExpressionToken::IntegerToken(Box::new(integer.value)); + Some(Tracked::from(expr, integer.source)) + } + MacroDefinitionBody::List(list) => { + let expr = ExpressionToken::ListToken(list.value); + Some(Tracked::from(expr, list.source)) } } - tokens } - /// Parse the remaining syntactic tokens as a list of integer tokens. - fn parse_integer_list(&mut self, location: SemanticLocation) -> Vec<Tracked<IntegerToken>> { + /// Parse the remaining syntactic tokens as the contents of a block. + fn parse_block(&mut self) -> Vec<Tracked<BlockToken>> { let mut tokens = Vec::new(); while !self.syntactic.is_empty() { - if let Some(token) = self.pull_integer_token(location) { + if let Some(token) = self.pull_block_token(SemanticLocation::BlockLiteral) { tokens.push(token); } } @@ -331,34 +353,8 @@ impl SemanticParser { /// Parse the remaining syntactic tokens as the contents of an expression. fn parse_expression(&mut self) -> Expression { let mut tokens = Vec::new(); - for token in self.parse_integer_list(SemanticLocation::Expression) { - let source = token.source; - match token.value { - IntegerToken::IntegerLiteral(value) => { - let integer = Box::new(IntegerToken::IntegerLiteral(value)); - let token = ExpressionToken::IntegerToken(integer); - tokens.push(Tracked::from(token, source)); - } - IntegerToken::Expression(expression) => { - let integer = Box::new(IntegerToken::Expression(expression)); - let token = ExpressionToken::IntegerToken(integer); - tokens.push(Tracked::from(token, source)); - } - IntegerToken::Invocation(invocation) => { - // Parse the invocation as an operator instead. - if invocation.arguments.is_empty() { - if let Some(operator) = Operator::from_str(&invocation.name) { - let token = ExpressionToken::Operator(operator); - tokens.push(Tracked::from(token, source)); - continue; - } - } - // Parse the invocation as an invocation. - let integer = Box::new(IntegerToken::Invocation(invocation)); - let token = ExpressionToken::IntegerToken(integer); - tokens.push(Tracked::from(token, source)); - } - } + while let Some(token) = self.pull_expression_token() { + tokens.push(token); } Expression { tokens } } |