Add new operations and intrinsics
This commit is contained in:
parent
d1883ff3ab
commit
0de0838284
65
src/main.rs
65
src/main.rs
|
@ -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;
|
||||
|
|
|
@ -5,4 +5,4 @@ function int => print
|
|||
deq
|
||||
}
|
||||
|
||||
42 print
|
||||
42 print
|
||||
|
|
|
@ -3,4 +3,6 @@
|
|||
function int =>
|
||||
{
|
||||
deq
|
||||
}
|
||||
}
|
||||
|
||||
42 print
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
function bool bool bool => bool rule110
|
||||
{
|
||||
if
|
||||
{
|
||||
if
|
||||
{
|
||||
if
|
||||
{
|
||||
false
|
||||
}
|
||||
else
|
||||
{
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if
|
||||
{
|
||||
deq true
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue