USG_PG3/usr/source/lil/lexl.l
#include 'com'
"extern byte (_name sizeof NSIZE)"; % holds lookup name
"extern rsave(), rretrn()"; % special functions
"extern _sn, _compare, _lookup, _add, _lex, _dostring";
". = .data";
peek{ -1; % holds returned lookahead character
}
". = .text";
get{ if (peek < 0) _getchar();
else a = peek;
if (a == '\0') peek = '\0';
else peek = -1;
if (a == '\n') _line + 1;
} return;
putback{
if (arg -> peek == '\n') _line - 1;
} return;
alf{ arg -> a;
if ('a' <= a && a <= 'z' || 'A' <= a && a <= 'Z' ||
a == '.' || a == '_') a = TRUE;
else a = FALSE;
} return;
num{ if ('0' <= arg && arg <= '9') a = TRUE;
else a = FALSE;
} return;
op{ "\n = byte ='=+-<>?*/&~!|^'";
a = 0;
while (n[a] ~= '\0')
{if (byte arg == n[a])
{a = byte ='=+-<>?*/&!!^^'[a]; break op; }
a + 1; }
a = '\0';
} return;
strend{ if (arg == '\'') {a = TRUE; break; }
if (arg == '\n' || arg == '\0')
{putback(arg);
_error(='unbalanced \'');
a = TRUE; break; }
a = FALSE;
} return;
strc{ if (a = arg ~= '\\') break;
if (strend(get() -> arg)) {a = '\''; break; }
if (a = arg == '0') a = 000;
else if (a == 'a') a = 006;
else if (a == 'e') a = 004;
else if (a == 'n') a = 012;
else if (a == 'p') a = 033;
else if (a == 'r') a = 015;
else if (a == 't') a = 011;
else ; % default is \x = x
} return;
_sn{
".data(byte tname sizeof (NSIZE + 2))";
a = arg; b = 0;
do tname[b] = byte [a]++; while (b + 1 < NSIZE);
tname[b] = '\0';
a = &tname;
} return;
_compare{
arg -> a = 0; arg2 -> b;
do if (byte [a] ~= byte [b]++) {a = FALSE; break _compare; }
while (byte [a]++ && arg + 1 < NSIZE);
a = TRUE;
} return;
_lookup{ "args(p1, n)";
call; rsave; 0;
e = _sptop;
while (e ~= p1)
{if (_compare(a = &name + e, n)) {a = e; break _lookup; }
e = prev[e]; }
a = NULL;
} goto rretrn;
_add{ "args(s, byte f, byte t, v, z)";
call; rsave; 0;
if (_space - 1 < 0)
{if (_sbrk("100 * SYMSIZE") < 0)
{_error(='symbol table full');
_exit(TRUE); }
if (_symtab == NULL) _symtab = a;
_space = 99; }
b = _spused * SYMSIZE + _symtab -> e;
_spused + 1;
prev[e] = _sptop; _sptop = e;
c = 0; d = &name + e;
while (byte [s] ~= '\0' && c < NSIZE)
{byte [d]++ = byte [s];
s + 1; c + 1; }
while (c < NSIZE) {byte [d]++ = '\0'; c + 1; }
flags[e] = f; type[e] = t; value[e] = v;
if (flags[e] ?& DEFF) a = 0;
else a = e - _symtab * 1 / SYMSIZE;
bias[e] = a;
size[e] = z;
a = e;
} goto rretrn;
_lex{ call; rsave; &"auto(escape)";
escape = FALSE;
e = &_e;
0 -> flags[e] -> value[e] -> bias[e];
2 -> size[e];
NULL -> prev[e] -> tbran[e] -> fbran[e];
while (true) {
if (get() == '%')
{while (get() ~= '\n' && a ~= '\0') ; }
if (a == ' ' || a == '\t' || a == '\n') continue;
if (a == ';') {a = SCOLON; break _lex; }
if (a == ',') {a = COMMA; break _lex; }
if (a -> c == '0')
{flags[e] = DEFF;
do value[e] ** 1 ** 1 ** 1 + (c - '0');
while (num(c = get()));
putback(c); a = CON; break _lex; }
if (c == '\'')
{flags[e] = DEFF;
if (strend(c = get())) {a = CON; break _lex; }
value[e] = strc(c);
if (strend(c = get())) {a = CON; break _lex; }
value[e] | (strc(c) <*> 8 &~ 0377);
if (strend(c = get())) {a = CON; break _lex; }
putback(c); a = STRING; break _lex; }
if (c == '[') {a = LBRAK; break _lex; }
if (c == ']') {a = RBRAK; break _lex; }
if (c == '(' || c == '{') {a = LPAREN; break _lex; }
if (c == ')' || c == '}') {a = RPAREN; break _lex; }
if (c == '"') {a = QUOTES; break _lex; }
if (c == '\0') {a = EOF; break _lex; }
if (c == '\\') {escape =~ escape; continue; }
if (c == 021) {a = _debug + 1 * 1 / 3; b -> _debug; continue; }
if (c == 001) {_line - 1; continue; }
if (op(c))
{d = 0;
do if (d < NSIZE) {_name[d] = a; d + 1; }
while (op(c = get()));
if (d < NSIZE) _name[d] = '\0';
putback(c);
if (_lookup(NULL, &_name)) a -> value[e] = type[a];
else {_error(='illegal operator %s', _sn(&_name));
_setvb(e, NOP, 0); a = OP; }
break _lex; }
if (alf(c))
{d = 0;
do if (d < NSIZE) {_name[d] = c; d + 1; }
while (alf(c = get()) || num(c));
if (d < NSIZE) _name[d] = '\0';
putback(c);
if (_lookup(NULL, &_name) == NULL)
{flags[e] | DCLF;
a = MEM; break _lex; }
else if (escape && type[a] < KOND)
{type[a] = MEM;
flags[a] = 0;
value[a] = 0;
bias[a] = 0;
size[a] = 2; }
flags[e] = (b = flags[a] & ATTR);
value[e] = a;
size[e] = size[a];
a = type[a]; break _lex; }
if (num(c))
{flags[e] = DEFF;
do value[e] = (b = value[e] * 10 + c - '0');
while (num(c = get()));
putback(c); a = CON; break _lex; }
_error(='illegal character %o', c);
}
} goto rretrn;
_dostring{ "args(p1)";
call; rsave; 0;
p1 -> e;
_gen(d = value[e], 0);
while (strend(c = get()) == FALSE)
{d = strc(c);
if (strend(c = get()))
{_gen(d, 0); a = d; break _dostring; }
_gen(d | (strc(c) <*> 8 &~ 0377), 0); }
a = d;
} goto rretrn;