summaryrefslogtreecommitdiff
path: root/asm/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'asm/lex.c')
-rw-r--r--asm/lex.c685
1 files changed, 0 insertions, 685 deletions
diff --git a/asm/lex.c b/asm/lex.c
deleted file mode 100644
index 7fb5ec71..00000000
--- a/asm/lex.c
+++ /dev/null
@@ -1,685 +0,0 @@
-#include "asm.h"
-#include "y.tab.h"
-#include "../libinterp/tab.h"
-
-Biobuf* bin;
-Biobuf* bout;
-Biobuf output;
-int line;
-int heapid;
-char symbol[1024];
-int nerr;
-char cmap[256];
-char* file;
-Desc* dlist;
-int dcount;
-int dseg;
-List* mdata;
-Sym* module;
-Link* links;
-Link* linkt;
-int nlink;
-int listing;
-int mustcompile;
-int dontcompile;
-char *ofile;
-int dentry;
-int pcentry;
-
-void
-usage(void)
-{
- fprint(2, "usage: asm [-l] file.s\n");
- exits("usage");
-}
-
-static char*
-mkfile(char *file, char *oldext, char *ext)
-{
- char *ofile;
- int n, n2;
-
- n = strlen(file);
- n2 = strlen(oldext);
- if(n >= n2 && strcmp(&file[n-n2], oldext) == 0)
- n -= n2;
- ofile = malloc(n + strlen(ext) + 1);
- memmove(ofile, file, n);
- strcpy(ofile+n, ext);
- return ofile;
-}
-
-void
-main(int argc, char *argv[])
-{
- int fd;
- char *p;
-
- ARGBEGIN{
- case 'C':
- dontcompile++;
- break;
- case 'c':
- mustcompile++;
- break;
- case 'l':
- listing++;
- break;
- default:
- usage();
- }ARGEND;
-
- fmtinstall('i', iconv);
- fmtinstall('a', aconv);
- kinit();
- pcentry = -1;
- dentry = -1;
-
- if(argc != 1)
- usage();
- file = argv[0];
- bin = Bopen(file, OREAD);
- if(bin == 0) {
- nerr++;
- print("open: %s: %r\n", file);
- exits("errors");
- }
- p = strrchr(file, '/');
- if(p == nil)
- p = file;
- else
- p++;
- ofile = mkfile(p, ".s", ".dis");
- fd = create(ofile, OWRITE, 0666);
- if(fd < 0) {
- nerr++;
- print("can't create: %s: %r\n", ofile);
- exits("errors");
- }
- Binit(&output, fd, OWRITE);
- bout = &output;
- line = 1;
- yyparse();
- Bterm(bin);
- Bterm(bout);
- close(fd);
-
- if(nerr != 0){
- remove(ofile);
- exits("errors");
- }
-
- exits(0);
-}
-
-int
-opcode(Inst *i)
-{
- return keywds[i->op].op;
-}
-
-int
-iconv(Fmt *f)
-{
- Inst *i;
- char buf[128];
-
- i = va_arg(f->args, Inst*);
- if(i == nil)
- return fmtstrcpy(f, "IZ");
-
- switch(keywds[i->op].terminal) {
- case TOKI0:
- sprint(buf, "%s", keywds[i->op].name);
- break;
- case TOKI1:
- sprint(buf, "%s\t%a", keywds[i->op].name, i->dst);
- break;
- case TOKI3:
- if(i->reg != 0) {
- char *pre = "";
- char *post = "";
- switch(i->reg->mode) {
- case AXIMM:
- pre = "$";
- break;
- case AXINF:
- post = "(fp)";
- break;
- case AXINM:
- post = "(mp)";
- break;
- }
- sprint(buf, "%s\t%a, %s%ld%s, %a", keywds[i->op].name, i->src, pre, i->reg->val, post, i->dst);
- break;
- }
- case TOKI2:
- sprint(buf, "%s\t%a, %a", keywds[i->op].name, i->src, i->dst);
- break;
- }
-
- return fmtstrcpy(f, buf);
-}
-
-int
-aconv(Fmt *f)
-{
- Addr *a;
- char buf[64];
-
- a = va_arg(f->args, Addr*);
-
- if(a == nil)
- return fmtstrcpy(f, "AZ");
-
- if(a->mode & AIND) {
- switch(a->mode & ~AIND) {
- case AFP:
- sprint(buf, "%ld(%d(fp))", a->val, a->off);
- break;
- case AMP:
- sprint(buf, "%ld(%d(mp))", a->val, a->off);
- break;
- }
- }
- else {
- switch(a->mode) {
- case AFP:
- sprint(buf, "%ld(fp)", a->val);
- break;
- case AMP:
- sprint(buf, "%ld(mp)", a->val);
- break;
- case AIMM:
- sprint(buf, "$%ld", a->val);
- break;
- }
- }
-
- return fmtstrcpy(f, buf);
-}
-
-void
-kinit(void)
-{
- int i;
- Sym *s;
-
- for(i = 0; keywds[i].name; i++) {
- s = enter(keywds[i].name, keywds[i].terminal);
- s->value = keywds[i].op;
- }
-
- enter("desc", TOKHEAP);
- enter("mp", TOKSB);
- enter("fp", TOKFP);
-
- enter("byte", TOKDB);
- enter("word", TOKDW);
- enter("long", TOKDL);
- enter("real", TOKDF);
- enter("string", TOKDS);
- enter("var", TOKVAR);
- enter("ext", TOKEXT);
- enter("module", TOKMOD);
- enter("link", TOKLINK);
- enter("entry", TOKENTRY);
- enter("array", TOKARRAY);
- enter("indir", TOKINDIR);
- enter("apop", TOKAPOP);
- enter("ldts", TOKLDTS);
- enter("exceptions", TOKEXCS);
- enter("exception", TOKEXC);
- enter("exctab", TOKETAB);
- enter("source", TOKSRC);
-
- cmap['0'] = '\0'+1;
- cmap['z'] = '\0'+1;
- cmap['n'] = '\n'+1;
- cmap['r'] = '\r'+1;
- cmap['t'] = '\t'+1;
- cmap['b'] = '\b'+1;
- cmap['f'] = '\f'+1;
- cmap['a'] = '\a'+1;
- cmap['v'] = '\v'+1;
- cmap['\\'] = '\\'+1;
- cmap['"'] = '"'+1;
-}
-
-int
-escchar(char c)
-{
- int n;
- char buf[32];
-
- if(c >= '0' && c <= '9') {
- n = 1;
- buf[0] = c;
- for(;;) {
- c = Bgetc(bin);
- if(c == Eof)
- fatal("%d: <eof> in escape sequence", line);
- if(strchr("0123456789xX", c) == 0) {
- Bungetc(bin);
- break;
- }
- buf[n++] = c;
- }
- buf[n] = '\0';
- return strtol(buf, 0, 0);
- }
-
- n = cmap[c];
- if(n == 0)
- return c;
- return n-1;
-}
-
-static char *strbuf;
-static int bufmax;
-
-static void
-resizebuf(void)
-{
- bufmax += Strsize;
- strbuf = realloc(strbuf, bufmax);
-}
-
-void
-eatstring(void)
-{
- String *s;
- int esc, c, cnt;
-
- esc = 0;
- for(cnt = 0;;) {
- c = Bgetc(bin);
- switch(c) {
- case Eof:
- fatal("%d: <eof> in string constant", line);
-
- case '\n':
- line++;
- diag("newline in string constant");
- goto done;
-
- case '\\':
- if(esc) {
- if(cnt >= bufmax)
- resizebuf();
- strbuf[cnt++] = c;
- esc = 0;
- break;
- }
- esc = 1;
- break;
-
- case '"':
- if(esc == 0)
- goto done;
-
- /* Fall through */
- default:
- if(esc) {
- c = escchar(c);
- esc = 0;
- }
- if(cnt >= bufmax)
- resizebuf();
- strbuf[cnt++] = c;
- break;
- }
- }
-done:
- if(cnt >= bufmax)
- resizebuf();
- strbuf[cnt] = '\0';
- s = malloc(sizeof(String));
- s->len = cnt+1;
- s->string = malloc(s->len);
- memmove(s->string, strbuf, s->len);
- yylval.string = s;
-}
-
-void
-eatnl(void)
-{
- int c;
-
- line++;
- for(;;) {
- c = Bgetc(bin);
- if(c == Eof)
- diag("eof in comment");
- if(c == '\n')
- return;
- }
-}
-
-int
-yylex(void)
-{
- int c;
-
-loop:
- c = Bgetc(bin);
- switch(c) {
- case Eof:
- return Eof;
- case '"':
- eatstring();
- return TSTRING;
- case ' ':
- case '\t':
- case '\r':
- goto loop;
- case '\n':
- line++;
- goto loop;
- case '.':
- c = Bgetc(bin);
- Bungetc(bin);
- if(isdigit(c))
- return numsym('.');
- return '.';
- case '#':
- eatnl();
- goto loop;
- case '(':
- case ')':
- case ';':
- case ',':
- case '~':
- case '$':
- case '+':
- case '/':
- case '%':
- case '^':
- case '*':
- case '&':
- case '=':
- case '|':
- case '<':
- case '>':
- case '-':
- case ':':
- return c;
- case '\'':
- c = Bgetrune(bin);
- if(c == '\\')
- yylval.ival = escchar(Bgetc(bin));
- else
- yylval.ival = c;
- c = Bgetc(bin);
- if(c != '\'') {
- diag("missing '");
- Bungetc(bin);
- }
- return TCONST;
-
- default:
- return numsym(c);
- }
-}
-
-int
-numsym(char first)
-{
- int c;
- char *p;
- Sym *s;
- enum { Int, Hex, Frac, Expsign, Exp } state;
-
- symbol[0] = first;
- p = symbol;
-
- if(first == '.')
- state = Frac;
- else
- state = Int;
-
- if(isdigit(*p++) || state == Frac) {
- for(;;) {
- c = Bgetc(bin);
- if(c < 0)
- fatal("%d: <eof> eating numeric", line);
-
- switch(state) {
- case Int:
- if(strchr("01234567890", c))
- break;
- switch(c) {
- case 'x':
- case 'X':
- state = Hex;
- break;
- case '.':
- state = Frac;
- break;
- case 'e':
- case 'E':
- state = Expsign;
- break;
- default:
- goto done;
- }
- break;
- case Hex:
- if(strchr("01234567890abcdefABCDEF", c) == 0)
- goto done;
- break;
- case Frac:
- if(strchr("01234567890", c))
- break;
- if(c == 'e' || c == 'E')
- state = Expsign;
- else
- goto done;
- break;
- case Expsign:
- state = Exp;
- if(c == '-' || c == '+')
- break;
- /* else fall through */
- case Exp:
- if(strchr("01234567890", c) == 0)
- goto done;
- break;
- }
- *p++ = c;
- }
- done:
- Bungetc(bin);
- *p = '\0';
- switch(state) {
- default:
- yylval.ival = strtoll(symbol, 0, 0);
- return TCONST;
- case Frac:
- case Expsign:
- case Exp:
- yylval.fval = strtod(symbol, 0);
- return TFCONST;
- }
- }
-
- for(;;) {
- c = Bgetc(bin);
- if(c < 0)
- fatal("%d <eof> eating symbols", line);
- /* '$' and '/' can occur in fully-qualified Java class names */
- if(c != '_' && c != '.' && c != '/' && c != '$' && !isalnum(c)) {
- Bungetc(bin);
- break;
- }
- *p++ = c;
- }
-
- *p = '\0';
-
- s = enter(symbol, TID);
- switch(s->lexval) {
- default:
- yylval.sym = s;
- break;
- case TOKI0:
- case TOKI1:
- case TOKI2:
- case TOKI3:
- yylval.ival = s->value;
- break;
- }
- return s->lexval;
-}
-
-static Sym *hash[Hashsize];
-
-Sym *
-enter(char *name, int type)
-{
- Sym *s;
- ulong h;
- char *p;
-
- s = lookup(name);
- if(s != nil)
- return s;
-
- h = 0;
- for(p = name; *p; p++)
- h = h*3 + *p;
- h %= Hashsize;
-
- s = malloc(sizeof(Sym));
- memset(s, 0, sizeof(Sym));
- s->name = strdup(name);
- s->lexval = type;
- s->hash = hash[h];
- hash[h] = s;
- return s;
-}
-
-Sym *
-lookup(char *name)
-{
- Sym *s;
- ulong h;
- char *p;
-
- h = 0;
- for(p = name; *p; p++)
- h = h*3 + *p;
- h %= Hashsize;
-
- for(s = hash[h]; s; s = s->hash)
- if(strcmp(name, s->name) == 0)
- return s;
- return 0;
-}
-
-void
-yyerror(char *a, ...)
-{
- va_list arg;
- char buf[128];
-
- if(strcmp(a, "syntax error") == 0) {
- yyerror("syntax error, near symbol '%s'", symbol);
- return;
- }
- va_start(arg, a);
- vseprint(buf, buf+sizeof(buf), a, arg);
- va_end(arg);
- print("%s %d: %s\n", file, line, buf);
- if(nerr++ > 10) {
- fprint(2, "%s %d: too many errors, giving up\n", file, line);
- remove(ofile);
- exits("yyerror");
- }
-}
-
-void
-fatal(char *fmt, ...)
-{
- va_list arg;
- char buf[512];
-
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- fprint(2, "asm: %d (fatal compiler problem) %s\n", line, buf);
- exits(buf);
-}
-
-void
-diag(char *fmt, ...)
-{
- int srcline;
- va_list arg;
- char buf[512];
-
- srcline = line;
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- fprint(2, "%s %d: %s\n", file, srcline, buf);
- if(nerr++ > 10) {
- fprint(2, "%s %d: too many errors, giving up\n", file, line);
- remove(ofile);
- exits("errors");
- }
-}
-
-Inst*
-ai(int op)
-{
- Inst *i;
-
- i = malloc(sizeof(Inst));
- memset(i, 0, sizeof(Inst));
- i->op = op;
-
- return i;
-}
-
-Addr*
-aa(int val)
-{
- Addr *a;
-
- a = malloc(sizeof(Addr));
- memset(a, 0, sizeof(Addr));
- a->val = val;
- if(val <= -1073741824 && val > 1073741823)
- diag("offset out of range");
-
- return a;
-}
-
-vlong
-dtocanon(double d)
-{
- int swap;
- ulong t;
- union { double d; ulong ul[2]; } u1;
- union { vlong v; ulong ul[2]; } u2;
-
- u2.v = 1;
- swap = u2.ul[0];
- u1.d = 1.;
- if(u1.ul[0]){
- u1.d = d;
- u2.ul[0] = u1.ul[0];
- u2.ul[1] = u1.ul[1];
- }else{
- u1.d = d;
- u2.ul[0] = u1.ul[1];
- u2.ul[1] = u1.ul[0];
- }
- if(swap){
- t = u2.ul[0];
- u2.ul[0] = u2.ul[1];
- u2.ul[1] = t;
- }
- return u2.v;
-}