1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <ctype.h>
5bd389b36SDavid du Colombier #include <mach.h>
6bd389b36SDavid du Colombier #define Extern extern
7bd389b36SDavid du Colombier #include "acid.h"
8bd389b36SDavid du Colombier #include "y.tab.h"
9bd389b36SDavid du Colombier
10bd389b36SDavid du Colombier struct keywd
11bd389b36SDavid du Colombier {
12bd389b36SDavid du Colombier char *name;
13bd389b36SDavid du Colombier int terminal;
14bd389b36SDavid du Colombier }
15bd389b36SDavid du Colombier keywds[] =
16bd389b36SDavid du Colombier {
17bd389b36SDavid du Colombier "do", Tdo,
18bd389b36SDavid du Colombier "if", Tif,
19bd389b36SDavid du Colombier "then", Tthen,
20bd389b36SDavid du Colombier "else", Telse,
21bd389b36SDavid du Colombier "while", Twhile,
22bd389b36SDavid du Colombier "loop", Tloop,
23bd389b36SDavid du Colombier "head", Thead,
24bd389b36SDavid du Colombier "tail", Ttail,
25bd389b36SDavid du Colombier "append", Tappend,
26bd389b36SDavid du Colombier "defn", Tfn,
27bd389b36SDavid du Colombier "return", Tret,
28bd389b36SDavid du Colombier "local", Tlocal,
29bd389b36SDavid du Colombier "aggr", Tcomplex,
30219b2ee8SDavid du Colombier "union", Tcomplex,
31bd389b36SDavid du Colombier "adt", Tcomplex,
32bd389b36SDavid du Colombier "complex", Tcomplex,
33bd389b36SDavid du Colombier "delete", Tdelete,
34bd389b36SDavid du Colombier "whatis", Twhat,
35219b2ee8SDavid du Colombier "eval", Teval,
360b459c2cSDavid du Colombier "builtin", Tbuiltin,
37bd389b36SDavid du Colombier 0, 0
38bd389b36SDavid du Colombier };
39bd389b36SDavid du Colombier
40bd389b36SDavid du Colombier char cmap[256] =
41bd389b36SDavid du Colombier {
42bd389b36SDavid du Colombier ['0'] '\0'+1,
43bd389b36SDavid du Colombier ['n'] '\n'+1,
44bd389b36SDavid du Colombier ['r'] '\r'+1,
45bd389b36SDavid du Colombier ['t'] '\t'+1,
46bd389b36SDavid du Colombier ['b'] '\b'+1,
47bd389b36SDavid du Colombier ['f'] '\f'+1,
48bd389b36SDavid du Colombier ['a'] '\a'+1,
49bd389b36SDavid du Colombier ['v'] '\v'+1,
50bd389b36SDavid du Colombier ['\\'] '\\'+1,
51bd389b36SDavid du Colombier ['"'] '"'+1,
52bd389b36SDavid du Colombier };
53bd389b36SDavid du Colombier
54bd389b36SDavid du Colombier void
kinit(void)55bd389b36SDavid du Colombier kinit(void)
56bd389b36SDavid du Colombier {
57bd389b36SDavid du Colombier int i;
58bd389b36SDavid du Colombier
59bd389b36SDavid du Colombier for(i = 0; keywds[i].name; i++)
60bd389b36SDavid du Colombier enter(keywds[i].name, keywds[i].terminal);
61219b2ee8SDavid du Colombier }
62bd389b36SDavid du Colombier
63219b2ee8SDavid du Colombier typedef struct IOstack IOstack;
64219b2ee8SDavid du Colombier struct IOstack
65219b2ee8SDavid du Colombier {
66219b2ee8SDavid du Colombier char *name;
67219b2ee8SDavid du Colombier int line;
68219b2ee8SDavid du Colombier char *text;
69219b2ee8SDavid du Colombier char *ip;
70219b2ee8SDavid du Colombier Biobuf *fin;
71219b2ee8SDavid du Colombier IOstack *prev;
72219b2ee8SDavid du Colombier };
73219b2ee8SDavid du Colombier IOstack *lexio;
74219b2ee8SDavid du Colombier
75219b2ee8SDavid du Colombier void
pushfile(char * file)76219b2ee8SDavid du Colombier pushfile(char *file)
77219b2ee8SDavid du Colombier {
78219b2ee8SDavid du Colombier Biobuf *b;
79219b2ee8SDavid du Colombier IOstack *io;
80219b2ee8SDavid du Colombier
81219b2ee8SDavid du Colombier if(file)
82219b2ee8SDavid du Colombier b = Bopen(file, OREAD);
83219b2ee8SDavid du Colombier else{
84219b2ee8SDavid du Colombier b = Bopen("/fd/0", OREAD);
85219b2ee8SDavid du Colombier file = "<stdin>";
86219b2ee8SDavid du Colombier }
87219b2ee8SDavid du Colombier
88219b2ee8SDavid du Colombier if(b == 0)
89219b2ee8SDavid du Colombier error("pushfile: %s: %r", file);
90219b2ee8SDavid du Colombier
91219b2ee8SDavid du Colombier io = malloc(sizeof(IOstack));
92219b2ee8SDavid du Colombier if(io == 0)
93219b2ee8SDavid du Colombier fatal("no memory");
94219b2ee8SDavid du Colombier io->name = strdup(file);
95219b2ee8SDavid du Colombier if(io->name == 0)
96219b2ee8SDavid du Colombier fatal("no memory");
97219b2ee8SDavid du Colombier io->line = line;
98219b2ee8SDavid du Colombier line = 1;
99219b2ee8SDavid du Colombier io->text = 0;
100219b2ee8SDavid du Colombier io->fin = b;
101219b2ee8SDavid du Colombier io->prev = lexio;
102219b2ee8SDavid du Colombier lexio = io;
103219b2ee8SDavid du Colombier }
104219b2ee8SDavid du Colombier
105219b2ee8SDavid du Colombier void
pushstr(Node * s)106219b2ee8SDavid du Colombier pushstr(Node *s)
107219b2ee8SDavid du Colombier {
108219b2ee8SDavid du Colombier IOstack *io;
109219b2ee8SDavid du Colombier
110219b2ee8SDavid du Colombier io = malloc(sizeof(IOstack));
111219b2ee8SDavid du Colombier if(io == 0)
112219b2ee8SDavid du Colombier fatal("no memory");
113219b2ee8SDavid du Colombier io->line = line;
114219b2ee8SDavid du Colombier line = 1;
115219b2ee8SDavid du Colombier io->name = strdup("<string>");
116219b2ee8SDavid du Colombier if(io->name == 0)
117219b2ee8SDavid du Colombier fatal("no memory");
118219b2ee8SDavid du Colombier io->line = line;
119219b2ee8SDavid du Colombier line = 1;
120219b2ee8SDavid du Colombier io->text = strdup(s->string->string);
121219b2ee8SDavid du Colombier if(io->text == 0)
122219b2ee8SDavid du Colombier fatal("no memory");
123219b2ee8SDavid du Colombier io->ip = io->text;
124219b2ee8SDavid du Colombier io->fin = 0;
125219b2ee8SDavid du Colombier io->prev = lexio;
126219b2ee8SDavid du Colombier lexio = io;
127219b2ee8SDavid du Colombier }
128219b2ee8SDavid du Colombier
129219b2ee8SDavid du Colombier void
restartio(void)130219b2ee8SDavid du Colombier restartio(void)
131219b2ee8SDavid du Colombier {
132219b2ee8SDavid du Colombier Bflush(lexio->fin);
133219b2ee8SDavid du Colombier Binit(lexio->fin, 0, OREAD);
134219b2ee8SDavid du Colombier }
135219b2ee8SDavid du Colombier
136219b2ee8SDavid du Colombier int
popio(void)137219b2ee8SDavid du Colombier popio(void)
138219b2ee8SDavid du Colombier {
139219b2ee8SDavid du Colombier IOstack *s;
140219b2ee8SDavid du Colombier
141219b2ee8SDavid du Colombier if(lexio == 0)
142219b2ee8SDavid du Colombier return 0;
143219b2ee8SDavid du Colombier
144219b2ee8SDavid du Colombier if(lexio->prev == 0){
145219b2ee8SDavid du Colombier if(lexio->fin)
146219b2ee8SDavid du Colombier restartio();
147219b2ee8SDavid du Colombier return 0;
148219b2ee8SDavid du Colombier }
149219b2ee8SDavid du Colombier
150219b2ee8SDavid du Colombier if(lexio->fin)
151219b2ee8SDavid du Colombier Bterm(lexio->fin);
152219b2ee8SDavid du Colombier else
153219b2ee8SDavid du Colombier free(lexio->text);
154219b2ee8SDavid du Colombier free(lexio->name);
155219b2ee8SDavid du Colombier line = lexio->line;
156219b2ee8SDavid du Colombier s = lexio;
157219b2ee8SDavid du Colombier lexio = s->prev;
158219b2ee8SDavid du Colombier free(s);
159219b2ee8SDavid du Colombier return 1;
160219b2ee8SDavid du Colombier }
161219b2ee8SDavid du Colombier
162219b2ee8SDavid du Colombier int
Lfmt(Fmt * f)1639a747e4fSDavid du Colombier Lfmt(Fmt *f)
164219b2ee8SDavid du Colombier {
165219b2ee8SDavid du Colombier int i;
166219b2ee8SDavid du Colombier char buf[1024];
167219b2ee8SDavid du Colombier IOstack *e;
168219b2ee8SDavid du Colombier
169219b2ee8SDavid du Colombier e = lexio;
170219b2ee8SDavid du Colombier if(e) {
171*4de34a7eSDavid du Colombier i = snprint(buf, sizeof(buf), "%s:%d", e->name, line);
172219b2ee8SDavid du Colombier while(e->prev) {
173219b2ee8SDavid du Colombier e = e->prev;
174219b2ee8SDavid du Colombier if(initialising && e->prev == 0)
175219b2ee8SDavid du Colombier break;
176*4de34a7eSDavid du Colombier i += snprint(buf+i, sizeof(buf)-i, " [%s:%d]", e->name, e->line);
177219b2ee8SDavid du Colombier }
178219b2ee8SDavid du Colombier } else
179*4de34a7eSDavid du Colombier snprint(buf, sizeof(buf), "no file:0");
1809a747e4fSDavid du Colombier fmtstrcpy(f, buf);
181219b2ee8SDavid du Colombier return 0;
182219b2ee8SDavid du Colombier }
183219b2ee8SDavid du Colombier
184219b2ee8SDavid du Colombier void
unlexc(int s)185219b2ee8SDavid du Colombier unlexc(int s)
186219b2ee8SDavid du Colombier {
187219b2ee8SDavid du Colombier if(s == '\n')
188219b2ee8SDavid du Colombier line--;
189219b2ee8SDavid du Colombier
190219b2ee8SDavid du Colombier if(lexio->fin)
191219b2ee8SDavid du Colombier Bungetc(lexio->fin);
192219b2ee8SDavid du Colombier else
193219b2ee8SDavid du Colombier lexio->ip--;
194219b2ee8SDavid du Colombier }
195219b2ee8SDavid du Colombier
196219b2ee8SDavid du Colombier int
lexc(void)197219b2ee8SDavid du Colombier lexc(void)
198219b2ee8SDavid du Colombier {
199219b2ee8SDavid du Colombier int c;
200219b2ee8SDavid du Colombier
201219b2ee8SDavid du Colombier if(lexio->fin) {
202219b2ee8SDavid du Colombier c = Bgetc(lexio->fin);
203219b2ee8SDavid du Colombier if(gotint)
204219b2ee8SDavid du Colombier error("interrupt");
205219b2ee8SDavid du Colombier return c;
206219b2ee8SDavid du Colombier }
207219b2ee8SDavid du Colombier
208219b2ee8SDavid du Colombier c = *lexio->ip++;
209219b2ee8SDavid du Colombier if(c == 0)
210219b2ee8SDavid du Colombier return -1;
211219b2ee8SDavid du Colombier return c;
212bd389b36SDavid du Colombier }
213bd389b36SDavid du Colombier
214bd389b36SDavid du Colombier int
escchar(char c)215bd389b36SDavid du Colombier escchar(char c)
216bd389b36SDavid du Colombier {
217bd389b36SDavid du Colombier int n;
218bd389b36SDavid du Colombier char buf[Strsize];
219bd389b36SDavid du Colombier
220bd389b36SDavid du Colombier if(c >= '0' && c <= '9') {
221bd389b36SDavid du Colombier n = 1;
222bd389b36SDavid du Colombier buf[0] = c;
223bd389b36SDavid du Colombier for(;;) {
224219b2ee8SDavid du Colombier c = lexc();
225bd389b36SDavid du Colombier if(c == Eof)
226bd389b36SDavid du Colombier error("%d: <eof> in escape sequence", line);
227bd389b36SDavid du Colombier if(strchr("0123456789xX", c) == 0) {
228219b2ee8SDavid du Colombier unlexc(c);
229bd389b36SDavid du Colombier break;
230bd389b36SDavid du Colombier }
231*4de34a7eSDavid du Colombier if(n >= Strsize)
232*4de34a7eSDavid du Colombier error("string escape too long");
233bd389b36SDavid du Colombier buf[n++] = c;
234bd389b36SDavid du Colombier }
235bd389b36SDavid du Colombier buf[n] = '\0';
236bd389b36SDavid du Colombier return strtol(buf, 0, 0);
237bd389b36SDavid du Colombier }
238bd389b36SDavid du Colombier
239bd389b36SDavid du Colombier n = cmap[c];
240bd389b36SDavid du Colombier if(n == 0)
241bd389b36SDavid du Colombier return c;
242bd389b36SDavid du Colombier return n-1;
243bd389b36SDavid du Colombier }
244bd389b36SDavid du Colombier
245bd389b36SDavid du Colombier void
eatstring(void)246bd389b36SDavid du Colombier eatstring(void)
247bd389b36SDavid du Colombier {
248bd389b36SDavid du Colombier int esc, c, cnt;
249bd389b36SDavid du Colombier char buf[Strsize];
250bd389b36SDavid du Colombier
251bd389b36SDavid du Colombier esc = 0;
252bd389b36SDavid du Colombier for(cnt = 0;;) {
253219b2ee8SDavid du Colombier c = lexc();
254bd389b36SDavid du Colombier switch(c) {
255bd389b36SDavid du Colombier case Eof:
256bd389b36SDavid du Colombier error("%d: <eof> in string constant", line);
257bd389b36SDavid du Colombier
258bd389b36SDavid du Colombier case '\n':
259bd389b36SDavid du Colombier error("newline in string constant");
260bd389b36SDavid du Colombier goto done;
261bd389b36SDavid du Colombier
262bd389b36SDavid du Colombier case '\\':
2639a747e4fSDavid du Colombier if(esc)
2649a747e4fSDavid du Colombier goto Default;
265bd389b36SDavid du Colombier esc = 1;
266bd389b36SDavid du Colombier break;
267bd389b36SDavid du Colombier
268bd389b36SDavid du Colombier case '"':
269bd389b36SDavid du Colombier if(esc == 0)
270bd389b36SDavid du Colombier goto done;
271bd389b36SDavid du Colombier
272bd389b36SDavid du Colombier /* Fall through */
273bd389b36SDavid du Colombier default:
2749a747e4fSDavid du Colombier Default:
275bd389b36SDavid du Colombier if(esc) {
276bd389b36SDavid du Colombier c = escchar(c);
277bd389b36SDavid du Colombier esc = 0;
278bd389b36SDavid du Colombier }
279bd389b36SDavid du Colombier buf[cnt++] = c;
280bd389b36SDavid du Colombier break;
281bd389b36SDavid du Colombier }
282219b2ee8SDavid du Colombier if(cnt >= Strsize)
283219b2ee8SDavid du Colombier error("string token too long");
284bd389b36SDavid du Colombier }
285bd389b36SDavid du Colombier done:
286bd389b36SDavid du Colombier buf[cnt] = '\0';
287bd389b36SDavid du Colombier yylval.string = strnode(buf);
288bd389b36SDavid du Colombier }
289bd389b36SDavid du Colombier
290bd389b36SDavid du Colombier void
eatnl(void)291bd389b36SDavid du Colombier eatnl(void)
292bd389b36SDavid du Colombier {
293bd389b36SDavid du Colombier int c;
294bd389b36SDavid du Colombier
295bd389b36SDavid du Colombier line++;
296bd389b36SDavid du Colombier for(;;) {
297219b2ee8SDavid du Colombier c = lexc();
298bd389b36SDavid du Colombier if(c == Eof)
299bd389b36SDavid du Colombier error("eof in comment");
300bd389b36SDavid du Colombier if(c == '\n')
301bd389b36SDavid du Colombier return;
302bd389b36SDavid du Colombier }
303bd389b36SDavid du Colombier }
304bd389b36SDavid du Colombier
305bd389b36SDavid du Colombier int
yylex(void)306bd389b36SDavid du Colombier yylex(void)
307bd389b36SDavid du Colombier {
308bd389b36SDavid du Colombier int c;
309219b2ee8SDavid du Colombier extern char vfmt[];
310bd389b36SDavid du Colombier
311bd389b36SDavid du Colombier loop:
312bd389b36SDavid du Colombier Bflush(bout);
313219b2ee8SDavid du Colombier c = lexc();
314bd389b36SDavid du Colombier switch(c) {
315bd389b36SDavid du Colombier case Eof:
316bd389b36SDavid du Colombier if(gotint) {
317bd389b36SDavid du Colombier gotint = 0;
318bd389b36SDavid du Colombier stacked = 0;
319bd389b36SDavid du Colombier Bprint(bout, "\nacid: ");
320bd389b36SDavid du Colombier goto loop;
321bd389b36SDavid du Colombier }
322bd389b36SDavid du Colombier return Eof;
323bd389b36SDavid du Colombier
324bd389b36SDavid du Colombier case '"':
325bd389b36SDavid du Colombier eatstring();
326bd389b36SDavid du Colombier return Tstring;
327bd389b36SDavid du Colombier
328bd389b36SDavid du Colombier case ' ':
329bd389b36SDavid du Colombier case '\t':
330bd389b36SDavid du Colombier goto loop;
331bd389b36SDavid du Colombier
332bd389b36SDavid du Colombier case '\n':
333bd389b36SDavid du Colombier line++;
334bd389b36SDavid du Colombier if(interactive == 0)
335bd389b36SDavid du Colombier goto loop;
336bd389b36SDavid du Colombier if(stacked) {
337bd389b36SDavid du Colombier print("\t");
338bd389b36SDavid du Colombier goto loop;
339bd389b36SDavid du Colombier }
340bd389b36SDavid du Colombier return ';';
341bd389b36SDavid du Colombier
342bd389b36SDavid du Colombier case '.':
343219b2ee8SDavid du Colombier c = lexc();
344219b2ee8SDavid du Colombier unlexc(c);
345bd389b36SDavid du Colombier if(isdigit(c))
346bd389b36SDavid du Colombier return numsym('.');
347bd389b36SDavid du Colombier
348bd389b36SDavid du Colombier return '.';
349bd389b36SDavid du Colombier
350bd389b36SDavid du Colombier case '(':
351bd389b36SDavid du Colombier case ')':
352bd389b36SDavid du Colombier case '[':
353bd389b36SDavid du Colombier case ']':
354bd389b36SDavid du Colombier case ';':
355bd389b36SDavid du Colombier case ':':
356bd389b36SDavid du Colombier case ',':
357bd389b36SDavid du Colombier case '~':
358bd389b36SDavid du Colombier case '?':
359bd389b36SDavid du Colombier case '*':
360bd389b36SDavid du Colombier case '@':
361bd389b36SDavid du Colombier case '^':
362bd389b36SDavid du Colombier case '%':
363bd389b36SDavid du Colombier return c;
364bd389b36SDavid du Colombier case '{':
365bd389b36SDavid du Colombier stacked++;
366bd389b36SDavid du Colombier return c;
367bd389b36SDavid du Colombier case '}':
368bd389b36SDavid du Colombier stacked--;
369bd389b36SDavid du Colombier return c;
370bd389b36SDavid du Colombier
371219b2ee8SDavid du Colombier case '\\':
372219b2ee8SDavid du Colombier c = lexc();
373219b2ee8SDavid du Colombier if(strchr(vfmt, c) == 0) {
374219b2ee8SDavid du Colombier unlexc(c);
375219b2ee8SDavid du Colombier return '\\';
376219b2ee8SDavid du Colombier }
377219b2ee8SDavid du Colombier yylval.ival = c;
378219b2ee8SDavid du Colombier return Tfmt;
379219b2ee8SDavid du Colombier
380bd389b36SDavid du Colombier case '!':
381219b2ee8SDavid du Colombier c = lexc();
382bd389b36SDavid du Colombier if(c == '=')
383bd389b36SDavid du Colombier return Tneq;
384219b2ee8SDavid du Colombier unlexc(c);
385bd389b36SDavid du Colombier return '!';
386bd389b36SDavid du Colombier
387bd389b36SDavid du Colombier case '+':
388219b2ee8SDavid du Colombier c = lexc();
389bd389b36SDavid du Colombier if(c == '+')
390bd389b36SDavid du Colombier return Tinc;
391219b2ee8SDavid du Colombier unlexc(c);
392bd389b36SDavid du Colombier return '+';
393bd389b36SDavid du Colombier
394bd389b36SDavid du Colombier case '/':
395219b2ee8SDavid du Colombier c = lexc();
396bd389b36SDavid du Colombier if(c == '/') {
397bd389b36SDavid du Colombier eatnl();
398bd389b36SDavid du Colombier goto loop;
399bd389b36SDavid du Colombier }
400219b2ee8SDavid du Colombier unlexc(c);
401bd389b36SDavid du Colombier return '/';
402bd389b36SDavid du Colombier
403bd389b36SDavid du Colombier case '\'':
404219b2ee8SDavid du Colombier c = lexc();
405bd389b36SDavid du Colombier if(c == '\\')
406219b2ee8SDavid du Colombier yylval.ival = escchar(lexc());
407bd389b36SDavid du Colombier else
408bd389b36SDavid du Colombier yylval.ival = c;
409219b2ee8SDavid du Colombier c = lexc();
410bd389b36SDavid du Colombier if(c != '\'') {
411bd389b36SDavid du Colombier error("missing '");
412219b2ee8SDavid du Colombier unlexc(c);
413bd389b36SDavid du Colombier }
414bd389b36SDavid du Colombier return Tconst;
415bd389b36SDavid du Colombier
416bd389b36SDavid du Colombier case '&':
417219b2ee8SDavid du Colombier c = lexc();
418bd389b36SDavid du Colombier if(c == '&')
419bd389b36SDavid du Colombier return Tandand;
420219b2ee8SDavid du Colombier unlexc(c);
421bd389b36SDavid du Colombier return '&';
422bd389b36SDavid du Colombier
423bd389b36SDavid du Colombier case '=':
424219b2ee8SDavid du Colombier c = lexc();
425bd389b36SDavid du Colombier if(c == '=')
426bd389b36SDavid du Colombier return Teq;
427219b2ee8SDavid du Colombier unlexc(c);
428bd389b36SDavid du Colombier return '=';
429bd389b36SDavid du Colombier
430bd389b36SDavid du Colombier case '|':
431219b2ee8SDavid du Colombier c = lexc();
432bd389b36SDavid du Colombier if(c == '|')
433bd389b36SDavid du Colombier return Toror;
434219b2ee8SDavid du Colombier unlexc(c);
435bd389b36SDavid du Colombier return '|';
436bd389b36SDavid du Colombier
437bd389b36SDavid du Colombier case '<':
438219b2ee8SDavid du Colombier c = lexc();
439bd389b36SDavid du Colombier if(c == '=')
440bd389b36SDavid du Colombier return Tleq;
441bd389b36SDavid du Colombier if(c == '<')
442bd389b36SDavid du Colombier return Tlsh;
443219b2ee8SDavid du Colombier unlexc(c);
444bd389b36SDavid du Colombier return '<';
445bd389b36SDavid du Colombier
446bd389b36SDavid du Colombier case '>':
447219b2ee8SDavid du Colombier c = lexc();
448bd389b36SDavid du Colombier if(c == '=')
449bd389b36SDavid du Colombier return Tgeq;
450bd389b36SDavid du Colombier if(c == '>')
451bd389b36SDavid du Colombier return Trsh;
452219b2ee8SDavid du Colombier unlexc(c);
453bd389b36SDavid du Colombier return '>';
454bd389b36SDavid du Colombier
455bd389b36SDavid du Colombier case '-':
456219b2ee8SDavid du Colombier c = lexc();
457219b2ee8SDavid du Colombier
458bd389b36SDavid du Colombier if(c == '>')
459bd389b36SDavid du Colombier return Tindir;
460219b2ee8SDavid du Colombier
461bd389b36SDavid du Colombier if(c == '-')
462bd389b36SDavid du Colombier return Tdec;
463219b2ee8SDavid du Colombier unlexc(c);
464bd389b36SDavid du Colombier return '-';
465bd389b36SDavid du Colombier
466bd389b36SDavid du Colombier default:
467bd389b36SDavid du Colombier return numsym(c);
468bd389b36SDavid du Colombier }
469bd389b36SDavid du Colombier }
470bd389b36SDavid du Colombier
471bd389b36SDavid du Colombier int
numsym(char first)472bd389b36SDavid du Colombier numsym(char first)
473bd389b36SDavid du Colombier {
474219b2ee8SDavid du Colombier int c, isbin, isfloat, ishex;
475bd389b36SDavid du Colombier char *sel, *p;
476bd389b36SDavid du Colombier Lsym *s;
477bd389b36SDavid du Colombier
478bd389b36SDavid du Colombier symbol[0] = first;
479bd389b36SDavid du Colombier p = symbol;
480bd389b36SDavid du Colombier
481bd389b36SDavid du Colombier ishex = 0;
482219b2ee8SDavid du Colombier isbin = 0;
483bd389b36SDavid du Colombier isfloat = 0;
484bd389b36SDavid du Colombier if(first == '.')
485bd389b36SDavid du Colombier isfloat = 1;
486bd389b36SDavid du Colombier
487bd389b36SDavid du Colombier if(isdigit(*p++) || isfloat) {
488bd389b36SDavid du Colombier for(;;) {
489219b2ee8SDavid du Colombier c = lexc();
490bd389b36SDavid du Colombier if(c < 0)
491bd389b36SDavid du Colombier error("%d: <eof> eating symbols", line);
492bd389b36SDavid du Colombier
493bd389b36SDavid du Colombier if(c == '\n')
494bd389b36SDavid du Colombier line++;
495219b2ee8SDavid du Colombier sel = "01234567890.xb";
496bd389b36SDavid du Colombier if(ishex)
497bd389b36SDavid du Colombier sel = "01234567890abcdefABCDEF";
498219b2ee8SDavid du Colombier else if(isbin)
499219b2ee8SDavid du Colombier sel = "01";
5007dd7cddfSDavid du Colombier else if(isfloat)
5017dd7cddfSDavid du Colombier sel = "01234567890eE-+";
502bd389b36SDavid du Colombier
503bd389b36SDavid du Colombier if(strchr(sel, c) == 0) {
504219b2ee8SDavid du Colombier unlexc(c);
505bd389b36SDavid du Colombier break;
506bd389b36SDavid du Colombier }
507bd389b36SDavid du Colombier if(c == '.')
508bd389b36SDavid du Colombier isfloat = 1;
509219b2ee8SDavid du Colombier if(!isbin && c == 'x')
510bd389b36SDavid du Colombier ishex = 1;
511219b2ee8SDavid du Colombier if(!ishex && c == 'b')
512219b2ee8SDavid du Colombier isbin = 1;
513bd389b36SDavid du Colombier *p++ = c;
514bd389b36SDavid du Colombier }
515bd389b36SDavid du Colombier *p = '\0';
516bd389b36SDavid du Colombier if(isfloat) {
517bd389b36SDavid du Colombier yylval.fval = atof(symbol);
518bd389b36SDavid du Colombier return Tfconst;
519bd389b36SDavid du Colombier }
520bd389b36SDavid du Colombier
521219b2ee8SDavid du Colombier if(isbin)
522*4de34a7eSDavid du Colombier yylval.ival = strtoull(symbol+2, 0, 2);
523219b2ee8SDavid du Colombier else
524*4de34a7eSDavid du Colombier yylval.ival = strtoull(symbol, 0, 0);
525bd389b36SDavid du Colombier return Tconst;
526bd389b36SDavid du Colombier }
527bd389b36SDavid du Colombier
528bd389b36SDavid du Colombier for(;;) {
529219b2ee8SDavid du Colombier c = lexc();
530bd389b36SDavid du Colombier if(c < 0)
531bd389b36SDavid du Colombier error("%d <eof> eating symbols", line);
532bd389b36SDavid du Colombier if(c == '\n')
533bd389b36SDavid du Colombier line++;
5349a747e4fSDavid du Colombier if(c != '_' && c != '$' && c <= '~' && !isalnum(c)) { /* checking against ~ lets UTF names through */
535219b2ee8SDavid du Colombier unlexc(c);
536bd389b36SDavid du Colombier break;
537bd389b36SDavid du Colombier }
538bd389b36SDavid du Colombier *p++ = c;
539bd389b36SDavid du Colombier }
540bd389b36SDavid du Colombier
541bd389b36SDavid du Colombier *p = '\0';
542bd389b36SDavid du Colombier
543bd389b36SDavid du Colombier s = look(symbol);
544bd389b36SDavid du Colombier if(s == 0)
545bd389b36SDavid du Colombier s = enter(symbol, Tid);
546bd389b36SDavid du Colombier
547bd389b36SDavid du Colombier yylval.sym = s;
548bd389b36SDavid du Colombier return s->lexval;
549bd389b36SDavid du Colombier }
550bd389b36SDavid du Colombier
551bd389b36SDavid du Colombier Lsym*
enter(char * name,int t)552bd389b36SDavid du Colombier enter(char *name, int t)
553bd389b36SDavid du Colombier {
554bd389b36SDavid du Colombier Lsym *s;
555*4de34a7eSDavid du Colombier uint h;
556bd389b36SDavid du Colombier char *p;
557bd389b36SDavid du Colombier Value *v;
558bd389b36SDavid du Colombier
559bd389b36SDavid du Colombier h = 0;
560bd389b36SDavid du Colombier for(p = name; *p; p++)
561bd389b36SDavid du Colombier h = h*3 + *p;
562bd389b36SDavid du Colombier h %= Hashsize;
563bd389b36SDavid du Colombier
564bd389b36SDavid du Colombier s = gmalloc(sizeof(Lsym));
565bd389b36SDavid du Colombier memset(s, 0, sizeof(Lsym));
566bd389b36SDavid du Colombier s->name = strdup(name);
567bd389b36SDavid du Colombier
568bd389b36SDavid du Colombier s->hash = hash[h];
569bd389b36SDavid du Colombier hash[h] = s;
570bd389b36SDavid du Colombier s->lexval = t;
571bd389b36SDavid du Colombier
572bd389b36SDavid du Colombier v = gmalloc(sizeof(Value));
573bd389b36SDavid du Colombier s->v = v;
574bd389b36SDavid du Colombier
575bd389b36SDavid du Colombier v->fmt = 'X';
576bd389b36SDavid du Colombier v->type = TINT;
577bd389b36SDavid du Colombier memset(v, 0, sizeof(Value));
578bd389b36SDavid du Colombier
579bd389b36SDavid du Colombier return s;
580bd389b36SDavid du Colombier }
581bd389b36SDavid du Colombier
582bd389b36SDavid du Colombier Lsym*
look(char * name)583bd389b36SDavid du Colombier look(char *name)
584bd389b36SDavid du Colombier {
585bd389b36SDavid du Colombier Lsym *s;
586*4de34a7eSDavid du Colombier uint h;
587bd389b36SDavid du Colombier char *p;
588bd389b36SDavid du Colombier
589bd389b36SDavid du Colombier h = 0;
590bd389b36SDavid du Colombier for(p = name; *p; p++)
591bd389b36SDavid du Colombier h = h*3 + *p;
592bd389b36SDavid du Colombier h %= Hashsize;
593bd389b36SDavid du Colombier
594bd389b36SDavid du Colombier for(s = hash[h]; s; s = s->hash)
595bd389b36SDavid du Colombier if(strcmp(name, s->name) == 0)
596bd389b36SDavid du Colombier return s;
597bd389b36SDavid du Colombier return 0;
598bd389b36SDavid du Colombier }
599bd389b36SDavid du Colombier
600bd389b36SDavid du Colombier Lsym*
mkvar(char * s)601bd389b36SDavid du Colombier mkvar(char *s)
602bd389b36SDavid du Colombier {
603bd389b36SDavid du Colombier Lsym *l;
604bd389b36SDavid du Colombier
605bd389b36SDavid du Colombier l = look(s);
606bd389b36SDavid du Colombier if(l == 0)
607bd389b36SDavid du Colombier l = enter(s, Tid);
608bd389b36SDavid du Colombier return l;
609bd389b36SDavid du Colombier }
610