-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
183 lines (174 loc) · 4.81 KB
/
main.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
module : main.c
version : 1.1.1.2
date : 10/02/23
*/
/* file: main.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <time.h>
#define ALLOC
#include "globals.h"
PUBLIC void inilinebuffer(); /* file scan.c */
PUBLIC int endofbuffer();
PUBLIC void doinclude();
PUBLIC void getsym();
PUBLIC void inimem1(); /* file utils.c */
PUBLIC void inimem2();
PUBLIC void inisymboltable();
PUBLIC void readterm();
PUBLIC void writeterm();
PUBLIC void writefactor();
PUBLIC void error();
PUBLIC void exeterm(); /* file interp.c */
PUBLIC void abortexecution_(); /* forward */
PUBLIC void enterglobal()
{
location = symtabindex++;
D( printf("getsym, new: '%s'\n",id); )
location->name = (char *) malloc(strlen(id) + 1);
strcpy(location->name,id);
location->u.body = NULL; /* may be assigned in definition */
location->next = hashentry[hashvalue];
D( printf("entered %s at %ld\n",id,LOC2INT(location)); )
hashentry[hashvalue] = location;
}
PUBLIC void lookup()
{
D( printf("%s hashes to %d\n",id,hashvalue); )
location = localentry;
while (location != symtab &&
strcmp(id,location->name) != 0)
location = location->next;
if (location != symtab) /* found in local table */
{
D( printf("found %s in local table\n",id); )
return; }
location = hashentry[hashvalue];
while (location != symtab &&
strcmp(id,location->name) != 0)
location = location->next;
if (location == symtab) /* not found, enter in global */
enterglobal();
}
PRIVATE void defsequence(); /* forward */
PRIVATE void definition(hidden)
int hidden;
{
Entry *here = NULL;
Entry *savelocalentry;
if (sym == HIDE)
{ getsym();
savelocalentry = localentry;
defsequence(1);
if (sym == IN) getsym();
else error(" IN expected in HIDE-declaration");
defsequence(hidden);
localentry = savelocalentry;
if (sym == END) getsym();
else error(" END expected in HIDE-declaration");
return; }
if (sym != ATOM)
{ error("atom expected at start of definition");
abortexecution_(); }
else if (hidden)
{ location = symtabindex++;
D( printf("hidden definition '%s' at %ld \n",id,LOC2INT(location)); )
location->name = (char *) malloc(strlen(id) + 1);
strcpy(location->name, id);
location->u.body = NULL; /* may be assigned later */
location->next = localentry;
localentry = location; }
else lookup();
if (location < firstlibra)
{ printf("warning: overwriting inbuilt '%s'\n",location->name);
enterglobal(); }
here = location; getsym();
if (sym == EQDEF) getsym();
else error(" == expected in definition");
readterm();
D( printf("assigned this body: "); )
D( writeterm(stk->u.lis); )
D( printf("\n"); )
if (here != NULL) here->u.body = stk->u.lis;
stk = stk->next;
}
PRIVATE void defsequence(hidden)
int hidden;
{
definition(hidden);
while (sym == SEMICOL)
{ getsym(); definition(hidden); }
}
jmp_buf begin;
PUBLIC void abortexecution_()
{
conts = dump = dump1 = dump2 = dump3 = dump4 = dump5 = NULL;
longjmp(begin,0);
}
PUBLIC void execerror(message,op)
char *message, *op;
{
printf("run time error: %s needed for %s\n",message,op);
abortexecution_();
}
PUBLIC void quit_()
{
long totaltime;
totaltime = clock() - startclock;
printf("time: %ld CPU, %d gc (= %ld%%)\n",
totaltime, gc_clock,
totaltime ? (1004*gc_clock)/(10*totaltime) : 0);
exit(EXIT_SUCCESS);
}
static int mustinclude = 1;
#define CHECK(D,NAME) \
if (D) \
{ printf("-> %s is not empty:\n",NAME); \
writeterm(D); printf("\n"); }
int main(int argc, char *argv[])
{
if (argc == 2 && !freopen(argv[1], "r", stdin)) {
fprintf(stderr, "failed to open the file '%s'.\n", argv[1]);
exit(EXIT_FAILURE);
}
printf("JOY - compiled at %s on %s \n",__TIME__,__DATE__);
startclock = clock();
gc_clock = 0;
echoflag = INIECHOFLAG;
tracegc = INITRACEGC;
autoput = INIAUTOPUT;
ch = ' ';
inilinebuffer();
inisymboltable();
inimem1(); inimem2();
setjmp(begin);
D( printf("starting main loop\n"); )
while (1)
{ if (mustinclude)
{ mustinclude = 0;
if (fopen("usrlib.joy","r"))
doinclude("usrlib.joy"); }
getsym();
if (sym == LIBRA)
{ inimem1();
getsym(); defsequence(0);
inimem2(); }
else
{ readterm();
D( printf("program is: "); writeterm(stk->u.lis); printf("\n"); )
prog = stk->u.lis;
stk = stk->next;
conts = NULL;
exeterm(prog);
if (conts || dump || dump1 || dump2 || dump3 || dump4 || dump5)
{ printf("the dumps are not empty\n");
CHECK(conts,"conts");
CHECK(dump,"dump"); CHECK(dump1,"dump1");
CHECK(dump2,"dump2"); CHECK(dump3,"dump3");
CHECK(dump4,"dump4"); CHECK(dump5,"dump5"); }
if (autoput && stk != NULL)
{ writefactor(stk); printf("\n"); stk = stk->next; } } }
}