revert compiler
This commit is contained in:
@@ -6,8 +6,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, MethodCallExpression, Span, Spanned,
|
LiteralOrVariable, LogicalExpression, LoopExpression, Span, Spanned, WhileExpression,
|
||||||
WhileExpression,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use quick_error::quick_error;
|
use quick_error::quick_error;
|
||||||
@@ -352,9 +351,6 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
|||||||
temp_name: Some(result_name),
|
temp_name: Some(result_name),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Expression::MethodCall(method_expr) => {
|
|
||||||
self.expression_method_call(method_expr.node, scope, method_expr.span)
|
|
||||||
}
|
|
||||||
_ => Err(Error::Unknown(
|
_ => Err(Error::Unknown(
|
||||||
format!(
|
format!(
|
||||||
"Expression type not yet supported in general expression context: {:?}",
|
"Expression type not yet supported in general expression context: {:?}",
|
||||||
@@ -544,28 +540,6 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
|||||||
scope,
|
scope,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Expression::MethodCall(method_expr) => {
|
|
||||||
if let Some(result) =
|
|
||||||
self.expression_method_call(method_expr.node, scope, method_expr.span)?
|
|
||||||
{
|
|
||||||
let var_loc = scope.add_variable(&name_str, LocationRequest::Persist)?;
|
|
||||||
|
|
||||||
// Move result from temp to new persistent variable
|
|
||||||
let result_reg = self.resolve_register(&result.location)?;
|
|
||||||
self.emit_variable_assignment(&name_str, &var_loc, result_reg)?;
|
|
||||||
|
|
||||||
// Free the temp result
|
|
||||||
if let Some(name) = result.temp_name {
|
|
||||||
scope.free_temp(name)?;
|
|
||||||
}
|
|
||||||
(var_loc, None)
|
|
||||||
} else {
|
|
||||||
return Err(Error::Unknown(
|
|
||||||
"Method call did not return a value".into(),
|
|
||||||
Some(method_expr.span),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::Unknown(
|
return Err(Error::Unknown(
|
||||||
format!("`{name_str}` declaration of this type is not supported/implemented."),
|
format!("`{name_str}` declaration of this type is not supported/implemented."),
|
||||||
@@ -1278,25 +1252,6 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
|||||||
scope.free_temp(name)?;
|
scope.free_temp(name)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::Invocation(invoke_expr) => {
|
|
||||||
self.expression_function_invocation(invoke_expr, scope)?;
|
|
||||||
// The result is already in RETURN_REGISTER from the call
|
|
||||||
}
|
|
||||||
Expression::MethodCall(method_expr) => {
|
|
||||||
if let Some(result) =
|
|
||||||
self.expression_method_call(method_expr.node, scope, method_expr.span)?
|
|
||||||
{
|
|
||||||
let result_reg = self.resolve_register(&result.location)?;
|
|
||||||
self.write_output(format!(
|
|
||||||
"move r{} {}",
|
|
||||||
VariableScope::RETURN_REGISTER,
|
|
||||||
result_reg
|
|
||||||
))?;
|
|
||||||
if let Some(name) = result.temp_name {
|
|
||||||
scope.free_temp(name)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::Unknown(
|
return Err(Error::Unknown(
|
||||||
format!("Unsupported `return` statement: {:?}", expr),
|
format!("Unsupported `return` statement: {:?}", expr),
|
||||||
@@ -1591,117 +1546,5 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
|||||||
self.write_output("j ra")?;
|
self.write_output("j ra")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expression_method_call<'v>(
|
|
||||||
&mut self,
|
|
||||||
expr: MethodCallExpression,
|
|
||||||
scope: &mut VariableScope<'v>,
|
|
||||||
span: Span,
|
|
||||||
) -> Result<Option<CompilationResult>, Error> {
|
|
||||||
let object_name = expr.object.node;
|
|
||||||
|
|
||||||
if let Some(device_val) = self.devices.get(&object_name).cloned() {
|
|
||||||
match expr.method.node.as_str() {
|
|
||||||
"load" => {
|
|
||||||
if expr.arguments.len() != 1 {
|
|
||||||
return Err(Error::AgrumentMismatch(
|
|
||||||
"load expects 1 argument".into(),
|
|
||||||
span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let arg = expr.arguments.into_iter().next().unwrap();
|
|
||||||
let logic_type = match arg.node {
|
|
||||||
Expression::Literal(l) => match l.node {
|
|
||||||
Literal::String(s) => s,
|
|
||||||
_ => {
|
|
||||||
return Err(Error::AgrumentMismatch(
|
|
||||||
"load argument must be a string literal".into(),
|
|
||||||
arg.span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return Err(Error::AgrumentMismatch(
|
|
||||||
"load argument must be a string literal".into(),
|
|
||||||
arg.span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.write_output(format!(
|
|
||||||
"l r{} {} {}",
|
|
||||||
VariableScope::RETURN_REGISTER,
|
|
||||||
device_val,
|
|
||||||
logic_type
|
|
||||||
))?;
|
|
||||||
|
|
||||||
// Move result to a temp register to be safe for use in expressions
|
|
||||||
let temp_name = self.next_temp_name();
|
|
||||||
let temp_loc = scope.add_variable(&temp_name, LocationRequest::Temp)?;
|
|
||||||
self.emit_variable_assignment(
|
|
||||||
&temp_name,
|
|
||||||
&temp_loc,
|
|
||||||
format!("r{}", VariableScope::RETURN_REGISTER),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
return Ok(Some(CompilationResult {
|
|
||||||
location: temp_loc,
|
|
||||||
temp_name: Some(temp_name),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
"set" => {
|
|
||||||
if expr.arguments.len() != 2 {
|
|
||||||
return Err(Error::AgrumentMismatch(
|
|
||||||
"set expects 2 arguments".into(),
|
|
||||||
span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut args_iter = expr.arguments.into_iter();
|
|
||||||
let logic_type_arg = args_iter.next().unwrap();
|
|
||||||
let value_arg = args_iter.next().unwrap();
|
|
||||||
|
|
||||||
let logic_type = match logic_type_arg.node {
|
|
||||||
Expression::Literal(l) => match l.node {
|
|
||||||
Literal::String(s) => s,
|
|
||||||
_ => {
|
|
||||||
return Err(Error::AgrumentMismatch(
|
|
||||||
"set expects a string literal as first argument".into(),
|
|
||||||
logic_type_arg.span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return Err(Error::AgrumentMismatch(
|
|
||||||
"set expects a string literal as first argument".into(),
|
|
||||||
logic_type_arg.span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let (val_str, cleanup) = self.compile_operand(value_arg, scope)?;
|
|
||||||
|
|
||||||
self.write_output(format!("s {} {} {}", device_val, logic_type, val_str))?;
|
|
||||||
|
|
||||||
if let Some(name) = cleanup {
|
|
||||||
scope.free_temp(name)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(Error::Unknown(
|
|
||||||
format!(
|
|
||||||
"Unknown method '{}' on device '{}'",
|
|
||||||
expr.method.node, object_name
|
|
||||||
),
|
|
||||||
Some(span),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(Error::UnknownIdentifier(object_name, expr.object.span))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user