-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrat.c
120 lines (98 loc) · 2.82 KB
/
rat.c
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
112
113
114
115
116
117
118
119
120
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "env.h"
#include "error.h"
#include "eval.h"
#include "lexeme.h"
#include "lexer.h"
#include "parser.h"
#include "prettyPrint.h"
#include "types.h"
void installBuiltin(char *name, Lexeme *(*fp)(Lexeme*), Lexeme *env);
void installBuiltins(Lexeme *env);
Lexeme *squeek(Lexeme *args);
Lexeme *squeekln(Lexeme *args);
Lexeme *array(Lexeme *args);
Lexeme *include(Lexeme *args);
Lexeme *isNumber(Lexeme *args);
Lexeme *globalEnv;
int main(int argc, char *argv[]) {
Parser *p = newParser(argv[1]);
Lexeme *pt = parse(p);
if (argc > 2)
prettyPrint(pt, 0);
globalEnv = createEnv();
installBuiltins(globalEnv);
eval(pt, globalEnv);
return 0;
}
void installBuiltin(char *name, Lexeme *(*fp)(Lexeme*), Lexeme *env) {
Lexeme *var = newLexeme(ID);
var->sval = name;
Lexeme *val = newLexeme(BUILTIN);
val->fp = fp;
insertEnv(env, var, val);
}
void installBuiltins(Lexeme *env) {
installBuiltin("squeek", squeek, env);
installBuiltin("squeekln", squeekln, env);
installBuiltin("array", array, env);
installBuiltin("include", include, env);
installBuiltin("isNumber", isNumber, env);
}
Lexeme *squeek(Lexeme *args) {
Lexeme *arg;
while (args != NULL) {
arg = car(args);
if (arg->type == NUMBER) {
printf("%d", arg->ival);
} else if (arg->type == STRING) {
printf("%s", arg->sval);
} else if (arg->type == NIL) {
printf("NIL");
} else {
fatalError("RuntimeError, can't print a %s\n", arg->type);
}
args = cdr(args);
}
return arg;
}
Lexeme *squeekln(Lexeme *args) {
Lexeme *result = squeek(args);
printf("\n");
return result;
}
Lexeme *array(Lexeme *args) {
if (args == NULL || cdr(args) != NULL) {
fatalError("Incorrect number of arguments to array()\n");
}
Lexeme *size = car(args);
if (size->type != NUMBER || size->ival <= 0) {
fatalError("Argument to array() must be a number > 0\n");
}
Lexeme *result = newLexeme(ARRAY);
result->ival = size->ival;
result->arr = malloc(size->ival * sizeof(Lexeme *));
return result;
}
Lexeme *include(Lexeme *args) {
if (args == NULL || cdr(args) != NULL) {
fatalError("Incorrect number of arguments to array()\n");
}
Lexeme *file = car(args);
if (file->type != STRING) {
fatalError("Argument to include() must be a string\n");
}
Parser *p = newParser(file->sval);
Lexeme *pt = parse(p);
return eval(pt, globalEnv);
}
Lexeme *isNumber(Lexeme *args) {
if (args == NULL || cdr(args) != NULL) {
fatalError("Incorrect number of arguments to array()\n");
}
Lexeme *result = newLexeme(NUMBER);
result->ival = car(args)->type == NUMBER;
return result;
}