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), StringLit(String, i32, i32),
IntLit(String, i32, i32), IntLit(String, i32, i32),
BoolLit(String, i32, i32),
Keyword(String, i32, i32), Keyword(String, i32, i32),
} }
@ -27,7 +26,6 @@ enum Datatype
{ {
Int, Int,
String, String,
Bool,
//Pointer, //Pointer,
Any, Any,
} }
@ -56,10 +54,7 @@ enum Operation
{ {
Enqueue(Datatype, String, i32, i32), Enqueue(Datatype, String, i32, i32),
Dequeue(i32, i32), Dequeue(i32, i32),
// TODO: req can be implemented in terms of dup and dequeue
Requeue(i32, i32), Requeue(i32, i32),
Swap(i32, i32),
Dup(i32, i32),
Intrinsic(String, i32, i32), Intrinsic(String, i32, i32),
FunctionCall(String, i32, i32), FunctionCall(String, i32, i32),
If(Vec<Operation>, Option<Vec<Operation>>, i32, i32), If(Vec<Operation>, Option<Vec<Operation>>, i32, i32),
@ -72,11 +67,6 @@ fn main()
[ [
("print", (Vec::from([Datatype::Any]), Vec::new())), ("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::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(); let args: Vec<String> = env::args().collect();
if args.len() < 2 if args.len() < 2
@ -142,18 +132,6 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
let val = queue.remove(0); let val = queue.remove(0);
queue.push(val); 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, _, _) => Operation::FunctionCall(function_name, _, _) =>
{ {
interpret_program(&functions.iter().find(|x| &x.name == function_name).unwrap().content, queue, functions, intrinsics, debug); 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); let val = queue.remove(0);
// TODO: Add bool type // TODO: Add bool type
if val == "true" if val == "0"
{ {
interpret_program(if_block, queue, functions, intrinsics, debug); 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(); let subtrahend = queue.remove(0).parse::<i64>().unwrap();
queue.push((minuend - subtrahend).to_string()); 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); panic!("Unexpected intrinsic '{}' at {}:{}", intrinsic_name, line, col);
@ -225,8 +173,8 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
{ {
loop loop
{ {
let val = queue.remove(0); let val = queue.get(0).unwrap();
if val == "false" if val == "0"
{ {
break; break;
} }
@ -279,8 +227,6 @@ fn typecheck_block(operations: &Vec<Operation>, ins: &Vec<Datatype>, outs: &Vec<
{ {
Operation::Enqueue(_, _, line, col) | Operation::Enqueue(_, _, line, col) |
Operation::Requeue(line, col) | Operation::Requeue(line, col) |
Operation::Dup(line, col) |
Operation::Swap(line, col) |
Operation::FunctionCall(_, line, col) | Operation::FunctionCall(_, line, col) |
Operation::If(_, _, line, col) | Operation::If(_, _, line, col) |
Operation::Intrinsic(_, 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); 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) => Operation::Requeue(line, col) =>
{ {
if type_queue.is_empty() 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); let typ = type_queue.remove(0);
type_queue.push(typ); 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) => Operation::FunctionCall(function_name, line, col) =>
{ {
let function = functions.iter().find(|x| &x.name == function_name).unwrap(); 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); panic!("Encountered if block with an empty queue at {}:{}", line, col);
} }
let comparison_type = type_queue.remove(0); 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 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); panic!("Encountered while block with an empty queue at {}:{}", line, col);
} }
let comparison_type = type_queue.remove(0); let &comparison_type = type_queue.get(0).unwrap();
if comparison_type != Datatype::Bool 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 if debug
{ {
println!("Starting to typecheck while block"); println!("Starting to typecheck while block");
} }
let mut outs = type_queue.clone(); typecheck_block(while_block, type_queue, type_queue, functions, intrinsics, debug);
outs.insert(0, Datatype::Bool);
typecheck_block(while_block, type_queue, &outs, functions, intrinsics, debug);
} }
} }
if debug if debug
@ -475,12 +393,12 @@ fn validate_function_calls_in_block(block: &Vec<Operation>, functions: &Vec<Func
{ {
match operation 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) => Operation::FunctionCall(function_name, line, col) =>
{ {
if !functions.iter().any(|x| &x.name == function_name) 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, _, _) => 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 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); 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), "any" => ins.push(Datatype::Any),
"str" => ins.push(Datatype::String), "str" => ins.push(Datatype::String),
"int" => ins.push(Datatype::Int), "int" => ins.push(Datatype::Int),
"bool" => ins.push(Datatype::Bool),
_ => panic!("Expected input parameters for a function but got {} instead at {}:{}", word, line, col) _ => 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 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); 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), "any" => outs.push(Datatype::Any),
"str" => outs.push(Datatype::String), "str" => outs.push(Datatype::String),
"int" => outs.push(Datatype::Int), "int" => outs.push(Datatype::Int),
"bool" => ins.push(Datatype::Bool), "{" | "}" | "deq" | "req" => panic!("Expected function name but got {} at {}:{}", word, line, col),
"{" | "}" | "deq" | "req" | "dup" | "swp" | "true" | "false" => panic!("Expected function name but got {} at {}:{}", word, line, col),
_ => _ =>
{ {
if functions.iter().any(|x| &x.name == word) 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)); 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) => Token::Keyword(word, line, col) =>
{ {
if intrinsics.contains_key(word.as_str()) 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" else if word == "req"
{ {
operations.push(Operation::Requeue(*line, *col)); 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 else if Some(word.as_str()) == delimiter
{ {
return operations; return operations;
@ -787,7 +692,7 @@ fn tokenize(text: &str) -> Vec<Token>
if ch == '"' if ch == '"'
{ {
state = TokenizerState::Whitespace; state = TokenizerState::Whitespace;
tokens.push(Token::StringLit(word.clone().replace("\\n", "\n"), line, col)); tokens.push(Token::StringLit(word.clone(), line, col));
word.clear(); word.clear();
} }
else else
@ -804,10 +709,6 @@ fn tokenize(text: &str) -> Vec<Token>
{ {
tokens.push(Token::IntLit(word.clone(), line, col)); tokens.push(Token::IntLit(word.clone(), line, col));
} }
else if word == "true" || word == "false"
{
tokens.push(Token::BoolLit(word.clone(), line, col));
}
else else
{ {
tokens.push(Token::Keyword(word.clone(), line, col)); 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 //valid
//output: Hello, World! //output: Hello, World!\n4242test2Falsetesttesttest
//4242test2Falsetesttesttest
"Hello, World!\n" print 43 foo foo deq "Hello, World!\n" print 43 foo foo deq
@ -11,12 +10,12 @@ function any => int foo
deq 42 17 print deq 42 17 print
} }
"test2" print false "test2" print 1
check check
print print
function bool => str check function int => str check
{ {
if if
{ {
@ -30,12 +29,9 @@ function bool => str check
function int => whileFunction function int => whileFunction
{ {
dup while
0 req >
req while
{ {
1 - 0 dup > 1 - "test" req print
"test" req req print req
} }
deq 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