Add interpreter

This commit is contained in:
0x4261756D 2022-12-14 09:34:41 +01:00
parent abfb3d2f3d
commit 48cb618d5a
1 changed files with 92 additions and 1 deletions

View File

@ -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);