summaryrefslogtreecommitdiff
path: root/src/stages/semantic.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stages/semantic.rs')
-rw-r--r--src/stages/semantic.rs72
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 }
}