home *** CD-ROM | disk | FTP | other *** search
- /* bsgram.y -- grammer specification for bs.
- */
- %{
- #include "bsdefs.h"
-
- char *p; /* the generic pointer */
- int i; /* the generic counter */
- int (*l[300])(); /* array to generate the code list into. */
- int lp; /* pointer to current spot in l[] */
-
- struct stk {
- int stack[40];
- int stkp;
- };
-
- struct stk ifstk,whstk,forstk,repstk,lpstk;
- int gomax=0, ifmax=0, whmax=0, formax=0, repmax=0, lpmax=0;
-
- extern char *yytext;
- extern char *bsyysval;
- extern int yyleng;
- %}
-
- %term EQUAL NEQ LE LT GE WHILE
- %term GT OR AND NOT RET REPEAT
- %term IF THEN ELSE GOTO GOSUB UNTIL
- %term STOP END INTEGER REAL SCONST ELIHW
- %term LET SWORD PRINT INPUT DATA CFOR
- %term FOR TO STEP READ WRITE NEXT
- %term DEFINE LFUN SFUN FDEF SYMBOL DIM
- %term VALUE IWORD RWORD ROFC LOOP EXITIF
- %term ITOR RTOI ITOA RTOA LEAVE CONTINUE
- %term POOL
-
- %left ',' ';'
- %right '='
- %nonassoc OR AND
- %nonassoc LE LT GE GT EQUAL NEQ
- %left '+' '-'
- %left '*' '/' '%'
- %left UNARY
- %left '('
-
-
- %start lines
-
- %%
-
- lines : /* empty */
- | lines line
- ;
-
- line : lnum stat '\n'
- { printf("\n"); }
- | '\n'
- ;
-
- lnum : INTEGER
- { bundle(2,_line,atoi($1); }
- ;
-
- stat : LET let_xpr
- | let_xpr
- | PRINT pe
- { bundle(1,_print); }
- | GOTO INTEGER
- {
- sprintf(s,"LN%s",$2);
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- }
- | GOSUB INTEGER
- {
- sprintf(s,"LN%s",$2);
- bundle(4,_rlabel,gvadr(s,T_LBL),_gosub,0);
- }
- | LEAVE
- { bundle(2,_leave,0); }
- | CONTINUE
- { bundle(2,_contin,0); }
- | RET
- { bundle(1,_return); }
- | IF bexpr
- {
- lpush(&ifstk,ifmax);
- sprintf(s,"IF%d",ifmax);
- bundle(4,_rlabel,gvadr(s,T_LBL),_if,0);
- ifmax += 2;
- }
- THEN stat
- {
- i = ltop(&ifstk);
- sprintf(s,"IF%d",i+1);
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- }
- if_else
- | INPUT
- { bundle(2,_pushstate,M_INPUT); }
- var_lst
- { bundle(1,_popstate); }
- | STOP
- { bundle(1,_stop); }
- | END
- { bundle(1,_end); }
- | FOR nvar '=' rexpr TO rexpr for_step
- {
- lpush(&forstk,formax);
- sprintf(s,"FOR%d",formax+2);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"FOR%d",formax+1);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"FOR%d",formax+1);
- bundle(5,_icon,(long)0,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"FOR%d",formax);
- bundle(4,_dlabel,gvadr(s,T_LBL),_for,0);
- formax += 3;
- }
- | NEXT
- {
- i = ltop(&forstk);
- sprintf(s,"FOR%d",i+2);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- nvar
- {
- i = lpop(&forstk);
- sprintf(s,"FOR%d",i);
- bundle(5,_next,_rlabel,gvadr(s,T_LBL),_goto,0);
- sprintf(s,"FOR%d",i+1);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- | READ
- { bundle(2,_pushstate,M_READ); }
- var_lst
- { bundle(1,_popstate); }
- | DATA
- { bundle(2,_data,0); }
- data_lst
- | LOOP
- {
- lpush(&lpstk,lpmax);
- sprintf(s,"LP%d",lpmax+2);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"LP%d",lpmax+1);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"LP%d",lpmax);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- lpmax += 3;
- }
- | EXITIF bexpr
- {
- i = ltop(&lpstk);
- sprintf(s,"LP%d",i+1);
- bundle(5,_not,_rlabel,gvadr(s,T_LBL),_if,0);
- }
- | POOL
- {
- i = lpop(&lpstk);
- sprintf(s,"LP%d",i+2);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- sprintf(s,"LP%d",i);
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- sprintf(s,"LP%d",i+1);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- | WHILE
- {
- lpush(&whstk,whmax);
- sprintf(s,"WH%d",whmax+2);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"WH%d",whmax+1);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"WH%d",whmax);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- whmax += 3;
- }
- bexpr
- {
- i = ltop(&whstk);
- sprintf(s,"WH%d",i+1);
- bundle(4,_rlabel,gvadr(s,T+LBL),_if,0);
- }
- | ELIHW
- {
- i = lpop(&whstk);
- sprintf(s,"WH%d",i+2);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- sprintf(s,"WH%d",i)
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- sprintf(s,"WH%d",i+1);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- | REPEAT
- {
- lpush(&repstk,repmax);
- sprintf(s,"REP%d",repmax+1);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"REP%d",repmax+2);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"REP%d",repmax);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- repmax += 3;
- }
- | UNTIL
- {
- i = ltop(&repstk);
- sprintf(s,"REP%d",i+1);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- bexpr
- {
- i = lpop(&repstk);
- sprintf(s,"REP%d",i);
- bundle(5,_not,_rlabel,gvadr(s,T_LBL),_if,0);
- sprintf(s,"REP%d",i+2);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- ;
-
- nvar : ivar
- | rvar
- ;
-
- let_xpr : ivar '=' rexpr
- { bundle(4,_rtoi,_store,T_DBL,_pop); }
- | rvar '=' rexpr
- { bundle(3,_store,T_DBL,_pop); }
- | svar '=' sexpr
- { bundle(3,_store,T_CHR,spop); }
- ;
-
- data_lst : rexpr
- { bundle(2,_dsep,0); }
- | sexpr
- { bundle(1,_dsep); }
- | data_lst ',' rexpr
- { bundle(1,_dsep); }
- | data_lst ',' sexpr
- { bundle(1,_dsep); }
- ;
-
- ind_lst : rexpr
- | ind_lst ',' rexpr
- ;
-
- for_step : /* empty */
- { bundle(3,_icon,(long)0); }
- | STEP rexpr
- ;
-
- if_else : /* empty */
- {
- i = lpop(&ifstk);
- sprintf(s,"IF%d",i);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- sprintf(s,"IF%d",i+1);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- | ELSE
- {
- i = ltop(&ifstk);
- sprintf(s,"IF%d",i);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- stat
- {
- i = lpop(&ifstk);
- sprintf(s,"IF%d",i+1);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- ;
-
-
- pe : sexpr ','
- { bundle(3,_scon,"",_comma); }
- | sexpr ';'
- | sexpr
- { bundle(3,_scon,"\\n",_scolon); }
- | /* empty */
- { bundle(2,_scon,"\\n"); }
- ;
-
-
- var_lst : ivar
- | rvar
- | svar
- | var_lst ',' var_lst
- ;
-
- sexpr : SCONST
- { p=myalloc(yyleng); strcpy(p,$1); bundle(2,_scon,p); }
- | svar
- { bundle(2,_val,T_CHR); }
- | rexpr
- { bundle(1,_rtoa); }
- | svar '=' sexpr
- { bundle(2,_store,T_CHR); }
- | sexpr ';' sexpr
- { bundle(1,_scolon); }
- | sexpr '+' sexpr
- { bundle(1,_scolon); }
- | sexpr ',' sexpr
- { bundle(1,_comma); }
- | '(' sexpr ')'
- ;
- sbe : sexpr EQUAL sexpr
- { bundle(1,_seq); }
- | sexpr NEQ sexpr
- { bundle(1,_sneq); }
- | sexpr LE sexpr
- { bundle(1,_sleq); }
- | sexpr LT sexpr
- { bundle(1,_slt); }
- | sexpr GE sexpr
- { bundle(1,_sgeq); }
- | sexpr GT sexpr
- { bundle(1,_sgt); }
- ;
-
- ivar : IWORD
- { bundle(2,_var,gvadr($1,T_INT)); }
- | IWORD '('
- { bundle(2,_pushstate,M_EXECUTE); }
- ind_lst ')'
- { bundle(3,_popstate,_var,gvadr($1,T_INT+Q_ARY)); }
- ;
- rvar : RWORD
- { bundle(2,_var,gvadr($1,T_DBL)); }
- | RWORD '('
- { bundle(2,_pushstate,M_EXECUTE); }
- ind_lst ')'
- { bundle(3,_popstate,_var,gvadr($1,T_DBL+Q_ARY)); }
- ;
-
- svar : SWORD
- { bundle(2,_var,gvadr($1,T_CHR)); }
- | SWORD '('
- { bundle(2,_pushstate,M_EXECUTE); }
- ind_lst ')'
- { bundle(3,_popstate,_var,gvadr($1,T_CHR+Q_ARY)); }
- ;
-
-
-
- rexpr : rvar
- { bundle(2,_val,T_DBL); }
- | REAL
- { bundle(5,_rcon,(double)atof($1)); }
- | INTEGER
- { bundle(5,_rcon,(double)atof($1)); }
- | ivar
- { bundle(3,_val,T_INT,_itor); }
- | rvar '=' rexpr
- { bundle(2,_store,T_DBL); }
- | '(' rexpr ')'
- | rexpr '+' rexpr
- { bundle(1,_radd); }
- | rexpr '-' rexpr
- { bundle(1,_rsub); }
- | rexpr '*' rexpr
- { bundle(1,_rmult); }
- | rexpr '/' rexpr
- { bundle(1,_rdiv); }
- | '+' rexpr %prec UNARY
- | '-' rexpr %prec UNARY
- { bundle(6,_rcon,(double)(-1),_rmult); }
- ;
-
- rbe : rexpr EQUAL rexpr
- { bundle(1,_req); }
- | rexpr NEQ rexpr
- { bundle(1,_rneq); }
- | rexpr LE rexpr
- { bundle(1,_rleq); }
- | rexpr LT rexpr
- { bundle(1,_rlt); }
- | rexpr GE rexpr
- { bundle(1,_rgeq); }
- | rexpr GT rexpr
- { bundle(1,_rgt); }
- ;
- bexpr : sbe
- | rbe
- | NOT bexpr %prec UNARY
- { bundle(1,_not); }
- | bexpr OR bexpr
- { bundle(1,_or); }
- | bexpr AND bexpr
- { bundle(1,_and); }
- | '(' bexpr ')'
- ;
- %%
-
- main()
- {
- rdlin(bsin);
- return(yyparse());
- }
-
- yyerror(s)
- char *s;
- {
- fprintf(stderr,"%s\n",s);
- }
-
- lpush(stack,val) struct stk *stack; int val;
- {
- stack->stack[stack->stkp++] = val;
- }
-
- int ltop(stack) struct stk *stack;
- {
- return(stack->stack[stack->stkp-1]);
- }
-
- int lpop(stack) struct stk *stack;
- {
- return(stack->stack[--stack->stkp]);
- }
-
- /* bundle() -- append argument list to l[]. Idea tooken from bc.y.
- *
- * Usage: bundle(cnt,arg,arg,...,arg)
- *
- * The "arg"'s can be anything. "cnt" is a count of the number of integers
- * it would take to hold all the args.
- *
- * e.g. bundle(4,(double)a); is the correct count for a.
- *
- * ******* NOTE *******
- *
- * This routine is machine dependant. It depends on the way arguments are
- * passed on the stack on the PDP-11 machines. It may not work elsewhere.
- */
- bundle(a)
- int a;
- {
- register int *p;
- register int sz;
-
- p = &a;
- sz = *p++;
- while(sz-- > 0)
- l[lp++] = *p++;
- }
-