prompts revisited
[unix-history] / usr / src / usr.bin / pascal / pdx / command / token.l
CommitLineData
6858bd7a
ML
1%{
2/* Copyright (c) 1982 Regents of the University of California */
3
23cc830f 4static char sccsid[] = "@(#)token.l 1.3 %G%";
6858bd7a
ML
5
6/*
7 * Token definitions for pdx scanner.
8 */
9
10#include "defs.h"
11#include "command.h"
12#include "y.tab.h"
23cc830f 13#include "main.h"
6858bd7a
ML
14#include "symtab.h"
15#include "sym.h"
16#include "process.h"
17#include "process/pxinfo.h"
18
19char *initfile = ".pdxinit";
20
21/*
22 * This is a silly "lex" thing.
23 */
24
25#define yywrap() (1)
26
27/*
28 * Override Lex default input macros.
29 */
30
31#undef input
32#undef unput
33
34#define unput(c) ungetc(c, yyin)
35
36%}
37
38blank [ \t]
39white {blank}+
40alpha [a-zA-Z]
41digit [0-9]
42n {digit}+
43h [0-9a-fA-F]+
44e (("e"|"E")("+"|"-")?{n})
45alphanum [a-zA-Z0-9]
46ident {alpha}{alphanum}*
47filenm [^ \t\n"<>!*"]+
48qfilenm {filenm}/":"
49string '[^']+'('[^']*')*
50newline "\n"
51char .
52
53%Start file sh
54
55%%
56
57{white} ;
58^sh{white}.*$ { BEGIN 0; yylval.y_string = &yytext[3]; return(SH); }
59^sh { BEGIN 0; yylval.y_string = NIL; return(SH); }
60^{ident} { return(findcmd(yytext)); }
f677c8e6
ML
61<file>{filenm} { yylval.y_string = strdup(yytext); return(FILENAME); }
62{qfilenm} { yylval.y_string = strdup(yytext); return(FILENAME); }
6858bd7a
ML
63{n}?\.{n}{e}? { yylval.y_real = atof(yytext); return(REAL); }
640{n} { yylval.y_long = octal(yytext); return(INT); }
650x{h} { yylval.y_long = hex(yytext); return(INT); }
66{n} { yylval.y_long = atol(yytext); return(INT); }
6858bd7a
ML
67at { return(AT); }
68{ident} { return(ident(yytext)); }
69{string} { yylval.y_string = yytext; return(STRING); }
70"%dp" { yylval.y_long = (long) DP; return(INT); }
71{newline} { BEGIN 0; nlflag = TRUE; return('\n'); }
72{char} { return(yylval.y_int = yytext[0]); }
73
74%%
75
76LOCAL SYMTAB *dbtab, *specialtab;
77
78/*
79 * Look for the given string in the debugger keyword table.
80 * If it's there, return the associated token, otherwise report an error.
81 */
82
83LOCAL int findcmd(s)
84char *s;
85{
86 register SYM *p;
87
88 if ((p = st_lookup(dbtab, s)) == NIL) {
89 error("\"%s\" is not a command", s);
90 }
91 yylval.y_int = tokval(p);
92 switch (toknum(p)) {
93 case ALIAS:
94 case DUMP:
95 case EDIT:
96 case CHFILE:
97 case RUN:
98 case SOURCE:
99 case STATUS:
100 BEGIN file;
101 break;
102
103 default:
104 /* do nothing */;
105 }
106 return(toknum(p));
107}
108
109/*
110 * Look for a symbol, first in the special table (if, in, etc.)
111 * then in the symbol table. If it's there, return the SYM pointer,
112 * otherwise it's an error.
113 */
114
115LOCAL int ident(s)
116char *s;
117{
118 register SYM *p;
119
120 if ((p = st_lookup(specialtab, s)) != NIL) {
121 yylval.y_sym = p;
122 return(toknum(p));
123 }
124 p = st_lookup(symtab, s);
125 if (p == NIL) {
126 if (strcmp(s, "nil") == 0) {
127 yylval.y_long = 0L;
128 return(INT);
129 } else {
130 error("\"%s\" is not defined", s);
131 }
132 }
133 yylval.y_sym = p;
134 return(NAME);
135}
136
137/*
138 * Convert a string to octal. No check that digits are less than 8.
139 */
140
141LOCAL int octal(s)
142char *s;
143{
144 register char *p;
145 register int n;
146
147 n = 0;
148 for (p = s; *p != '\0'; p++) {
149 n = 8*n + (*p - '0');
150 }
151 return(n);
152}
153
154/*
155 * Convert a string to hex.
156 */
157
158LOCAL int hex(s)
159char *s;
160{
161 register char *p;
162 register int n;
163
164 n = 0;
165 for (p = s+2; *p != '\0'; p++) {
166 n *= 16;
167 if (*p >= 'a' && *p <= 'f') {
168 n += (*p - 'a' + 10);
169 } else if (*p >= 'A' && *p <= 'F') {
170 n += (*p - 'A' + 10);
171 } else {
172 n += (*p - '0');
173 }
174 }
175 return(n);
176}
177
178/*
179 * Initialize the debugger keyword table (dbtab) and special symbol
180 * table (specialtab).
181 */
182
183#define db_keyword(nm, n) make_keyword(dbtab, nm, n)
184#define sp_keyword(nm, n) make_keyword(specialtab, nm, n)
185
186lexinit()
187{
188 dbtab = st_creat(150);
189 db_keyword("alias", ALIAS);
190 db_keyword("assign", ASSIGN);
191 db_keyword("call", CALL);
192 db_keyword("cont", CONT);
193 db_keyword("delete", DELETE);
194 db_keyword("dump", DUMP);
195 db_keyword("edit", EDIT);
196 db_keyword("file", CHFILE);
197 db_keyword("gripe", GRIPE);
198 db_keyword("help", HELP);
199 db_keyword("list", LIST);
200 db_keyword("next", NEXT);
201 db_keyword("pi", REMAKE);
202 db_keyword("print", PRINT);
203 db_keyword("quit", QUIT);
204 db_keyword("run", RUN);
205 db_keyword("sh", SH);
206 db_keyword("source", SOURCE);
207 db_keyword("status", STATUS);
208 db_keyword("step", STEP);
209 db_keyword("stop", STOP);
210 db_keyword("stopi", STOPI);
211 db_keyword("trace", TRACE);
212 db_keyword("tracei", TRACEI);
213 db_keyword("whatis", WHATIS);
214 db_keyword("where", WHERE);
215 db_keyword("which", WHICH);
216 db_keyword("xd", XD);
217 db_keyword("xi", XI);
218
219 specialtab = st_creat(10);
220 sp_keyword("div", DIV);
221 sp_keyword("mod", MOD);
222 sp_keyword("in", IN);
223 sp_keyword("if", IF);
224 sp_keyword("and", AND);
225 sp_keyword("or", OR);
226}
227
228/*
229 * Send an alias directive over to the symbol table manager.
230 */
231
232alias(new, old)
233char *new, *old;
234{
235 if (old == NIL) {
236 print_alias(dbtab, new);
237 } else {
238 enter_alias(dbtab, new, old);
239 }
240}
241
242/*
243 * Input file management routines, "yyin" is Lex's idea of
244 * where the input comes from.
245 */
246
247#define MAXINPUT 10
248
249LOCAL FILE *infp[MAXINPUT];
250LOCAL FILE **curfp = &infp[0];
251
252LOCAL BOOLEAN isnewfile;
23cc830f 253LOCAL BOOLEAN firsttime;
6858bd7a
ML
254
255/*
256 * Initially, we set the input to the initfile if it exists.
257 * If it does exist, we play a game or two to avoid generating
258 * multiple prompts.
259 */
260
261initinput()
262{
263 FILE *fp;
264
23cc830f 265 firsttime = FALSE;
6858bd7a
ML
266 fp = fopen(initfile, "r");
267 if (fp != NIL) {
268 fclose(fp);
269 setinput(initfile);
23cc830f
ML
270 if (!option('r')) {
271 firsttime = TRUE;
272 }
6858bd7a
ML
273 }
274 nlflag = TRUE;
275}
276
277/*
278 * Set the input to the named file. It is expected that the file exists
279 * and is readable.
280 */
281
282setinput(filename)
283char *filename;
284{
285 register FILE *fp;
286
287 if ((fp = fopen(filename, "r")) == NIL) {
288 error("can't open %s", filename);
289 }
290 if (curfp >= &infp[MAXINPUT]) {
291 error("unreasonable input nesting on %s", filename);
292 }
293 *curfp++ = yyin;
294 yyin = fp;
295 isnewfile = TRUE;
296}
297
298BOOLEAN isstdin()
299{
300 return((BOOLEAN) (yyin == stdin));
301}
302
303LOCAL int input()
304{
305 register int c;
306
307 if (isnewfile) {
308 isnewfile = FALSE;
309 return('\n');
310 }
311 while ((c = getc(yyin)) == EOF) {
312 if (curfp == &infp[0]) {
313 return(0);
314 } else {
315 fclose(yyin);
316 yyin = *--curfp;
317 if (yyin == stdin) {
23cc830f
ML
318 if (firsttime) {
319 firsttime = FALSE;
320 } else {
321 prompt();
322 }
6858bd7a
ML
323 }
324 }
325 }
326 return(c);
327}
328
329/*
330 * Handle an input string by stripping the quotes and converting
331 * two interior quotes to one. Copy to newly allocated space and
332 * return a pointer to it.
333 *
334 * The handling of strings here is not particularly efficient,
335 * nor need it be.
336 */
337
338LOCAL char *pstring(p)
339char *p;
340{
341 int i, len;
342 char *r, *newp;
343
344 len = strlen(p);
345 r = newp = alloc(len - 2 + 1, char);
346 for (i = 1; i < len - 1; i++) {
347 if (p[i] == '\'' && p[i+1] == '\'') {
348 i++;
349 }
350 *newp++ = p[i];
351 }
352 *newp = '\0';
353 return(r);
354}
355
356/*
357 * prompt for a command
358 */
359
360prompt()
361{
362 nlflag = FALSE;
363 if (yyin == stdin) {
364 printf("> ");
365 fflush(stdout);
366 }
367}