Add interpreter
This commit is contained in:
parent
abfb3d2f3d
commit
48cb618d5a
93
src/main.rs
93
src/main.rs
|
@ -74,11 +74,13 @@ fn main()
|
|||
usage()
|
||||
}
|
||||
let mut debug = false;
|
||||
let mut interpret = false;
|
||||
for arg in &args[3..]
|
||||
{
|
||||
match arg.as_str()
|
||||
{
|
||||
"-d" | "--debug" => debug = true,
|
||||
"-i" | "--interpret" => interpret = true,
|
||||
_ => panic!("Unknown option {}", arg),
|
||||
}
|
||||
}
|
||||
|
@ -97,11 +99,96 @@ fn main()
|
|||
println!("---Done validating function calls---");
|
||||
typecheck(&operations, &functions, &intrinsics, debug);
|
||||
println!("---Done typechecking---");
|
||||
if interpret
|
||||
{
|
||||
println!("---Starting to interpret the program---\n\n");
|
||||
interpret_program(&operations, &mut Vec::new(), &functions, &intrinsics, debug);
|
||||
}
|
||||
}
|
||||
_ => panic!("Unknown option {}", args[1])
|
||||
}
|
||||
}
|
||||
|
||||
fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool)
|
||||
{
|
||||
for operation in operations
|
||||
{
|
||||
if debug
|
||||
{
|
||||
println!("before: {:?}: {:?}", operation, queue);
|
||||
}
|
||||
match operation
|
||||
{
|
||||
Operation::Dequeue(_, _) =>
|
||||
{
|
||||
queue.remove(0);
|
||||
}
|
||||
Operation::Enqueue(_, value, _, _) =>
|
||||
{
|
||||
queue.push(value.clone());
|
||||
}
|
||||
Operation::Requeue(_, _) =>
|
||||
{
|
||||
let val = queue.remove(0);
|
||||
queue.push(val);
|
||||
}
|
||||
Operation::FunctionCall(function_name, _, _) =>
|
||||
{
|
||||
interpret_program(&functions.iter().find(|x| &x.name == function_name).unwrap().content, queue, functions, intrinsics, debug);
|
||||
}
|
||||
Operation::If(if_block, maybe_else_block, _, _) =>
|
||||
{
|
||||
let val = queue.remove(0);
|
||||
// TODO: Add bool type
|
||||
if val == "0"
|
||||
{
|
||||
interpret_program(if_block, queue, functions, intrinsics, debug);
|
||||
}
|
||||
else if let Some(else_block) = maybe_else_block
|
||||
{
|
||||
interpret_program(else_block, queue, functions, intrinsics, debug);
|
||||
}
|
||||
}
|
||||
Operation::Intrinsic(intrinsic_name, line, col) =>
|
||||
{
|
||||
match intrinsic_name.as_str()
|
||||
{
|
||||
"print" =>
|
||||
{
|
||||
print!("{}", queue.remove(0));
|
||||
}
|
||||
"-" =>
|
||||
{
|
||||
let minuend = queue.remove(0).parse::<i64>().unwrap();
|
||||
let subtrahend = queue.remove(0).parse::<i64>().unwrap();
|
||||
queue.push((minuend - subtrahend).to_string());
|
||||
}
|
||||
_ =>
|
||||
{
|
||||
panic!("Unexpected intrinsic '{}' at {}:{}", intrinsic_name, line, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
Operation::While(while_block, _, _) =>
|
||||
{
|
||||
loop
|
||||
{
|
||||
let val = queue.get(0).unwrap();
|
||||
if val == "0"
|
||||
{
|
||||
break;
|
||||
}
|
||||
interpret_program(while_block, queue, functions, intrinsics, debug);
|
||||
}
|
||||
}
|
||||
}
|
||||
if debug
|
||||
{
|
||||
println!("after: {:?}: {:?}", operation, queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn typecheck(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool)
|
||||
{
|
||||
for function in functions
|
||||
|
@ -403,13 +490,17 @@ fn extract_functions(tokens: &mut Vec<Token>, intrinsics: &HashMap<&str, (Vec<Da
|
|||
"any" => outs.push(Datatype::Any),
|
||||
"str" => outs.push(Datatype::String),
|
||||
"int" => outs.push(Datatype::Int),
|
||||
"{" | "}" => panic!("Expected function name but got {} at {}:{}", word, line, col),
|
||||
"{" | "}" | "deq" | "req" => panic!("Expected function name but got {} at {}:{}", word, line, col),
|
||||
_ =>
|
||||
{
|
||||
if functions.iter().any(|x| &x.name == word)
|
||||
{
|
||||
panic!("Redeclaration of function '{}' at {}:{}", word, line, col);
|
||||
}
|
||||
if intrinsics.contains_key(word.as_str())
|
||||
{
|
||||
panic!("Function name {} at {}:{} is already an intrinsic", word, line, col);
|
||||
}
|
||||
if debug
|
||||
{
|
||||
println!("outs: {:?}", outs);
|
||||
|
|
Loading…
Reference in New Issue