/
bc
executable file
·3136 lines (2586 loc) · 86.5 KB
/
bc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/perl
=begin metadata
Name: bc
Description: an arbitrary precision calculator language
Author: Philip A. Nelson, phil@cs.wwu.edu
License: gpl
=end metadata
=cut
=head1 NAME
bc - an arbitrary precision calculator language
=head1 SYNOPSIS
Show a help message
% bc -h
Run a bc program from FILE
bc [-bdiqswy] FILE
Run a bc program from standard input
bc [-bdiqswy]
=head1 DESCRIPTION
This is the PerlPowerTools implementations of GNU version of bc, a
souped-up calculator language. This is documented at:
https://www.gnu.org/software/bc/manual/html_mono/bc.html
=head2 Options
=over
=item * -b - use Math::BigFloat
=item * -d - turn on debugging output
=item * -h - show a help message and exit
=item * -i - force interactive mode (a no-op for compatibility)
=item * -l - use mathlib
=item * -q - suppress the welcome message
=item * -s - process the POSIX bc language (a no-op for compatibility)
=item * -w - give warnings for POSIX bc extensions (a no-op for compatibility)
=item * -y - turn on parsing debugging output
=back
=head2 Environment
There are no environment variables that affect this program.
=head1 The bc language
NOTE: Some of this documentation is lifted straight from the GNU
documentation for its version of B<bc>.
C<bc> is a language that supports arbitrary precision numbers with
interactive execution of statements. There are some similarities in
the syntax to the C programming language.
=begin comment ### XXX hidden because function support generate syntax errors
A standard math library is
available by command line option. If requested, the math library is
defined before processing any files.
=end comment
C<bc> starts by processing code from all the files listed on the
command line in the order listed. If no files are listed, then stdin
is read. If a file contains a command to halt the processor,
C<bc> will never read from the standard input.
Dash ('-') is a pseudo-filename which represents stdin. This makes
it possible to do something like C<bc fileA - fileB> and have bc
run commands from fileA before prompting for input, and then run
commands from fileB after interactive input is finished.
=begin comment ### XXX for accuracy, the following is superceded by the above
C<bc> starts by processing code from all the files listed on the
command line in the order listed. After all files have been
processed, C<bc> reads from the standard input. All code is executed
as it is read. (If a file contains a command to halt the processor,
C<bc> will never read from the standard input.)
=end comment
C<bc> will terminate interactive input via stdin if you enter C<quit>
or press C<CTRL-C>.
Pressing C<CTRL-Z> will end stdin input and move on the the next
filename on the command line (if there is one). Otherwise, execution
ends.
=head1 OPTIONS
C<bc> takes the following options from the command line:
=over 4
=item -b
Use Math::BigFloat for arbitrarily large number support.
=item -d
Print debugging data (using Data::Dumper).
=item -y
Turn on parser debugging.
=begin comment ### -l hidden because it generate syntax errors
=item -l
Define the standard math library.
=end comment
=begin comment ### -h and hidden because it's not supported
=item -h
Print the documentation.
=end comment
=back
=head1 BASIC ELEMENTS
=head2 Numbers
The most basic element in C<bc> is the number. Numbers are arbitrary
precision numbers. This precision is both in the integer part and the
fractional part. All numbers are represented internally in decimal and
all computation is done in decimal.
=begin comment ### hidden because it doesn't seem to be true in this implementation
(This version truncates results
from divide and multiply operations.)
=end comment
There are two attributes of
numbers, the length and the scale. The length is the total number of
significant decimal digits in a number and the scale is the total number
of decimal digits after the decimal point. For example, .000001 has a
length of 6 and scale of 6, while 1935.000 has a length of 7 and a scale
of 3.
=head2 Variables
Numbers are stored in two types of variables, simple variables and
arrays. Both simple variables and array variables are named. Names
begin with a letter followed by any number of letters, digits and
underscores. All letters must be lower case.
=begin comment ### hidden because it's not applicable and confusing
(Full alphanumeric names
are an extension. In POSIX C<bc> all names are a single lower case
letter.)
=end comment
The type of variable is clear by the context because all
array variable names will be followed by brackets ( [ ] ).
=head2 Special Variables
=over 8
=item C<scale>
Defines how some operations use digits after the decimal point.
The default value is 0.
=item C<ibase>
Defines the conversion base for input numbers. Defaults to 10.
=item C<obase>
Defines the conversion base for output numbers. Defaults to 10.
=back
=head2 Comments
Comments in C<bc> start with the characters '/*' and end with the
characters '*/'. Comments may start anywhere and appear as a single
space in the input. Note that this causes comments to delimit other
input items, therefore a comment cannot be included the middle of a
variable name. Comments include any newlines (end of line) between
the start and the end of the comment.
To support the use of scripts for C<bc>, a single line comment has
been added as an extension. A single line comment starts at a '#'
character and continues to the next end of the line. The end of line
character is not part of the comment and is processed normally.
=head1 EXPRESSIONS
Numbers are manipulated by expressions and statements. Since
the language was designed to be interactive, statements and expressions
are executed as soon as possible. There is no main program. Instead,
code is executed as it is encountered.
A simple expression is just a constant. C<bc> converts constants into
internal decimal numbers using the current input base, specified by the
variable C<ibase>.
Full expressions are similar to many other high level languages.
Since there is only one kind of number, there are no rules for mixing
types. Instead, there are rules on the scale of expressions. Every
expression has a scale. This is derived from the scale of original
numbers, the operation performed and in many cases, the value of the
variable C<scale>.
=begin comment ### replace by the above for accurary w.r.t this implementation
The numbers are manipulated by expressions and statements. Since the language was designed to be interactive, statements and expressions are executed as soon as possible. There is no main program. Instead, code is executed as it is encountered. (Functions, discussed in detail later, are defined when encountered.)
A simple expression is just a constant. bc converts constants into internal decimal numbers using the current input base, specified by the variable ibase. (There is an exception in functions.) The legal values of ibase are 2 through 16. Assigning a value outside this range to ibase will result in a value of 2 or 16. Input numbers may contain the characters 0-9 and A-F. (Note: They must be capitals. Lower case letters are variable names.) Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number FFF always be the largest 3 digit number of the input base.
Full expressions are similar to many other high level languages. Since there is only one kind of number, there are no rules for mixing types. Instead, there are rules on the scale of expressions. Every expression has a scale. This is derived from the scale of original numbers, the operation performed and in many cases, the value of the variable scale. Legal values of the variable scale are 0 to the maximum number representable by a C integer.
=end comment
=head2 Basic Expressions
In the following descriptions of legal expressions, "expr" refers to
a complete expression and "VAR" refers to a simple or an array variable.
A simple variable is just a NAME and an array variable is specified as
NAME[EXPR].
Unless specifically mentioned the scale of the result is the maximum
scale of the expressions involved.
=over 4
=item C<- expr>
The result is the negation of the expression.
=item C<++ VAR>
The variable is incremented by one and the new value is the result
of the expression.
=item C<-- VAR>
The variable is decremented by one and the new value is the result
of the expression.
=item C<VAR ++>
The result of the expression is the value of the variable and then
the variable is incremented by one.
=item C<VAR -->
The result of the expression is the value of the variable and then
the variable is decremented by one.
=item C<expr + expr>
The result of the expression is the sum of the two expressions.
=item C<expr - expr>
The result of the expression is the difference of the two
expressions.
=item C<expr * expr>
The result of the expression is the product of the two expressions.
=item C<expr / expr>
The result of the expression is the quotient of the two
expressions. The scale of the result is the value of the variable
C<scale>
=item C<expr % expr>
The result of the expression is the "remainder" and it is computed
in the following way. To compute a%b, first a/b is computed to
SCALE digits. That result is used to compute a-(a/b)*b to the
scale of the maximum of SCALE+scale(b) and scale(a). If SCALE is
set to zero and both expressions are integers this expression is
the integer remainder function.
=item C<expr ^ expr>
The result of the expression is the value of the first raised to
the second.
=begin comment ### hidden because it doesn't seem to be true in the implementation
The second expression must be an integer. (If the
second expression is not an integer, a warning is generated and the
expression is truncated to get an integer value.)
=end comment
The scale of the result is SCALE if the exponent is negative. If the
exponent is positive the scale of the result is the minimum of the
scale of the first expression times the value of the exponent and the
maximum of SCALE and the scale of the first expression. (e.g.
scale(a^b) = min(scale(a)*b, max(SCALE, scale(a))).) It should be
noted that expr^0 will always return the value of 1.
=item C<( expr )>
This alters the standard precedence to force the evaluation of the
expression.
=item C<VAR = expr>
The variable is assigned the value of the expression.
=item C<VAR op= expr>
This is equivalent to "VAR = VAR op expr" with the exception
that the "VAR" part is evaluated only once. This can make a
difference if "VAR" is an array.
=back
=head2 Relational Expressions
Relational expressions are a special kind of expression that always
evaluate to 0 or 1, 0 if the relation is false and 1 if the relation is
true. These may appear in any legal expression. (POSIX C<bc> requires
that relational expressions are used only in C<if>, C<while>, and C<for>
statements and that only one relational test may be done in them.) The
relational operators are
=over 4
=item expr1 < expr2
The result is 1 if expr1 is strictly less than expr2.
=item expr1 <= expr2
The result is 1 if expr1 is less than or equal to expr2.
=item expr1 > expr2
The result is 1 if expr1 is strictly greater than expr2.
=item expr1 >= expr2
The result is 1 if expr1 is greater than or equal to expr2.
=item expr1 == expr2
The result is 1 if expr1 is equal to expr2.
=item expr1 != expr2
The result is 1 if expr1 is not equal to expr2.
=back
=head2 Boolean Expressions
Boolean operations are also legal. (POSIX C<bc> does NOT have
boolean operations). The result of all boolean operations are 0 and 1
(for false and true) as in relational expressions. The boolean
operators are:
=over 4
=item C<!expr>
The result is 1 if expr is 0.
=item C<expr && expr>
The result is 1 if both expressions are non-zero.
=item C<expr || expr>
The result is 1 if either expression is non-zero.
=back
=head2 Precedence
The expression precedence is as follows: (lowest to highest)
= += etc operators (assigment) right associative
|| OR operator left associative
&& AND operator left associative
! NOT operator nonassociative
< > etc relational operators left associative
+ and - operators left associative
*, / and % operators left associative
^ operator (power) right associative
unary - operator nonassociative
++ and -- operators nonassociative
This differs from POSIX-compliant C<bc>, which puts assignment between
relational operators and addition/subtraction. As a result, expressions
behave more like they do in most languages (including perl and C).
=head2 Special Expressions
There are a few more special expressions that are provided in C<bc>.
These have to do with user-defined functions and standard functions.
These are:
=over 4
=item C<length ( expression )>
The value of the C<length> function is the number of significant
digits in the expression.
=begin comment ### hidden because it's not supported
=item C<read ( )>
The C<read> function (an extension) will read a number from the
standard input, regardless of where the function occurs. Beware,
this can cause problems with the mixing of data and program in the
standard input. The best use for this function is in a previously
written program that needs input from the user, but never allows
program code to be input from the user. The value of the `read'
function is the number read from the standard input using the
current value of the variable C<ibase> for the conversion base.
=end comment
=item C<scale ( expression )>
The value of the C<scale> function is the number of digits after the
decimal point in the expression.
=item C<sqrt ( expression )>
The value of the C<sqrt> function is the square root of the
expression. If the expression is negative, a run time error is
generated.
=back
=head2 Statements
Statements (as in most algebraic languages) provide the sequencing of
expression evaluation. In C<bc> statements are executed "as soon as
possible." Execution happens when a newline in encountered and there
is one or more complete statements. Due to this immediate execution,
newlines are very important in C<bc>. In fact, both a semicolon and a
newline are used as statement separators. An improperly placed
newline will cause a syntax error.
Because newlines are statement separators, it is possible to hide a
newline by using the backslash character. The sequence "\<nl>" (where
<nl> represents a newline your typed) appears to C<bc> as whitespace
instead of an actual newline.
A statement list is a series of statements separated by semicolons
and newlines.
The following is a list of C<bc> statements and what they do. Things
enclosed in brackets ( [ ] ) are optional parts of the statement.
=over 4
=item EXPRESSION
This statement does one of two things. If the expression starts
with "<variable> <assignment> ...", it is considered to be an
assignment statement. If the expression is not an assignment
statement, the expression is evaluated and printed to the output.
After the number is printed, a newline is printed.
For example, "a=1" is an assignment statement and "(a=1)" is an
expression that has an embedded assignment.
=begin comment ### hidden because obase and last don't seem to work
All numbers that are printed are printed in the base specified by the
variable OBASE. The legal values for OBASE are 2 through BC_BASE_MAX
(*note Environment Variables::). For bases 2 through 16, the usual
method of writing numbers is used. For bases greater than 16, C<bc>
uses a multi-character digit method of printing the numbers where each
higher base digit is printed as a base 10 number. The multi-character
digits are separated by spaces. Each digit contains the number of
characters required to represent the base ten value of "OBASE -1".
Since numbers are of arbitrary precision, some numbers may not be
printable on a single output line. These long numbers will be split
across lines using the "\" as the last character on a line. The
maximum number of characters printed per line is 70. Due to the
interactive nature of C<bc>, printing a number causes the side effect
of assigning the printed value to the special variable LAST. This
allows the user to recover the last value printed without having to
retype the expression that printed the number. Assigning to LAST 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 LAST. (Some installations may
allow the use of a single period (.) which is not part of a number as
a short hand notation for for LAST.)
=end comment
=item 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. All characters are taken literally, including
any newline. No newline character is printed after the string.
=item C<print> LIST
The C<print> statement (an extension) provides another method of
output. The LIST is a list of strings and expressions separated by
commas. Each string or expression is printed in the order of the
list. No terminating newline is printed. Expressions are
evaluated and their value is printed and assigned to the variable
C<last>. Strings in the print statement are printed to the output
and may contain special characters. Special characters start with
the backslash character. The special characters include:
\a alert or bell
\b backspace
\f form feed
\n newline
\r carriage return
\q double quote
\t tab
\e backslash.
Any other character following a backslash will be ignored.
=item { STATEMENT_LIST }
This is the compound statement. It allows multiple statements to
be grouped together for execution.
=item C<if> ( EXPRESSION ) STATEMENT
The C<if> statement evaluates the expression and executes STATEMENT
depending on the value of the expression. If the expression is
non-zero, STATEMENT is executed. Otherwise it isn't. (The statement
can be a block enclosed in { }.)
=begin comment ### if-else is not supported in this implementation
If the expression is non-zero, statement1 is executed. If statement2
is present and the value of the expression is 0, then statement2 is
executed. (The C<else> clause is an extension.)
=end comment
=item C<while> ( EXPRESSION ) STATEMENT
The while statement will execute the statement while the expression
is non-zero. It evaluates the expression before each execution of
the statement. Termination of the loop is caused by a zero
expression value or the execution of a C<break> statement.
=item C<for> ( [EXPRESSION1] ; [EXPRESSION2] ; [EXPRESSION3] ) STATEMENT
The C<for> statement controls repeated execution of the statement.
EXPRESSION1 is evaluated before the loop. EXPRESSION2 is
evaluated before each execution of the statement. If it is
non-zero, the statement is evaluated. If it is zero, the loop is
terminated.
After each execution of the statement, EXPRESSION3 is
evaluated before the reevaluation of expression2. If EXPRESSION1
or EXPRESSION3 are missing, nothing is evaluated at the point they
would be evaluated. If EXPRESSION2 is missing, it is the same as
substituting the value 1 for EXPRESSION2.
(The optional expressions are an extension. POSIX C<bc> requires all
three expressions.)
The following is equivalent code for the C<for>
statement:
expression1;
while (expression2) {
statement;
expression3;
}
=item C<break>
This statement causes a forced exit of the most recent enclosing
C<while> statement or C<for> statement.
=item C<quit>
When the C<quit> statement is read, the C<bc> processor is
terminated, regardless of where the C<quit> statement is found. For
example, C<if (0 == 1) quit> will cause C<bc> to terminate.
=back
=begin comment ### hidden because functions aren't working
=head1 MATH LIBRARY FUNCTIONS
If C<bc> is invoked with the C<-l> option, a math library is preloaded
and the default SCALE is set to 20. The math functions will calculate
their results to the scale set at the time of their call. The math
library defines the following functions:
=over 4
=item C<s (X)>
The sine of X, X is in radians.
=item C<c (X)>
The cosine of X, X is in radians.
=item C<a (X)>
The arctangent of X, arctangent returns radians.
=item C<l (X)>
The natural logarithm of X.
=item C<E (X)>
The exponential function of raising E to the value X.
=item C<J (N,X)>
The bessel function of integer order N of X.
=back
=end comment
=head1 EXAMPLE
The following illustrates how C<bc> expressions can be written in
script form and fed to C<bc> via stdin.
=begin comment
Note that the /* and */ are necessary to around the C<bc> code example
in order to prevent -l from processing these statements when reading <DATA>
/*
=end comment
print "\nCompute balances after withdrawals\n"
bal = 100.00
withdrawal = 20.00;
while (1) {
print "Balance: ", "\t", bal, "\n"
print "Withdrawal: ", "\t", withdrawal, "\n"
if ( (bal - withdrawal) < 0 ) break;
bal -= withdrawal
}
print "Balance:", bal
quit
=begin comment
*/
=end comment
=head1 BUGS AND LIMITATIONS
This implementation of C<bc> is mostly POSIX compliant and has similar
extensions to GNU C<bc>. However, some features and extensions are
either not supported or are not working.
Perhaps the biggest non-working feature would be Function definitions
via the C<define> syntax, which if used generats syntax errors. As a
consequence, the -l option (to load math library definitions) doesn't
work either.
Setting the following variables don't seem to have the intended effects:
scale
ibase
obase
Hexadecimal values, for use when ibase is > 10, are not supported.
Old style assignment operators (=+, =-, =*, =/, =%, =^) are not
required to be supported by the POSIX standard, and they are not
supported by this implementation. However, they will not generate
any errors. Instead you will get a result you don't expect.
For example:
v=3; v += 2 # v is 5 as you would expect
v=3; v =+ 2 # v is 2 because the 2nd expression is seen as v = +2
=head1 COMPARISON TO GNU C<bc> AND OTHERS
The following C<bc> features are not supported in this implementation.
(Some are syntactically accepted, but simply return zero).
* -w, --warn option
* -s, --standard option
* -q, --quiet option
* -v, --version option
* long options (e.g. --help)
* LC_ language and NLSPATH environment variables
* "last" special variable
* "if" statement: "else" clause
* "read" function
* "continue" statement
* "halt" statement
* "limits" pseudo statement
* "warranty" pseudo statement
* function definitions
In addition, the GNU implementation set the precedence of assignent
below + and - and above relational operators (< > etc). This
implementation seems to make it the lowest precedence (i.e. below ||),
as most perl (and C) users would expect.
=head1 REFERENCES
POSIX C<bc> L<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html>
GNU C<bc> L<https://www.gnu.org/software/bc/manual/html_mono/bc.html>
=head2 GNU's mathlib
Load the GNU math extensions with the C<-l> switch:
% bc -l FILE
The library provides these functions:
=over 4
=item * a(x) - the arctangent of X, where X is expressed in radians
=item * c(x) - the cosine of X, where X is expressed in radians
=item * e(X) - the natural base, e, raised to the X power
=item * j(X) - the Bessel function of order X, where X is an integer
=item * l(X) - the natural logarithm of X
=item * s(x) - the sine of X, where X is expressed in radians
=back
=head1 AUTHOR
Philip A. Nelson originally translated GNU bc to Perl for the PerlPowerTools
project.
https://github.com/briandfoy/PerlPowerTools
=head1 LICENSE
You can use and modify this program under the terms of the GNU Public
License version 2. A copy of this license is in the PerlPowerTools
repository:
https://github.com/briandfoy/PerlPowerTools/
=cut
#define YYBYACC 1
#line 49 "bc.y"
;# The symbol table : the keys are the identifiers, the value is in the
;# "var" field if it is a variable, in the "func" field if it is a
;# function.
my %sym_table;
my @stmt_list = ();
my @ope_stack;
my @backup_sym_table;
my $input;
my $cur_file = '-';
my $bignum = 0;
my $do_stdin = 0;
$debug = 0;
sub debug(&) {
my $fn = shift;
print STDERR "\t".&$fn()
if $debug;
}
;#$yydebug=1;
#line 32 "y.tab.pl"
$INT=257;
$FLOAT=258;
$STRING=259;
$IDENT=260;
$C_COMMENT=261;
$BREAK=262;
$DEFINE=263;
$AUTO=264;
$RETURN=265;
$PRINT=266;
$AUTO_LIST=267;
$IF=268;
$ELSE=269;
$QUIT=270;
$WHILE=271;
$FOR=272;
$EQ=273;
$NE=274;
$GT=275;
$GE=276;
$LT=277;
$LE=278;
$PP=279;
$MM=280;
$P_EQ=281;
$M_EQ=282;
$F_EQ=283;
$D_EQ=284;
$EXP_EQ=285;
$MOD_EQ=286;
$L_SHIFT=287;
$R_SHIFT=288;
$E_E=289;
$O_O=290;
$EXP=291;
$UNARY=292;
$PPP=293;
$MMM=294;
$YYERRCODE=256;
@yylhs = ( -1,
0, 0, 1, 1, 1, 3, 4, 9, 3, 3,
3, 12, 3, 13, 3, 14, 3, 15, 17, 3,
18, 19, 20, 3, 3, 10, 10, 16, 16, 8,
8, 6, 6, 2, 2, 5, 5, 22, 22, 23,
23, 24, 24, 7, 7, 25, 25, 11, 11, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 26, 26,
);
@yylen = ( 2,
0, 2, 1, 2, 2, 1, 0, 0, 13, 1,
1, 0, 3, 0, 4, 0, 7, 0, 0, 8,
0, 0, 0, 13, 1, 1, 4, 0, 1, 1,
3, 0, 1, 1, 1, 0, 1, 1, 3, 0,
1, 1, 3, 0, 3, 1, 3, 1, 3, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
2, 3, 6, 1, 1, 1, 1, 1, 4,
);
@yydefred = ( 1,
0, 0, 85, 86, 87, 0, 0, 11, 7, 0,
12, 0, 6, 18, 0, 0, 0, 0, 0, 0,
14, 0, 34, 35, 2, 3, 0, 10, 0, 0,
5, 0, 0, 0, 81, 0, 0, 0, 0, 0,
0, 0, 76, 77, 80, 74, 0, 0, 75, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 78, 79, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 29, 0, 0, 51, 0,
30, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 50, 0, 0, 0, 27, 0, 16,
0, 21, 0, 15, 0, 0, 0, 38, 0, 0,
0, 0, 0, 0, 89, 31, 0, 0, 0, 33,
0, 19, 0, 0, 39, 17, 0, 22, 0, 20,
0, 0, 0, 0, 8, 23, 46, 0, 0, 0,
0, 45, 0, 0, 47, 9, 24,
);
@yydgoto = ( 1,
25, 140, 86, 36, 129, 141, 155, 90, 159, 28,
82, 38, 48, 132, 40, 91, 147, 134, 151, 160,
29, 130, 77, 78, 158, 30,
);
@yysindex = ( 0,
475, -8, 0, 0, 0, 84, -239, 0, 0, -11,
0, 3, 0, 0, 19, -218, -218, 899, 899, 899,
0, 899, 0, 0, 0, 0, -8, 0, 893, -54,
0, 899, 899, 899, 0, -199, 899, 899, 958, 24,
958, -26, 0, 0, 0, 0, -32, 958, 0, 0,
899, 899, 899, 899, 899, 899, 899, 899, 899, 899,
899, 899, 899, 899, 899, 899, 899, 899, 899, 899,
899, 899, 0, 0, 893, 893, 25, 48, 830, 65,
852, 64, 893, 27, 958, 0, 53, 899, 0, 26,
0, 923, 923, 142, 142, 142, 142, 416, 416, -21,
-21, -30, -30, -29, -29, -180, -180, 142, 142, 142,
142, 142, 142, 0, 899, 67, -146, 0, 899, 0,
85, 0, 874, 0, 958, 893, 899, 0, 86, 87,
893, -8, -8, 958, 0, 0, 893, -8, -127, 0,
958, 0, 88, 41, 0, 0, 958, 0, -8, 0,
958, -116, 108, -103, 0, 0, 0, 18, 958, -8,
-100, 0, 31, 958, 0, 0, 0,
);
@yyrindex = ( 0,
0, 0, 0, 0, 0, -10, 0, 0, 0, 28,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 30, 37,
0, 0, 127, 0, 0, 0, 0, 0, 0, 0,
119, 57, 0, 0, 0, 0, 0, 36, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 4, -40, 0, 139, 0, 0,
0, 34, 66, 0, 145, 0, 0, 0, 0, 0,
0, 820, 822, 507, 518, 537, 551, 405, 442, 298,
380, 122, 192, 129, 167, 76, 99, 572, 579, 680,
758, 777, 799, 0, 0, 13, 149, 0, 0, 0,
0, 0, 0, 0, 36, -38, 0, 0, 0, 153,
93, 1023, 1023, 119, 0, 0, 29, 60, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
145, 499, 0, 0, 0, 0, 0, 0, 36, 1023,
0, 0, 0, 0, 0, 0, 0,
);
@yygindex = ( 0,
0, 358, 52, 0, 0, -108, 0, 38, 0, 0,
0, 0, 0, 0, 0, 337, 0, 0, 0, 0,
1278, 0, 0, 0, 0, 2,
);
@yytable = ( 88,
42, 24, 43, 42, 65, 43, 65, 65, 89, 63,
61, 63, 62, 82, 64, 65, 64, 43, 44, 35,
63, 61, 89, 62, 142, 64, 88, 24, 37, 144,
88, 88, 88, 88, 88, 24, 88, 26, 83, 25,
24, 42, 39, 13, 82, 28, 84, 82, 88, 89,
23, 164, 27, 89, 89, 89, 89, 89, 41, 89,
80, 161, 82, 85, 88, 114, 88, 120, 26, 83,
25, 89, 83, 84, 13, 48, 23, 84, 84, 84,
84, 84, 88, 84, 23, 67, 26, 83, 25, 23,
84, 115, 13, 88, 28, 84, 82, 88, 88, 88,
88, 88, 49, 88, 117, 89, 48, 119, 66, 48,
66, 122, 67, 128, 88, 88, 67, 67, 67, 67,
67, 83, 67, 33, 48, 133, 138, 127, 82, 84,
139, 62, 145, 49, 67, 66, 49, 89, 64, 66,
66, 66, 66, 66, 32, 66, 148, 154, 156, 88,
124, 49, 26, 83, 25, 166, 157, 66, 13, 165,
28, 84, 62, 149, 62, 62, 62, 40, 67, 64,
64, 64, 64, 64, 34, 64, 65, 28, 65, 41,
62, 88, 32, 63, 61, 28, 62, 64, 64, 36,
48, 66, 146, 37, 0, 0, 163, 0, 150, 0,
67, 63, 0, 0, 0, 0, 0, 65, 65, 65,
65, 65, 0, 65, 62, 167, 0, 49, 0, 0,
0, 64, 0, 66, 0, 65, 67, 68, 69, 70,
71, 72, 63, 0, 63, 63, 63, 0, 73, 74,
51, 52, 53, 54, 55, 56, 62, 0, 0, 0,
63, 0, 0, 64, 57, 58, 59, 60, 66, 65,
66, 66, 88, 88, 88, 88, 88, 88, 0, 66,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 0, 88, 88, 63, 89, 89, 89, 89, 89,
89, 65, 0, 89, 89, 89, 89, 89, 89, 89,
89, 89, 89, 89, 0, 89, 89, 53, 0, 84,
84, 84, 84, 84, 84, 0, 63, 0, 0, 0,
0, 0, 0, 84, 84, 84, 84, 84, 0, 88,
88, 88, 88, 88, 88, 0, 0, 0, 53, 0,
0, 53, 0, 88, 88, 88, 88, 88, 67, 67,
67, 67, 67, 67, 0, 0, 53, 0, 26, 31,
0, 0, 67, 67, 67, 67, 0, 0, 0, 0,
0, 66, 66, 66, 66, 66, 66, 87, 0, 0,
0, 0, 0, 0, 50, 66, 66, 66, 66, 52,
53, 0, 0, 0, 62, 62, 62, 62, 62, 62,
0, 64, 64, 64, 64, 64, 64, 0, 62, 62,
62, 62, 0, 0, 60, 64, 64, 64, 64, 0,
52, 121, 53, 52, 0, 0, 0, 0, 57, 58,
59, 60, 66, 0, 0, 0, 0, 0, 52, 65,