parser and tree nodes seem to be working. Need to fix compiler

This commit is contained in:
2025-11-30 15:35:54 -07:00
parent db389045fc
commit 1c52ec2b9c
3 changed files with 121 additions and 81 deletions

View File

@@ -5,7 +5,7 @@ use parser::{
tree_node::{ tree_node::{
AssignmentExpression, BinaryExpression, BlockExpression, DeviceDeclarationExpression, AssignmentExpression, BinaryExpression, BlockExpression, DeviceDeclarationExpression,
Expression, FunctionExpression, IfExpression, InvocationExpression, Literal, Expression, FunctionExpression, IfExpression, InvocationExpression, Literal,
LiteralOrVariable, LogicalExpression, LoopExpression, WhileExpression, LiteralOrVariable, LogicalExpression, LoopExpression, Span, Spanned, WhileExpression,
}, },
}; };
use quick_error::quick_error; use quick_error::quick_error;
@@ -22,6 +22,14 @@ macro_rules! debug {
"".into() "".into()
} }
}; };
($self: expr, $debug_value: expr, $args: expr) => {
if $self.config.debug {
format!($debug_value, $args)
} else {
"".into()
}
};
} }
quick_error! { quick_error! {
@@ -36,19 +44,19 @@ quick_error! {
ScopeError(error: variable_manager::Error) { ScopeError(error: variable_manager::Error) {
from() from()
} }
DuplicateIdentifier(func_name: String) { DuplicateIdentifier(func_name: String, span: Span) {
display("`{func_name}` has already been defined") display("`{func_name}` has already been defined")
} }
UnknownIdentifier(ident: String) { UnknownIdentifier(ident: String, span: Span) {
display("`{ident}` is not found in the current scope.") display("`{ident}` is not found in the current scope.")
} }
InvalidDevice(device: String) { InvalidDevice(device: String, span: Span) {
display("`{device}` is not valid") display("`{device}` is not valid")
} }
AgrumentMismatch(func_name: String) { AgrumentMismatch(func_name: String, span: Span) {
display("Incorrect number of arguments passed into `{func_name}`") display("Incorrect number of arguments passed into `{func_name}`")
} }
Unknown(reason: String) { Unknown(reason: String, span: Option<Span>) {
display("{reason}") display("{reason}")
} }
} }
@@ -173,7 +181,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
Ok(None) Ok(None)
} }
Expression::Declaration(var_name, expr) => { Expression::Declaration(var_name, expr) => {
self.expression_declaration(var_name, *expr, scope) self.expression_declaration(var_name.node, *expr, scope)
} }
Expression::Assignment(assign_expr) => { Expression::Assignment(assign_expr) => {
self.expression_assignment(assign_expr, scope)?; self.expression_assignment(assign_expr, scope)?;
@@ -223,7 +231,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
})) }))
} }
Expression::Variable(name) => { Expression::Variable(name) => {
let loc = scope.get_location_of(&name)?; let loc = scope.get_location_of(&name.node)?;
Ok(Some(CompilationResult { Ok(Some(CompilationResult {
location: loc, location: loc,
temp_name: None, // User variable, do not free temp_name: None, // User variable, do not free
@@ -368,7 +376,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
(var_loc, None) (var_loc, None)
} }
Expression::Variable(name) => { Expression::Variable(name) => {
let src_loc = scope.get_location_of(&name)?; let src_loc = scope.get_location_of(&name.node)?;
let var_loc = scope.add_variable(&var_name, LocationRequest::Persist)?; let var_loc = scope.add_variable(&var_name, LocationRequest::Persist)?;
// Handle loading from stack if necessary // Handle loading from stack if necessary
@@ -417,11 +425,11 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
expression, expression,
} = expr; } = expr;
let location = scope.get_location_of(&identifier)?; let location = scope.get_location_of(&identifier.node)?;
let (val_str, cleanup) = self.compile_operand(*expression, scope)?; let (val_str, cleanup) = self.compile_operand(*expression, scope)?;
let debug_tag = if self.config.debug { let debug_tag = if self.config.debug {
format!(" #{}", identifier) format!(" #{}", identifier.node)
} else { } else {
String::new() String::new()
}; };
@@ -456,16 +464,16 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
invoke_expr: InvocationExpression, invoke_expr: InvocationExpression,
stack: &mut VariableScope, stack: &mut VariableScope,
) -> Result<(), Error> { ) -> Result<(), Error> {
if !self.function_locations.contains_key(&invoke_expr.name) { if !self.function_locations.contains_key(&invoke_expr.name.node) {
return Err(Error::UnknownIdentifier(invoke_expr.name)); return Err(Error::UnknownIdentifier(invoke_expr.name.node));
} }
let Some(args) = self.function_metadata.get(&invoke_expr.name) else { let Some(args) = self.function_metadata.get(&invoke_expr.name.node) else {
return Err(Error::UnknownIdentifier(invoke_expr.name)); return Err(Error::UnknownIdentifier(invoke_expr.name.node));
}; };
if args.len() != invoke_expr.arguments.len() { if args.len() != invoke_expr.arguments.len() {
return Err(Error::AgrumentMismatch(invoke_expr.name)); return Err(Error::AgrumentMismatch(invoke_expr.name.node));
} }
// backup all used registers to the stack // backup all used registers to the stack
@@ -484,7 +492,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
let val = if b { "1" } else { "0" }; let val = if b { "1" } else { "0" };
self.write_output(format!("push {val}"))?; self.write_output(format!("push {val}"))?;
} }
Expression::Variable(var_name) => match stack.get_location_of(var_name)? { Expression::Variable(var_name) => match stack.get_location_of(var_name.node)? {
VariableLocation::Persistant(reg) | VariableLocation::Temporary(reg) => { VariableLocation::Persistant(reg) | VariableLocation::Temporary(reg) => {
self.write_output(format!("push r{reg}"))?; self.write_output(format!("push r{reg}"))?;
} }
@@ -524,14 +532,14 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
_ => { _ => {
return Err(Error::Unknown(format!( return Err(Error::Unknown(format!(
"Attempted to call `{}` with an unsupported argument type", "Attempted to call `{}` with an unsupported argument type",
invoke_expr.name invoke_expr.name.node
))); )));
} }
} }
} }
// jump to the function and store current line in ra // jump to the function and store current line in ra
self.write_output(format!("jal {}", invoke_expr.name))?; self.write_output(format!("jal {}", invoke_expr.name.node))?;
for register in active_registers { for register in active_registers {
let VariableLocation::Stack(stack_offset) = let VariableLocation::Stack(stack_offset) =
@@ -557,10 +565,10 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
} }
fn expression_device(&mut self, expr: DeviceDeclarationExpression) -> Result<(), Error> { fn expression_device(&mut self, expr: DeviceDeclarationExpression) -> Result<(), Error> {
if self.devices.contains_key(&expr.name) { if self.devices.contains_key(&expr.name.node) {
return Err(Error::DuplicateIdentifier(expr.name)); return Err(Error::DuplicateIdentifier(expr.name.node));
} }
self.devices.insert(expr.name, expr.device); self.devices.insert(expr.name.node, expr.device);
Ok(()) Ok(())
} }
@@ -589,7 +597,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
// Compile Body // Compile Body
// Scope variables in body are ephemeral to the block, handled by expression_block // Scope variables in body are ephemeral to the block, handled by expression_block
self.expression_block(expr.body, scope)?; self.expression_block(expr.body.node, scope)?;
// If we have an else branch, we need to jump over it after the 'if' body // If we have an else branch, we need to jump over it after the 'if' body
if expr.else_branch.is_some() { if expr.else_branch.is_some() {
@@ -597,8 +605,8 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
self.write_output(format!("{else_label}:"))?; self.write_output(format!("{else_label}:"))?;
match *expr.else_branch.unwrap() { match *expr.else_branch.unwrap() {
Expression::Block(block) => self.expression_block(block, scope)?, Expression::Block(block) => self.expression_block(block.node, scope)?,
Expression::If(if_expr) => self.expression_if(if_expr, scope)?, Expression::If(if_expr) => self.expression_if(if_expr.node, scope)?,
_ => unreachable!("Parser ensures else branch is Block or If"), _ => unreachable!("Parser ensures else branch is Block or If"),
} }
} }
@@ -623,7 +631,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
self.write_output(format!("{start_label}:"))?; self.write_output(format!("{start_label}:"))?;
// Compile Body // Compile Body
self.expression_block(expr.body, scope)?; self.expression_block(expr.body.node, scope)?;
// Jump back to start // Jump back to start
self.write_output(format!("j {start_label}"))?; self.write_output(format!("j {start_label}"))?;
@@ -887,9 +895,11 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
) -> Result<(), Error> { ) -> Result<(), Error> {
// First, sort the expressions to ensure functions are hoisted // First, sort the expressions to ensure functions are hoisted
expr.0.sort_by(|a, b| { expr.0.sort_by(|a, b| {
if matches!(b, Expression::Function(_)) && matches!(a, Expression::Function(_)) { if matches!(b.node, Expression::Function(_))
&& matches!(a.node, Expression::Function(_))
{
std::cmp::Ordering::Equal std::cmp::Ordering::Equal
} else if matches!(a, Expression::Function(_)) { } else if matches!(a.node, Expression::Function(_)) {
std::cmp::Ordering::Less std::cmp::Ordering::Less
} else { } else {
std::cmp::Ordering::Greater std::cmp::Ordering::Greater
@@ -898,19 +908,19 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
for expr in expr.0 { for expr in expr.0 {
if !self.declared_main if !self.declared_main
&& !matches!(expr, Expression::Function(_)) && !matches!(expr.node, Expression::Function(_))
&& !scope.has_parent() && !scope.has_parent()
{ {
self.write_output("main:")?; self.write_output("main:")?;
self.declared_main = true; self.declared_main = true;
} }
match expr { match expr.node {
Expression::Return(ret_expr) => { Expression::Return(ret_expr) => {
self.expression_return(*ret_expr, scope)?; self.expression_return(*ret_expr, scope)?;
} }
_ => { _ => {
let result = self.expression(expr, scope)?; let result = self.expression(expr.node, scope)?;
// If the expression was a statement that returned a temp result (e.g. `1 + 2;` line), // If the expression was a statement that returned a temp result (e.g. `1 + 2;` line),
// we must free it to avoid leaking registers. // we must free it to avoid leaking registers.
if let Some(comp_res) = result if let Some(comp_res) = result
@@ -940,7 +950,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
}; };
match expr { match expr {
Expression::Variable(var_name) => match scope.get_location_of(var_name)? { Expression::Variable(var_name) => match scope.get_location_of(var_name.node)? {
VariableLocation::Temporary(reg) | VariableLocation::Persistant(reg) => { VariableLocation::Temporary(reg) | VariableLocation::Persistant(reg) => {
self.write_output(format!( self.write_output(format!(
"move r{} r{reg} {}", "move r{} r{reg} {}",
@@ -1055,8 +1065,8 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
)); ));
}; };
let Some(device) = self.devices.get(&device) else { let Some(device) = self.devices.get(&device.node) else {
return Err(Error::InvalidDevice(device)); return Err(Error::InvalidDevice(device.node));
}; };
let Literal::String(logic_type) = logic_type else { let Literal::String(logic_type) = logic_type else {
@@ -1102,8 +1112,8 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
)); ));
}; };
let Some(device) = self.devices.get(&device) else { let Some(device) = self.devices.get(&device.node) else {
return Err(Error::InvalidDevice(device)); return Err(Error::InvalidDevice(device.node));
}; };
let Literal::String(logic_type) = logic_type else { let Literal::String(logic_type) = logic_type else {
@@ -1133,27 +1143,29 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
/// Calees are responsible for backing up any registers they wish to use. /// Calees are responsible for backing up any registers they wish to use.
fn expression_function<'v>( fn expression_function<'v>(
&mut self, &mut self,
expr: FunctionExpression, expr: Spanned<FunctionExpression>,
scope: &mut VariableScope<'v>, scope: &mut VariableScope<'v>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let FunctionExpression { let FunctionExpression {
name, name,
arguments, arguments,
body, body,
} = expr; } = *expr;
if self.function_locations.contains_key(&name) { if self.function_locations.contains_key(&name.node) {
return Err(Error::DuplicateIdentifier(name)); return Err(Error::DuplicateIdentifier(name.node));
} }
self.function_metadata self.function_metadata.insert(
.insert(name.clone(), arguments.clone()); name.node.clone(),
arguments.iter().map(|a| a.node.clone()).collect(),
);
// Declare the function as a line identifier // Declare the function as a line identifier
self.write_output(format!("{}:", name))?; self.write_output(format!("{}:", name.node))?;
self.function_locations self.function_locations
.insert(name.clone(), self.current_line); .insert(name.node.clone(), self.current_line);
// Create a new block scope for the function body // Create a new block scope for the function body
let mut block_scope = VariableScope::scoped(scope); let mut block_scope = VariableScope::scoped(scope);
@@ -1166,13 +1178,16 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
.rev() .rev()
.take(VariableScope::PERSIST_REGISTER_COUNT as usize) .take(VariableScope::PERSIST_REGISTER_COUNT as usize)
{ {
let loc = block_scope.add_variable(var_name, LocationRequest::Persist)?; let loc = block_scope.add_variable(var_name.node.clone(), LocationRequest::Persist)?;
// we don't need to imcrement the stack offset as it's already on the stack from the // we don't need to imcrement the stack offset as it's already on the stack from the
// previous scope // previous scope
match loc { match loc {
VariableLocation::Persistant(loc) => { VariableLocation::Persistant(loc) => {
self.write_output(format!("pop r{loc} {}", debug!(self, "#{var_name}")))?; self.write_output(format!(
"pop r{loc} {}",
debug!(self, "#{}", var_name.node)
))?;
} }
VariableLocation::Stack(_) => { VariableLocation::Stack(_) => {
return Err(Error::Unknown( return Err(Error::Unknown(
@@ -1194,19 +1209,19 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
// anything as they already exist on the stack, but we DO need to let our block_scope be // anything as they already exist on the stack, but we DO need to let our block_scope be
// aware that the variables exist on the stack (left to right) // aware that the variables exist on the stack (left to right)
for var_name in arguments.iter().take(arguments.len() - saved_variables) { for var_name in arguments.iter().take(arguments.len() - saved_variables) {
block_scope.add_variable(var_name, LocationRequest::Stack)?; block_scope.add_variable(var_name.node.clone(), LocationRequest::Stack)?;
} }
self.write_output("push ra")?; self.write_output("push ra")?;
block_scope.add_variable(format!("{name}_ra"), LocationRequest::Stack)?; block_scope.add_variable(format!("{}_ra", name.node), LocationRequest::Stack)?;
for expr in body.0 { for expr in body.0 {
match expr { match expr.node {
Expression::Return(ret_expr) => { Expression::Return(ret_expr) => {
self.expression_return(*ret_expr, &mut block_scope)?; self.expression_return(*ret_expr, &mut block_scope)?;
} }
_ => { _ => {
let result = self.expression(expr, &mut block_scope)?; let result = self.expression(expr.node, &mut block_scope)?;
// Free unused statement results // Free unused statement results
if let Some(comp_res) = result if let Some(comp_res) = result
&& let Some(name) = comp_res.temp_name && let Some(name) = comp_res.temp_name
@@ -1219,7 +1234,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
// Get the saved return address and save it back into `ra` // Get the saved return address and save it back into `ra`
let VariableLocation::Stack(ra_stack_offset) = let VariableLocation::Stack(ra_stack_offset) =
block_scope.get_location_of(format!("{name}_ra"))? block_scope.get_location_of(format!("{}_ra", name.node))?
else { else {
return Err(Error::Unknown( return Err(Error::Unknown(
"Stored return address not in stack as expected".into(), "Stored return address not in stack as expected".into(),

View File

@@ -544,6 +544,7 @@ impl<'a> Parser<'a> {
} }
let identifier_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; let identifier_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?;
let identifier_span = Self::token_to_span(identifier_token);
let identifier = match identifier_token.token_type { let identifier = match identifier_token.token_type {
TokenType::Identifier(ref id) => id.clone(), TokenType::Identifier(ref id) => id.clone(),
_ => { _ => {
@@ -574,13 +575,18 @@ impl<'a> Parser<'a> {
}; };
Ok(DeviceDeclarationExpression { Ok(DeviceDeclarationExpression {
name: identifier, name: Spanned {
span: identifier_span,
node: identifier,
},
device, device,
}) })
} }
fn assignment(&mut self) -> Result<AssignmentExpression, Error> { fn assignment(&mut self) -> Result<AssignmentExpression, Error> {
let identifier = match self.current_token.as_ref().unwrap().token_type { let identifier_token = self.current_token.as_ref().unwrap();
let identifier_span = Self::token_to_span(identifier_token);
let identifier = match identifier_token.token_type {
TokenType::Identifier(ref id) => id.clone(), TokenType::Identifier(ref id) => id.clone(),
_ => { _ => {
return Err(Error::UnexpectedToken( return Err(Error::UnexpectedToken(
@@ -602,7 +608,10 @@ impl<'a> Parser<'a> {
let expression = self.expression()?.ok_or(Error::UnexpectedEOF)?; let expression = self.expression()?.ok_or(Error::UnexpectedEOF)?;
Ok(AssignmentExpression { Ok(AssignmentExpression {
identifier, identifier: Spanned {
span: identifier_span,
node: identifier,
},
expression: boxed!(expression), expression: boxed!(expression),
}) })
} }
@@ -905,7 +914,9 @@ impl<'a> Parser<'a> {
} }
fn invocation(&mut self) -> Result<InvocationExpression, Error> { fn invocation(&mut self) -> Result<InvocationExpression, Error> {
let identifier = match self.current_token.as_ref().unwrap().token_type { let identifier_token = self.current_token.as_ref().unwrap();
let identifier_span = Self::token_to_span(identifier_token);
let identifier = match identifier_token.token_type {
TokenType::Identifier(ref id) => id.clone(), TokenType::Identifier(ref id) => id.clone(),
_ => { _ => {
return Err(Error::UnexpectedToken( return Err(Error::UnexpectedToken(
@@ -956,7 +967,10 @@ impl<'a> Parser<'a> {
} }
Ok(InvocationExpression { Ok(InvocationExpression {
name: identifier, name: Spanned {
span: identifier_span,
node: identifier,
},
arguments, arguments,
}) })
} }
@@ -1022,13 +1036,6 @@ impl<'a> Parser<'a> {
} }
fn declaration(&mut self) -> Result<Expression, Error> { fn declaration(&mut self) -> Result<Expression, Error> {
// "let" consumed by unary before calling spanned(declaration).
// But spanned() peeks start. Unary did NOT consume let inside unary match...
// Wait, Unary DOES match on current_token. It is `Let`.
// Then Unary calls `self.spanned(|p| p.declaration())`.
// `declaration()` checks `self.current_token` is `Let`.
// So `declaration` expects `Let` to be current.
let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?;
if !self_matches_current!(self, TokenType::Keyword(Keyword::Let)) { if !self_matches_current!(self, TokenType::Keyword(Keyword::Let)) {
return Err(Error::UnexpectedToken( return Err(Error::UnexpectedToken(
@@ -1037,6 +1044,7 @@ impl<'a> Parser<'a> {
)); ));
} }
let identifier_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; let identifier_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?;
let identifier_span = Self::token_to_span(identifier_token);
let identifier = match identifier_token.token_type { let identifier = match identifier_token.token_type {
TokenType::Identifier(ref id) => id.clone(), TokenType::Identifier(ref id) => id.clone(),
_ => { _ => {
@@ -1068,7 +1076,10 @@ impl<'a> Parser<'a> {
} }
Ok(Expression::Declaration( Ok(Expression::Declaration(
identifier, Spanned {
span: identifier_span,
node: identifier,
},
boxed!(assignment_expression), boxed!(assignment_expression),
)) ))
} }
@@ -1210,6 +1221,7 @@ impl<'a> Parser<'a> {
fn function(&mut self) -> Result<FunctionExpression, Error> { fn function(&mut self) -> Result<FunctionExpression, Error> {
// 'fn' is current // 'fn' is current
let fn_ident_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; let fn_ident_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?;
let fn_ident_span = Self::token_to_span(fn_ident_token);
let fn_ident = match fn_ident_token.token_type { let fn_ident = match fn_ident_token.token_type {
TokenType::Identifier(ref id) => id.clone(), TokenType::Identifier(ref id) => id.clone(),
_ => { _ => {
@@ -1228,13 +1240,14 @@ impl<'a> Parser<'a> {
)); ));
} }
let mut arguments = Vec::<String>::new(); let mut arguments = Vec::<Spanned<String>>::new();
while !token_matches!( while !token_matches!(
self.get_next()?.ok_or(Error::UnexpectedEOF)?, self.get_next()?.ok_or(Error::UnexpectedEOF)?,
TokenType::Symbol(Symbol::RParen) TokenType::Symbol(Symbol::RParen)
) { ) {
let current_token = self.current_token.as_ref().unwrap(); let current_token = self.current_token.as_ref().unwrap();
let arg_span = Self::token_to_span(current_token);
let argument = match current_token.token_type { let argument = match current_token.token_type {
TokenType::Identifier(ref id) => id.clone(), TokenType::Identifier(ref id) => id.clone(),
_ => { _ => {
@@ -1245,14 +1258,19 @@ impl<'a> Parser<'a> {
} }
}; };
if arguments.contains(&argument) { let spanned_arg = Spanned {
span: arg_span,
node: argument,
};
if arguments.contains(&spanned_arg) {
return Err(Error::DuplicateIdentifier( return Err(Error::DuplicateIdentifier(
Self::token_to_span(current_token), Self::token_to_span(current_token),
current_token.clone(), current_token.clone(),
)); ));
} }
arguments.push(argument); arguments.push(spanned_arg);
if !self_matches_peek!(self, TokenType::Symbol(Symbol::Comma)) if !self_matches_peek!(self, TokenType::Symbol(Symbol::Comma))
&& !self_matches_peek!(self, TokenType::Symbol(Symbol::RParen)) && !self_matches_peek!(self, TokenType::Symbol(Symbol::RParen))
@@ -1278,7 +1296,10 @@ impl<'a> Parser<'a> {
}; };
Ok(FunctionExpression { Ok(FunctionExpression {
name: fn_ident, name: Spanned {
span: fn_ident_span,
node: fn_ident,
},
arguments, arguments,
body: self.block()?, body: self.block()?,
}) })
@@ -1305,9 +1326,7 @@ impl<'a> Parser<'a> {
Some(Expression::Literal(literal)) => { Some(Expression::Literal(literal)) => {
LiteralOrVariable::Literal(literal.node.clone()) LiteralOrVariable::Literal(literal.node.clone())
} }
Some(Expression::Variable(ident)) => { Some(Expression::Variable(ident)) => LiteralOrVariable::Variable(ident),
LiteralOrVariable::Variable(ident.node.clone())
}
_ => { _ => {
return Err(Error::UnexpectedToken( return Err(Error::UnexpectedToken(
self.current_span(), self.current_span(),
@@ -1334,7 +1353,7 @@ impl<'a> Parser<'a> {
let invocation = self.invocation()?; let invocation = self.invocation()?;
match invocation.name.as_str() { match invocation.name.node.as_str() {
"yield" => { "yield" => {
check_length(self, &invocation.arguments, 0)?; check_length(self, &invocation.arguments, 0)?;
Ok(SysCall::System(sys_call::System::Yield)) Ok(SysCall::System(sys_call::System::Yield))
@@ -1420,3 +1439,4 @@ impl<'a> Parser<'a> {
} }
} }
} }

View File

@@ -74,7 +74,7 @@ impl std::fmt::Display for LogicalExpression {
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct AssignmentExpression { pub struct AssignmentExpression {
pub identifier: String, pub identifier: Spanned<String>,
pub expression: Box<Spanned<Expression>>, pub expression: Box<Spanned<Expression>>,
} }
@@ -86,8 +86,8 @@ impl std::fmt::Display for AssignmentExpression {
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct FunctionExpression { pub struct FunctionExpression {
pub name: String, pub name: Spanned<String>,
pub arguments: Vec<String>, pub arguments: Vec<Spanned<String>>,
pub body: BlockExpression, pub body: BlockExpression,
} }
@@ -97,7 +97,11 @@ impl std::fmt::Display for FunctionExpression {
f, f,
"(fn {}({}) {{ {} }})", "(fn {}({}) {{ {} }})",
self.name, self.name,
self.arguments.to_vec().join(", "), self.arguments
.iter()
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join(", "),
self.body self.body
) )
} }
@@ -122,7 +126,7 @@ impl std::fmt::Display for BlockExpression {
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct InvocationExpression { pub struct InvocationExpression {
pub name: String, pub name: Spanned<String>,
pub arguments: Vec<Expression>, pub arguments: Vec<Expression>,
} }
@@ -144,7 +148,7 @@ impl std::fmt::Display for InvocationExpression {
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum LiteralOrVariable { pub enum LiteralOrVariable {
Literal(Literal), Literal(Literal),
Variable(String), Variable(Spanned<String>),
} }
impl std::fmt::Display for LiteralOrVariable { impl std::fmt::Display for LiteralOrVariable {
@@ -159,7 +163,7 @@ impl std::fmt::Display for LiteralOrVariable {
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct DeviceDeclarationExpression { pub struct DeviceDeclarationExpression {
/// any variable-like name /// any variable-like name
pub name: String, pub name: Spanned<String>,
/// The device port, ex. (db, d0, d1, d2, d3, d4, d5) /// The device port, ex. (db, d0, d1, d2, d3, d4, d5)
pub device: String, pub device: String,
} }
@@ -218,7 +222,7 @@ pub struct Span {
pub end_col: usize, pub end_col: usize,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Spanned<T> { pub struct Spanned<T> {
pub span: Span, pub span: Span,
pub node: T, pub node: T,
@@ -248,7 +252,7 @@ pub enum Expression {
Block(Spanned<BlockExpression>), Block(Spanned<BlockExpression>),
Break(Span), Break(Span),
Continue(Span), Continue(Span),
Declaration(String, Box<Spanned<Expression>>), Declaration(Spanned<String>, Box<Spanned<Expression>>),
DeviceDeclaration(Spanned<DeviceDeclarationExpression>), DeviceDeclaration(Spanned<DeviceDeclarationExpression>),
Function(Spanned<FunctionExpression>), Function(Spanned<FunctionExpression>),
If(Spanned<IfExpression>), If(Spanned<IfExpression>),
@@ -289,3 +293,4 @@ impl std::fmt::Display for Expression {
} }
} }
} }