-
Notifications
You must be signed in to change notification settings - Fork 2
/
notes
111 lines (104 loc) · 4.46 KB
/
notes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
NOTES:
* Implement Logo list as VecDeque.
* Code coverage for tests (cargo-llvm-cov?).
* Lexer
* Implement Iter(able) on Lexer (? old comment).
* Don't lex if line ends in LineCont, wait for next one.
* TO \ BK defines the function " BK", ie. \ can escape a space making it a "letter", it can also escape other things (like arithmetic operators).
* Parser
* Parser should have its own "Tokens", only Parser should depend on Lexer (currently Evaluator uses Lexer::Token).
* Turtle
* Fix floating point comparison (https://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison/32334103#32334103).
* Evaluator
* Turning `stack_expr` into a RefCell would probably solve problems.
* Remove `eval_list`, have REPEAT/FOR take in a ExprBlock.
* MakeListType! macro (old).
* Implement (LIST arg1 arg2 arg3 ...) - functions that take N arguments (old).
* Remove imports, create proper types for VecDeque & HashMap.
* Tests. Capturing graphics, output (printed, running commands, functions), errors.
* Test function return (eg. 1 + FUNC_RET_2 == 3).
* Bug where stack_expr keeps growing on error (because ? operator jumps over the pop) - use scopeguard?
* LOAD <file> - "Loading from file <file>", "KV defined", "KV redefined".
* Implement REPEAT with FOR.
* Get rid of the stack_expr remainder.
* Get "STAZA" & "STAZA2" to work.
* Replace "match self.eval(ast_node)?" with "if let AST::Num(num) ..." (overuse of match)
* Main
* Convert point to Vec2 as well (would involve converting other pieces)?
* Both Point type and Vec type (could be same underlying thing, but for semantical difference)?
Idea
self.push_expr(expr).eval_with_pop()?
1)
let list = evaluator.borrow_mut().get_next_list()?;
evaluator.borrow_mut().stack_expr.push(list);
let x = evaluator.borrow_mut().get_next_number()?;
let y = evaluator.borrow_mut().get_next_number()?;
evaluator.borrow_mut().turtle.setxy(x, y);
2) ? what do I need this for?
fn eval_list(&mut self, list: &ListType) -> Result<(), String> {
self.stack_expr.push(list.clone());
let mut ret = Ok(());
while let Some(expr) = self.current_expr_list().pop_front() {
match self.eval(&expr) {
3) ? self.stack_vars ?
fn eval_user_function(&mut self, name: &str) -> Result<AST, String> {
// Setup the args as local vars.
for arg in args {
local_vars.insert(arg.clone(), self.eval_next_expr()?);
}
self.stack_vars.push(local_vars);
// TODO: Probably don't need this push here?
self.stack_expr.push(VecDeque::new());
let mut ret = AST::None;
// Run the lines.
let mut err = None;
for line in lines {
match self.eval(&line) { ???????
4)
fn eval(&mut self, ast_node: &AST) -> Result<AST, String> {
match ast_node {
// TODO: Type that pushes during construction, and pops during destruction.
AST::ExprLine(expr_list) => {
// self.stack_expr.push(expr_list.clone());
// defer! {
// self.stack_expr.pop();
// }
while let Some(expr) = self.current_expr_list().pop_front() {
ret = self.eval(&expr)?;
if ret != AST::None {
break;
}
}
// self.stack_expr.pop();
5)
fn eval(&mut self, ast_node: &AST) -> Result<AST, String> {
match ast_node {
// TODO: Builtin functions behave differently if they open Parens.
AST::Parens(expr_list) => {
// Evaluates only the first expr and returns result (if any). If the expression list is
// empty, returns the empty list.
if expr_list.is_empty() {
ret = AST::List(ListType::new());
} else {
// TODO: Can this be simplified to just (probably) - nope, needs recursive parsing with pushing onto stack:
// ret = self.eval(&expr_list[0])?;
self.stack_expr.push(expr_list.clone());
let next_expr = self.current_expr_list().pop_front().unwrap();
ret = self.eval(&next_expr)?;
self.stack_expr.pop();
}
},
add_builtin!(SETXY, (|E: &mut Evaluator| {
let evaluator = RefCell::new(E);
let list = evaluator.borrow_mut().get_next_list()?;
evaluator.borrow_mut().stack_expr.push(list);
defer ! {
evaluator.borrow_mut().stack_expr.pop();
println!("Hi From Deferred Block!")
}
let x = evaluator.borrow_mut().get_next_number()?;
let y = evaluator.borrow_mut().get_next_number()?;
evaluator.borrow_mut().turtle.setxy(x, y);
// evaluator.stack_expr.pop();
Ok(AST::None)
}));