|
|
researchv10 Norman
/* @(#)kas0.y 1.1 */
%union {
int ival;
struct exp *expr;
struct symtab *sym;
char *str;
}
%token NOCHAR NL
%token CM SEMI COLON LP RP
%token PLUS MINUS MUL DIV NOT POP BAR INC
%token AND XOR LS RS
%token <ival> INT
%token <sym> DNAME UNAME TNAME PAGE
%token <str> STR
%token <sym> REG BRG MEM MAR REGL REGH PC PCR
%token <sym> MVINS SFINS DFINS BRINS JMPINS
%token <sym> SEG ORG DATA DEBUG
%nonassoc COLON
%left BAR XOR
%left AND
%left LS RS
%left PLUS MINUS
%left MUL DIV
%left NOT POP
%type <sym> fref
%type <ival> mach func page dst pdst sdst udst boreg oreg reg2
%type <expr> expr val db debug
%{
#include <stdio.h>
#include "kas.h"
struct exp explist[10];
struct exp *xp = { explist};
%}
%%
%{
int dinc;
int nlf;
%}
prog: /* empty */
| prog line = {
xp = explist;
if (nlf)
lineno++;
}
;
line: labels close
| labels mach = {
putins($2);
}
| labels pseudo close
| debug close = {
debug($1->xvalue, $1->xtype);
}
| error close = {
yyerrok;
}
;
labels: /* empty */
| labels UNAME COLON = {
$2->type = dot->type;
backup($2,dot->value);
}
| labels INT COLON = {
if ($2<0 || $2>9) {
yyerror("illegal numeric label");
} else {
loclab[$2].name[0] = 1;
backup(&loclab[$2], dot->value);
loclab[$2].type = dot->value;
loclab[$2].value = 0;
}
}
;
close: NL = {
nlf = 1;
}
| SEMI = {
nlf = 0;
}
;
mach: MVINS fref CM udst close = {
$$ = $1->value|$4;
reloc[dot->value] = $2->value;
$2->value = dot->value|RLCMV;
}
| MVINS POP fref CM udst close = {
$$ = $1->value|$5;
reloc[dot->value] = $3->value;
$3->value = dot->value|RLCPOP;
}
| MVINS expr CM dst close = {
$$ = $1->value|cksrc($2->xvalue&0377, $4);
}
| MVINS REG CM dst close = {
$$ = $1->value|SRCBRG|SELA|ckreg($2->value, $4);
}
| MVINS oreg CM dst close = {
$$ = $1->value|$2|$4;
}
| SFINS REG CM dst close = {
$$ = $1->value|SRCBRG|ckreg($2->value, $4);
}
| SFINS REG close = {
$$ = $1->value|SRCBRG|$2->value|DSTREG;
}
| DFINS reg2 CM REG CM dst close = {
$$ = $1->value|$2|ckreg($4->value, $6);
}
| DFINS reg2 CM REG close = {
$$ = $1->value|$2|$4->value|DSTREG;
}
| BRINS expr close = {
$$ = $1->value|($2->xvalue&0377)|(($2->xvalue&01400)<<3);
if ((dot->value&~01777) != ($2->xvalue&~01777))
yyerror("branch out of range");
}
| BRINS fref close = {
$$ = $1->value;
reloc[dot->value] = $2->value;
$2->value = dot->value|RLCBR;
}
| BRINS LP func RP page close = {
$$ = $1->value|$3|$5;
}
| JMPINS expr close = {
$$ = $1->value|($2->xvalue&0377);
}
| JMPINS fref close = {
$$ = $1->value;
reloc[dot->value] = $2->value;
$2->value = dot->value|RLCMV;
}
| JMPINS LP func RP close = {
$$ = $1->value|$3;
}
;
func: REG = {
$$ = $1->value|SRCBRG|SELA;
}
| reg2 = {
$$ = $1|SELB;
}
| SFINS CM REG = {
$$ = $1->value|$3->value|SRCBRG;
}
| DFINS CM reg2 CM REG = {
$$ = $1->value|$3|$5->value;
}
;
page: /* empty */ = {
$$ = 0;
}
| CM PAGE = {
$$ = $2->value;
}
| CM POP val = {
$$ = ($3->xvalue&01400)<<3;
}
| CM POP fref = {
$$ = 0;
reloc[dot->value] = $3->value;
$3->value = dot->value|RLCPG;
}
;
fref:
UNAME
| TNAME
;
dst: MINUS = {
$$ = 0;
}
| pdst
| pdst BAR pdst = {
$$ = ckdst($1, $3);
}
| pdst BAR pdst BAR pdst = {
$$ = ckdst(ckdst($1, $3), $5);
}
;
pdst: REG = {
$$ = $1->value|DSTREG;
}
| BRG = {
$$ = DSTBRG;
}
| MEM = {
$$ = DSTMEM;
}
| REGL = {
$$ = $1->value|DSTREGL;
}
| REGH = {
$$ = $1->value|DSTREGH;
}
| BRG RS = {
$$ = DSTBGRS;
}
| MAR = {
$$ = DSTMAR;
}
| MAR INC = {
$$ = DSTMARI;
}
| POP MAR = {
$$ = DSTMARP;
}
| PCR = {
$$ = DSTPCH|DSTREGH;
}
;
udst: sdst
| sdst BAR sdst = {
$$ = ckdst($1, $3);
}
;
sdst: BRG = {
$$ = DSTBRG;
}
| MEM = {
$$ = DSTMEM;
}
| MAR = {
$$ = DSTMAR;
}
| MAR INC = {
$$ = DSTMARI;
}
| POP MAR = {
$$ = DSTMARP;
}
;
oreg: reg2 = {
$$ = $1|SELB;
}
| REGL = {
$$ = ($1->value<<4)|SRCREGL;
}
| REGH = {
$$ = ($1->value<<4)|SRCREGH;
}
| boreg = {
$$ = ($1<<4)|SRCREGH;
}
;
reg2: BRG = {
$$ = SRCBRG;
}
| MEM = {
$$ = SRCMEM;
}
;
boreg: MAR = {
$$ = SRCMARL;
}
| POP MAR = {
$$ = SRCMARH;
}
| PC = {
$$ = SRCPCL;
}
| POP PC = {
$$ = SRCPCH;
}
;
expr: val
| LP expr RP = {
$$ = $2;
}
| expr BAR expr = {
$1->xvalue |= $3->xvalue;
}
| expr XOR expr = {
$1->xvalue ^= $3->xvalue;
}
| expr AND expr = {
$1->xvalue &= $3->xvalue;
}
| expr LS expr = {
$1->xvalue <<= $3->xvalue;
}
| expr RS expr = {
$1->xvalue >>= $3->xvalue;
}
| expr PLUS expr = {
$1->xvalue += $3->xvalue;
}
| expr MINUS expr = {
$1->xvalue -= $3->xvalue;
}
| expr MUL expr = {
$1->xvalue *= $3->xvalue;
}
| expr DIV expr = {
$1->xvalue /= $3->xvalue;
}
| NOT expr = {
$2->xvalue = ~$2->xvalue;
$$ = $2;
}
| POP expr = {
$2->xvalue = ($2->xvalue>>8)&0377;
$$ = $2;
}
| MINUS expr %prec POP = {
$2->xvalue = -$2->xvalue;
$$ = $2;
}
;
val: DNAME = {
$$ = xp++;
$$->xtype = XABS;
$$->xvalue = $1->value;
}
| INT = {
$$ = xp++;
$$->xtype = XABS;
$$->xvalue = $1;
}
;
pseudo: SEG = {
if (dot->type==XTEXT)
textsv = dot->value;
else datasv = dot->value;
dot->type = $1->value;
if (dot->type==XTEXT)
dot->value = textsv;
else dot->value = datasv;
}
| ORG expr = {
if ($2->xvalue<0 || $2->xvalue>=NKMCI)
yyerror("illegal org value");
else dot->value = $2->xvalue;
}
| data explist
;
data: DATA = {
if (dot->type != XDATA) {
yyerror("no data in text");
}
dinc = $1->value;
}
;
explist: outexpr
| explist CM outexpr
;
outexpr: expr = {
putdat($1->xvalue&0377);
if (dinc==2)
putdat(($1->xvalue>>8)&0377);
xp = explist;
}
;
debug: db
| db INT = {
$1->xtype = $2;
}
| db STR = {
$1->xtype = (int)$2;
}
;
db: DEBUG = {
$$ = xp++;
$$->xvalue = $1->value;
$$->xtype = 0;
}
;
%%
yyerror(s, a)
char *s;
{
anyerrs++;
if (infile)
fprintf(stderr, "%s:", infile);
fprintf(stderr, "%d:", lineno);
fprintf(stderr, s, a);
fprintf(stderr, "\n");
}
#include "kas0.yl"
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.