Introduce boolean types
This commit is contained in:
parent
2a560cfcef
commit
d1883ff3ab
62
src/main.rs
62
src/main.rs
@ -10,6 +10,7 @@ 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),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ enum Datatype
|
|||||||
{
|
{
|
||||||
Int,
|
Int,
|
||||||
String,
|
String,
|
||||||
|
Bool,
|
||||||
//Pointer,
|
//Pointer,
|
||||||
Any,
|
Any,
|
||||||
}
|
}
|
||||||
@ -71,6 +73,10 @@ 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::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
|
||||||
@ -156,7 +162,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 == "0"
|
if val == "true"
|
||||||
{
|
{
|
||||||
interpret_program(if_block, queue, functions, intrinsics, debug);
|
interpret_program(if_block, queue, functions, intrinsics, debug);
|
||||||
}
|
}
|
||||||
@ -185,6 +191,30 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
|||||||
let addend2 = queue.remove(0).parse::<i64>().unwrap();
|
let addend2 = queue.remove(0).parse::<i64>().unwrap();
|
||||||
queue.push((addend1 + addend2).to_string());
|
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);
|
||||||
@ -196,7 +226,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
|||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
let val = queue.remove(0);
|
let val = queue.remove(0);
|
||||||
if val == "0"
|
if val == "false"
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -348,9 +378,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::Int
|
if comparison_type != Datatype::Bool
|
||||||
{
|
{
|
||||||
panic!("Expected an int as an if condition but got {:?} instead at {}:{}", comparison_type, line, col);
|
panic!("Expected a Bool as an if condition but got {:?} instead at {}:{}", comparison_type, line, col);
|
||||||
}
|
}
|
||||||
if debug
|
if debug
|
||||||
{
|
{
|
||||||
@ -401,16 +431,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.remove(0);
|
||||||
if comparison_type != Datatype::Int
|
if comparison_type != Datatype::Bool
|
||||||
{
|
{
|
||||||
panic!("Expected an int as a while condition but got {:?} instead at {}:{}", comparison_type, line, col);
|
panic!("Expected a Bool 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();
|
let mut outs = type_queue.clone();
|
||||||
outs.insert(0, Datatype::Int);
|
outs.insert(0, Datatype::Bool);
|
||||||
typecheck_block(while_block, type_queue, &outs, functions, intrinsics, debug);
|
typecheck_block(while_block, type_queue, &outs, functions, intrinsics, debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,7 +524,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::IntLit(_, line, col) | Token::StringLit(_, line, col) | Token::BoolLit(_, 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);
|
||||||
}
|
}
|
||||||
@ -509,6 +539,7 @@ 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,7 +562,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::IntLit(_, line, col) | Token::StringLit(_, line, col) | Token::BoolLit(_, 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);
|
||||||
}
|
}
|
||||||
@ -542,7 +573,8 @@ 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),
|
||||||
"{" | "}" | "deq" | "req" | "dup" | "swp" => panic!("Expected function name but got {} at {}:{}", word, line, col),
|
"bool" => ins.push(Datatype::Bool),
|
||||||
|
"{" | "}" | "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)
|
||||||
@ -620,6 +652,10 @@ 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())
|
||||||
@ -751,7 +787,7 @@ fn tokenize(text: &str) -> Vec<Token>
|
|||||||
if ch == '"'
|
if ch == '"'
|
||||||
{
|
{
|
||||||
state = TokenizerState::Whitespace;
|
state = TokenizerState::Whitespace;
|
||||||
tokens.push(Token::StringLit(word.clone(), line, col));
|
tokens.push(Token::StringLit(word.clone().replace("\\n", "\n"), line, col));
|
||||||
word.clear();
|
word.clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -768,6 +804,10 @@ 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));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//valid
|
//valid
|
||||||
//output: Hello, World!\n4242test2Falsetesttesttest
|
//output: Hello, World!
|
||||||
|
//4242test2Falsetesttesttest
|
||||||
|
|
||||||
"Hello, World!\n" print 43 foo foo deq
|
"Hello, World!\n" print 43 foo foo deq
|
||||||
|
|
||||||
@ -10,12 +11,12 @@ function any => int foo
|
|||||||
deq 42 17 print
|
deq 42 17 print
|
||||||
}
|
}
|
||||||
|
|
||||||
"test2" print 1
|
"test2" print false
|
||||||
check
|
check
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
||||||
function int => str check
|
function bool => str check
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
{
|
{
|
||||||
@ -27,20 +28,14 @@ function int => str check
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3
|
|
||||||
// 3 3
|
|
||||||
// 3
|
|
||||||
// 3 1
|
|
||||||
// 2
|
|
||||||
// 2 "test"
|
|
||||||
// "test" 2
|
|
||||||
|
|
||||||
function int => whileFunction
|
function int => whileFunction
|
||||||
{
|
{
|
||||||
dup
|
dup
|
||||||
while
|
0 req >
|
||||||
|
req while
|
||||||
{
|
{
|
||||||
1 - "test" req print dup
|
1 - 0 dup >
|
||||||
|
"test" req req print req
|
||||||
}
|
}
|
||||||
deq
|
deq
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
//valid,output:10987654321
|
//valid,output:10987654321
|
||||||
|
|
||||||
12 while
|
true while
|
||||||
{
|
{
|
||||||
0
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
10 dup while
|
10 0 dup > req
|
||||||
|
while
|
||||||
{
|
{
|
||||||
dup print 1 - dup
|
dup print
|
||||||
|
|
||||||
|
1 - 0 dup > req
|
||||||
}
|
}
|
||||||
deq
|
deq
|
||||||
|
|
||||||
|
true true true while
|
||||||
|
{
|
||||||
|
false
|
||||||
|
}
|
||||||
|
print print
|
Loading…
x
Reference in New Issue
Block a user