view tests/agcl/contrib/bug-I158.syn @ 6:607e3be6bad8

Adjust to the moving target called the C++ standard. Apparently nowadays it's not allowed to define an explicit copy constructor but not an assignment operator. Consequently, defining the explicit copy constructor in terms of the implicit/automatic assignment operator for general convenience no longer works. Add assignment operators. Caution: not tested with the IBM compiler, but there's no particular reason it shouldn't work.
author David A. Holland
date Mon, 30 May 2022 23:46:22 -0400
parents 13d2b8934445
children
line wrap: on
line source


{

/*
     YABASIC --- a tiny integrated Basic Compiler/Interpreter

     BISON - part

     this Program is subject to the GNU General Public License;
     see the file yabasic.c for details.
*/


#undef WINDOWS
#include "yabasic.h"     /* definitions of yabasic */
#include <malloc.h>

#if HAVE_ALLOCA_H
#include <alloca.h>
#endif

void __yy_bcopy(char *,char *,int); /* prototype missing */

int yylineno=1;
int yylex(void);

}

/* float number *//* integer number *//* token of command *//* number of newlines *//* quoted string *//* general symbol *//* string of digits *//* string symbol */
(double ) step_part

(double ) const

(double ) number

(int ) intnum

(char *) symbol_or_lineno

(int ) hashed_number

(int ) SEP

(int ) EOFILE


FNUM
 -> simple real
 -> simple real:x, 'e'+'E', '+'?,exponent:e            =x*pow(10,e);
 -> simple real:x, 'e'+'E', '-',exponent:e            =x*pow(10,-e);

simple real
 -> integer part:i, '.', fraction part:f                      = i+f;
 -> integer part, '.'?
 -> '.', fraction part:f                                        = f;

integer part
 -> digit:d                                                 = d-'0';
 -> integer part:x, digit:d                          = 10*x + d-'0';

fraction part
 -> digit:d                                            =(d-'0')/10.;
 -> digit:d, fraction part:f                       =(d-'0' + f)/10.;

(int) exponent
 -> digit:d                                                 = d-'0';
 -> exponent:x, digit:d                              = 10*x + d-'0';

(int) name           //value of name token is length of name string
 -> letter: c                                       =pushChar(c), 1;
 -> name:k, letter+digit: c                       =pushChar(c), k+1;


(char *) SYMBOL
  -> name:k                                   =strdup(popString(k));

(char *) STRSYM
  -> name:k, '$'                              =pushChar('$'), strdup(popString(k+1));

(char *) DIGITS
  -> digit string:k                                  =strdup(popString(k));

(int) digit string
 -> digit:d                                         =pushChar(d), 1;
 -> digit string:k, digit:d                         =pushChar(d), k+1;

(char *) STRING
 -> '"', string text:k, '"'                         =strdup(popString(k));
 -> '"', string text:k, '\n'                        =strdup(popString(k));

GOSUB, LABEL, ON

INTERRUPT, BREAK, CONTINUE, SEP, EOFILE

IF, THEN, ELSE, ENDIF

PRINT, INPUT, LINE, RETURN, DIM, END, AT, SCREEN, REVERSE

AND, OR, NOT

NE, LE, GE, LT, GT, EQ

READ, DATA, RESTORE

OPEN, CLOSE

WINDOW, DOT, LINE, CIRCLE, TEXT, CLEAR, PRINTER

WAIT, BELL, MAP, XMAP, YMAP, ARROW, XTICK, YTICK


SIN, ASIN, COS, ACOS, TAN, ATAN, EXP, LOG, SQRT, MYEOF

INT, FRAC, MOD, RAN, LEN, VAL, LEFT, RIGHT, MID, LEN, MIN, MAX

STR, INKEY, CHR, ASC, UPPER, LOWER, TRIM, LTRIM, RTRIM, INSTR

SYSTEM, SYSTEM2, PEEK, PEEK2, POKE, DATE, TIME



[
  left {OR}
  left {AND}
  left {NOT}
  left {'-', '+'}
  left {'*', '/'}
  left {'^'}
  nonassoc {UMINUS}
]

letter = 'a-z' + 'A-Z'
digit  = '0-9'
eof = 0 + -1

NAME
 -> letter
 -> NAME, letter+digit


program $
 -> statement list, eof

statement list
 ->
 -> statement_list, !{
if (errorlevel<=ERROR) {YYABORT;}},
   SEP, !{
yylineno+=$3;},
   statement

statement  /* empty */
 ->
 -> string_assignment
 -> assignment
 -> for_loop
 -> if_clause
 -> "GOTO", symbol_or_lineno ={create_goto($2);}
 -> "GOSUB", symbol_or_lineno ={create_gosub($2);}
 -> ON, INTERRUPT, BREAK ={create_exception(TRUE);}
 -> ON, INTERRUPT, CONTINUE ={create_exception(FALSE);}
 -> ON, expression, "GOTO", !{create_skipper();}, goto_list ={create_nop();}
 -> ON, expression, "GOSUB", !{create_skipper();}, gosub_list ={create_nop();}
 -> LABEL, symbol_or_lineno ={create_label($2);}
 -> OPEN, hashed_number, ',', string_expression, ',', string_expression ={create_myopen($2,'+');}
 -> OPEN, hashed_number, ',', string_expression ={create_myopen($2,'-');}
 -> CLOSE, hashed_number ={create_myclose($2);}
 -> PRINT, printintro, printlist, !{
create_revert(FALSE);},
   semicolon
 -> INPUT, inputintro, inputlist ={lastinput->args=0;}
 -> READ, readlist
 -> DATA, datalist
 -> RESTORE ={create_restore("");}
 -> RESTORE, symbol_or_lineno ={create_restore($2);}
 -> RETURN ={create_return();}
 -> DIM, dimlist
 -> OPEN, WINDOW, expression, ',', expression ={create_openwin(FALSE);}
 -> OPEN, WINDOW, expression, ',', expression, ',', string_expression ={create_openwin(TRUE);}
 -> DOT, mapping ={create_dot();}
 -> LINE, mapping, "TO", mapping ={create_line('l');}
 -> CIRCLE, mapping, ',', expression ={create_circle()}
 -> TEXT, string_expression, ',', mapping ={create_text(TRUE);}
 -> TEXT, mapping, ',', string_expression ={create_text(FALSE);}
 -> MAP, expression, ',', expression, ',', expression, ',', expression, "TO", expression, ',', expression, ',', expression, ',', expression ={create_makemap();}
 -> ARROW, mapping, "TO", mapping ={create_line('a');}
 -> XTICK, mapping, ',', string_expression ={create_tick(1);}
 -> YTICK, mapping, ',', string_expression ={create_tick(3);}
 -> XTICK, mapping ={create_tick(0);}
 -> YTICK, mapping ={create_tick(2);}
 -> CLOSE, WINDOW ={create_closewin();}
 -> CLEAR, WINDOW ={create_clearwin();}
 -> CLEAR, SCREEN ={create_clearscreen();}
 -> OPEN, PRINTER ={create_openprinter(0);}
 -> OPEN, PRINTER, string_expression ={create_openprinter(1);}
 -> CLOSE, PRINTER ={create_closeprinter();}
 -> WAIT, expression ={create_mywait();}
 -> BELL ={create_bell();}
 -> INKEY ={create_function(MYINKEY); create_popstrsym(NULL);}
 -> SYSTEM2, '(', string_expression, ')' ={create_function(MYSYSTEM2);
	create_popdblsym(NULL);}
 -> POKE, string_expression, ',', string_expression ={create_poke('s');}
 -> POKE, string_expression, ',', expression ={create_poke('d');}
 -> END ={create_myend();}

string_assignment
 -> STRSYM, EQ, string_expression ={create_popstrsym($1);}
 -> MID, '(', STRSYM, !{
create_pushstrptr($3);},
   ',', expression, ',', expression, ')', EQ, string_expression ={create_changestring(MYMID);}
 -> LEFT, '(', STRSYM, !{
create_pushstrptr($3);},
   ',', expression, ')', EQ, string_expression ={create_changestring(MYLEFT);}
 -> RIGHT, '(', STRSYM, !{
create_pushstrptr($3);},
   ',', expression, ')', EQ, string_expression ={create_changestring(MYRIGHT);}
 -> STRSYM, '(', !{
pushcounter();},
   indexlist, ')', EQ, string_expression ={create_doarray($1,ASSIGNSTRINGARRAY);}
 -> MID, '(', STRSYM, '(', !{
pushcounter();},
   indexlist, ')', !{
create_doarray($3,GETSTRINGPOINTER);},
   ',', expression, ',', expression, ')', EQ, string_expression ={create_changestring(MYMID);}
 -> LEFT, '(', STRSYM, '(', !{
pushcounter();},
   indexlist, ')', !{
create_doarray($3,GETSTRINGPOINTER);},
   ',', expression, ')', EQ, string_expression ={create_changestring(MYLEFT);}
 -> RIGHT, '(', STRSYM, '(', !{
pushcounter();},
   indexlist, ')', !{
create_doarray($3,GETSTRINGPOINTER);},
   ',', expression, ')', EQ, string_expression ={create_changestring(MYRIGHT);}

string_expression
 -> STRSYM ={create_pushstrsym($1);}
 -> string_function
 -> STRING ={if ($1==NULL) {error(ERROR,"String not terminated");create_pushstr("");} else {create_pushstr($1);}}
 -> string_expression, '+', string_expression ={create_concat();}
 -> STRSYM, '(', !{
pushcounter();},
   indexlist, ')' ={create_doarray($1,CALLSTRINGARRAY);}
 -> '(', string_expression, ')'

string_function
 -> LEFT, '(', string_expression, ',', expression, ')' ={create_function(MYLEFT);}
 -> RIGHT, '(', string_expression, ',', expression, ')' ={create_function(MYRIGHT);}
 -> MID, '(', string_expression, ',', expression, ',', expression, ')' ={create_function(MYMID);}
 -> STR, '(', expression, ')' ={create_function(MYSTR);}
 -> STR, '(', expression, ',', string_expression, ')' ={create_function(MYSTR2);}
 -> INKEY ={create_function(MYINKEY);}
 -> CHR, '(', expression, ')' ={create_function(MYCHR);}
 -> UPPER, '(', string_expression, ')' ={create_function(MYUPPER);}
 -> LOWER, '(', string_expression, ')' ={create_function(MYLOWER);}
 -> LTRIM, '(', string_expression, ')' ={create_function(MYLTRIM);}
 -> RTRIM, '(', string_expression, ')' ={create_function(MYRTRIM);}
 -> TRIM, '(', string_expression, ')' ={create_function(MYTRIM);}
 -> SYSTEM, '(', string_expression, ')' ={create_function(MYSYSTEM);}
 -> DATE ={create_function(MYDATE);}
 -> TIME ={create_function(MYTIME);}
 -> PEEK2, '(', string_expression, ')' ={create_function(MYPEEK2);}

assignment
 -> SYMBOL, EQ, expression ={create_popdblsym($1);}
 -> SYMBOL, '(', !{
pushcounter();},
   indexlist, ')', EQ, expression ={create_doarray($1,ASSIGNARRAY);}

expression
 -> number ={create_pushdbl($1);}
 -> function
 -> SYMBOL ={create_pushdblsym($1);}
 -> SYMBOL, '(', !{
pushcounter();},
   indexlist, ')' ={create_doarray($1,CALLARRAY);}
 -> '(', expression, ')'
 -> expression, '+', expression ={create_dblbin('+');}
 -> expression, '-', expression ={create_dblbin('-');}
 -> expression, '*', expression ={create_dblbin('*');}
 -> expression, '/', expression ={create_dblbin('/');}
 -> expression, '^', expression ={create_dblbin('^');}
 -> '-', expression /* 1ef4:fa2arec <֠ */ ={create_negate();}

mapping
 -> expression, ',', expression
 -> MAP, '(', expression, ',', expression, ')' ={create_map();}

function
 -> SIN, '(', expression, ')' ={create_function(MYSIN);}
 -> ASIN, '(', expression, ')' ={create_function(MYASIN);}
 -> COS, '(', expression, ')' ={create_function(MYCOS);}
 -> ACOS, '(', expression, ')' ={create_function(MYACOS);}
 -> TAN, '(', expression, ')' ={create_function(MYTAN);}
 -> ATAN, '(', expression, ')' ={create_function(MYATAN);}
 -> ATAN, '(', expression, ',', expression, ')' ={create_function(MYATAN2);}
 -> EXP, '(', expression, ')' ={create_function(MYEXP);}
 -> LOG, '(', expression, ')' ={create_function(MYLOG);}
 -> SQRT, '(', expression, ')' ={create_function(MYSQRT);}
 -> INT, '(', expression, ')' ={create_function(MYINT);}
 -> FRAC, '(', expression, ')' ={create_function(MYFRAC);}
 -> MOD, '(', expression, ',', expression, ')' ={create_function(MYMOD);}
 -> RAN, '(', expression, ')' ={create_function(MYRAN);}
 -> RAN, '(', ')' ={create_function(MYRAN2);}
 -> MIN, '(', expression, ',', expression, ')' ={create_function(MYMIN);}
 -> MAX, '(', expression, ',', expression, ')' ={create_function(MYMAX);}
 -> XMAP, '(', expression, ')' ={create_function(MYXMAP);}
 -> YMAP, '(', expression, ')' ={create_function(MYYMAP);}
 -> LEN, '(', string_expression, ')' ={create_function(MYLEN);}
 -> VAL, '(', string_expression, ')' ={create_function(MYVAL);}
 -> ASC, '(', string_expression, ')' ={create_function(MYASC);}
 -> INSTR, '(', string_expression, ',', string_expression, ')' ={create_function(MYINSTR);}
 -> SYSTEM2, '(', string_expression, ')' ={create_function(MYSYSTEM2);}
 -> PEEK, '(', string_expression, ')' ={create_function(MYPEEK);}

const
 -> number ={$$=$1;}
 -> '+', number ={$$=$2;}
 -> '-', number ={$$=-$2;}

number
 -> FNUM ={$$=$1;}
 -> DIGITS ={$$=atoi($1);}

intnum
 -> DIGITS ={$$=atoi($1);}

symbol_or_lineno
 -> DIGITS ={$$=$1;}
 -> SYMBOL ={$$=$1;}

dimlist
 -> SYMBOL, '(', !{
pushcounter();},
   indexlist, ')' ={create_dim($1,'d');}
 -> dimlist, ',', SYMBOL, '(', !{
pushcounter();},
   indexlist, ')' ={create_dim($3,'d');}
 -> STRSYM, '(', !{
pushcounter();},
   indexlist, ')' ={create_dim($1,'s');}
 -> dimlist, ',', STRSYM, '(', !{
pushcounter();},
   indexlist, ')' ={create_dim($3,'s');}

indexlist
 -> expression ={inccounter();}
 -> indexlist, ',', expression ={inccounter();}

for_loop
 -> "FOR", SYMBOL, EQ, expression, !{
pushname($2);create_popdblsym($2);pushgoto();
             create_pushdblsym($2);},
   "TO", expression, step_part, !{

	     create_dblrelop(($8>0)?'{':'}');
             create_decide();
             pushlabel();},
   SEP, !{
yylineno+=$10;},
   statement_list, !{

             create_pushdbl($8);
	     create_pushdblsym($2);
             create_dblbin('+');
	     create_popdblsym($2);
             swap();popgoto();poplabel();},
   next_or_eofile, next_symbol

next_or_eofile
 -> "NEXT"
 -> EOFILE ={end_of_file=TRUE;
	    error(ERROR,"'next'-statement is missing"); YYABORT;}
step_part
 ->  /* can be omitted */ ={$$=1.0;}
 -> "STEP", const ={$$=$2;}

next_symbol
 -> /* can be omitted */ ={pop();}
 -> SYMBOL ={if (strcmp(pop()->pointer,$1))
             {error(ERROR,"'for' and 'next' do not match"); YYABORT;}
           }

if_clause
 -> IF, condition, !{
create_decide();pushlabel();},
   THEN, statement_list, !{
pushlabel();swap();poplabel();},
   else_part, !{
poplabel();},
   endif_or_eof

endif_or_eof
 -> ENDIF
 -> EOFILE ={end_of_file=TRUE;
            error(ERROR,"'endif'-statement is missing"); YYABORT;}

condition
 -> '(', condition, ')'
 -> condition, OR, condition ={create_boole('|');}
 -> condition, AND, condition ={create_boole('&');}
 -> NOT, condition ={create_boole('!');}
 -> string_expression, EQ, string_expression ={create_strrelop('=');}
 -> string_expression, NE, string_expression ={create_strrelop('!');}
 -> string_expression, LT, string_expression ={create_strrelop('<');}
 -> string_expression, LE, string_expression ={create_strrelop('{');}
 -> string_expression, GT, string_expression ={create_strrelop('>');}
 -> string_expression, GE, string_expression ={create_strrelop('}');}
 -> expression, EQ, expression ={create_dblrelop('=');}
 -> expression, NE, expression ={create_dblrelop('!');}
 -> expression, LT, expression ={create_dblrelop('<');}
 -> expression, LE, expression ={create_dblrelop('{');}
 -> expression, GT, expression ={create_dblrelop('>');}
 -> expression, GE, expression ={create_dblrelop('}');}
 -> MYEOF, '(', hashed_number, ')' ={create_testeof($3);}

else_part /* can be omitted */
 ->
 -> ELSE, statement_list

inputlist
 -> input
 -> input, ',', inputlist

input
 -> SYMBOL ={create_myread('d');create_popdblsym($1);}
 -> SYMBOL, '(', !{
pushcounter();},
   indexlist, ')' ={create_myread('d');create_doarray($1,ASSIGNARRAY);}
 -> STRSYM ={create_myread('s');create_popstrsym($1);}
 -> STRSYM, '(', !{
pushcounter();},
   indexlist, ')' ={create_myread('s');create_doarray($1,ASSIGNSTRINGARRAY);}

readlist
 -> readitem
 -> readlist, ',', readitem

readitem
 -> SYMBOL ={create_readdata('d');create_popdblsym($1);}
 -> SYMBOL, '(', !{
pushcounter();},
   indexlist, ')' ={create_readdata('d');create_doarray($1,ASSIGNARRAY);}
 -> STRSYM ={create_readdata('s');create_popstrsym($1);}
 -> STRSYM, '(', !{
pushcounter();},
   indexlist, ')' ={create_readdata('s');create_doarray($1,ASSIGNSTRINGARRAY);}

datalist
 -> STRING ={create_strdata($1);}
 -> const ={create_dbldata($1);}
 -> datalist, ',', STRING ={create_strdata($3);}
 -> datalist, ',', const ={create_dbldata($3);}

printlist  /* possible empty */
 ->
 -> expression ={create_print('d');}
 -> printlist, ',', expression ={create_print('d');}
 -> string_expression ={create_print('s');}
 -> printlist, ',', string_expression ={create_print('s');}

inputintro
 ->  ={create_myswitch(0);create_readline(NULL);}
 -> stream
 -> position ={create_myswitch(0);create_readline(NULL);}
 -> !{
create_myswitch(0);},
   prompt
 -> position, !{
create_myswitch(0);},
   prompt

printintro
 ->  /* can be empty */ ={create_myswitch(0);}
 -> stream
 -> REVERSE ={create_revert(TRUE);create_myswitch(0);}
 -> position ={create_myswitch(0);}
 -> REVERSE, position ={create_revert(TRUE);create_myswitch(0);}

prompt
 -> STRING ={create_readline($1);}

position
 -> AT, '(', expression, ',', expression, ')' ={create_mymove();}

stream
 -> '#', intnum ={create_myswitch($2);}

hashed_number
 -> '#', intnum ={$$=$2;}
 -> intnum /* need not contain hash */ ={$$=$1;}

semicolon /* can be left out */
 ->  ={create_print('n');}
 -> ';'

goto_list
 -> symbol_or_lineno ={create_goto($1);create_findnop();}
 -> goto_list, ',', symbol_or_lineno ={create_goto($3);create_findnop();}

gosub_list
 -> symbol_or_lineno ={create_gosub($1);create_findnop();}
 -> gosub_list, ',', symbol_or_lineno ={create_gosub($3);create_findnop();}