Clean up
This commit is contained in:
parent
e90a4d7353
commit
21099a4092
@ -1,7 +1,5 @@
|
||||
(output "This will print first.")
|
||||
|
||||
create_random_numbers = |count <int>| {
|
||||
numbers = [];
|
||||
create_random_numbers <fn int> |count| {
|
||||
mnumbers = [];
|
||||
|
||||
while (length numbers) < count {
|
||||
numbers += (random_integer)
|
||||
@ -10,6 +8,8 @@ create_random_numbers = |count <int>| {
|
||||
(output "Made " + count + " numbers.")
|
||||
}
|
||||
|
||||
(output "This will print first.")
|
||||
|
||||
async {
|
||||
(create_random_numbers 1000)
|
||||
(create_random_numbers 100)
|
||||
|
@ -4,25 +4,25 @@ all_cards = {
|
||||
weapons = ['Rope' 'Lead_Pipe' 'Knife']
|
||||
}
|
||||
|
||||
is_ready_to_solve = |cards <map>| <bool> {
|
||||
is_ready_to_solve <fn map -> bool> |cards| {
|
||||
((length cards:suspects) == 1)
|
||||
&& ((length cards:rooms) == 1)
|
||||
&& ((length cards:weapons) == 1)
|
||||
}
|
||||
|
||||
take_turn = |opponent_card <str>, current_room <str>, cards <map>| <map> {
|
||||
take_turn <fn str str map -> map> |opponent_card current_room cards| {
|
||||
(remove_card opponent_card cards)
|
||||
(make_guess current_room cards)
|
||||
cards
|
||||
}
|
||||
|
||||
remove_card = |opponent_card <str>, cards <map>| {
|
||||
remove_card <fn str map> |opponent_card cards| {
|
||||
cards:rooms -= opponent_card
|
||||
cards:suspects -= opponent_card
|
||||
cards:weapons -= opponent_card
|
||||
}
|
||||
|
||||
make_guess = |current_room <str>, cards <map>| {
|
||||
make_guess <fn str map> |current_room cards| {
|
||||
if (is_ready_to_solve cards) {
|
||||
(output 'It was '
|
||||
+ cards:suspects:0
|
||||
|
@ -1,4 +1,4 @@
|
||||
fib <fn int -> int> = |i| {
|
||||
fib <fn int -> int> |i| {
|
||||
if i <= 1 {
|
||||
1
|
||||
} else {
|
||||
|
@ -1,15 +0,0 @@
|
||||
my_table = table |text number bool| [
|
||||
["a", 1, true]
|
||||
["b", 2, true]
|
||||
["a", 3, true]
|
||||
]
|
||||
|
||||
test_table = table |text bool| [
|
||||
["a", true]
|
||||
["b", true]
|
||||
["a", true]
|
||||
]
|
||||
|
||||
test_select = select |text bool| from my_table;
|
||||
|
||||
(assert_equal test_select, test_table)
|
@ -1,43 +0,0 @@
|
||||
my_table = table |text number bool| [
|
||||
["a", 1, true]
|
||||
["b", 2, true]
|
||||
["a", 3, true]
|
||||
]
|
||||
|
||||
test_table = table |text bool| [
|
||||
["a", true]
|
||||
["b", true]
|
||||
["a", true]
|
||||
]
|
||||
|
||||
test_select = select |text bool| from my_table;
|
||||
|
||||
(assert_equal test_select, test_table)
|
||||
|
||||
test_table = table |number bool| [
|
||||
[1, true]
|
||||
[3, true]
|
||||
]
|
||||
|
||||
test_select_where = select |number, bool| from my_table {
|
||||
text == "a"
|
||||
}
|
||||
|
||||
(assert_equal test_select_where, test_table)
|
||||
|
||||
test_table = table |text number bool| [
|
||||
["a", 1, true]
|
||||
["b", 2, true]
|
||||
["a", 3, true]
|
||||
["c", 4, true]
|
||||
["d", 5, true]
|
||||
["e", 6, true]
|
||||
]
|
||||
|
||||
insert into my_table [
|
||||
["c", 4, true]
|
||||
["d", 5, true]
|
||||
["e", 6, true]
|
||||
]
|
||||
|
||||
(assert_equal test_table, my_table)
|
@ -1,6 +1,6 @@
|
||||
1 -> (output)
|
||||
|
||||
add_one = |numbers <list>| <list> {
|
||||
add_one <fn [int] -> [int]> |numbers| {
|
||||
new_numbers = []
|
||||
|
||||
for number in numbers {
|
||||
|
@ -186,23 +186,10 @@ mod tests {
|
||||
x <list int> = []
|
||||
x += 1
|
||||
x
|
||||
",
|
||||
",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(Value::List(List::with_items(vec![Value::Integer(1)])), test);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_assignment() {
|
||||
let test = evaluate(
|
||||
"
|
||||
foobar <fn str -> str> = |text| { 'hi' }
|
||||
foobar
|
||||
",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(Value::String("hi".to_string()), test);
|
||||
}
|
||||
}
|
||||
|
@ -91,3 +91,26 @@ impl AbstractTree for FunctionCall {
|
||||
self.function.expected_type(context)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{evaluate, Value};
|
||||
|
||||
#[test]
|
||||
fn evaluate_function_call() {
|
||||
assert_eq!(
|
||||
evaluate(
|
||||
"
|
||||
foobar <fn str -> str> |message| { message }
|
||||
(foobar 'Hiya')
|
||||
",
|
||||
),
|
||||
Ok(Value::String("Hiya".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_built_in_function_call() {
|
||||
assert_eq!(evaluate("(output 'Hiya')"), Ok(Value::Empty));
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ mod tests {
|
||||
fn simple_function_declaration() {
|
||||
let test = evaluate(
|
||||
"
|
||||
fn foo <fn int -> int> = |x| { x }
|
||||
foo <fn int -> int> |x| { x }
|
||||
(foo 42)
|
||||
",
|
||||
)
|
||||
|
@ -85,3 +85,65 @@ impl AbstractTree for IfElse {
|
||||
self.if_block.expected_type(context)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{evaluate, Value};
|
||||
|
||||
#[test]
|
||||
fn evaluate_if() {
|
||||
assert_eq!(
|
||||
evaluate("if true { 'true' }"),
|
||||
Ok(Value::String("true".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_if_else() {
|
||||
assert_eq!(evaluate("if false { 1 } else { 2 }"), Ok(Value::Integer(2)));
|
||||
assert_eq!(
|
||||
evaluate("if true { 1.0 } else { 42.0 }"),
|
||||
Ok(Value::Float(1.0))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_if_else_else_if_else() {
|
||||
assert_eq!(
|
||||
evaluate(
|
||||
"
|
||||
if false {
|
||||
'no'
|
||||
} else if 1 + 1 == 3 {
|
||||
'nope'
|
||||
} else {
|
||||
'ok'
|
||||
}
|
||||
"
|
||||
),
|
||||
Ok(Value::String("ok".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_if_else_if_else_if_else_if_else() {
|
||||
assert_eq!(
|
||||
evaluate(
|
||||
"
|
||||
if false {
|
||||
'no'
|
||||
} else if 1 + 1 == 1 {
|
||||
'nope'
|
||||
} else if 9 / 2 == 4 {
|
||||
'nope'
|
||||
} else if 'foo' == 'bar' {
|
||||
'nope'
|
||||
} else {
|
||||
'ok'
|
||||
}
|
||||
"
|
||||
),
|
||||
Ok(Value::String("ok".to_string()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +147,12 @@ impl AbstractTree for Type {
|
||||
let type_node = node.child(0).unwrap();
|
||||
|
||||
let r#type = match type_node.kind() {
|
||||
"[" => {
|
||||
let item_type_node = node.child(1).unwrap();
|
||||
let item_type = Type::from_syntax_node(source, item_type_node, context)?;
|
||||
|
||||
Type::List(Box::new(item_type))
|
||||
}
|
||||
"any" => Type::Any,
|
||||
"bool" => Type::Boolean,
|
||||
"float" => Type::Float,
|
||||
@ -171,12 +177,6 @@ impl AbstractTree for Type {
|
||||
}
|
||||
}
|
||||
"int" => Type::Integer,
|
||||
"list" => {
|
||||
let item_type_node = node.child(1).unwrap();
|
||||
let item_type = Type::from_syntax_node(source, item_type_node, context)?;
|
||||
|
||||
Type::List(Box::new(item_type))
|
||||
}
|
||||
"map" => Type::Map,
|
||||
"num" => Type::Number,
|
||||
"str" => Type::String,
|
||||
|
@ -215,3 +215,68 @@ impl AbstractTree for ValueNode {
|
||||
Ok(type_definition)
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{evaluate, List};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn evaluate_empty() {
|
||||
assert_eq!(evaluate("x = 9"), Ok(Value::Empty));
|
||||
assert_eq!(evaluate("x = 1 + 1"), Ok(Value::Empty));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_integer() {
|
||||
assert_eq!(evaluate("1"), Ok(Value::Integer(1)));
|
||||
assert_eq!(evaluate("123"), Ok(Value::Integer(123)));
|
||||
assert_eq!(evaluate("-666"), Ok(Value::Integer(-666)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_float() {
|
||||
assert_eq!(evaluate("0.1"), Ok(Value::Float(0.1)));
|
||||
assert_eq!(evaluate("12.3"), Ok(Value::Float(12.3)));
|
||||
assert_eq!(evaluate("-6.66"), Ok(Value::Float(-6.66)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_string() {
|
||||
assert_eq!(evaluate("\"one\""), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(evaluate("'one'"), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(evaluate("`one`"), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(evaluate("`'one'`"), Ok(Value::String("'one'".to_string())));
|
||||
assert_eq!(evaluate("'`one`'"), Ok(Value::String("`one`".to_string())));
|
||||
assert_eq!(
|
||||
evaluate("\"'one'\""),
|
||||
Ok(Value::String("'one'".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_list() {
|
||||
assert_eq!(
|
||||
evaluate("[1, 2, 'foobar']"),
|
||||
Ok(Value::List(List::with_items(vec![
|
||||
Value::Integer(1),
|
||||
Value::Integer(2),
|
||||
Value::String("foobar".to_string()),
|
||||
])))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_map() {
|
||||
let map = Map::new();
|
||||
|
||||
{
|
||||
let mut variables = map.variables_mut().unwrap();
|
||||
|
||||
variables.insert("x".to_string(), Value::Integer(1));
|
||||
variables.insert("foo".to_string(), Value::String("bar".to_string()));
|
||||
}
|
||||
|
||||
assert_eq!(evaluate("{ x = 1, foo = 'bar' }"), Ok(Value::Map(map)));
|
||||
}
|
||||
}
|
||||
|
141
src/evaluate.rs
141
src/evaluate.rs
@ -84,144 +84,3 @@ impl<'c, 's> Interpreter<'c, 's> {
|
||||
self.syntax_tree.root_node().to_sexp()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{List, Table};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn evaluate_empty() {
|
||||
assert_eq!(evaluate("x = 9"), Ok(Value::Empty));
|
||||
assert_eq!(evaluate("x = 1 + 1"), Ok(Value::Empty));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_integer() {
|
||||
assert_eq!(evaluate("1"), Ok(Value::Integer(1)));
|
||||
assert_eq!(evaluate("123"), Ok(Value::Integer(123)));
|
||||
assert_eq!(evaluate("-666"), Ok(Value::Integer(-666)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_float() {
|
||||
assert_eq!(evaluate("0.1"), Ok(Value::Float(0.1)));
|
||||
assert_eq!(evaluate("12.3"), Ok(Value::Float(12.3)));
|
||||
assert_eq!(evaluate("-6.66"), Ok(Value::Float(-6.66)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_string() {
|
||||
assert_eq!(evaluate("\"one\""), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(evaluate("'one'"), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(evaluate("`one`"), Ok(Value::String("one".to_string())));
|
||||
assert_eq!(evaluate("`'one'`"), Ok(Value::String("'one'".to_string())));
|
||||
assert_eq!(evaluate("'`one`'"), Ok(Value::String("`one`".to_string())));
|
||||
assert_eq!(
|
||||
evaluate("\"'one'\""),
|
||||
Ok(Value::String("'one'".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_list() {
|
||||
assert_eq!(
|
||||
evaluate("[1, 2, 'foobar']"),
|
||||
Ok(Value::List(List::with_items(vec![
|
||||
Value::Integer(1),
|
||||
Value::Integer(2),
|
||||
Value::String("foobar".to_string()),
|
||||
])))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_map() {
|
||||
let map = Map::new();
|
||||
|
||||
{
|
||||
let mut variables = map.variables_mut().unwrap();
|
||||
|
||||
variables.insert("x".to_string(), Value::Integer(1));
|
||||
variables.insert("foo".to_string(), Value::String("bar".to_string()));
|
||||
}
|
||||
|
||||
assert_eq!(evaluate("{ x = 1, foo = 'bar' }"), Ok(Value::Map(map)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_if() {
|
||||
assert_eq!(
|
||||
evaluate("if true { 'true' }"),
|
||||
Ok(Value::String("true".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_if_else() {
|
||||
assert_eq!(evaluate("if false { 1 } else { 2 }"), Ok(Value::Integer(2)));
|
||||
assert_eq!(
|
||||
evaluate("if true { 1.0 } else { 42.0 }"),
|
||||
Ok(Value::Float(1.0))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_if_else_else_if_else() {
|
||||
assert_eq!(
|
||||
evaluate(
|
||||
"
|
||||
if false {
|
||||
'no'
|
||||
} else if 1 + 1 == 3 {
|
||||
'nope'
|
||||
} else {
|
||||
'ok'
|
||||
}
|
||||
"
|
||||
),
|
||||
Ok(Value::String("ok".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_if_else_if_else_if_else_if_else() {
|
||||
assert_eq!(
|
||||
evaluate(
|
||||
"
|
||||
if false {
|
||||
'no'
|
||||
} else if 1 + 1 == 1 {
|
||||
'nope'
|
||||
} else if 9 / 2 == 4 {
|
||||
'nope'
|
||||
} else if 'foo' == 'bar' {
|
||||
'nope'
|
||||
} else {
|
||||
'ok'
|
||||
}
|
||||
"
|
||||
),
|
||||
Ok(Value::String("ok".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_function_call() {
|
||||
assert_eq!(
|
||||
evaluate(
|
||||
"
|
||||
foobar <fn str -> str> = |message| { message }
|
||||
(foobar 'Hiya')
|
||||
",
|
||||
),
|
||||
Ok(Value::String("Hiya".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_built_in_function_call() {
|
||||
assert_eq!(evaluate("(output 'Hiya')"), Ok(Value::Empty));
|
||||
}
|
||||
}
|
||||
|
@ -95,20 +95,6 @@ fn sea_creatures() {
|
||||
evaluate(&file_contents).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn select() {
|
||||
let file_contents = read_to_string("examples/select.ds").unwrap();
|
||||
|
||||
evaluate(&file_contents).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table() {
|
||||
let file_contents = read_to_string("examples/table.ds").unwrap();
|
||||
|
||||
evaluate(&file_contents).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn variables() {
|
||||
let file_contents = read_to_string("examples/variables.ds").unwrap();
|
||||
|
@ -341,7 +341,7 @@ module.exports = grammar({
|
||||
optional(seq('->', $.type)),
|
||||
),
|
||||
'int',
|
||||
seq('list', $.type),
|
||||
seq('[', $.type, ']'),
|
||||
'map',
|
||||
'num',
|
||||
'str',
|
||||
|
@ -1096,11 +1096,15 @@
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "list"
|
||||
"value": "["
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "type"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "]"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -748,10 +748,6 @@
|
||||
"type": "integer",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "map",
|
||||
"named": false
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user