diff options
Diffstat (limited to 'src/stages/semantic_tokens.rs')
| -rw-r--r-- | src/stages/semantic_tokens.rs | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/src/stages/semantic_tokens.rs b/src/stages/semantic_tokens.rs index 95a7f21..a873df0 100644 --- a/src/stages/semantic_tokens.rs +++ b/src/stages/semantic_tokens.rs @@ -37,7 +37,7 @@ impl std::fmt::Display for ArgumentType { pub enum MacroDefinitionBody { Integer(Tracked<IntegerToken>), Block(Vec<Tracked<BlockToken>>), - String(Tracked<StringToken>), + List(Tracked<ListToken>), Invocation(Tracked<Invocation>), } @@ -58,6 +58,7 @@ pub struct Expression { pub enum ExpressionToken { IntegerToken(Box<IntegerToken>), + ListToken(ListToken), Invocation(Invocation), Operator(Operator), } @@ -71,8 +72,9 @@ pub enum BlockToken { Invocation(Invocation), } -pub enum StringToken { +pub enum ListToken { StringLiteral(StringLiteral), + ListLiteral(Vec<Tracked<IntegerToken>>), Invocation(Invocation), } @@ -84,13 +86,48 @@ pub struct Invocation { pub enum InvocationArgument { IntegerToken(IntegerToken), BlockToken(BlockToken), - StringToken(StringToken), + ListToken(ListToken), Invocation(Invocation), } + +impl Expression { + pub fn is_list(&self) -> bool { + self.tokens.iter().all(|t| { + match t.value { + ExpressionToken::IntegerToken(_) => true, + ExpressionToken::Invocation(_) => true, + ExpressionToken::ListToken(_) => false, + ExpressionToken::Operator(_) => false, + } + }) + } + + pub fn to_list(self) -> Vec<Tracked<IntegerToken>> { + let mut list = Vec::new(); + for token in self.tokens { + let source = token.source; + match token.value { + ExpressionToken::IntegerToken(token) => { + let tracked = Tracked::from(*token, source); + list.push(tracked); + } + ExpressionToken::Invocation(invocation) => { + let token = IntegerToken::Invocation(invocation); + list.push(Tracked::from(token, source)); + } + ExpressionToken::ListToken(_) => unreachable!( + "Could not convert expression containing a list token to a list"), + ExpressionToken::Operator(_) => unreachable!( + "Could not convert expression containing an operator to a list"), + }; + } + return list; + } +} + + pub enum SemanticError { - MisplacedStringLiteral, - MisplacedListLiteral, MisplacedSeparator, MisplacedMacroDefinition, @@ -149,10 +186,6 @@ pub fn report_semantic_errors(errors: &[Tracked<SemanticError>], source_code: &s fn report_semantic_error(error: &Tracked<SemanticError>, source_code: &str) { let context = Context { source_code: &source_code, source: &error.source }; let message = match &error.value { - SemanticError::MisplacedStringLiteral => - "String literals can only be used as invocation arguments", - SemanticError::MisplacedListLiteral => - "List literals can only be used as invocation arguments", SemanticError::MisplacedSeparator => "Separators can only be used for constructing an argument list", SemanticError::MisplacedMacroDefinition => @@ -196,8 +229,8 @@ pub fn print_semantic_token(i: usize, token: &SemanticToken) { MacroDefinitionBody::Block(tokens) => { print_block(i+1, tokens); } - MacroDefinitionBody::String(string) => { - print_string_token(i+1, string); + MacroDefinitionBody::List(list) => { + print_list_token(i+1, list); } MacroDefinitionBody::Invocation(invocation) => { print_invocation(i+1, invocation); @@ -266,8 +299,8 @@ fn print_invocation(i: usize, invocation: &Invocation) { fn print_invocation_argument(i: usize, argument: &InvocationArgument) { match &argument { - InvocationArgument::StringToken(string) => { - print_string_token(i, string) + InvocationArgument::ListToken(list) => { + print_list_token(i, list) } InvocationArgument::IntegerToken(integer) => { print_integer_token(i, integer) @@ -295,12 +328,18 @@ fn print_integer_token(i: usize, integer: &IntegerToken) { } } -fn print_string_token(i: usize, string: &StringToken) { +fn print_list_token(i: usize, string: &ListToken) { match string { - StringToken::StringLiteral(string_literal) => { - indent!(i, "String({string_literal})") + ListToken::StringLiteral(string_literal) => { + indent!(i, "StringLiteral({string_literal})") } - StringToken::Invocation(invocation) => { + ListToken::ListLiteral(integers) => { + indent!(i, "ListLiteral"); + for integer in integers { + print_integer_token(i+1, integer); + } + } + ListToken::Invocation(invocation) => { print_invocation(i, invocation) } } @@ -313,6 +352,9 @@ fn print_expression(i: usize, expression: &Expression) { ExpressionToken::IntegerToken(integer) => { print_integer_token(i+1, &integer) } + ExpressionToken::ListToken(list) => { + print_list_token(i+1, &list) + } ExpressionToken::Invocation(invocation) => { print_invocation(i+1, &invocation); } |
