Compare commits

..

No commits in common. "d1883ff3aba30b067dc40a42cbb149a502fe8b57" and "89a7780d10a880defc8de3dd2760728c53609d83" have entirely different histories.

5 changed files with 21 additions and 165 deletions

View File

@ -10,7 +10,6 @@ enum Token
{
StringLit(String, i32, i32),
IntLit(String, i32, i32),
BoolLit(String, i32, i32),
Keyword(String, i32, i32),
}
@ -27,7 +26,6 @@ enum Datatype
{
Int,
String,
Bool,
//Pointer,
Any,
}
@ -56,10 +54,7 @@ enum Operation
{
Enqueue(Datatype, String, i32, i32),
Dequeue(i32, i32),
// TODO: req can be implemented in terms of dup and dequeue
Requeue(i32, i32),
Swap(i32, i32),
Dup(i32, i32),
Intrinsic(String, i32, i32),
FunctionCall(String, i32, i32),
If(Vec<Operation>, Option<Vec<Operation>>, i32, i32),
@ -72,11 +67,6 @@ fn main()
[
("print", (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]))),
]);
let args: Vec<String> = env::args().collect();
if args.len() < 2
@ -142,18 +132,6 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
let val = queue.remove(0);
queue.push(val);
}
Operation::Dup(_, _) =>
{
let val = queue.get(0).unwrap();
queue.push(val.clone());
}
Operation::Swap(_, _) =>
{
let first = queue.remove(0);
let second = queue.remove(0);
queue.push(second);
queue.push(first);
}
Operation::FunctionCall(function_name, _, _) =>
{
interpret_program(&functions.iter().find(|x| &x.name == function_name).unwrap().content, queue, functions, intrinsics, debug);
@ -162,7 +140,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
{
let val = queue.remove(0);
// TODO: Add bool type
if val == "true"
if val == "0"
{
interpret_program(if_block, queue, functions, intrinsics, debug);
}
@ -185,36 +163,6 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
let subtrahend = queue.remove(0).parse::<i64>().unwrap();
queue.push((minuend - subtrahend).to_string());
}
"+" =>
{
let addend1 = queue.remove(0).parse::<i64>().unwrap();
let addend2 = queue.remove(0).parse::<i64>().unwrap();
queue.push((addend1 + addend2).to_string());
}
">" =>
{
let first = queue.remove(0).parse::<i64>().unwrap();
let second = queue.remove(0).parse::<i64>().unwrap();
queue.push((first > second).to_string());
}
"<" =>
{
let first = queue.remove(0).parse::<i64>().unwrap();
let second = queue.remove(0).parse::<i64>().unwrap();
queue.push((first < second).to_string());
}
"==" =>
{
let first = queue.remove(0).parse::<i64>().unwrap();
let second = queue.remove(0).parse::<i64>().unwrap();
queue.push((first == second).to_string());
}
"!=" =>
{
let first = queue.remove(0).parse::<i64>().unwrap();
let second = queue.remove(0).parse::<i64>().unwrap();
queue.push((first != second).to_string());
}
_ =>
{
panic!("Unexpected intrinsic '{}' at {}:{}", intrinsic_name, line, col);
@ -225,8 +173,8 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
{
loop
{
let val = queue.remove(0);
if val == "false"
let val = queue.get(0).unwrap();
if val == "0"
{
break;
}
@ -279,8 +227,6 @@ fn typecheck_block(operations: &Vec<Operation>, ins: &Vec<Datatype>, outs: &Vec<
{
Operation::Enqueue(_, _, line, col) |
Operation::Requeue(line, col) |
Operation::Dup(line, col) |
Operation::Swap(line, col) |
Operation::FunctionCall(_, line, col) |
Operation::If(_, _, line, col) |
Operation::Intrinsic(_, line, col) |
@ -319,17 +265,6 @@ fn get_return_type(operations: &Vec<Operation>, ins: &Vec<Datatype>, functions:
{
type_queue.push(*datatype);
}
Operation::Dup(line, col) =>
{
if let Some(typ) = type_queue.get(0)
{
type_queue.push(typ.clone());
}
else
{
panic!("Attempted to dup an element while the queue was empty at {}:{}", line, col);
}
}
Operation::Requeue(line, col) =>
{
if type_queue.is_empty()
@ -339,21 +274,6 @@ fn get_return_type(operations: &Vec<Operation>, ins: &Vec<Datatype>, functions:
let typ = type_queue.remove(0);
type_queue.push(typ);
}
Operation::Swap(line, col) =>
{
if type_queue.is_empty()
{
panic!("Attempted to get the first element for a swap while the queue was empty at {}:{}", line, col);
}
let first_typ = type_queue.remove(0);
if type_queue.is_empty()
{
panic!("Attempted to get the second element for a swap while the queue was empty at {}:{}", line, col);
}
let second_typ = type_queue.remove(0);
type_queue.push(second_typ);
type_queue.push(first_typ);
}
Operation::FunctionCall(function_name, line, col) =>
{
let function = functions.iter().find(|x| &x.name == function_name).unwrap();
@ -378,9 +298,9 @@ fn get_return_type(operations: &Vec<Operation>, ins: &Vec<Datatype>, functions:
panic!("Encountered if block with an empty queue at {}:{}", line, col);
}
let comparison_type = type_queue.remove(0);
if comparison_type != Datatype::Bool
if comparison_type != Datatype::Int
{
panic!("Expected a Bool as an if condition but got {:?} instead at {}:{}", comparison_type, line, col);
panic!("Expected an int as an if condition but got {:?} instead at {}:{}", comparison_type, line, col);
}
if debug
{
@ -430,18 +350,16 @@ fn get_return_type(operations: &Vec<Operation>, ins: &Vec<Datatype>, functions:
{
panic!("Encountered while block with an empty queue at {}:{}", line, col);
}
let comparison_type = type_queue.remove(0);
if comparison_type != Datatype::Bool
let &comparison_type = type_queue.get(0).unwrap();
if comparison_type != Datatype::Int
{
panic!("Expected a Bool as a while condition but got {:?} instead at {}:{}", comparison_type, line, col);
panic!("Expected an int as a while condition but got {:?} instead at {}:{}", comparison_type, line, col);
}
if debug
{
println!("Starting to typecheck while block");
}
let mut outs = type_queue.clone();
outs.insert(0, Datatype::Bool);
typecheck_block(while_block, type_queue, &outs, functions, intrinsics, debug);
typecheck_block(while_block, type_queue, type_queue, functions, intrinsics, debug);
}
}
if debug
@ -475,12 +393,12 @@ 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::Intrinsic(_, _, _) | Operation::Enqueue(_, _, _, _) | Operation::Dequeue(_, _) | Operation::Requeue(_, _) => {},
Operation::FunctionCall(function_name, line, col) =>
{
if !functions.iter().any(|x| &x.name == function_name)
{
panic!("Call to unknown function '{}' at {}:{}", function_name, line, col);
panic!("Call to unknown function {} at {}:{}", function_name, line, col);
}
}
Operation::If(if_block, maybe_else_block, _, _) =>
@ -524,7 +442,7 @@ fn extract_functions(tokens: &mut Vec<Token>, intrinsics: &HashMap<&str, (Vec<Da
{
match token
{
Token::IntLit(_, line, col) | Token::StringLit(_, line, col) | Token::BoolLit(_, line, col) =>
Token::IntLit(_, line, col) | Token::StringLit(_, line, col) =>
{
panic!("Expected input parameters for a function but got {:?} instead at {}:{}", token, line, col);
}
@ -539,7 +457,6 @@ fn extract_functions(tokens: &mut Vec<Token>, intrinsics: &HashMap<&str, (Vec<Da
"any" => ins.push(Datatype::Any),
"str" => ins.push(Datatype::String),
"int" => ins.push(Datatype::Int),
"bool" => ins.push(Datatype::Bool),
_ => panic!("Expected input parameters for a function but got {} instead at {}:{}", word, line, col)
}
}
@ -562,7 +479,7 @@ fn extract_functions(tokens: &mut Vec<Token>, intrinsics: &HashMap<&str, (Vec<Da
{
match token
{
Token::IntLit(_, line, col) | Token::StringLit(_, line, col) | Token::BoolLit(_, line, col) =>
Token::IntLit(_, line, col) | Token::StringLit(_, line, col) =>
{
panic!("Expected input parameters for a function but got {:?} instead at {}:{}", token, line, col);
}
@ -573,8 +490,7 @@ 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),
"{" | "}" | "deq" | "req" => panic!("Expected function name but got {} at {}:{}", word, line, col),
_ =>
{
if functions.iter().any(|x| &x.name == word)
@ -652,10 +568,6 @@ fn parse_until_delimiter(tokens_iter: &mut Peekable<std::slice::Iter<Token>>, in
{
operations.push(Operation::Enqueue(Datatype::String, value.clone(), *line, *col));
}
Token::BoolLit(value, line, col) =>
{
operations.push(Operation::Enqueue(Datatype::Bool, value.clone(), *line, *col));
}
Token::Keyword(word, line, col) =>
{
if intrinsics.contains_key(word.as_str())
@ -694,16 +606,9 @@ fn parse_until_delimiter(tokens_iter: &mut Peekable<std::slice::Iter<Token>>, in
}
else if word == "req"
{
operations.push(Operation::Requeue(*line, *col));
}
else if word == "dup"
{
operations.push(Operation::Dup(*line, *col));
}
else if word == "swp"
{
operations.push(Operation::Swap(*line, *col));
}
else if Some(word.as_str()) == delimiter
{
return operations;
@ -787,7 +692,7 @@ fn tokenize(text: &str) -> Vec<Token>
if ch == '"'
{
state = TokenizerState::Whitespace;
tokens.push(Token::StringLit(word.clone().replace("\\n", "\n"), line, col));
tokens.push(Token::StringLit(word.clone(), line, col));
word.clear();
}
else
@ -804,10 +709,6 @@ fn tokenize(text: &str) -> Vec<Token>
{
tokens.push(Token::IntLit(word.clone(), line, col));
}
else if word == "true" || word == "false"
{
tokens.push(Token::BoolLit(word.clone(), line, col));
}
else
{
tokens.push(Token::Keyword(word.clone(), line, col));

View File

@ -1,13 +0,0 @@
function int int int => int fibonacci
{
dup if
{
req deq deq
}
else
{
1 dup + - swp fibonacci
}
}
20 1 0 fibonacci print

View File

@ -1,7 +0,0 @@
function int int => int int req_impl
{
dup deq
}
1 2 3 req_impl print print print
1 2 3 req print print print

View File

@ -1,6 +1,5 @@
//valid
//output: Hello, World!
//4242test2Falsetesttesttest
//output: Hello, World!\n4242test2Falsetesttesttest
"Hello, World!\n" print 43 foo foo deq
@ -11,12 +10,12 @@ function any => int foo
deq 42 17 print
}
"test2" print false
"test2" print 1
check
print
function bool => str check
function int => str check
{
if
{
@ -30,12 +29,9 @@ function bool => str check
function int => whileFunction
{
dup
0 req >
req while
while
{
1 - 0 dup >
"test" req req print req
1 - "test" req print
}
deq
}

View File

@ -1,21 +0,0 @@
//valid,output:10987654321
true while
{
false
}
10 0 dup > req
while
{
dup print
1 - 0 dup > req
}
deq
true true true while
{
false
}
print print