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