summaryrefslogtreecommitdiff
path: root/src/stages/semantic.rs
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-10-13 18:14:51 +1300
committerBen Bridle <ben@derelict.engineering>2025-10-14 16:54:44 +1300
commit0f32d50293ffb1a990acf9eec128415ba54a9561 (patch)
tree6855b4f1e6942347aac5137ec2952854be25a220 /src/stages/semantic.rs
parenta051139f6d59cbc77eff99e9417dc21d87eaba6a (diff)
downloadtorque-asm-0f32d50293ffb1a990acf9eec128415ba54a9561.zip
Implement lists as a first-class type
Previously, strings were implemented as lists of integers, but there was no way to create an arbitrary list of integers to pass to a macro invocation. This commit extends the []-delimited expression syntax, treating expressions that contain only integers and invocations as lists of integers. Strings are implemented as a sub-type of list.
Diffstat (limited to 'src/stages/semantic.rs')
-rw-r--r--src/stages/semantic.rs46
1 files changed, 30 insertions, 16 deletions
diff --git a/src/stages/semantic.rs b/src/stages/semantic.rs
index b72cfa8..fdd1766 100644
--- a/src/stages/semantic.rs
+++ b/src/stages/semantic.rs
@@ -144,9 +144,9 @@ impl SemanticParser {
MacroDefinitionBody::Block(mut tokens) => {
block_tokens.append(&mut tokens);
}
- MacroDefinitionBody::String(string) => {
+ MacroDefinitionBody::List(list) => {
let error = SemanticError::ExpectedBlock(location);
- let tracked = Tracked::from(error, string.source);
+ let tracked = Tracked::from(error, list.source);
self.errors.push(tracked);
}
MacroDefinitionBody::Invocation(invocation) => {
@@ -184,9 +184,9 @@ impl SemanticParser {
Some(MacroDefinitionBody::Integer(tracked))
}
SyntacticToken::StringLiteral(value) => {
- let token = StringToken::StringLiteral(value);
+ let token = ListToken::StringLiteral(value);
let tracked = Tracked::from(token, source);
- Some(MacroDefinitionBody::String(tracked))
+ Some(MacroDefinitionBody::List(tracked))
}
SyntacticToken::WordTemplate(word_template) => {
let token = BlockToken::WordTemplate(word_template);
@@ -205,9 +205,16 @@ impl SemanticParser {
let mut parser = SemanticParser::from(tokens, self.namespace.clone());
let expression = parser.parse_expression();
self.pull_from(parser);
- let token = IntegerToken::Expression(expression);
- let tracked = Tracked::from(token, source);
- Some(MacroDefinitionBody::Integer(tracked))
+ if expression.is_list() {
+ let list = expression.to_list();
+ let token = ListToken::ListLiteral(list);
+ let tracked = Tracked::from(token, source);
+ Some(MacroDefinitionBody::List(tracked))
+ } else {
+ let token = IntegerToken::Expression(expression);
+ let tracked = Tracked::from(token, source);
+ Some(MacroDefinitionBody::Integer(tracked))
+ }
}
SyntacticToken::Symbol(symbol) => {
let name = self.resolve_symbol_name(symbol, &source)?;
@@ -265,9 +272,9 @@ impl SemanticParser {
self.errors.push(Tracked::from(error, token.source));
None
}
- MacroDefinitionBody::String(string) => {
+ MacroDefinitionBody::List(list) => {
let error = SemanticError::ExpectedInteger(location);
- self.errors.push(Tracked::from(error, string.source));
+ self.errors.push(Tracked::from(error, list.source));
None
}
}
@@ -291,9 +298,9 @@ impl SemanticParser {
self.errors.push(Tracked::from(error, integer.source));
None
}
- MacroDefinitionBody::String(string) => {
+ MacroDefinitionBody::List(list) => {
let error = SemanticError::ExpectedBlock(location);
- self.errors.push(Tracked::from(error, string.source));
+ self.errors.push(Tracked::from(error, list.source));
None
}
}
@@ -372,8 +379,8 @@ impl SemanticParser {
let source = token.source;
match token.value {
SyntacticToken::StringLiteral(string_literal) => {
- let string = StringToken::StringLiteral(string_literal);
- let argument = InvocationArgument::StringToken(string);
+ let string = ListToken::StringLiteral(string_literal);
+ let argument = InvocationArgument::ListToken(string);
Some(Tracked::from(argument, source))
}
SyntacticToken::IntegerLiteral(value) => {
@@ -385,9 +392,16 @@ impl SemanticParser {
let mut parser = SemanticParser::from(tokens, self.namespace.clone());
let expression = parser.parse_expression();
self.pull_from(parser);
- let integer = IntegerToken::Expression(expression);
- let argument = InvocationArgument::IntegerToken(integer);
- Some(Tracked::from(argument, source))
+ if expression.is_list() {
+ let list = expression.to_list();
+ let token = ListToken::ListLiteral(list);
+ let argument = InvocationArgument::ListToken(token);
+ Some(Tracked::from(argument, source))
+ } else {
+ let integer = IntegerToken::Expression(expression);
+ let argument = InvocationArgument::IntegerToken(integer);
+ Some(Tracked::from(argument, source))
+ }
}
SyntacticToken::BlockLiteral(tokens) => {
let mut parser = SemanticParser::from(tokens, self.namespace.clone());