-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrepl.c
89 lines (81 loc) · 1.49 KB
/
repl.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
#include <stdio.h>
#include <stdlib.h>
#include <editline/readline.h>
#include "parse.c"
enum err_code {
UNEXP_TOKEN, INCOMPL_EXP, TRAIL_CHARS
};
void printerr(const char *s, unsigned pad, enum err_code err)
{
static const char arrow[] = "^--";
static const char *err_msgs[] = {
"Unexpected token",
"Incomplete expression",
"Trailing characters"
};
puts(s);
while (pad--)
putchar(' ');
printf("%s %s\n", arrow, err_msgs[err]);
}
Cell *parse(const char *s)
{
Cell *cp;
unsigned i = 0;
if (cp = parse_sexp(s, &i)) {
if (s[i] != '\0') {
printerr(s, i, TRAIL_CHARS);
return NULL;
}
} else {
if (s[i] == '\0')
printerr(s, i, INCOMPL_EXP);
else
printerr(s, i, UNEXP_TOKEN);
return NULL;
}
return cp;
}
int initenv(Cell **env, const char *fname)
{
FILE *fp;
char *s;
int err = 0;
Cell *cp = NULL;
*env = nil;
if ((fp = fopen(fname, "r")) == NULL)
err = 1;
while (!err && (s = read_input(fp))) {
if (*s && !(cp = parse(s)))
err = 2;
free(s);
if (cp) {
eval(cp, *env);
cp = NULL;
}
}
return err;
}
const char *greeting = "SLIP: A Small LIst Processor\n";
const char *initfile = "init.lisp";
int main()
{
int err;
char *s;
Cell *cp;
initkeys(keysyms);
if (err = initenv(&envlist, initfile)) {
fprintf(stderr, "Unable to load %s\n", initfile);
return err;
}
puts(greeting);
while ((s = read_input(stdin))) { // -Wparen
if (*s && (cp = parse(s))) {
print(eval(cp, envlist));
putchar('\n');
}
add_history(s);
free(s);
}
return 0;
}