-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheval.cpp
executable file
·75 lines (56 loc) · 1.61 KB
/
eval.cpp
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
/**
* \file eval.cpp
*
* Evaluates the s-expression. Recursive approach. Each death level returns
* its result as a cell to the upper level.
*/
#include "eval.hpp"
#include "DefinitionManager.hpp"
#include <stdexcept>
Cell* eval(Cell* const c) {
/// just returns Cell if deepest level reached
/// this approach gets rid of loads of if-then checks
if (!listp(c)) {
if (symbolp(c)) {
string sym = get_symbol(c);
if (FunctionCell::is_function(sym)) {
return new FunctionCell(sym.c_str());
}
if (ArithmeticCell::is_arithmetic(sym)) {
return new ArithmeticCell(sym.c_str());
}
return c->get_definition();
}
return c;
}
Cell* func = eval_function(car(c));
Cell* args = cdr(c);
#ifdef L_DEBUG
cout << "func: " << *func << endl;
cout << " args: " << *args << endl;
#endif
/// The right operation/ function will be called through overwriting
return func->apply(args);
}
Cell* eval_function(Cell* const c) {
if (listp(c)) {
/// in case for nested cases such as ((quote if) 1 0)
return eval(c);
}
if (symbolp(c)) {
string sym = get_symbol(c);
/// checks wether it is a user-defined function or a built in function
if (DefinitionManager::Instance()->is_definition(sym)) {
if (c->get_definition()->is_lambda()) {
return c->get_definition();
}
}
if (FunctionCell::is_function(sym)) {
return new FunctionCell(sym.c_str());
}
if (ArithmeticCell::is_arithmetic(sym)) {
return new ArithmeticCell(sym.c_str());
}
}
throw runtime_error("No operator/ function in front");
}