12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127 |
- %{
- #ifndef NORCSID
- static char rcsid[]="$Id$";
- #endif
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- * Author: Hans van Staveren
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include <em_spec.h>
- #include <em_flag.h>
- #include <em_reg.h>
- #define extern
- #include "booth.h"
- #undef extern
- %}
- %union {
- int yy_int;
- int *yy_intp;
- string yy_string;
- list1 yy_list1;
- list2 yy_list2;
- expr_t yy_expr;
- cost_t yy_cost;
- set_t yy_set;
- ident_p yy_ident;
- char yy_char;
- inst_t yy_instance;
- }
- %type <yy_list1> list1 structlistel
- %type <yy_list2> structlist structdecl
- %type <yy_expr> expr optexpr
- %type <yy_cost> optcost cost optcommacost
- %type <yy_int> optboolexpr optnocoerc mnem emargno tokargno optprop
- %type <yy_int> optcommabool optstack subreg tokenexpressionno optregvar
- %type <yy_int> tokeninstanceno code stackreplacement optslashnumber
- %type <yy_set> tokenexpression
- %type <yy_instance> tokeninstance
- %type <yy_string> optformat
- %token <yy_string> IDENT TYPENAME
- %token <yy_ident> RIDENT PIDENT TIDENT EIDENT
- %token <yy_string> LSTRING STRING
- %token <yy_int> NUMBER
- %token <yy_intp> CIDENT
- %token REGISTERHEAD TOKENHEAD EXPRESSIONHEAD CODEHEAD MOVEHEAD TESTHEAD STACKHEAD
- %token REGVAR INREG LOOP POINTER FLOAT
- %token TIMEFAC SIZEFAC FORMAT RETURN
- %token MOVE ERASE ALLOCATE ELLIPS COST REMOVE STACK
- %token SEP SAMESIGN SFIT UFIT ROM DEFINED TOSTRING LOWW HIGHW
- %token NOCC SETCC SAMECC TEST NOCOERC
- %token <yy_char> LCASELETTER
- %start machinespec
- %left OR2
- %left AND2
- %left CMPEQ CMPNE
- %left CMPLT CMPLE CMPGT CMPGE
- %left RSHIFT LSHIFT
- %left '+' '-'
- %left '*' '/' '%'
- %nonassoc NOT COMP UMINUS
- %nonassoc '$'
- %%
- machinespec
- : rcsid constants registersection tokensection
- { inbetween(); }
- expressionsection codesection movesection testsection stacksection
- ;
- rcsid
- : /* empty */
- | STRING
- { strlookup($1); }
- ;
- constants
- : /* empty */
- | constants CIDENT '=' NUMBER
- { *$2 = $4; }
- | constants SIZEFAC '=' NUMBER optslashnumber
- { cc1 = $4; cc2 = $5; }
- | constants TIMEFAC '=' NUMBER optslashnumber
- { cc3 = $4; cc4 = $5; }
- | constants FORMAT '=' STRING
- { fmt = $4; }
- ;
- optslashnumber
- : /* empty */
- { $$ = 1; }
- | '/' NUMBER
- { $$ = $2; }
- ;
- registersection
- : REGISTERHEAD registerdefs
- ;
- registerdefs
- : /* empty */
- | registerdefs registerdef
- ;
- registerdef
- : IDENT '=' '(' STRING ',' NUMBER list1 ')' optregvar list1 '.'
- { register ident_p ip;
- register list1 l;
- register reginfo r;
- int i;
- r=(reginfo) myalloc(sizeof(struct reginfo));
- r->rname = $1;
- r->rrepr = $4;
- r->rsize = $6;
- if($9>=0 && $7!=0)
- yyerror("No subregisters allowed in regvar");
- for (i=0;i<MAXMEMBERS;i++)
- r->rmembers[i] = 0;
- i=0;
- for (l=$7;l!=0;l=l->l1next) {
- ip=ilookup(l->l1name,LOOKUP);
- if (ip->i_type != IREG)
- yyerror("Bad member of set");
- chktabsiz(i,MAXMEMBERS,"Member of register");
- r->rmembers[i++] = ip->i_i.i_regno;
- }
- maxmembers=max(maxmembers,i);
- r->rregvar=$9;
- if ($9>=0) {
- rvused=1;
- chktabsiz(nregvar[$9],MAXREGVARS,"Regvar");
- rvnumbers[$9][nregvar[$9]++] = nmachregs;
- }
- for(i=0;i<PROPSETSIZE;i++)
- r->rprop[i] = 0;
- ip=ilookup($1,ENTER);
- ip->i_type=IREG;
- ip->i_i.i_regno=nmachregs;
- for (l = $10; l!= 0; l=l->l1next) {
- ip = ilookup(l->l1name,HALFWAY);
- if (ip->i_type) {
- if (ip->i_type != IPRP)
- yyerror("Multiple defined symbol");
- else if(machprops[ip->i_i.i_prpno].propset.set_size != r->rsize)
- yyerror("property has more than 1 size");
- } else {
- chktabsiz(nprops,MAXPROPS,"Property");
- ip->i_type = IPRP;
- ip->i_i.i_prpno = nprops;
- machprops[nprops].propname = ip;
- machprops[nprops++].propset.set_size = r->rsize;
- }
- r->rprop[ip->i_i.i_prpno>>4] |= (1<<(ip->i_i.i_prpno&017));
- }
- chktabsiz(nmachregs,MAXREGS,"Register table");
- machregs[nmachregs++] = r;
- }
- | error '.'
- ;
- optregvar
- : /* nothing */
- { $$ = -1; }
- | REGVAR
- { $$ = reg_any; }
- | REGVAR '(' LOOP ')'
- { $$ = reg_loop; }
- | REGVAR '(' POINTER ')'
- { $$ = reg_pointer; }
- | REGVAR '(' FLOAT ')'
- { $$ = reg_float; }
- ;
- tokensection
- : TOKENHEAD tkdefs
- ;
- tkdefs
- : /* empty */
- | tkdefs tkdef
- ;
- tkdef
- : IDENT '=' structdecl NUMBER optcost optformat
- { register token_p tp;
- register ident_p ip;
- chktabsiz(nmachtokens,MAXTOKENS,"Token table");
- tp = &machtokens[nmachtokens];
- tp->t_name = $1;
- tp->t_struct = $3;
- tp->t_size = $4;
- tp->t_cost = $5;
- ip = ilookup($1,ENTER);
- ip->i_type = ITOK;
- ip->i_i.i_tokno = nmachtokens++;
- maxtokensize=max(maxtokensize,structsize($3));
- setfields(tp,$6);
- }
- | error
- ;
- structdecl
- : '{' structlist '}'
- { $$ = lookstruct($2); }
- ;
- structlist
- : /* empty */
- { $$=0; }
- | structlistel structlist
- { $$=(list2) myalloc(sizeof(struct list2str));
- $$->l2next = $2;
- $$->l2list = $1;
- }
- ;
- structlistel
- : TYPENAME list1 ';'
- { $$=(list1) myalloc(sizeof(struct list1str));
- $$->l1next = $2;
- $$->l1name = $1;
- }
- ;
- optcost : /* empty */
- { $$.c_size = $$.c_time = 0; }
- | COST '=' '(' expr ',' expr ')'
- { MUST2BEINT($4,$6);
- $$.c_size = exp1;
- $$.c_time = exp2;
- }
- ;
- optformat
- : /* empty */
- { $$ = 0; }
- | STRING
- ;
- expressionsection
- : /* empty */
- | EXPRESSIONHEAD tokenexpressions
- ;
- tokenexpressions
- : tokenexpressionline
- | tokenexpressionline tokenexpressions
- ;
- tokenexpressionline
- : IDENT '=' tokenexpression
- {
- { register ident_p ip;
- chktabsiz(nmachsets,MAXSETS,"Expression table");
- machsets[nmachsets] = $3;
- ip=ilookup($1,ENTER);
- ip->i_type = IEXP;
- ip->i_i.i_expno = nmachsets++;
- }
- }
- | error
- ;
- tokenexpression
- : PIDENT
- { $$ = machprops[$1->i_i.i_prpno].propset; }
- | TIDENT
- { register i;
- for(i=0;i<SETSIZE;i++) $$.set_val[i]=0;
- $$.set_val[($1->i_i.i_tokno+nmachregs+1)>>4] |=
- 01<<(($1->i_i.i_tokno+nmachregs+1)&017);
- $$.set_size = machtokens[$1->i_i.i_tokno].t_size;
- }
- | EIDENT
- { $$=machsets[$1->i_i.i_expno]; }
- | tokenexpression '*' tokenexpression
- { register i;
- if (($$.set_size=$1.set_size)==0)
- $$.set_size = $3.set_size;
- for (i=0;i<SETSIZE;i++)
- $$.set_val[i] = $1.set_val[i] & $3.set_val[i];
- }
- | tokenexpression '+' tokenexpression
- { register i;
- if ($1.set_size == -1)
- $$.set_size = $3.set_size;
- else if ($3.set_size == -1)
- $$.set_size = $1.set_size;
- else if ($1.set_size == $3.set_size)
- $$.set_size = $1.set_size;
- else
- $$.set_size = 0;
- for (i=0;i<SETSIZE;i++)
- $$.set_val[i] = $1.set_val[i] | $3.set_val[i];
- }
- | tokenexpression '-' tokenexpression
- { register i;
- if ($1.set_size == -1)
- $$.set_size = $3.set_size;
- else if ($3.set_size == -1)
- $$.set_size = $1.set_size;
- else if ($1.set_size == $3.set_size)
- $$.set_size = $1.set_size;
- else
- $$.set_size = 0;
- for (i=0;i<SETSIZE;i++)
- $$.set_val[i] = $1.set_val[i] & ~ $3.set_val[i];
- }
- | '(' tokenexpression ')'
- { $$ = $2; }
- ;
- codesection
- : CODEHEAD coderules
- ;
- coderules
- : coderule
- | coderules coderule
- ;
- coderule
- : { nallreg=emrepllen=tokrepllen=0; }
- empattern SEP stackpattern SEP code SEP stackreplacement SEP
- emreplacement SEP cost
- { int i;
- if (emrepllen) {
- outbyte(DO_EMREPLACE+(emrepllen<<5));
- for (i=0;i<emrepllen;i++) {
- out(replmnem[i]);
- out(replexpr[i]);
- }
- }
- if ($8==0) {
- outbyte(DO_TOKREPLACE+(tokrepllen<<5));
- for(i=0;i<tokrepllen;i++)
- out(replinst[i]);
- } else {
- static int warncount=0;
- if (!warncount++)
- fprintf(stderr,
- "WARNING: convert to stacksection, will disappear soon");
- outbyte(DO_TOKREPLACE);
- }
- if ($12.c_size!=0 || $12.c_time!=0) {
- outbyte(DO_COST);
- out($12.c_size);
- out($12.c_time);
- }
- outbyte(empatlen==0? DO_RETURN : DO_NEXTEM);
- fprintf(cfile,"\n");
- ncoderules++;
- maxallreg=max(maxallreg,nallreg);
- if (empatlen==0) { /* coercion */
- if (tokrepllen<1 && $8==0)
- yyerror("No replacement in coercion");
- if (tokpatlen>1)
- yyerror("Token pattern too long");
- if ($8!=0) { /* stacking */
- c1_p cp;
- chktabsiz(nc1,MAXC1,"Coerc table 1");
- cp = &c1coercs[nc1++];
- cp->c1_texpno = pattokexp[1];
- cp->c1_prop = -1;
- cp->c1_codep = $6;
- } else if (tokrepllen>1) { /* splitting */
- c2_p cp;
- chktabsiz(nc2,MAXC2,"Coerc table 2");
- cp= &c2coercs[nc2++];
- cp->c2_texpno = pattokexp[1];
- cp->c2_nsplit = tokrepllen;
- maxsplit=max(maxsplit,tokrepllen);
- for (i=0;i<tokrepllen;i++)
- cp->c2_repl[i] = replinst[i];
- cp->c2_codep = $6;
- if (nallreg>0)
- yyerror("No allocates allowed here");
- } else { /* one to one coercion */
- c3_p cp;
- chktabsiz(nc3,MAXC3,"Coerc table 3");
- cp= &c3coercs[nc3++];
- if (tokpatlen)
- cp->c3_texpno = pattokexp[1];
- else
- cp->c3_texpno = 0;
- if (nallreg>1)
- yyerror("Too many allocates in coercion");
- cp->c3_prop = nallreg==0 ? 0 : allreg[0];
- cp->c3_repl = replinst[0];
- cp->c3_codep = $6;
- }
- }
- }
- | error
- ;
- empattern
- : /* empty */
- { empatlen=0; }
- | mnemlist optboolexpr
- { register i;
- empatexpr = $2;
- patbyte(0);
- patshort(prevind);
- prevind = npatbytes - 3;
- maxempatlen = max(empatlen,maxempatlen);
- pat(empatlen);
- for(i=1;i<=empatlen;i++)
- patbyte(patmnem[i]);
- pat(empatexpr);
- rulecount = npatbytes;
- patbyte(1); /* number of different rules with this pattern */
- pat(codebytes); /* first rule */
- }
- | ELLIPS
- { pattern[rulecount]++;
- maxrule= max(maxrule,pattern[rulecount]);
- pat(codebytes);
- }
- ;
- mnemlist
- : mnem
- { empatlen = 1; patmnem[empatlen] = $1; }
- | mnemlist mnem
- { chktabsiz(empatlen+1,MAXEMPATLEN,"EM pattern");
- patmnem[++empatlen] = $2;
- }
- ;
- mnem : IDENT
- { if(strlen($1)!=3 || ($$=mlookup($1))==0)
- yyerror("not an EM-mnemonic");
- }
- ;
- stackpattern
- : optnocoerc tokenexpressionlist optstack
- { register i;
- if (tokpatlen != 0) {
- outbyte(($1 ? ( $3 ? DO_XXMATCH: DO_XMATCH ) : DO_MATCH)+(tokpatlen<<5));
- for(i=1;i<=tokpatlen;i++) {
- out(pattokexp[i]);
- }
- }
- if ($3 && tokpatlen==0 && empatlen==0) {
- outbyte(DO_COERC);
- }
- if ($3 && !$1 && empatlen!=0) {
- outbyte(DO_REMOVE);
- out(allexpno);
- }
- }
- ;
- optnocoerc
- : /* empty */
- { $$ = 0; }
- | NOCOERC ':'
- { $$ = 1; }
- ;
- tokenexpressionlist
- : /* empty */
- { tokpatlen = 0; }
- | tokenexpressionlist tokenexpressionno
- { chktabsiz(tokpatlen+1,MAXPATLEN,"Token pattern");
- pattokexp[++tokpatlen] = $2;
- if (machsets[$2].set_size==0)
- yyerror("Various sized set in tokenpattern");
- }
- ;
- tokenexpressionno
- : tokenexpression
- { $$ = exprlookup($1); }
- ;
- optstack
- : /* empty */
- { $$ = 0; }
- | STACK
- { $$ = 1; }
- ;
- code :
- { $$ = codebytes; cchandled=ccspoiled=0; }
- initcode restcode
- { if (cchandled==0 && ccspoiled!=0) {
- outbyte(DO_ERASE);
- out(ccregexpr);
- }
- }
- ;
- initcode
- : /* empty */
- | initcode remove
- | initcode allocate
- ;
- remove
- : REMOVE '(' tokenexpressionno
- { curtokexp = $3; }
- optcommabool ')'
- { outbyte(DO_REMOVE+ ($5!=0 ? 32 : 0));
- out($3);
- if ($5!=0) out($5);
- }
- | REMOVE '(' expr ')'
- { if ($3.expr_typ != TYPREG)
- yyerror("Expression must be register");
- outbyte(DO_RREMOVE);
- out($3.expr_index);
- }
- ;
- optcommabool
- : /* empty */
- { $$ = 0; }
- | ',' expr
- { MUST1BEBOOL($2);
- $$ = exp1;
- }
- ;
- restcode: /* empty */
- | restcode LSTRING expr
- { outbyte(DO_LOUTPUT);
- out(stringno($2));
- free($2);
- out($3.expr_index);
- ccspoiled++;
- }
- | restcode stringlist
- { int i;
- for(i=0;nstr>0;i++,nstr--) {
- if (i%8==0) outbyte(DO_ROUTPUT+(nstr>7 ? 7 : nstr-1)*32);
- out(strar[i]);
- }
- ccspoiled++;
- }
- | restcode RETURN
- { outbyte(DO_PRETURN); }
- | restcode move
- | restcode erase
- | restcode NOCC
- { outbyte(DO_ERASE);
- out(ccregexpr);
- cchandled++;
- }
- | restcode SAMECC
- { cchandled++; }
- | restcode SETCC '(' tokeninstanceno ')'
- { outbyte(DO_MOVE);
- out(ccinstanceno);
- out($4);
- cchandled++;
- }
- | restcode TEST '(' tokeninstanceno ')'
- { outbyte(DO_MOVE);
- out($4);
- out(ccinstanceno);
- ccspoiled=0;
- }
- ;
- stringlist
- : STRING
- { nstr=1;
- strar[0]=stringno($1);
- free($1);
- }
- | stringlist STRING
- { chktabsiz(nstr,MAXNSTR,"Consecutiv strings");
- strar[nstr++] = stringno($2);
- free($2);
- }
- ;
- move
- : MOVE '(' tokeninstanceno ',' tokeninstanceno ')'
- { outbyte(DO_MOVE);
- out($3);
- out($5);
- }
- ;
- erase
- : ERASE '(' expr ')'
- { outbyte(DO_ERASE);
- out($3.expr_index);
- if($3.expr_typ != TYPREG)
- yyerror("Bad argument of erase");
- }
- ;
- allocate
- : ALLOCATE { dealflag=0; } '(' alloclist ')'
- { if (dealflag)
- outbyte(DO_REALLOCATE);
- }
- ;
- alloclist
- : allocel
- | alloclist optcomma allocel
- ;
- allocel
- : tokeninstanceno /* deallocate */
- { outbyte(DO_DEALLOCATE);
- out($1);
- dealflag++;
- }
- | PIDENT
- { allreg[nallreg++] = $1->i_i.i_prpno;
- outbyte(DO_ALLOCATE);
- out($1->i_i.i_prpno);
- }
- | PIDENT '=' tokeninstanceno
- { allreg[nallreg++] = $1->i_i.i_prpno;
- outbyte(DO_ALLOCATE+32);
- out($1->i_i.i_prpno);
- out($3);
- }
- ;
- stackreplacement
- : /* empty */
- { $$=0; }
- | STACK
- { $$=1; }
- | '{' STACK '}'
- { $$=1; }
- | stackrepllist
- { $$=0; }
- ;
- stackrepllist
- : tokeninstanceno
- { tokrepllen=1; replinst[0] = $1; }
- | stackrepllist tokeninstanceno
- { chktabsiz(tokrepllen+1,MAXPATLEN,"Stack replacement");
- replinst[tokrepllen++] = $2;
- }
- ;
- emreplacement
- : /* empty, normal case */
- | emrepllist
- ;
- emrepllist
- : mnem optexpr
- { emrepllen=1;
- replmnem[0]=$1;
- replexpr[0]=$2.expr_index;
- }
- | emrepllist mnem optexpr
- { chktabsiz(emrepllen+1,MAXEMPATLEN,"EM replacement");
- replmnem[emrepllen]=$2;
- replexpr[emrepllen]=$3.expr_index;
- emrepllen++;
- }
- ;
- cost : /* empty */
- { $$.c_size = $$.c_time = 0;
- }
- | '(' expr ',' expr ')'
- { MUST2BEINT($2,$4);
- $$.c_size = exp1;
- $$.c_time = exp2;
- }
- | cost '+' '%' '[' tokargno ']'
- { $$.c_size = lookup(1,EX_PLUS,$1.c_size,
- lookup(0,EX_COST,$5,0));
- $$.c_time = lookup(1,EX_PLUS,$1.c_time,
- lookup(0,EX_COST,$5,1));
- }
- ;
- movesection
- : MOVEHEAD movedefs
- ;
- movedefs
- : movedef
- | movedefs movedef
- ;
- movedef
- : '(' tokenexpressionno
- { curtokexp = $2; }
- optboolexpr ',' tokenexpressionno
- { curtokexp = $6;
- pattokexp[1] = $2;
- pattokexp[2] = $6;
- tokpatlen=2;
- }
- optboolexpr ',' code optcommacost ')'
- { register move_p mp;
- outbyte(DO_RETURN);
- fprintf(cfile,"\n");
- chktabsiz(nmoves,NMOVES,"Move definition table");
- mp = &machmoves[nmoves++];
- mp->m_set1 = $2;
- mp->m_expr1= $4;
- mp->m_set2 = $6;
- mp->m_expr2= $8;
- mp->m_cindex=$10;
- mp->m_cost = $11;
- }
- | error
- ;
- testsection
- : /* empty */
- | TESTHEAD testdefs
- ;
- testdefs: testdef
- | testdefs testdef
- ;
- testdef : '(' tokenexpressionno
- { curtokexp = $2;
- pattokexp[1] = $2;
- pattokexp[2] = cocosetno;
- tokpatlen=2;
- }
- optboolexpr ',' code optcommacost ')'
- { register move_p mp;
- outbyte(DO_RETURN);
- fprintf(cfile,"\n");
- chktabsiz(nmoves,NMOVES,"Move definition table(tests)");
- mp = &machmoves[nmoves++];
- mp->m_set1 = $2;
- mp->m_expr1 = $4;
- mp->m_set2 = cocosetno;
- mp->m_expr2 = 0;
- mp->m_cindex = $6;
- mp->m_cost = $7;
- }
- ;
- stacksection
- : STACKHEAD stackdefs
- | /* empty */
- ;
- stackdefs
- : stackdef
- | stackdefs stackdef
- ;
- stackdef
- : '(' tokenexpressionno
- { curtokexp = $2;
- pattokexp[1] = $2;
- tokpatlen=1;
- }
- optboolexpr ',' optprop ',' code optcommacost ')'
- { register c1_p cp;
- outbyte(DO_TOKREPLACE);
- outbyte(DO_RETURN);
- fprintf(cfile,"\n");
- chktabsiz(nc1,MAXC1,"Stacking table");
- cp = &c1coercs[nc1++];
- cp->c1_texpno = $2;
- cp->c1_expr = $4;
- cp->c1_prop = $6;
- cp->c1_codep = $8;
- cp->c1_cost = $9;
- }
- ;
- optprop
- : /* empty */
- { $$ = -1; }
- | PIDENT
- { $$ = $1->i_i.i_prpno; }
- ;
- optcommacost
- : /* empty */
- { $$.c_size = 0; $$.c_time = 0;}
- | ',' cost
- { $$ = $2; }
- ;
- list1 : /* empty */
- { $$ = 0; }
- | optcomma IDENT list1
- { $$=(list1) myalloc(sizeof(struct list1str));
- $$->l1next = $3;
- $$->l1name = $2;
- }
- ;
- optcomma: /* nothing */
- | ','
- ;
- emargno : NUMBER
- { if ($1<1 || $1>empatlen)
- yyerror("Number after $ out of range");
- $$ = $1;
- }
- ;
- tokargno
- : NUMBER
- { if ($1<1 || $1>tokpatlen)
- yyerror("Number within %[] out of range");
- $$ = $1;
- }
- ;
- expr : '$' emargno
- { $$.expr_index = lookup(0,EX_ARG,$2,0); $$.expr_typ = argtyp(patmnem[$2]);
- }
- | NUMBER
- { $$.expr_index = lookup(0,EX_CON,(int)($1&0177777),(int)($1>>16));
- $$.expr_typ = TYPINT;
- }
- | STRING
- { $$.expr_index = lookup(0,EX_STRING,strlookup($1),0);
- $$.expr_typ = TYPSTR;
- }
- | RIDENT
- { $$.expr_index = lookup(0,EX_REG,$1->i_i.i_regno,0);
- $$.expr_typ = TYPREG;
- }
- | '%' '[' tokargno '.' IDENT ']'
- { $$.expr_index = lookup(0,EX_TOKFIELD,$3,
- findstructel(pattokexp[$3],$5,&$$.expr_typ));
- }
- | '%' '[' tokargno subreg ']'
- { chkregexp(pattokexp[$3]);
- $$.expr_index = lookup(0,EX_SUBREG,$3,$4);
- $$.expr_typ = TYPREG;
- }
- | '%' '[' LCASELETTER subreg ']'
- { if ($3 >= 'a'+nallreg)
- yyerror("Bad letter in %[x] construct");
- $$.expr_index = lookup(0,EX_ALLREG,$3-'a'+1,$4);
- $$.expr_typ = TYPREG;
- }
- | '%' '[' IDENT ']'
- { $$.expr_index = lookup(0,EX_TOKFIELD,0,
- findstructel(curtokexp,$3,&$$.expr_typ));
- }
- | TOSTRING '(' expr ')'
- { MUST1BEINT($3);
- $$.expr_index = lookup(0,EX_TOSTRING,exp1,0);
- $$.expr_typ = TYPSTR;
- }
- | DEFINED '(' expr ')'
- { $$.expr_index = lookup(0,EX_DEFINED,$3.expr_index,0);
- $$.expr_typ = TYPBOOL;
- }
- | SAMESIGN '(' expr ',' expr ')'
- { MUST2BEINT($3,$5);
- $$.expr_index = lookup(1,EX_SAMESIGN,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | SFIT '(' expr ',' expr ')'
- { MUST2BEINT($3,$5);
- $$.expr_index = lookup(0,EX_SFIT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | UFIT '(' expr ',' expr ')'
- { MUST2BEINT($3,$5);
- $$.expr_index = lookup(0,EX_UFIT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | ROM '(' emargno ',' NUMBER ')'
- { if ($5<1 || $5>3)
- yyerror("Second argument of rom must be >=1 and <=3");
- $$.expr_index = lookup(0,EX_ROM,$3-1,$5-1);
- $$.expr_typ = TYPINT;
- }
- | LOWW '(' emargno ')'
- {
- $$.expr_index = lookup(0,EX_LOWW,$3-1,0);
- $$.expr_typ = TYPINT;
- }
- | HIGHW '(' emargno ')'
- {
- $$.expr_index = lookup(0,EX_HIGHW,$3-1,0);
- $$.expr_typ = TYPINT;
- }
- | '(' expr ')'
- { $$ = $2; }
- | expr CMPEQ expr
- { switch(commontype($1,$3)) {
- case TYPINT:
- $$.expr_index = lookup(1,EX_NCPEQ,$1.expr_index,$3.expr_index);
- break;
- case TYPSTR:
- $$.expr_index = lookup(1,EX_SCPEQ,$1.expr_index,$3.expr_index);
- break;
- case TYPREG:
- $$.expr_index = lookup(1,EX_RCPEQ,$1.expr_index,$3.expr_index);
- break;
- }
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPNE expr
- { switch(commontype($1,$3)) {
- case TYPINT:
- $$.expr_index = lookup(1,EX_NCPNE,$1.expr_index,$3.expr_index);
- break;
- case TYPSTR:
- $$.expr_index = lookup(1,EX_SCPNE,$1.expr_index,$3.expr_index);
- break;
- case TYPREG:
- $$.expr_index = lookup(1,EX_RCPNE,$1.expr_index,$3.expr_index);
- break;
- }
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPGT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPGT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPGE expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPGE,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPLT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPLT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPLE expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPLE,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr OR2 expr
- { MUST2BEBOOL($1,$3);
- $$.expr_index = lookup(0,EX_OR2,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr AND2 expr
- { MUST2BEBOOL($1,$3);
- $$.expr_index = lookup(0,EX_AND2,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr '+' expr
- { switch(commontype($1,$3)) {
- case TYPINT:
- $$.expr_index = lookup(1,EX_PLUS,$1.expr_index,$3.expr_index);
- break;
- case TYPSTR:
- $$.expr_index = lookup(0,EX_CAT,$1.expr_index,$3.expr_index);
- break;
- default:
- yyerror("Bad types");
- }
- $$.expr_typ = $1.expr_typ;
- }
- | expr '-' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_MINUS,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr '*' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(1,EX_TIMES,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr '/' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_DIVIDE,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr '%' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_MOD,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr LSHIFT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_LSHIFT,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr RSHIFT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_RSHIFT,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | NOT expr
- { MUST1BEBOOL($2);
- $$.expr_index = lookup(0,EX_NOT,exp1,0);
- $$.expr_typ = TYPBOOL;
- }
- | COMP expr
- { MUST1BEINT($2);
- $$.expr_index = lookup(0,EX_COMP,exp1,0);
- $$.expr_typ = TYPINT;
- }
- | INREG '(' expr ')'
- { MUST1BEINT($3);
- $$.expr_index = lookup(0,EX_INREG,exp1,0);
- $$.expr_typ = TYPINT;
- }
- | REGVAR '(' expr ')'
- { MUST1BEINT($3);
- $$.expr_index = lookup(0,EX_REGVAR,exp1,0);
- $$.expr_typ = TYPREG;
- }
- /*
- | '-' expr %prec UMINUS
- { MUST1BEINT($2);
- $$.expr_index = lookup(0,EX_UMINUS,exp1,0);
- $$.expr_typ = TYPINT;
- }
- */
- ;
- subreg : /* empty */
- { $$=0; }
- | '.' NUMBER
- { $$=$2; }
- ;
- optboolexpr
- : /* empty */
- { $$ = 0; }
- | expr
- { MUST1BEBOOL($1);
- $$=exp1;
- }
- ;
- optexpr
- : /* empty */
- { $$.expr_typ=0;
- $$.expr_index=0;
- }
- | expr
- ;
- tokeninstanceno
- : tokeninstance
- { $$ = instno($1); }
- ;
- tokeninstance
- : '%' '[' tokargno subreg ']'
- { register i;
- if ($4!=0)
- chkregexp(pattokexp[$3]);
- $$.in_which = IN_COPY;
- $$.in_info[0] = $3;
- $$.in_info[1] = $4;
- for (i=2;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | '%' '[' tokargno '.' IDENT ']'
- { int typ;
- register i;
- $$.in_which = IN_COPY;
- $$.in_info[0] = $3;
- $$.in_info[1] = findstructel(pattokexp[$3],$5,&typ);
- if (typ != TYPREG)
- yyerror("Must be register");
- for (i=2;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | RIDENT
- { register i;
- $$.in_which = IN_RIDENT;
- $$.in_info[0] = $1->i_i.i_regno;
- for (i=1;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | REGVAR '(' expr ')'
- { register i;
- MUST1BEINT($3);
- $$.in_which = IN_REGVAR;
- $$.in_info[0] = exp1;
- for (i=1;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | '%' '[' LCASELETTER subreg ']'
- { register i;
- if ($3 >= 'a'+nallreg)
- yyerror("Bad letter in %[x] construct");
- $$.in_which = IN_ALLOC;
- $$.in_info[0] = $3-'a';
- $$.in_info[1] = $4;
- for (i=2;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | '{' TIDENT attlist '}'
- { register i;
- $$.in_which = IN_DESCR;
- $$.in_info[0] = $2->i_i.i_tokno;
- for(i=0;i<narexp;i++) {
- if (arexp[i].expr_typ !=
- machtokens[$2->i_i.i_tokno].t_fields[i].t_type)
- yyerror("Attribute %d has wrong type",i+1);
- $$.in_info[i+1] = arexp[i].expr_index;
- }
- for (i=narexp+1;i<TOKENSIZE;i++) {
- if (machtokens[$2->i_i.i_tokno].t_fields[i-1].t_type!=0)
- yyerror("Too few attributes");
- $$.in_info[i] = 0;
- }
- }
- ;
- attlist
- : /* empty */
- { narexp = 0; }
- | attlist ',' expr
- { arexp[narexp++] = $3; }
- ;
- %%
|