Upgrade to version 1.03.
This commit is contained in:
parent
e1384c5e2d
commit
7e0d34dec8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=19380
@ -1,6 +1,10 @@
|
||||
PROG= bc
|
||||
SRCS= bc.c global.c scan.c util.c main.c number.c storage.c load.c execute.c
|
||||
MAN1= bc.1
|
||||
|
||||
BCSRCS= execute.c global.c load.c main.c number.c storage.c util.c
|
||||
GENSRCS= bc.c scan.c
|
||||
SRCS= ${GENSRCS} ${BCSRCS}
|
||||
|
||||
CFLAGS+= -D_POSIX_SOURCE -I$(.CURDIR)
|
||||
CLEANFILES+= ${GENSRCS} y.tab.h
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,8 +1,8 @@
|
||||
.\"
|
||||
.\" bc.1 - the *roff document processor source for the bc manual
|
||||
.\"
|
||||
.\" This file is part of bc written for MINIX.
|
||||
.\" Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
.\" This file is part of bc written initially for MINIX.
|
||||
.\" Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This program is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the GNU General Public License as published by
|
||||
@ -25,15 +25,15 @@
|
||||
.\" Western Washington University
|
||||
.\" Bellingham, WA 98226-9062
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\" $Id: bc.1,v 1.3 1996/10/05 22:26:19 wosch Exp $
|
||||
.\"
|
||||
.TH bc 1 .\" "Command Manual" v1.02 "Feb 3, 1992"
|
||||
.TH bc 1 .\" "Command Manual" v1.03 "Nov 2, 1994"
|
||||
.SH NAME
|
||||
bc - An arbitrary precision calculator language
|
||||
.SH SYNTAX
|
||||
\fBbc\fR [ \fB-lws\fR ] [ \fI file ...\fR ]
|
||||
.SH VERSION
|
||||
This man page documents GNU bc version 1.02.
|
||||
This man page documents GNU bc version 1.03.
|
||||
.SH DESCRIPTION
|
||||
\fBbc\fR is a language that supports arbitrary precision numbers
|
||||
with interactive execution of statements. There are some similarities
|
||||
@ -317,7 +317,9 @@ last value printed without having to retype the expression that
|
||||
printed the number. Assigning to \fBlast\fR is legal and will
|
||||
overwrite the last printed value with the assigned value. The newly
|
||||
assigned value will remain until the next number is printed or another
|
||||
value is assigned to \fBlast\fR.
|
||||
value is assigned to \fBlast\fR. (Some installations may allow the
|
||||
use of a single period (.) which is not part of a number as a short
|
||||
hand notation for for \fBlast\fR.)
|
||||
.IP "string"
|
||||
The string is printed to the output. Strings start with a double quote
|
||||
character and contain all characters until the next double quote character.
|
||||
@ -332,10 +334,9 @@ value is printed and assigned the variable \fBlast\fR. Strings
|
||||
in the print statement are printed to the output and may contain
|
||||
special characters. Special characters start with the backslash
|
||||
character (\e). The special characters recognized by \fBbc\fR are
|
||||
"b" (bell), "f" (form feed), "n" (newline), "r" (carriage return), "t"
|
||||
(tab), and "\e" (backslash). Any other character following the
|
||||
backslash will be ignored. This still does not allow the double quote
|
||||
character to be part of any string.
|
||||
"a" (alert or bell), "b" (backspace), "f" (form feed), "n" (newline),
|
||||
"r" (carriage return), "q" (double quote), "t" (tab), and "\e" (backslash).
|
||||
Any other character following the backslash will be ignored.
|
||||
.IP "{ statement_list }"
|
||||
This is the compound statement. It allows multiple statements to be
|
||||
grouped together for execution.
|
||||
@ -702,9 +703,9 @@ The multiply routine may yield incorrect results if a number
|
||||
has more than LONG_MAX / 90 total digits. For 32 bit longs, this number is
|
||||
23,860,929 digits.
|
||||
.IP "code size"
|
||||
Each function and the "main" program are limited to 10240 bytes of
|
||||
Each function and the "main" program are limited to 16384 bytes of
|
||||
compiled byte code each. This limit (BC_MAX_SEGS) can be easily changed
|
||||
to have more than 10 segments of 1024 bytes.
|
||||
to have more than 16 segments of 1024 bytes.
|
||||
.IP "variable names"
|
||||
The current limit on the number of unique names is 32767 for each of
|
||||
simple variables, arrays and functions.
|
||||
@ -726,6 +727,6 @@ Philip A. Nelson
|
||||
phil@cs.wwu.edu
|
||||
.fi
|
||||
.SH ACKNOWLEDGEMENTS
|
||||
The author would like to thank Steve Sommars (sesv@iwtsf.att.com) for
|
||||
The author would like to thank Steve Sommars (Steve.Sommars@att.com) for
|
||||
his extensive help in testing the implementation. Many great suggestions
|
||||
were given. This is a much better product due to his involvement.
|
||||
|
1369
gnu/usr.bin/bc/bc.c
1369
gnu/usr.bin/bc/bc.c
File diff suppressed because it is too large
Load Diff
615
gnu/usr.bin/bc/bc.y
Normal file
615
gnu/usr.bin/bc/bc.y
Normal file
@ -0,0 +1,615 @@
|
||||
%{
|
||||
/* bc.y: The grammar for a POSIX compatable bc processor with some
|
||||
extensions to the language. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License , or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
You may contact the author by:
|
||||
e-mail: phil@cs.wwu.edu
|
||||
us-mail: Philip A. Nelson
|
||||
Computer Science Department, 9062
|
||||
Western Washington University
|
||||
Bellingham, WA 98226-9062
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
#include "bcdefs.h"
|
||||
#include "global.h"
|
||||
#include "proto.h"
|
||||
%}
|
||||
|
||||
%start program
|
||||
|
||||
%union {
|
||||
char *s_value;
|
||||
char c_value;
|
||||
int i_value;
|
||||
arg_list *a_value;
|
||||
}
|
||||
|
||||
/* Extensions over POSIX bc.
|
||||
a) NAME was LETTER. This grammer allows longer names.
|
||||
Single letter names will still work.
|
||||
b) Relational_expression allowed only one comparison.
|
||||
This grammar has added boolean expressions with
|
||||
&& (and) || (or) and ! (not) and allowed all of them in
|
||||
full expressions.
|
||||
c) Added an else to the if.
|
||||
d) Call by variable array parameters
|
||||
e) read() procedure that reads a number under program control from stdin.
|
||||
f) halt statement that halts the the program under program control. It
|
||||
is an executed statement.
|
||||
g) continue statement for for loops.
|
||||
h) optional expressions in the for loop.
|
||||
i) print statement to print multiple numbers per line.
|
||||
j) warranty statement to print an extended warranty notice.
|
||||
j) limits statement to print the processor's limits.
|
||||
*/
|
||||
|
||||
%token <i_value> NEWLINE AND OR NOT
|
||||
%token <s_value> STRING NAME NUMBER
|
||||
/* '-', '+' are tokens themselves */
|
||||
%token <c_value> MUL_OP
|
||||
/* '*', '/', '%' */
|
||||
%token <c_value> ASSIGN_OP
|
||||
/* '=', '+=', '-=', '*=', '/=', '%=', '^=' */
|
||||
%token <s_value> REL_OP
|
||||
/* '==', '<=', '>=', '!=', '<', '>' */
|
||||
%token <c_value> INCR_DECR
|
||||
/* '++', '--' */
|
||||
%token <i_value> Define Break Quit Length
|
||||
/* 'define', 'break', 'quit', 'length' */
|
||||
%token <i_value> Return For If While Sqrt Else
|
||||
/* 'return', 'for', 'if', 'while', 'sqrt', 'else' */
|
||||
%token <i_value> Scale Ibase Obase Auto Read
|
||||
/* 'scale', 'ibase', 'obase', 'auto', 'read' */
|
||||
%token <i_value> Warranty, Halt, Last, Continue, Print, Limits
|
||||
/* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */
|
||||
|
||||
/* Types of all other things. */
|
||||
%type <i_value> expression return_expression named_expression opt_expression
|
||||
%type <c_value> '+' '-'
|
||||
%type <a_value> opt_parameter_list opt_auto_define_list define_list
|
||||
%type <a_value> opt_argument_list argument_list
|
||||
%type <i_value> program input_item semicolon_list statement_list
|
||||
%type <i_value> statement function statement_or_error
|
||||
|
||||
/* precedence */
|
||||
%left OR
|
||||
%left AND
|
||||
%nonassoc NOT
|
||||
%left REL_OP
|
||||
%right ASSIGN_OP
|
||||
%left '+' '-'
|
||||
%left MUL_OP
|
||||
%right '^'
|
||||
%nonassoc UNARY_MINUS
|
||||
%nonassoc INCR_DECR
|
||||
|
||||
%%
|
||||
program : /* empty */
|
||||
{
|
||||
$$ = 0;
|
||||
if (interactive)
|
||||
{
|
||||
printf ("%s\n", BC_VERSION);
|
||||
welcome ();
|
||||
}
|
||||
}
|
||||
| program input_item
|
||||
;
|
||||
input_item : semicolon_list NEWLINE
|
||||
{ run_code (); }
|
||||
| function
|
||||
{ run_code (); }
|
||||
| error NEWLINE
|
||||
{
|
||||
yyerrok;
|
||||
init_gen ();
|
||||
}
|
||||
;
|
||||
semicolon_list : /* empty */
|
||||
{ $$ = 0; }
|
||||
| statement_or_error
|
||||
| semicolon_list ';' statement_or_error
|
||||
| semicolon_list ';'
|
||||
;
|
||||
statement_list : /* empty */
|
||||
{ $$ = 0; }
|
||||
| statement_or_error
|
||||
| statement_list NEWLINE
|
||||
| statement_list NEWLINE statement_or_error
|
||||
| statement_list ';'
|
||||
| statement_list ';' statement
|
||||
;
|
||||
statement_or_error : statement
|
||||
| error statement
|
||||
{ $$ = $2; }
|
||||
;
|
||||
statement : Warranty
|
||||
{ warranty (""); }
|
||||
| Limits
|
||||
{ limits (); }
|
||||
| expression
|
||||
{
|
||||
if ($1 & 2)
|
||||
warn ("comparison in expression");
|
||||
if ($1 & 1)
|
||||
generate ("W");
|
||||
else
|
||||
generate ("p");
|
||||
}
|
||||
| STRING
|
||||
{
|
||||
$$ = 0;
|
||||
generate ("w");
|
||||
generate ($1);
|
||||
free ($1);
|
||||
}
|
||||
| Break
|
||||
{
|
||||
if (break_label == 0)
|
||||
yyerror ("Break outside a for/while");
|
||||
else
|
||||
{
|
||||
sprintf (genstr, "J%1d:", break_label);
|
||||
generate (genstr);
|
||||
}
|
||||
}
|
||||
| Continue
|
||||
{
|
||||
warn ("Continue statement");
|
||||
if (continue_label == 0)
|
||||
yyerror ("Continue outside a for");
|
||||
else
|
||||
{
|
||||
sprintf (genstr, "J%1d:", continue_label);
|
||||
generate (genstr);
|
||||
}
|
||||
}
|
||||
| Quit
|
||||
{ exit (0); }
|
||||
| Halt
|
||||
{ generate ("h"); }
|
||||
| Return
|
||||
{ generate ("0R"); }
|
||||
| Return '(' return_expression ')'
|
||||
{ generate ("R"); }
|
||||
| For
|
||||
{
|
||||
$1 = break_label;
|
||||
break_label = next_label++;
|
||||
}
|
||||
'(' opt_expression ';'
|
||||
{
|
||||
if ($4 > 1)
|
||||
warn ("Comparison in first for expression");
|
||||
$4 = next_label++;
|
||||
if ($4 < 0)
|
||||
sprintf (genstr, "N%1d:", $4);
|
||||
else
|
||||
sprintf (genstr, "pN%1d:", $4);
|
||||
generate (genstr);
|
||||
}
|
||||
opt_expression ';'
|
||||
{
|
||||
if ($7 < 0) generate ("1");
|
||||
$7 = next_label++;
|
||||
sprintf (genstr, "B%1d:J%1d:", $7, break_label);
|
||||
generate (genstr);
|
||||
$<i_value>$ = continue_label;
|
||||
continue_label = next_label++;
|
||||
sprintf (genstr, "N%1d:", continue_label);
|
||||
generate (genstr);
|
||||
}
|
||||
opt_expression ')'
|
||||
{
|
||||
if ($10 > 1)
|
||||
warn ("Comparison in third for expression");
|
||||
if ($10 < 0)
|
||||
sprintf (genstr, "J%1d:N%1d:", $4, $7);
|
||||
else
|
||||
sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
|
||||
generate (genstr);
|
||||
}
|
||||
statement
|
||||
{
|
||||
sprintf (genstr, "J%1d:N%1d:",
|
||||
continue_label, break_label);
|
||||
generate (genstr);
|
||||
break_label = $1;
|
||||
continue_label = $<i_value>9;
|
||||
}
|
||||
| If '(' expression ')'
|
||||
{
|
||||
$3 = if_label;
|
||||
if_label = next_label++;
|
||||
sprintf (genstr, "Z%1d:", if_label);
|
||||
generate (genstr);
|
||||
}
|
||||
statement opt_else
|
||||
{
|
||||
sprintf (genstr, "N%1d:", if_label);
|
||||
generate (genstr);
|
||||
if_label = $3;
|
||||
}
|
||||
| While
|
||||
{
|
||||
$1 = next_label++;
|
||||
sprintf (genstr, "N%1d:", $1);
|
||||
generate (genstr);
|
||||
}
|
||||
'(' expression
|
||||
{
|
||||
$4 = break_label;
|
||||
break_label = next_label++;
|
||||
sprintf (genstr, "Z%1d:", break_label);
|
||||
generate (genstr);
|
||||
}
|
||||
')' statement
|
||||
{
|
||||
sprintf (genstr, "J%1d:N%1d:", $1, break_label);
|
||||
generate (genstr);
|
||||
break_label = $4;
|
||||
}
|
||||
| '{' statement_list '}'
|
||||
{ $$ = 0; }
|
||||
| Print
|
||||
{ warn ("print statement"); }
|
||||
print_list
|
||||
;
|
||||
print_list : print_element
|
||||
| print_element ',' print_list
|
||||
;
|
||||
print_element : STRING
|
||||
{
|
||||
generate ("O");
|
||||
generate ($1);
|
||||
free ($1);
|
||||
}
|
||||
| expression
|
||||
{ generate ("P"); }
|
||||
;
|
||||
opt_else : /* nothing */
|
||||
| Else
|
||||
{
|
||||
warn ("else clause in if statement");
|
||||
$1 = next_label++;
|
||||
sprintf (genstr, "J%d:N%1d:", $1, if_label);
|
||||
generate (genstr);
|
||||
if_label = $1;
|
||||
}
|
||||
statement
|
||||
function : Define NAME '(' opt_parameter_list ')' '{'
|
||||
NEWLINE opt_auto_define_list
|
||||
{
|
||||
/* Check auto list against parameter list? */
|
||||
check_params ($4,$8);
|
||||
sprintf (genstr, "F%d,%s.%s[",
|
||||
lookup($2,FUNCTDEF),
|
||||
arg_str ($4), arg_str ($8));
|
||||
generate (genstr);
|
||||
free_args ($4);
|
||||
free_args ($8);
|
||||
$1 = next_label;
|
||||
next_label = 1;
|
||||
}
|
||||
statement_list /* NEWLINE */ '}'
|
||||
{
|
||||
generate ("0R]");
|
||||
next_label = $1;
|
||||
}
|
||||
;
|
||||
opt_parameter_list : /* empty */
|
||||
{ $$ = NULL; }
|
||||
| define_list
|
||||
;
|
||||
opt_auto_define_list : /* empty */
|
||||
{ $$ = NULL; }
|
||||
| Auto define_list NEWLINE
|
||||
{ $$ = $2; }
|
||||
| Auto define_list ';'
|
||||
{ $$ = $2; }
|
||||
;
|
||||
define_list : NAME
|
||||
{ $$ = nextarg (NULL, lookup ($1,SIMPLE)); }
|
||||
| NAME '[' ']'
|
||||
{ $$ = nextarg (NULL, lookup ($1,ARRAY)); }
|
||||
| define_list ',' NAME
|
||||
{ $$ = nextarg ($1, lookup ($3,SIMPLE)); }
|
||||
| define_list ',' NAME '[' ']'
|
||||
{ $$ = nextarg ($1, lookup ($3,ARRAY)); }
|
||||
;
|
||||
opt_argument_list : /* empty */
|
||||
{ $$ = NULL; }
|
||||
| argument_list
|
||||
;
|
||||
argument_list : expression
|
||||
{
|
||||
if ($1 > 1) warn ("comparison in argument");
|
||||
$$ = nextarg (NULL,0);
|
||||
}
|
||||
| NAME '[' ']'
|
||||
{
|
||||
sprintf (genstr, "K%d:", -lookup ($1,ARRAY));
|
||||
generate (genstr);
|
||||
$$ = nextarg (NULL,1);
|
||||
}
|
||||
| argument_list ',' expression
|
||||
{
|
||||
if ($3 > 1) warn ("comparison in argument");
|
||||
$$ = nextarg ($1,0);
|
||||
}
|
||||
| argument_list ',' NAME '[' ']'
|
||||
{
|
||||
sprintf (genstr, "K%d:", -lookup ($3,ARRAY));
|
||||
generate (genstr);
|
||||
$$ = nextarg ($1,1);
|
||||
}
|
||||
;
|
||||
opt_expression : /* empty */
|
||||
{
|
||||
$$ = -1;
|
||||
warn ("Missing expression in for statement");
|
||||
}
|
||||
| expression
|
||||
;
|
||||
return_expression : /* empty */
|
||||
{
|
||||
$$ = 0;
|
||||
generate ("0");
|
||||
}
|
||||
| expression
|
||||
{
|
||||
if ($1 > 1)
|
||||
warn ("comparison in return expresion");
|
||||
}
|
||||
;
|
||||
expression : named_expression ASSIGN_OP
|
||||
{
|
||||
if ($2 != '=')
|
||||
{
|
||||
if ($1 < 0)
|
||||
sprintf (genstr, "DL%d:", -$1);
|
||||
else
|
||||
sprintf (genstr, "l%d:", $1);
|
||||
generate (genstr);
|
||||
}
|
||||
}
|
||||
expression
|
||||
{
|
||||
if ($4 > 1) warn("comparison in assignment");
|
||||
if ($2 != '=')
|
||||
{
|
||||
sprintf (genstr, "%c", $2);
|
||||
generate (genstr);
|
||||
}
|
||||
if ($1 < 0)
|
||||
sprintf (genstr, "S%d:", -$1);
|
||||
else
|
||||
sprintf (genstr, "s%d:", $1);
|
||||
generate (genstr);
|
||||
$$ = 0;
|
||||
}
|
||||
;
|
||||
| expression AND
|
||||
{
|
||||
warn("&& operator");
|
||||
$2 = next_label++;
|
||||
sprintf (genstr, "DZ%d:p", $2);
|
||||
generate (genstr);
|
||||
}
|
||||
expression
|
||||
{
|
||||
sprintf (genstr, "DZ%d:p1N%d:", $2, $2);
|
||||
generate (genstr);
|
||||
$$ = $1 | $4;
|
||||
}
|
||||
| expression OR
|
||||
{
|
||||
warn("|| operator");
|
||||
$2 = next_label++;
|
||||
sprintf (genstr, "B%d:", $2);
|
||||
generate (genstr);
|
||||
}
|
||||
expression
|
||||
{
|
||||
int tmplab;
|
||||
tmplab = next_label++;
|
||||
sprintf (genstr, "B%d:0J%d:N%d:1N%d:",
|
||||
$2, tmplab, $2, tmplab);
|
||||
generate (genstr);
|
||||
$$ = $1 | $4;
|
||||
}
|
||||
| NOT expression
|
||||
{
|
||||
$$ = $2;
|
||||
warn("! operator");
|
||||
generate ("!");
|
||||
}
|
||||
| expression REL_OP expression
|
||||
{
|
||||
$$ = 3;
|
||||
switch (*($2))
|
||||
{
|
||||
case '=':
|
||||
generate ("=");
|
||||
break;
|
||||
|
||||
case '!':
|
||||
generate ("#");
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if ($2[1] == '=')
|
||||
generate ("{");
|
||||
else
|
||||
generate ("<");
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if ($2[1] == '=')
|
||||
generate ("}");
|
||||
else
|
||||
generate (">");
|
||||
break;
|
||||
}
|
||||
}
|
||||
| expression '+' expression
|
||||
{
|
||||
generate ("+");
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| expression '-' expression
|
||||
{
|
||||
generate ("-");
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| expression MUL_OP expression
|
||||
{
|
||||
genstr[0] = $2;
|
||||
genstr[1] = 0;
|
||||
generate (genstr);
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| expression '^' expression
|
||||
{
|
||||
generate ("^");
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| '-' expression %prec UNARY_MINUS
|
||||
{
|
||||
generate ("n");
|
||||
$$ = $2;
|
||||
}
|
||||
| named_expression
|
||||
{
|
||||
$$ = 1;
|
||||
if ($1 < 0)
|
||||
sprintf (genstr, "L%d:", -$1);
|
||||
else
|
||||
sprintf (genstr, "l%d:", $1);
|
||||
generate (genstr);
|
||||
}
|
||||
| NUMBER
|
||||
{
|
||||
int len = strlen($1);
|
||||
$$ = 1;
|
||||
if (len == 1 && *$1 == '0')
|
||||
generate ("0");
|
||||
else if (len == 1 && *$1 == '1')
|
||||
generate ("1");
|
||||
else
|
||||
{
|
||||
generate ("K");
|
||||
generate ($1);
|
||||
generate (":");
|
||||
}
|
||||
free ($1);
|
||||
}
|
||||
| '(' expression ')'
|
||||
{ $$ = $2 | 1; }
|
||||
| NAME '(' opt_argument_list ')'
|
||||
{
|
||||
$$ = 1;
|
||||
if ($3 != NULL)
|
||||
{
|
||||
sprintf (genstr, "C%d,%s:",
|
||||
lookup ($1,FUNCT),
|
||||
call_str ($3));
|
||||
free_args ($3);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (genstr, "C%d:", lookup ($1,FUNCT));
|
||||
}
|
||||
generate (genstr);
|
||||
}
|
||||
| INCR_DECR named_expression
|
||||
{
|
||||
$$ = 1;
|
||||
if ($2 < 0)
|
||||
{
|
||||
if ($1 == '+')
|
||||
sprintf (genstr, "DA%d:L%d:", -$2, -$2);
|
||||
else
|
||||
sprintf (genstr, "DM%d:L%d:", -$2, -$2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($1 == '+')
|
||||
sprintf (genstr, "i%d:l%d:", $2, $2);
|
||||
else
|
||||
sprintf (genstr, "d%d:l%d:", $2, $2);
|
||||
}
|
||||
generate (genstr);
|
||||
}
|
||||
| named_expression INCR_DECR
|
||||
{
|
||||
$$ = 1;
|
||||
if ($1 < 0)
|
||||
{
|
||||
sprintf (genstr, "DL%d:x", -$1);
|
||||
generate (genstr);
|
||||
if ($2 == '+')
|
||||
sprintf (genstr, "A%d:", -$1);
|
||||
else
|
||||
sprintf (genstr, "M%d:", -$1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (genstr, "l%d:", $1);
|
||||
generate (genstr);
|
||||
if ($2 == '+')
|
||||
sprintf (genstr, "i%d:", $1);
|
||||
else
|
||||
sprintf (genstr, "d%d:", $1);
|
||||
}
|
||||
generate (genstr);
|
||||
}
|
||||
| Length '(' expression ')'
|
||||
{ generate ("cL"); $$ = 1;}
|
||||
| Sqrt '(' expression ')'
|
||||
{ generate ("cR"); $$ = 1;}
|
||||
| Scale '(' expression ')'
|
||||
{ generate ("cS"); $$ = 1;}
|
||||
| Read '(' ')'
|
||||
{
|
||||
warn ("read function");
|
||||
generate ("cI"); $$ = 1;
|
||||
}
|
||||
;
|
||||
named_expression : NAME
|
||||
{ $$ = lookup($1,SIMPLE); }
|
||||
| NAME '[' expression ']'
|
||||
{
|
||||
if ($3 > 1) warn("comparison in subscript");
|
||||
$$ = lookup($1,ARRAY);
|
||||
}
|
||||
| Ibase
|
||||
{ $$ = 0; }
|
||||
| Obase
|
||||
{ $$ = 1; }
|
||||
| Scale
|
||||
{ $$ = 2; }
|
||||
| Last
|
||||
{ $$ = 3;
|
||||
warn ("Last variable");
|
||||
}
|
||||
;
|
||||
%%
|
@ -1,7 +1,7 @@
|
||||
/* bcdefs.h: The single file to include all constants and type definitions. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* const.h: Constants for bc. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -71,9 +71,13 @@
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define SIMPLE 0
|
||||
#define ARRAY 1
|
||||
#define FUNCT 2
|
||||
|
||||
/* for use with lookup (). */
|
||||
#define SIMPLE 0
|
||||
#define ARRAY 1
|
||||
#define FUNCT 2
|
||||
#define FUNCTDEF 3
|
||||
|
||||
#define EXTERN extern
|
||||
#ifdef __STDC__
|
||||
#define CONST const
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* execute.c - run a bc program. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -213,11 +213,13 @@ execute ()
|
||||
if (ch == '"') break;
|
||||
switch (ch)
|
||||
{
|
||||
case 'n': out_char ('\n'); break;
|
||||
case 't': out_char ('\t'); break;
|
||||
case 'r': out_char ('\r'); break;
|
||||
case 'b': out_char (007); break;
|
||||
case 'a': out_char (007); break;
|
||||
case 'b': out_char ('\b'); break;
|
||||
case 'f': out_char ('\f'); break;
|
||||
case 'n': out_char ('\n'); break;
|
||||
case 'q': out_char ('"'); break;
|
||||
case 'r': out_char ('\r'); break;
|
||||
case 't': out_char ('\t'); break;
|
||||
case '\\': out_char ('\\'); break;
|
||||
default: break;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* global.c: This defines the global variables. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* global.h: The global variables for bc. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -27,24 +27,41 @@
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
/* For the current "break level" and if statements. */
|
||||
/* The current break level's label. */
|
||||
EXTERN int break_label;
|
||||
|
||||
/* The current if statement's else label or label after else. */
|
||||
EXTERN int if_label;
|
||||
|
||||
/* The current for statement label for continuing the loop. */
|
||||
EXTERN int continue_label;
|
||||
|
||||
/* Label numbers. */
|
||||
/* Next available label number. */
|
||||
EXTERN int next_label;
|
||||
|
||||
/* Used for "code" generation. */
|
||||
/* Byte code character storage. Used in many places for generation of code. */
|
||||
EXTERN char genstr[80];
|
||||
|
||||
/* Count of characters printed to the output in compile_only mode. */
|
||||
EXTERN int out_count;
|
||||
|
||||
/* Have we generated any code since the last initialization of the code
|
||||
generator. */
|
||||
EXTERN char did_gen;
|
||||
|
||||
/* Interactive and other flags. */
|
||||
/* Is this run an interactive execution. (Is stdin a terminal?) */
|
||||
EXTERN char interactive;
|
||||
|
||||
/* Just generate the byte code. -c flag. */
|
||||
EXTERN char compile_only;
|
||||
|
||||
/* Load the standard math functions. -l flag. */
|
||||
EXTERN char use_math;
|
||||
|
||||
/* Give a warning on use of any non-standard feature (non-POSIX). -w flag. */
|
||||
EXTERN char warn_not_std;
|
||||
|
||||
/* Accept POSIX bc only! -s flag. */
|
||||
EXTERN char std_only;
|
||||
|
||||
/* global variables for the bc machine. All will be dynamic in size.*/
|
||||
|
@ -1,255 +0,0 @@
|
||||
/* libmath.b for bc for minix. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License , or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
You may contact the author by:
|
||||
e-mail: phil@cs.wwu.edu
|
||||
us-mail: Philip A. Nelson
|
||||
Computer Science Department, 9062
|
||||
Western Washington University
|
||||
Bellingham, WA 98226-9062
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
scale = 20
|
||||
|
||||
/* Uses the fact that e^x = (e^(x/2))^2
|
||||
When x is small enough, we use the series:
|
||||
e^x = 1 + x + x^2/2! + x^3/3! + ...
|
||||
*/
|
||||
|
||||
define e(x) {
|
||||
auto a, d, e, f, i, m, v, z
|
||||
|
||||
/* Check the sign of x. */
|
||||
if (x<0) {
|
||||
m = 1
|
||||
x = -x
|
||||
}
|
||||
|
||||
/* Precondition x. */
|
||||
z = scale;
|
||||
scale = 4 + z + .44*x;
|
||||
while (x > 1) {
|
||||
f += 1;
|
||||
x /= 2;
|
||||
}
|
||||
|
||||
/* Initialize the variables. */
|
||||
v = 1+x
|
||||
a = x
|
||||
d = 1
|
||||
|
||||
for (i=2; 1; i++) {
|
||||
e = (a *= x) / (d *= i)
|
||||
if (e == 0) {
|
||||
if (f>0) while (f--) v = v*v;
|
||||
scale = z
|
||||
if (m) return (1/v);
|
||||
return (v/1);
|
||||
}
|
||||
v += e
|
||||
}
|
||||
}
|
||||
|
||||
/* Natural log. Uses the fact that ln(x^2) = 2*ln(x)
|
||||
The series used is:
|
||||
ln(x) = 2(a+a^3/3+a^5/5+...) where a=(x-1)/(x+1)
|
||||
*/
|
||||
|
||||
define l(x) {
|
||||
auto e, f, i, m, n, v, z
|
||||
|
||||
/* return something for the special case. */
|
||||
if (x <= 0) return (1 - 10^scale)
|
||||
|
||||
/* Precondition x to make .5 < x < 2.0. */
|
||||
z = scale;
|
||||
scale += 4;
|
||||
f = 2;
|
||||
i=0
|
||||
while (x >= 2) { /* for large numbers */
|
||||
f *= 2;
|
||||
x = sqrt(x);
|
||||
}
|
||||
while (x <= .5) { /* for small numbers */
|
||||
f *= 2;
|
||||
x = sqrt(x);
|
||||
}
|
||||
|
||||
/* Set up the loop. */
|
||||
v = n = (x-1)/(x+1)
|
||||
m = n*n
|
||||
|
||||
/* Sum the series. */
|
||||
for (i=3; 1; i+=2) {
|
||||
e = (n *= m) / i
|
||||
if (e == 0) {
|
||||
v = f*v
|
||||
scale = z
|
||||
return (v/1)
|
||||
}
|
||||
v += e
|
||||
}
|
||||
}
|
||||
|
||||
/* Sin(x) uses the standard series:
|
||||
sin(x) = x - x^3/3! + x^5/5! - x^7/7! ... */
|
||||
|
||||
define s(x) {
|
||||
auto e, i, m, n, s, v, z
|
||||
|
||||
/* precondition x. */
|
||||
z = scale
|
||||
scale = 1.1*z + 1;
|
||||
v = a(1)
|
||||
if (x < 0) {
|
||||
m = 1;
|
||||
x = -x;
|
||||
}
|
||||
scale = 0
|
||||
n = (x / v + 2 )/4
|
||||
x = x - 4*n*v
|
||||
if (n%2) x = -x
|
||||
|
||||
/* Do the loop. */
|
||||
scale = z + 2;
|
||||
v = e = x
|
||||
s = -x*x
|
||||
for (i=3; 1; i+=2) {
|
||||
e *= s/(i*(i-1))
|
||||
if (e == 0) {
|
||||
scale = z
|
||||
if (m) return (-v/1);
|
||||
return (v/1);
|
||||
}
|
||||
v += e
|
||||
}
|
||||
}
|
||||
|
||||
/* Cosine : cos(x) = sin(x+pi/2) */
|
||||
define c(x) {
|
||||
auto v;
|
||||
scale += 1;
|
||||
v = s(x+a(1)*2);
|
||||
scale -= 1;
|
||||
return (v/1);
|
||||
}
|
||||
|
||||
/* Arctan: Using the formula:
|
||||
atan(x) = atan(c) + atan((x-c)/(1+xc)) for a small c (.2 here)
|
||||
For under .2, use the series:
|
||||
atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... */
|
||||
|
||||
define a(x) {
|
||||
auto a, e, f, i, m, n, s, v, z
|
||||
|
||||
/* Special case and for fast answers */
|
||||
if (x==1) {
|
||||
if (scale <= 25) return (.7853981633974483096156608/1)
|
||||
if (scale <= 40) return (.7853981633974483096156608458198757210492/1)
|
||||
if (scale <= 60) \
|
||||
return (.785398163397448309615660845819875721049292349843776455243736/1)
|
||||
}
|
||||
if (x==.2) {
|
||||
if (scale <= 25) return (.1973955598498807583700497/1)
|
||||
if (scale <= 40) return (.1973955598498807583700497651947902934475/1)
|
||||
if (scale <= 60) \
|
||||
return (.197395559849880758370049765194790293447585103787852101517688/1)
|
||||
}
|
||||
|
||||
/* Negative x? */
|
||||
if (x<0) {
|
||||
m = 1;
|
||||
x = -x;
|
||||
}
|
||||
|
||||
/* Save the scale. */
|
||||
z = scale;
|
||||
|
||||
/* Note: a and f are known to be zero due to being auto vars. */
|
||||
/* Calculate atan of a known number. */
|
||||
if (x > .2) {
|
||||
scale = z+4;
|
||||
a = a(.2);
|
||||
}
|
||||
|
||||
/* Precondition x. */
|
||||
scale = z+2;
|
||||
while (x > .2) {
|
||||
f += 1;
|
||||
x = (x-.2) / (1+x*.2);
|
||||
}
|
||||
|
||||
/* Initialize the series. */
|
||||
v = n = x;
|
||||
s = -x*x;
|
||||
|
||||
/* Calculate the series. */
|
||||
for (i=3; 1; i+=2) {
|
||||
e = (n *= s) / i;
|
||||
if (e == 0) {
|
||||
scale = z;
|
||||
if (m) return ((f*a+v)/-1);
|
||||
return ((f*a+v)/1);
|
||||
}
|
||||
v += e
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Bessel function of integer order. Uses the following:
|
||||
j(-n,x) = (-1)^n*j(n,x)
|
||||
j(n,x) = x^n/(2^n*n!) * (1 - x^2/(2^2*1!*(n+1)) + x^4/(2^4*2!*(n+1)*(n+2))
|
||||
- x^6/(2^6*3!*(n+1)*(n+2)*(n+3)) .... )
|
||||
*/
|
||||
define j(n,x) {
|
||||
auto a, d, e, f, i, m, s, v, z
|
||||
|
||||
/* Make n an integer and check for negative n. */
|
||||
z = scale;
|
||||
scale = 0;
|
||||
n = n/1;
|
||||
if (n<0) {
|
||||
n = -n;
|
||||
if (n%2 == 1) m = 1;
|
||||
}
|
||||
|
||||
/* Compute the factor of x^n/(2^n*n!) */
|
||||
f = 1;
|
||||
for (i=2; i<=n; i++) f = f*i;
|
||||
scale = 1.5*z;
|
||||
f = x^n / 2^n / f;
|
||||
|
||||
/* Initialize the loop .*/
|
||||
v = e = 1;
|
||||
s = -x*x/4
|
||||
scale = 1.5*z
|
||||
|
||||
/* The Loop.... */
|
||||
for (i=1; 1; i++) {
|
||||
e = e * s / i / (n+i);
|
||||
if (e == 0) {
|
||||
scale = z
|
||||
if (m) return (-f*v/1);
|
||||
return (f*v/1);
|
||||
}
|
||||
v += e;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/* load.c: This code "loads" code into the code segments. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* main.c: The main program for bc. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,40 +1,40 @@
|
||||
"@iK20:s2:p@r\
|
||||
@iF1,4.5,6,7,8,9,10,11,12[l4:0<Z0:1s10:pl4:ns4:pN0:l2:s12:pK4\
|
||||
:l12:+K.44:l4:*+s2:pN1:l4:1>Z2:l8:1+s8:pl4:K2:/s4:pJ1:N2:1l4:\
|
||||
+s11:pl4:s5:p1s6:pK2:s9:pN4:1B5:J3:N6:l9:i9:pJ4:N5:l5:l4:*s5:\
|
||||
l6:l9:*s6:/s7:pl7:0=Z7:l8:0>Z8:N9:l8:d8:Z10:l11:l11:*s11:pJ9:N10:\
|
||||
N8:l12:s2:pl10:Z11:1l11:/RN11:l11:1/RN7:l11:l7:+s11:pJ6:N3:0R]\
|
||||
@iF1,4.5,6,7,8,9,10,11,12,13[l4:0<Z1:1s10:pl4:ns4:pN1:l2:s13:\
|
||||
pK6:l13:+K.44:l4:*+s11:pl4:cS1+s2:pN2:l4:1>Z3:l8:1+s8:pl4:K2:\
|
||||
/s4:pl2:1+s2:pJ2:N3:l11:s2:p1l4:+s12:pl4:s5:p1s6:pK2:s9:pN5:1\
|
||||
B6:J4:N7:l9:i9:pJ5:N6:l5:l4:*s5:l6:l9:*s6:/s7:pl7:0=Z8:l8:0>Z9:\
|
||||
N10:l8:d8:Z11:l12:l12:*s12:pJ10:N11:N9:l13:s2:pl10:Z12:1l12:/\
|
||||
RN12:l12:1/RN8:l12:l7:+s12:pJ7:N4:0R]@r\
|
||||
@iF2,4.7,8,9,10,11,12,13[l4:0{Z1:1K10:l2:^-RN1:l2:s13:pK6:l2:\
|
||||
+s2:pK2:s8:p0s9:pN2:l4:K2:}Z3:l8:K2:*s8:pl4:cRs4:pJ2:N3:N4:l4:\
|
||||
K.5:{Z5:l8:K2:*s8:pl4:cRs4:pJ4:N5:l4:1-l4:1+/s11:s12:pl11:l11:\
|
||||
*s10:pK3:s9:pN7:1B8:J6:N9:l9:K2:+s9:pJ7:N8:l11:l10:*s11:l9:/s7:\
|
||||
pl7:0=Z10:l8:l12:*s12:pl13:s2:pl12:1/RN10:l12:l7:+s12:pJ9:N6:\
|
||||
0R]@r\
|
||||
@iF3,4.7,9,10,11,14,12,13[l2:s13:pK1.1:l13:*K2:+s2:p1C4,0:s12:\
|
||||
pl4:0<Z1:1s10:pl4:ns4:pN1:0s2:pl4:l12:/K2:+K4:/s11:pl4:K4:l11:\
|
||||
*l12:*-s4:pl11:K2:%Z2:l4:ns4:pN2:l13:K2:+s2:pl4:s7:s12:pl4:nl4:\
|
||||
*s14:pK3:s9:pN4:1B5:J3:N6:l9:K2:+s9:pJ4:N5:l7:l14:l9:l9:1-*/*\
|
||||
s7:pl7:0=Z7:l13:s2:pl10:Z8:l12:n1/RN8:l12:1/RN7:l12:l7:+s12:p\
|
||||
J6:N3:0R]@r\
|
||||
@iF5,4.12[l2:1+s2:pl4:1C4,0:K2:*+C3,0:s12:pl2:1-s2:pl12:1/R0R]\
|
||||
@r\
|
||||
@iF2,4.7,8,9,10,13,11,12[l4:0{Z0:1K10:l2:^-RN0:l2:s12:pl2:K4:\
|
||||
+s2:pK2:s8:p0s9:pN1:l4:K2:}Z2:l8:K2:*s8:pl4:cRs4:pJ1:N2:N3:l4:\
|
||||
K.5:{Z4:l8:K2:*s8:pl4:cRs4:pJ3:N4:l4:1-l4:1+/s13:s11:pl13:l13:\
|
||||
*s10:pK3:s9:pN6:1B7:J5:N8:l9:K2:+s9:pJ6:N7:l13:l10:*s13:l9:/s7:\
|
||||
pl7:0=Z9:l8:l11:*s11:pl12:s2:pl11:1/RN9:l11:l7:+s11:pJ8:N5:0R]\
|
||||
@r\
|
||||
@iF3,4.7,9,10,13,14,11,12[l2:s12:pK1.1:l12:*1+s2:p1C4,0:s11:p\
|
||||
l4:0<Z0:1s10:pl4:ns4:pN0:0s2:pl4:l11:/K2:+K4:/s13:pl4:K4:l13:\
|
||||
*l11:*-s4:pl13:K2:%Z1:l4:ns4:pN1:l12:K2:+s2:pl4:s7:s11:pl4:nl4:\
|
||||
*s14:pK3:s9:pN3:1B4:J2:N5:l9:K2:+s9:pJ3:N4:l7:l14:l9:l9:1-*/*\
|
||||
s7:pl7:0=Z6:l12:s2:pl10:Z7:l11:n1/RN7:l11:1/RN6:l11:l7:+s11:p\
|
||||
J5:N2:0R]@r\
|
||||
@iF5,4.11[l2:1+s2:pl4:1C4,0:K2:*+C3,0:s11:pl2:1-s2:pl11:1/R0R]\
|
||||
@r\
|
||||
@iF4,4.5,7,8,9,10,13,14,11,12[l4:1=Z0:l2:K25:{Z1:K.7853981633974483096156608\
|
||||
:1/RN1:l2:K40:{Z2:K.7853981633974483096156608458198757210492:\
|
||||
1/RN2:l2:K60:{Z3:K.785398163397448309615660845819875721049292349843776455243736\
|
||||
:1/RN3:N0:l4:K.2:=Z4:l2:K25:{Z5:K.1973955598498807583700497:1\
|
||||
/RN5:l2:K40:{Z6:K.1973955598498807583700497651947902934475:1/\
|
||||
RN6:l2:K60:{Z7:K.197395559849880758370049765194790293447585103787852101517688\
|
||||
:1/RN7:N4:l4:0<Z8:1s10:pl4:ns4:pN8:l2:s12:pl4:K.2:>Z9:l12:K4:\
|
||||
+s2:pK.2:C4,0:s5:pN9:l12:K2:+s2:pN10:l4:K.2:>Z11:l8:1+s8:pl4:\
|
||||
K.2:-1l4:K.2:*+/s4:pJ10:N11:l4:s13:s11:pl4:nl4:*s14:pK3:s9:pN13:\
|
||||
1B14:J12:N15:l9:K2:+s9:pJ13:N14:l13:l14:*s13:l9:/s7:pl7:0=Z16:\
|
||||
l12:s2:pl10:Z17:l8:l5:*l11:+1n/RN17:l8:l5:*l11:+1/RN16:l11:l7:\
|
||||
+s11:pJ15:N12:0R]@r\
|
||||
@iF6,13,4.5,6,7,8,9,10,14,11,12[l2:s12:p0s2:pl13:1/s13:pl13:0\
|
||||
<Z0:l13:ns13:pl13:K2:%1=Z1:1s10:pN1:N0:1s8:pK2:s9:pN3:l9:l13:\
|
||||
{B4:J2:N5:l9:i9:pJ3:N4:l8:l9:*s8:pJ5:N2:K1.5:l12:*s2:pl4:l13:\
|
||||
^K2:l13:^/l8:/s8:p1s7:s11:pl4:nl4:*K4:/s14:pK1.5:l12:*s2:p1s9:\
|
||||
pN7:1B8:J6:N9:l9:i9:pJ7:N8:l7:l14:*l9:/l13:l9:+/s7:pl7:0=Z10:\
|
||||
l12:s2:pl10:Z11:l8:nl11:*1/RN11:l8:l11:*1/RN10:l11:l7:+s11:pJ9:N6:\
|
||||
@iF4,4.5,7,8,9,10,11,14,12,13[1s10:pl4:0<Z1:1ns10:pl4:ns4:pN1:\
|
||||
l4:1=Z2:l2:K25:{Z3:K.7853981633974483096156608:l10:/RN3:l2:K40\
|
||||
:{Z4:K.7853981633974483096156608458198757210492:l10:/RN4:l2:K\
|
||||
60:{Z5:K.785398163397448309615660845819875721049292349843776455243736\
|
||||
:l10:/RN5:N2:l4:K.2:=Z6:l2:K25:{Z7:K.1973955598498807583700497\
|
||||
:l10:/RN7:l2:K40:{Z8:K.1973955598498807583700497651947902934475\
|
||||
:l10:/RN8:l2:K60:{Z9:K.197395559849880758370049765194790293447585103787852101517688\
|
||||
:l10:/RN9:N6:l2:s13:pl4:K.2:>Z10:l13:K5:+s2:pK.2:C4,0:s5:pN10:\
|
||||
l13:K3:+s2:pN11:l4:K.2:>Z12:l8:1+s8:pl4:K.2:-1l4:K.2:*+/s4:pJ11:N12:\
|
||||
l4:s11:s12:pl4:nl4:*s14:pK3:s9:pN14:1B15:J13:N16:l9:K2:+s9:pJ14:N15:\
|
||||
l11:l14:*s11:l9:/s7:pl7:0=Z17:l13:s2:pl8:l5:*l12:+l10:/RN17:l12:\
|
||||
l7:+s12:pJ16:N13:0R]@r\
|
||||
@iF6,11,4.5,6,7,8,9,10,14,12,13[l2:s13:p0s2:pl11:1/s11:pl11:0\
|
||||
<Z1:l11:ns11:pl11:K2:%1=Z2:1s10:pN2:N1:1s8:pK2:s9:pN4:l9:l11:\
|
||||
{B5:J3:N6:l9:i9:pJ4:N5:l8:l9:*s8:pJ6:N3:K1.5:l13:*s2:pl4:l11:\
|
||||
^K2:l11:^/l8:/s8:p1s7:s12:pl4:nl4:*K4:/s14:pK1.5:l13:*s2:p1s9:\
|
||||
pN8:1B9:J7:N10:l9:i9:pJ8:N9:l7:l14:*l9:/l11:l9:+/s7:pl7:0=Z11:\
|
||||
l13:s2:pl10:Z12:l8:nl12:*1/RN12:l8:l12:*1/RN11:l12:l7:+s12:pJ10:N7:\
|
||||
0R]@r"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* number.c: Implements arbitrary precision numbers. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -995,15 +995,23 @@ bc_raise (num1, num2, result, scale)
|
||||
neg = FALSE;
|
||||
rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale));
|
||||
}
|
||||
temp = copy_num (_one_);
|
||||
|
||||
/* Set initial value of temp. */
|
||||
power = copy_num (num1);
|
||||
while ((exponent & 1) == 0)
|
||||
{
|
||||
bc_multiply (power, power, &power, rscale);
|
||||
exponent = exponent >> 1;
|
||||
}
|
||||
temp = copy_num (power);
|
||||
exponent = exponent >> 1;
|
||||
|
||||
/* Do the calculation. */
|
||||
while (exponent != 0)
|
||||
while (exponent > 0)
|
||||
{
|
||||
if (exponent & 1 != 0)
|
||||
bc_multiply (temp, power, &temp, rscale);
|
||||
bc_multiply (power, power, &power, rscale);
|
||||
if ((exponent & 1) == 1)
|
||||
bc_multiply (temp, power, &temp, rscale);
|
||||
exponent = exponent >> 1;
|
||||
}
|
||||
|
||||
@ -1057,7 +1065,6 @@ bc_sqrt (num, scale)
|
||||
|
||||
/* Initialize the variables. */
|
||||
rscale = MAX (scale, (*num)->n_scale);
|
||||
cscale = rscale + 2;
|
||||
init_num (&guess);
|
||||
init_num (&guess1);
|
||||
point5 = new_num (1,1);
|
||||
@ -1073,14 +1080,15 @@ bc_sqrt (num, scale)
|
||||
/* The number is greater than 1. Guess should start at 10^(exp/2). */
|
||||
int2num (&guess,10);
|
||||
int2num (&guess1,(*num)->n_len);
|
||||
bc_multiply (guess1, point5, &guess1, rscale);
|
||||
bc_multiply (guess1, point5, &guess1, 0);
|
||||
guess1->n_scale = 0;
|
||||
bc_raise (guess, guess1, &guess, rscale);
|
||||
bc_raise (guess, guess1, &guess, 0);
|
||||
free_num (&guess1);
|
||||
}
|
||||
|
||||
/* Find the square root using Newton's algorithm. */
|
||||
done = FALSE;
|
||||
cscale = 2;
|
||||
while (!done)
|
||||
{
|
||||
free_num (&guess1);
|
||||
@ -1089,7 +1097,11 @@ bc_sqrt (num, scale)
|
||||
bc_add (guess,guess1,&guess);
|
||||
bc_multiply (guess,point5,&guess,cscale);
|
||||
cmp_res = _do_compare (guess,guess1,FALSE,TRUE);
|
||||
if (cmp_res == 0) done = TRUE;
|
||||
if (cmp_res == 0)
|
||||
if (cscale < rscale+1)
|
||||
cscale = MIN (cscale*3, rscale+1);
|
||||
else
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
/* Assign the number and clean up. */
|
||||
@ -1198,6 +1210,9 @@ out_num (num, o_base, out_char)
|
||||
init_num (&cur_dig);
|
||||
init_num (&base);
|
||||
bc_sub (num, int_part, &frac_part);
|
||||
/* Make the INT_PART and FRAC_PART positive. */
|
||||
int_part->n_sign = PLUS;
|
||||
frac_part->n_sign = PLUS;
|
||||
int2num (&base, o_base);
|
||||
init_num (&max_o_digit);
|
||||
int2num (&max_o_digit, o_base-1);
|
||||
@ -1273,7 +1288,6 @@ p_n (num)
|
||||
bc_num num;
|
||||
{
|
||||
out_num (num, 10, out_char);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* number.h: Arbitrary precision numbers header file. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* proto.h: Prototype function definitions for "external" functions. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -70,7 +70,8 @@ _PROTOTYPE(void assign, (int c_code));
|
||||
/* From util.c */
|
||||
_PROTOTYPE(char *strcopyof, (char *str));
|
||||
_PROTOTYPE(arg_list *nextarg, (arg_list *args, int val));
|
||||
_PROTOTYPE(char *arg_str, (arg_list *args, int));
|
||||
_PROTOTYPE(char *arg_str, (arg_list *args));
|
||||
_PROTOTYPE(char *call_str, (arg_list *args));
|
||||
_PROTOTYPE(void free_args, (arg_list *args));
|
||||
_PROTOTYPE(void check_params, (arg_list *params, arg_list *autos));
|
||||
_PROTOTYPE(void init_gen, (void));
|
||||
|
File diff suppressed because it is too large
Load Diff
196
gnu/usr.bin/bc/scan.l
Normal file
196
gnu/usr.bin/bc/scan.l
Normal file
@ -0,0 +1,196 @@
|
||||
%{
|
||||
/* scan.l: the (f)lex description file for the scanner. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License , or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
You may contact the author by:
|
||||
e-mail: phil@cs.wwu.edu
|
||||
us-mail: Philip A. Nelson
|
||||
Computer Science Department, 9062
|
||||
Western Washington University
|
||||
Bellingham, WA 98226-9062
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
#include "bcdefs.h"
|
||||
#include "y.tab.h"
|
||||
#include "global.h"
|
||||
#include "proto.h"
|
||||
|
||||
/* Using flex, we can ask for a smaller input buffer. With lex, this
|
||||
does nothing! */
|
||||
|
||||
#ifdef SMALL_BUF
|
||||
#undef YY_READ_BUF_SIZE
|
||||
#define YY_READ_BUF_SIZE 512
|
||||
#endif
|
||||
|
||||
/* We want to define our own yywrap. */
|
||||
#undef yywrap
|
||||
_PROTOTYPE(int yywrap, (void));
|
||||
|
||||
/* MINIX returns from read with < 0 if SIGINT is encountered.
|
||||
In flex, we can redefine YY_INPUT to the following. In lex, this
|
||||
does nothing! */
|
||||
#include <errno.h>
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
|
||||
if (errno != EINTR) \
|
||||
YY_FATAL_ERROR( "read() in flex scanner failed" );
|
||||
|
||||
%}
|
||||
DIGIT [0-9A-F]
|
||||
LETTER [a-z]
|
||||
%%
|
||||
define return(Define);
|
||||
break return(Break);
|
||||
quit return(Quit);
|
||||
length return(Length);
|
||||
return return(Return);
|
||||
for return(For);
|
||||
if return(If);
|
||||
while return(While);
|
||||
sqrt return(Sqrt);
|
||||
scale return(Scale);
|
||||
ibase return(Ibase);
|
||||
obase return(Obase);
|
||||
auto return(Auto);
|
||||
else return(Else);
|
||||
read return(Read);
|
||||
halt return(Halt);
|
||||
last return(Last);
|
||||
warranty return(Warranty);
|
||||
continue return(Continue);
|
||||
print return(Print);
|
||||
limits return(Limits);
|
||||
"." {
|
||||
#ifdef DOT_IS_LAST
|
||||
return(Last);
|
||||
#else
|
||||
yyerror ("illegal character: %s",yytext);
|
||||
#endif
|
||||
}
|
||||
"+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0];
|
||||
return((int)yytext[0]); }
|
||||
&& { return(AND); }
|
||||
\|\| { return(OR); }
|
||||
"!" { return(NOT); }
|
||||
"*"|"/"|"%" { yylval.c_value = yytext[0]; return(MUL_OP); }
|
||||
"="|\+=|-=|\*=|\/=|%=|\^= { yylval.c_value = yytext[0]; return(ASSIGN_OP); }
|
||||
=\+|=-|=\*|=\/|=%|=\^ {
|
||||
#ifdef OLD_EQ_OP
|
||||
char warn_save;
|
||||
warn_save = warn_not_std;
|
||||
warn_not_std = TRUE;
|
||||
warn ("Old fashioned =<op>");
|
||||
warn_not_std = warn_save;
|
||||
yylval.c_value = yytext[1];
|
||||
#else
|
||||
yylval.c_value = '=';
|
||||
yyless (1);
|
||||
#endif
|
||||
return(ASSIGN_OP);
|
||||
}
|
||||
==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); }
|
||||
\+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); }
|
||||
"\n" { line_no++; return(NEWLINE); }
|
||||
\\\n { line_no++; /* ignore a "quoted" newline */ }
|
||||
[ \t]+ { /* ignore spaces and tabs */ }
|
||||
"/*" {
|
||||
int c;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while ( ((c=input()) != '*') && (c != EOF))
|
||||
/* eat it */
|
||||
if (c == '\n') line_no++;
|
||||
if (c == '*')
|
||||
{
|
||||
while ( (c=input()) == '*') /* eat it*/;
|
||||
if (c == '/') break; /* at end of comment */
|
||||
if (c == '\n') line_no++;
|
||||
}
|
||||
if (c == EOF)
|
||||
{
|
||||
fprintf (stderr,"EOF encountered in a comment.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
[a-z][a-z0-9_]* { yylval.s_value = strcopyof(yytext); return(NAME); }
|
||||
\"[^\"]*\" {
|
||||
unsigned char *look;
|
||||
int count = 0;
|
||||
yylval.s_value = strcopyof(yytext);
|
||||
for (look = yytext; *look != 0; look++)
|
||||
{
|
||||
if (*look == '\n') line_no++;
|
||||
if (*look == '"') count++;
|
||||
}
|
||||
if (count != 2) yyerror ("NUL character in string.");
|
||||
return(STRING);
|
||||
}
|
||||
{DIGIT}({DIGIT}|\\\n)*("."({DIGIT}|\\\n)*)?|"."(\\\n)*{DIGIT}({DIGIT}|\\\n)* {
|
||||
unsigned char *src, *dst;
|
||||
int len;
|
||||
/* remove a trailing decimal point. */
|
||||
len = strlen(yytext);
|
||||
if (yytext[len-1] == '.')
|
||||
yytext[len-1] = 0;
|
||||
/* remove leading zeros. */
|
||||
src = yytext;
|
||||
dst = yytext;
|
||||
while (*src == '0') src++;
|
||||
if (*src == 0) src--;
|
||||
/* Copy strings removing the newlines. */
|
||||
while (*src != 0)
|
||||
{
|
||||
if (*src == '\\')
|
||||
{
|
||||
src++; src++;
|
||||
line_no++;
|
||||
}
|
||||
else
|
||||
*dst++ = *src++;
|
||||
}
|
||||
*dst = 0;
|
||||
yylval.s_value = strcopyof(yytext);
|
||||
return(NUMBER);
|
||||
}
|
||||
. {
|
||||
if (yytext[0] < ' ')
|
||||
yyerror ("illegal character: ^%c",yytext[0] + '@');
|
||||
else
|
||||
if (yytext[0] > '~')
|
||||
yyerror ("illegal character: \\%3d", (int) yytext[0]);
|
||||
else
|
||||
yyerror ("illegal character: %s",yytext);
|
||||
}
|
||||
%%
|
||||
|
||||
|
||||
|
||||
/* This is the way to get multiple files input into lex. */
|
||||
|
||||
int
|
||||
yywrap()
|
||||
{
|
||||
if (!open_new_file ()) return (1); /* EOF on standard in. */
|
||||
return (0); /* We have more input. */
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/* storage.c: Code and data storage manipulations. This includes labels. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -895,7 +895,6 @@ process_params (pc, func)
|
||||
{
|
||||
char ch;
|
||||
arg_list *params;
|
||||
char warned = FALSE;
|
||||
int ix, ix1;
|
||||
bc_var *v_temp;
|
||||
bc_var_array *a_src, *a_dest;
|
||||
@ -954,11 +953,8 @@ process_params (pc, func)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!warned)
|
||||
{
|
||||
rt_error ("Parameter number mismatch");
|
||||
warned = TRUE;
|
||||
}
|
||||
rt_error ("Parameter number mismatch");
|
||||
return;
|
||||
}
|
||||
params = params->next;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* util.c: Utility routines for bc. */
|
||||
|
||||
/* This file is part of bc written for MINIX.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -56,7 +56,7 @@ strcopyof (str)
|
||||
arg_list *
|
||||
nextarg (args, val)
|
||||
arg_list *args;
|
||||
char val;
|
||||
int val;
|
||||
{ arg_list *temp;
|
||||
|
||||
temp = (arg_list *) bc_malloc (sizeof (arg_list));
|
||||
@ -77,23 +77,22 @@ static char *arglist1 = NULL, *arglist2 = NULL;
|
||||
|
||||
/* make_arg_str does the actual construction of the argument string.
|
||||
ARGS is the pointer to the list and LEN is the maximum number of
|
||||
characters needed. 1 char is the minimum needed. COMMAS tells
|
||||
if each number should be seperated by commas.*/
|
||||
characters needed. 1 char is the minimum needed.
|
||||
*/
|
||||
|
||||
_PROTOTYPE (static char *make_arg_str, (arg_list *args, int len, int commas));
|
||||
_PROTOTYPE (static char *make_arg_str, (arg_list *args, int len));
|
||||
|
||||
static char *
|
||||
make_arg_str (args, len, commas)
|
||||
make_arg_str (args, len)
|
||||
arg_list *args;
|
||||
int len;
|
||||
int commas;
|
||||
{
|
||||
char *temp;
|
||||
char sval[20];
|
||||
|
||||
/* Recursive call. */
|
||||
if (args != NULL)
|
||||
temp = make_arg_str (args->next, len+11, commas);
|
||||
temp = make_arg_str (args->next, len+11);
|
||||
else
|
||||
{
|
||||
temp = (char *) bc_malloc (len);
|
||||
@ -102,7 +101,7 @@ make_arg_str (args, len, commas)
|
||||
}
|
||||
|
||||
/* Add the current number to the end of the string. */
|
||||
if (len != 1 && commas)
|
||||
if (len != 1)
|
||||
sprintf (sval, "%d,", args->av_name);
|
||||
else
|
||||
sprintf (sval, "%d", args->av_name);
|
||||
@ -111,17 +110,38 @@ make_arg_str (args, len, commas)
|
||||
}
|
||||
|
||||
char *
|
||||
arg_str (args, commas)
|
||||
arg_str (args)
|
||||
arg_list *args;
|
||||
int commas;
|
||||
{
|
||||
if (arglist2 != NULL)
|
||||
free (arglist2);
|
||||
arglist2 = arglist1;
|
||||
arglist1 = make_arg_str (args, 1, commas);
|
||||
arglist1 = make_arg_str (args, 1);
|
||||
return (arglist1);
|
||||
}
|
||||
|
||||
char *
|
||||
call_str (args)
|
||||
arg_list *args;
|
||||
{
|
||||
arg_list *temp;
|
||||
int arg_count;
|
||||
int ix;
|
||||
|
||||
if (arglist2 != NULL)
|
||||
free (arglist2);
|
||||
arglist2 = arglist1;
|
||||
|
||||
/* Count the number of args and add the 0's and 1's. */
|
||||
for (temp = args, arg_count = 0; temp != NULL; temp = temp->next)
|
||||
arg_count++;
|
||||
arglist1 = (char *) bc_malloc(arg_count+1);
|
||||
for (temp = args, ix=0; temp != NULL; temp = temp->next)
|
||||
arglist1[ix++] = ( temp->av_name ? '1' : '0');
|
||||
arglist1[ix] = 0;
|
||||
|
||||
return (arglist1);
|
||||
}
|
||||
|
||||
/* free_args frees an argument list ARGS. */
|
||||
|
||||
@ -522,9 +542,13 @@ lookup (name, namekind)
|
||||
exit (1);
|
||||
|
||||
case FUNCT:
|
||||
case FUNCTDEF:
|
||||
if (id->f_name != 0)
|
||||
{
|
||||
free(name);
|
||||
/* Check to see if we are redefining a math lib function. */
|
||||
if (use_math && namekind == FUNCTDEF && id->f_name <= 6)
|
||||
id->f_name = next_func++;
|
||||
return (id->f_name);
|
||||
}
|
||||
id->f_name = next_func++;
|
||||
|
@ -1,3 +1,3 @@
|
||||
#define BC_VERSION \
|
||||
"bc 1.02 (Mar 3, 92) Copyright (C) 1991, 1992 Free Software Foundation, Inc."
|
||||
"bc 1.03 (Nov 2, 1994)\nCopyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc."
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
#define NEWLINE 257
|
||||
#define AND 258
|
||||
#define OR 259
|
||||
#define NOT 260
|
||||
#define STRING 261
|
||||
#define NAME 262
|
||||
#define NUMBER 263
|
||||
#define MUL_OP 264
|
||||
#define ASSIGN_OP 265
|
||||
#define REL_OP 266
|
||||
#define INCR_DECR 267
|
||||
#define Define 268
|
||||
#define Break 269
|
||||
#define Quit 270
|
||||
#define Length 271
|
||||
#define Return 272
|
||||
#define For 273
|
||||
#define If 274
|
||||
#define While 275
|
||||
#define Sqrt 276
|
||||
#define Else 277
|
||||
#define Scale 278
|
||||
#define Ibase 279
|
||||
#define Obase 280
|
||||
#define Auto 281
|
||||
#define Read 282
|
||||
#define Warranty 283
|
||||
#define Halt 284
|
||||
#define Last 285
|
||||
#define Continue 286
|
||||
#define Print 287
|
||||
#define Limits 288
|
||||
#define UNARY_MINUS 289
|
||||
typedef union {
|
||||
char *s_value;
|
||||
char c_value;
|
||||
int i_value;
|
||||
arg_list *a_value;
|
||||
} YYSTYPE;
|
||||
extern YYSTYPE yylval;
|
Loading…
Reference in New Issue
Block a user