Add new operations and intrinsics

This commit is contained in:
0x4261756D 2022-12-15 20:34:56 +01:00
parent d1883ff3ab
commit 0de0838284
4 changed files with 87 additions and 9 deletions

View File

@ -64,6 +64,8 @@ enum Operation
FunctionCall(String, i32, i32),
If(Vec<Operation>, Option<Vec<Operation>>, i32, i32),
While(Vec<Operation>, i32, i32),
Depth(i32, i32),
QueueDiagnostic(i32, i32),
}
fn main()
@ -71,12 +73,14 @@ fn main()
let intrinsics: HashMap<&str, (Vec<Datatype>, Vec<Datatype>)> = HashMap::from(
[
("print", (Vec::from([Datatype::Any]), Vec::new())),
("println", (Vec::from([Datatype::Any]), Vec::new())),
("-", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Int]))),
("+", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Int]))),
("<", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Bool]))),
(">", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Bool]))),
("==", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Bool]))),
("!=", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Bool]))),
("decrease", (Vec::from([Datatype::Int]), Vec::from([Datatype::Int]))),
]);
let args: Vec<String> = env::args().collect();
if args.len() < 2
@ -156,12 +160,22 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
}
Operation::FunctionCall(function_name, _, _) =>
{
interpret_program(&functions.iter().find(|x| &x.name == function_name).unwrap().content, queue, functions, intrinsics, debug);
let function = functions.iter().find(|x| &x.name == function_name).unwrap();
let function_context: &mut Vec<String> = &mut Vec::new();
for _ in 0..function.ins.len()
{
let val = queue.remove(0);
function_context.push(val);
}
interpret_program(&function.content, function_context, functions, intrinsics, debug);
for val in function_context
{
queue.push(val.to_string());
}
}
Operation::If(if_block, maybe_else_block, _, _) =>
{
let val = queue.remove(0);
// TODO: Add bool type
if val == "true"
{
interpret_program(if_block, queue, functions, intrinsics, debug);
@ -215,6 +229,15 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
let second = queue.remove(0).parse::<i64>().unwrap();
queue.push((first != second).to_string());
}
"decrease" =>
{
let val = queue.remove(0).parse::<i64>().unwrap();
queue.push((val - 1).to_string());
}
"println" =>
{
println!("{}", queue.remove(0));
}
_ =>
{
panic!("Unexpected intrinsic '{}' at {}:{}", intrinsic_name, line, col);
@ -233,6 +256,15 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
interpret_program(while_block, queue, functions, intrinsics, debug);
}
}
Operation::Depth(_, _) =>
{
let depth = queue.len();
queue.push(depth.to_string());
}
Operation::QueueDiagnostic(line, col) =>
{
println!("---Queue state at {}:{}---\nlength: {}\n{:?}\n------------------------------", line, col, queue.len(), queue);
}
}
if debug
{
@ -278,6 +310,7 @@ fn typecheck_block(operations: &Vec<Operation>, ins: &Vec<Datatype>, outs: &Vec<
match operation
{
Operation::Enqueue(_, _, line, col) |
Operation::Dequeue(line, col) |
Operation::Requeue(line, col) |
Operation::Dup(line, col) |
Operation::Swap(line, col) |
@ -285,7 +318,8 @@ fn typecheck_block(operations: &Vec<Operation>, ins: &Vec<Datatype>, outs: &Vec<
Operation::If(_, _, line, col) |
Operation::Intrinsic(_, line, col) |
Operation::While(_, line, col) |
Operation::Dequeue(line, col) => (*line, *col),
Operation::QueueDiagnostic(line, col) |
Operation::Depth(line, col) => (*line, *col),
}
}
None => (-1, -1)
@ -443,6 +477,14 @@ fn get_return_type(operations: &Vec<Operation>, ins: &Vec<Datatype>, functions:
outs.insert(0, Datatype::Bool);
typecheck_block(while_block, type_queue, &outs, functions, intrinsics, debug);
}
Operation::Depth(_, _) =>
{
type_queue.push(Datatype::Int);
}
Operation::QueueDiagnostic(line, col) =>
{
println!("---Type queue state at {}:{}---\nlength: {}\n{:?}\n------------------------------", line, col, type_queue.len(), type_queue);
}
}
if debug
{
@ -475,7 +517,8 @@ fn validate_function_calls_in_block(block: &Vec<Operation>, functions: &Vec<Func
{
match operation
{
Operation::Intrinsic(_, _, _) | Operation::Enqueue(_, _, _, _) | Operation::Dequeue(_, _) | Operation::Requeue(_, _) | Operation::Dup(_, _) | Operation::Swap(_, _) => {},
Operation::Depth(_, _) | Operation::QueueDiagnostic(_, _) | Operation::Intrinsic(_, _, _) | Operation::Enqueue(_, _, _, _) | Operation::Dequeue(_, _) |
Operation::Requeue(_, _) | Operation::Dup(_, _) | Operation::Swap(_, _) => {},
Operation::FunctionCall(function_name, line, col) =>
{
if !functions.iter().any(|x| &x.name == function_name)
@ -512,7 +555,7 @@ fn extract_functions(tokens: &mut Vec<Token>, intrinsics: &HashMap<&str, (Vec<Da
{
if debug
{
print!("Found a function at {}:{}", line, col);
println!("Found a function at {}:{}", line, col);
}
let mut ins: Vec<Datatype> = Vec::new();
loop
@ -573,8 +616,8 @@ 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),
"bool" => ins.push(Datatype::Bool),
"{" | "}" | "deq" | "req" | "dup" | "swp" | "true" | "false" => panic!("Expected function name but got {} at {}:{}", word, line, col),
"bool" => outs.push(Datatype::Bool),
"{" | "}" | "deq" | "req" | "dup" | "swp" | "true" | "false" | "depth" | "???" => panic!("Expected function name but got {} at {}:{}", word, line, col),
_ =>
{
if functions.iter().any(|x| &x.name == word)
@ -704,6 +747,14 @@ fn parse_until_delimiter(tokens_iter: &mut Peekable<std::slice::Iter<Token>>, in
{
operations.push(Operation::Swap(*line, *col));
}
else if word == "depth"
{
operations.push(Operation::Depth(*line, *col));
}
else if word == "???"
{
operations.push(Operation::QueueDiagnostic(*line, *col));
}
else if Some(word.as_str()) == delimiter
{
return operations;

View File

@ -5,4 +5,4 @@ function int => print
deq
}
42 print
42 print

View File

@ -3,4 +3,6 @@
function int =>
{
deq
}
}
42 print

25
tests/rule110.qbl Normal file
View File

@ -0,0 +1,25 @@
function bool bool bool => bool rule110
{
if
{
if
{
if
{
false
}
else
{
true
}
}
}
else
{
if
{
deq true
}
}
}