diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-10-13 18:14:51 +1300 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-10-14 16:54:44 +1300 |
commit | 0f32d50293ffb1a990acf9eec128415ba54a9561 (patch) | |
tree | 6855b4f1e6942347aac5137ec2952854be25a220 /src/stages/semantic.rs | |
parent | a051139f6d59cbc77eff99e9417dc21d87eaba6a (diff) | |
download | torque-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.rs | 46 |
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()); |