home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume3 / hexcalc1.1 < prev    next >
Internet Message Format  |  1989-02-03  |  45KB

  1. Path: xanth!mcnc!uvaarpa!umd5!ames!necntc!ncoast!allbery
  2. From: richardh@killer.UUCP (Richard Hargrove)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i063: hexcalc 1.1
  5. Keywords: hex calculator utility
  6. Message-ID: <4622@killer.UUCP>
  7. Date: 28 Jun 88 01:35:22 GMT
  8. Sender: allbery@ncoast.UUCP
  9. Reply-To: richardh@killer.UUCP (Richard Hargrove)
  10. Organization: The Unix(R) Connection, Dallas, Texas
  11. Lines: 1875
  12. Approved: allbery@ncoast.UUCP
  13.  
  14. comp.sources.misc: Volume 3, Issue 63
  15. Submitted-By: "Richard Hargrove" <richardh@killer.UUCP>
  16. Archive-Name: hexcalc1.1
  17.  
  18. Brandon,
  19.  
  20. Just what the net needs. Another calculator program! This one is modeled
  21. the TI Programmer II (decimal radix is still integer, though). I won't 
  22. repeat the readme file here. I've tested the makefiles under MS-DOS,
  23. Microport Unix SYS V/AT, ATT SYS V, R3 (on a 3b2), SCO Xenix SYS V, and
  24. Intel Xenix 3.5 (SYS III based). All make without a hitch.
  25.  
  26. If you think it is a reasonable contribution, post away.
  27.  
  28. thanks,
  29. richard hargrove
  30.  
  31. -------- cut here -------- cut here -------- cut here -------- cut here --------
  32. #!/bin/sh
  33. # shar:    Shell Archiver  (v1.22)
  34. #
  35. #    Run the following text with /bin/sh to create:
  36. #      1st_read.me
  37. #      bltins.c
  38. #      hctest01.txt
  39. #      hctest02.txt
  40. #      hexcalc.h
  41. #      hexcalc.man
  42. #      hexcalc.y
  43. #      init.c
  44. #      makefile.dos
  45. #      makefile.unx
  46. #      symbol.c
  47. #      ulpow.c
  48. #      ytab.c
  49. #      ytab.h
  50. #      yylex.c
  51. #
  52. sed 's/^X//' << 'SHAR_EOF' > 1st_read.me &&
  53. X    ----------------
  54. X        Here is a yacc toy, a hexadecimal calculator program. It's based on
  55. X        hoc3 for those familiar with chapter 8 in _The Unix Programming
  56. X        Environment_ by Kernighan and Pike. To use it, run it and type help.
  57. X        Or better yet, read the included man pages.
  58. X
  59. X    This package is being distributed in both .ARC archive and shell
  60. X    archive (shar) form and is made up of the following files:
  61. X
  62. X        1st_read.me        this file
  63. X
  64. X        hexcalc.exe        executable (.ARC only)
  65. X
  66. X        hexcalc.h        c source code
  67. X        ytab.h
  68. X        bltins.c
  69. X        symbol.c
  70. X        ulpow.c
  71. X        yylex.c
  72. X        init.c
  73. X        ytab.c
  74. X
  75. X        hexcalc.y        yacc source code
  76. X
  77. X        makefile.dos        miscellaneous files
  78. X        makefile.unx
  79. X        hexcalc.man
  80. X        hctest01.txt
  81. X        hctest02.txt
  82. X
  83. X    Included are two simple test "programs" that when fed to hexcalc via
  84. X    stdin exercise expression evaluation and commands. See the test
  85. X    dependency in the Unix makefile.
  86. X
  87. X        I have included the yacc generated source and header files for those
  88. X        who are developing in a non-Unix environment and don't have
  89. X        immediate access to yacc(1). For the MS-DOS environment, I use the
  90. X        version of yacc distributed with the MKS Toolkit. That was the
  91. X        version used to generate the yacc output files.
  92. X
  93. X    The MS-DOS makefile requires the presence of the MKS Toolkit and
  94. X    Turbo C to be useable. The mv, rm, and tcc command invocations can 
  95. X    be modified as appropriate, but it still requires yacc to generate 
  96. X    new ytab.h and ytab.c files. However, the use of make is not required 
  97. X    to generate the executable. The tcc invocation line
  98. X
  99. X    tcc -ehexcalc.exe  ytab.c init.c symbol.c bltins.c yylex.c ulpow.c
  100. X
  101. X    should do it.
  102. X
  103. X        Needless to say, Unix is a trademark of AT&T, MKS Toolkit is a
  104. X    trademark of Mortice Kern Systems, Turbo C is a trademark of
  105. X    Borland International, and MS-DOS is a trademark of Microsoft.
  106. X
  107. X        Richard Hargrove, 25 June 1988
  108. X    ...!{ihnp4 | codas | cbosgd}!killer!richardh
  109. X    --------------------------------------------
  110. SHAR_EOF
  111. chmod 0666 1st_read.me || echo "restore of 1st_read.me fails"
  112. sed 's/^X//' << 'SHAR_EOF' > bltins.c &&
  113. X
  114. X/*    bltins.c    hexcalc built-in functions
  115. X */
  116. X
  117. X#include "hexcalc.h"
  118. X
  119. X/******************************************************************************/
  120. XBASE_TYPE dec(val)
  121. XBASE_TYPE val;
  122. X{
  123. X    printf("\t%lu\n", val);
  124. X    return val;
  125. X}
  126. X
  127. X/******************************************************************************/
  128. X
  129. XBASE_TYPE oct(val)
  130. XBASE_TYPE val;
  131. X{
  132. X    printf("\t%lo\n", val);
  133. X    return val;
  134. X}
  135. X
  136. X/******************************************************************************/
  137. X
  138. XBASE_TYPE hex(val)
  139. XBASE_TYPE val;
  140. X{
  141. X    printf("\t%lx\n", val);
  142. X    return val;
  143. X}
  144. SHAR_EOF
  145. chmod 0666 bltins.c || echo "restore of bltins.c fails"
  146. sed 's/^X//' << 'SHAR_EOF' > hctest01.txt &&
  147. X# simple expression evaluation test
  148. X
  149. X## numeric literals (12345678  fedcba98)
  150. X12345678
  151. X0fedcba98
  152. X
  153. X## assignment: assigning values to a and b (no output)
  154. Xa=0deaddead
  155. Xb=2bad2bad
  156. X
  157. X## a (deaddead)
  158. Xa
  159. X## b (2bad2bad)
  160. Xb
  161. X
  162. X## a << 3 (f56ef568)
  163. Xa << 3
  164. X## a >> 4 (deaddea); note unsigned shift 
  165. Xa >> 4
  166. X
  167. X## a | b (ffadffad)
  168. Xa | b
  169. X
  170. X## a ^ b (f500f500)
  171. Xa ^ b
  172. X
  173. X## a & b (aad0aad)
  174. Xa & b
  175. X
  176. X## reassigning values to a and b
  177. Xa = 0dead
  178. Xb = 2bad
  179. X## a + b (10a5a)
  180. Xa + b
  181. X
  182. X## a - b (b300)
  183. Xa - b
  184. X
  185. X## b - a (ffff4d00)
  186. Xb - a
  187. X
  188. X## a * b (25fd89e9)
  189. Xa * b
  190. X
  191. X## a / b (5)
  192. Xa / b
  193. X
  194. X## a % b (44c)
  195. Xa % b
  196. X
  197. X## b ** 2 (77392e9)
  198. Xb ** 2
  199. X
  200. X## a + b * 345 (8fab4e)
  201. Xa + b * 345
  202. X
  203. X## (a + b) * 345 (366d842)
  204. X(a + b) * 345
  205. X
  206. X## quitting
  207. Xexit
  208. SHAR_EOF
  209. chmod 0666 hctest01.txt || echo "restore of hctest01.txt fails"
  210. sed 's/^X//' << 'SHAR_EOF' > hctest02.txt &&
  211. X# hexcalc test script - test the commands, built-in functions, and both
  212. X# silent and echoing comments
  213. X
  214. Xhelp            ## help
  215. XHELP            ## HELP
  216. Xa=1000            # init a
  217. Xb=8888            # init b
  218. Xa+b            ## hex default: a + b (9888)
  219. XOCT(DEC(a+b))        ## 39048 114210  9888
  220. Xdec
  221. Xa+b            ## dec default: a + b (39048)
  222. XOCT(HEX(a+b))        ## 9888  114210  39048
  223. Xoct
  224. Xa+b            ## oct default: a + b (114210)
  225. XDEC(HEX(a+b))        ## 9888  39048    114210
  226. Xquit            ## quitting
  227. SHAR_EOF
  228. chmod 0666 hctest02.txt || echo "restore of hctest02.txt fails"
  229. sed 's/^X//' << 'SHAR_EOF' > hexcalc.h &&
  230. X
  231. X/*    hexcalc.h    include file supporting the calculator utility hexcalc
  232. X */
  233. X
  234. X#ifdef DEBUG
  235. X#define STATIC
  236. X#else
  237. X#define STATIC static
  238. X#endif
  239. X
  240. Xtypedef unsigned long BASE_TYPE;
  241. X
  242. XBASE_TYPE dec(), oct(), hex();
  243. XBASE_TYPE ulpow();
  244. X
  245. Xtypedef struct Symbol        /* symbol table entry */
  246. X{
  247. X    char *name;
  248. X    short type;        /* VAR, BLTIN, UNDEF */
  249. X    union
  250. X    {
  251. X        BASE_TYPE val;    /* if VAR */
  252. X        BASE_TYPE (*ptr)();    /* if BLTIN */
  253. X    } u;
  254. X    struct Symbol *next;    /* to link to another */
  255. X} Symbol;
  256. X
  257. XSymbol *install(), *lookup();
  258. SHAR_EOF
  259. chmod 0666 hexcalc.h || echo "restore of hexcalc.h fails"
  260. sed 's/^X//' << 'SHAR_EOF' > hexcalc.man &&
  261. X
  262. X
  263. X
  264. X    HEXCALC(1)                                                    HEXCALC(1)
  265. X
  266. X
  267. X
  268. X    NAME
  269. X        hexcalc - interactive hexadecimal calculator
  270. X
  271. X    SYNOPSIS
  272. X        hexcalc
  273. X
  274. X    DESCRIPTION
  275. X        Hexcalc reads standard input for a sequence of expressions and
  276. X        commands. Expressions are evaluated and the result is output in
  277. X        the default radix on standard output. Commands are executed,
  278. X        producing their defined action.
  279. X
  280. X        Expressions are made up of the following operands and operators:
  281. X
  282. X        Operands:       Numeric literals; in the default radix, must begin
  283. X                        with a digit (for example, 0cc01e).
  284. X
  285. X                        Variables; initialized with an assignment operation,
  286. X                        31 significant chars max.
  287. X
  288. X                        Built-in functions:
  289. X                        name            description
  290. X                        ---------       -----------
  291. X                        DEC(expr)       output decimal value of expr
  292. X                        OCT(expr)       output octal value of expr
  293. X                        HEX(expr)       output hex value of expr
  294. X
  295. X        Operators (highest to lowest precedence):
  296. X                        operator        description
  297. X                        --------        -----------
  298. X                        (  )            grouping
  299. X                        **              exponentiation
  300. X                        -  ~            unary minus, bitwise not
  301. X                        *  /  %         multiplication, division, modulus
  302. X                        +  -            addition, subtraction
  303. X                        <<  >>          left-shift, right-shift
  304. X                        &               bitwise and
  305. X                        ^               bitwise exclusive-or
  306. X                        |               bitwise or
  307. X                        =               assignment
  308. X
  309. X        The following commands are supported:
  310. X                        name            description
  311. X                        ----------      -----------
  312. X                        help  HELP      print a help message
  313. X                        quit  exit      terminate execution
  314. X                        hex dec oct     set the default radix
  315. X
  316. X        If assignment is the last operation performed when evaluating an
  317. X        expression, nothing is output.
  318. X
  319. X
  320. X
  321. X
  322. X
  323. X                                     [ 1 ]
  324. X
  325. X
  326. X    HEXCALC(1)                                                    HEXCALC(1)
  327. X
  328. X
  329. X
  330. X        Hexcalc also recognizes and ignores comments. Comments begin with
  331. X        either a '#' character or a '##' character pair and are terminated
  332. X        by a newline. Comments beginning with a single '#' are called non-
  333. X        echoing and are completely ignored. Comments beginning with a '##'
  334. X        pair are called echoing comments and are output to stdout, beginning
  335. X        with the second '#', without modification. While comments make
  336. X        little sense when using hexcalc interactively, they can be used in
  337. X        files that are fed to stdin to good effect.
  338. X
  339. X        The _rationale_ behind the current built-in functions is to allow
  340. X        the capture of intermediate results in the output stream as well as
  341. X        modifying the default radix for the results of expression
  342. X        evaluation. Note that they are functions which return the input
  343. X        value as a result so they can be used as operands in more complex
  344. X        expressions.
  345. X
  346. X        The initial default radix is hexadecimal.
  347. X
  348. X    NOTES
  349. X        Hexcalc is based on hoc3, a calculator program that can be found in
  350. X        _The Unix Programming Environment_ by Brian W. Kernighan and Rob
  351. X        Pike, chapter 8. The entire chapter is an exposition of a method of
  352. X        organizing a software development project which develops six
  353. X        different, and successively more complex, versions of hoc, a
  354. X        calculator program. It also serves as an excellent introduction to
  355. X        and tutorial for yacc(1).
  356. X
  357. X    AUTHOR
  358. X        Richard Hargrove
  359. X        25 June 1988
  360. X
  361. X
  362. X
  363. X
  364. X
  365. X
  366. X
  367. X
  368. X
  369. X
  370. X
  371. X
  372. X
  373. X
  374. X
  375. X
  376. X
  377. X
  378. X
  379. X
  380. X
  381. X
  382. X
  383. X
  384. X
  385. X
  386. X                                     [ 2 ]
  387. SHAR_EOF
  388. chmod 0666 hexcalc.man || echo "restore of hexcalc.man fails"
  389. sed 's/^X//' << 'SHAR_EOF' > hexcalc.y &&
  390. X%{
  391. X#include "hexcalc.h"
  392. X%}
  393. X
  394. X%union            /* stack type */
  395. X{
  396. X  BASE_TYPE val;    /* actual value */
  397. X  Symbol *sym;        /* symbol table pointer */
  398. X}
  399. X
  400. X%token    <val>    NUMBER
  401. X%token    <sym>    CONST VAR BLTIN UNDEF QUIT HELP CHRADIX
  402. X%type    <val>    expr asgn
  403. X%right    '='
  404. X%left    '|'
  405. X%left    '^'
  406. X%left    '&'
  407. X%left    LSH RSH
  408. X%left    '+' '-'
  409. X%left    '*' '/' '%'
  410. X%left    UNARYMINUS '~'
  411. X%right    POW        /* exponentiation */
  412. X
  413. X%%
  414. Xlist:          /* nothing */
  415. X        | list '\n'
  416. X        | list asgn '\n'
  417. X        | list expr '\n'    { 
  418. X                      if (radix == 16)
  419. X                        printf ("\t%lx\n", $2);
  420. X                      else if (radix == 10)
  421. X                        printf ("\t%lu\n", $2);
  422. X                      else
  423. X                        printf ("\t%lo\n", $2);
  424. X                    }
  425. X        | list HELP '\n'        { puthelp(); }
  426. X        | list QUIT '\n'        { longjmp (prog_end, 1); }
  427. X        | list CHRADIX '\n'    {
  428. X                      if (*($2->name) == 'h')
  429. X                        radix = 16; 
  430. X                      else if (*($2->name) == 'd')
  431. X                        radix = 10; 
  432. X                      else
  433. X                        radix = 8; 
  434. X                    }
  435. X        | list error '\n'    { yyerrok; }
  436. X        ;
  437. Xasgn:          VAR '=' expr        { $$ = $1->u.val = $3; $1->type = VAR; }
  438. X        ;
  439. Xexpr:          NUMBER        { $$ = $1; }
  440. X        | CONST            { $$ = $1->u.val; }
  441. X        | VAR            { 
  442. X            if ($1->type == UNDEF)
  443. X                execerror ("undefined variable", $1->name);
  444. X            $$ = $1->u.val; }
  445. X        | asgn
  446. X        | BLTIN '(' expr ')'    { $$ = (*($1->u.ptr))($3); }
  447. X        | expr LSH expr     { $$ = $1 << $3; }
  448. X        | expr RSH expr     { $$ = $1 >> $3; }
  449. X        | expr '|' expr         { $$ = $1 | $3; }
  450. X        | expr '^' expr         { $$ = $1 ^ $3; }
  451. X        | expr '&' expr         { $$ = $1 & $3; }
  452. X        | expr '+' expr        { $$ = $1 + $3; }
  453. X        | expr '-' expr        { $$ = $1 - $3; }
  454. X        | expr '*' expr        { $$ = $1 * $3; }
  455. X        | expr '/' expr        {    
  456. X            if ($3 == 0)
  457. X                execerror ("division by zero", (char *)0);
  458. X            $$ = $1 / $3; }
  459. X        | expr '%' expr        {    
  460. X            if ($3 == 0)
  461. X                execerror ("modulo zero", (char *)0);
  462. X            $$ = $1 % $3; }
  463. X        | expr POW expr     { $$ = ulpow ($1, $3); }
  464. X        | '(' expr ')'        { $$ = $2; }
  465. X        | '-' expr %prec UNARYMINUS { $$ = -$2; }
  466. X        | '~' expr              { $$ = ~ $2; }
  467. X        ;
  468. X%%
  469. X
  470. X#include <stdio.h>
  471. X#include <setjmp.h>
  472. X
  473. Xchar *progname;        /* for error messages */
  474. Xint lineno = 1;
  475. Xint radix = 16;
  476. X
  477. XSTATIC char *credit =
  478. X"hexcalc 1.1 by Richard Hargrove, 25 June 1988; based on hoc3 from Kernighan and Pike";
  479. X
  480. Xjmp_buf prog_begin, prog_end;
  481. X
  482. X/******************************************************************************/
  483. X
  484. Xvoid puthelp()
  485. X{
  486. X    static char *help_text[] = {
  487. X    "Type in an expression or command. Expressions other than assignment",
  488. X    "cause the evaluated result to be output. All values are 32-bit integers.",
  489. X    "Expressions are made up of the following operands and operators:",
  490. X    "",
  491. X    "Operands: numeric literals (must begin with a digit), variables",
  492. X    "(31 chars max, initialized with assignment), and built-in functions.",
  493. X    "Built-ins:    DEC(expr)    output decimal value of expr",
  494. X    "        OCT(expr)    output octal value of expr",
  495. X    "        HEX(expr)    output hex value of expr",
  496. X    "Operators:    (  )        grouping",
  497. X    "        **        exponentiation",
  498. X    "        -  ~        unary minus, bitwise not",
  499. X    "        *  /  %        multiplication, division, modulus",
  500. X    "        +  -        addition, subtraction",
  501. X    "        <<  >>        left-shift, right-shift",
  502. X    "        &        bitwise and",
  503. X    "        ^        bitwise exclusive-or",
  504. X    "        |        bitwise or",
  505. X    "        =        assignment",
  506. X    "",
  507. X    "Commands:    help  HELP    print this message",
  508. X    "        quit  exit    terminate execution",
  509. X    "        hex dec oct    set the default radix",
  510. X    (char *)0
  511. X    };
  512. X    int i = 0;
  513. X
  514. X    while (help_text[i] != (char *)0)
  515. X    {
  516. X      puts(help_text[i++]);
  517. X    }
  518. X}
  519. X
  520. X/******************************************************************************/
  521. X
  522. Xvoid warning (s, t)    /* print warning message */
  523. Xchar *s, *t;
  524. X{
  525. X    fprintf (stderr, "%s : %s", progname, s);
  526. X    if (t != (char *)0)
  527. X    {
  528. X        fprintf (stderr, " %s", t);
  529. X    }
  530. X    fprintf (stderr, " near line %d\n", lineno);
  531. X}
  532. X
  533. X
  534. X/******************************************************************************/
  535. X
  536. Xvoid yyerror (s)    /* called for yacc syntax error */
  537. Xchar *s;
  538. X{
  539. X    warning (s, (char *)0);
  540. X}
  541. X
  542. X/******************************************************************************/
  543. X
  544. Xvoid execerror (s, t)
  545. Xchar *s, *t;
  546. X{
  547. X    warning (s, t);
  548. X    longjmp (prog_begin, 1);
  549. X}
  550. X
  551. X/******************************************************************************/
  552. X
  553. Xmain (argc, argv)
  554. Xint argc;
  555. Xchar *argv [];
  556. X{
  557. X    progname = argv [0];
  558. X    init ();
  559. X    if (setjmp (prog_end) == 0)
  560. X    {
  561. X        (void)setjmp (prog_begin);
  562. X        yyparse ();
  563. X    }
  564. X    return 0;
  565. X}
  566. SHAR_EOF
  567. chmod 0666 hexcalc.y || echo "restore of hexcalc.y fails"
  568. sed 's/^X//' << 'SHAR_EOF' > init.c &&
  569. X
  570. X/*    init.c        hexcalc initilization code
  571. X */
  572. X
  573. X#include "hexcalc.h"
  574. X#ifdef __TURBOC__
  575. X#include "ytab.h"
  576. X#else
  577. X#include "y.tab.h"
  578. X#endif
  579. X
  580. XSTATIC struct        /* constants */
  581. X{
  582. X    char *name;
  583. X    BASE_TYPE cval;
  584. X} consts[] = 
  585. X    {
  586. X        (char *)0,        (BASE_TYPE)0
  587. X    };
  588. X
  589. XSTATIC struct        /* built-ins */
  590. X{
  591. X    char *name;
  592. X    BASE_TYPE (*func)();
  593. X} builtins[] = 
  594. X    {
  595. X        "DEC",        dec,
  596. X        "OCT",        oct,
  597. X        "HEX",        hex,
  598. X        (char *)0,    (BASE_TYPE(*)())0
  599. X    };
  600. X
  601. XSTATIC struct         /* keywords */
  602. X{
  603. X    char *name;
  604. X    short token;
  605. X} keywords[] =
  606. X    {
  607. X        "oct",        CHRADIX,
  608. X        "HELP",        HELP,
  609. X        "exit",         QUIT,
  610. X        "help",        HELP,
  611. X        "quit",         QUIT,
  612. X        "dec",        CHRADIX,
  613. X        "hex",        CHRADIX,
  614. X        (char *)0,    0
  615. X    };
  616. X
  617. X/******************************************************************************/
  618. X
  619. Xinit()        /* install keywords, constants, and built-ins in table */
  620. X{
  621. X    int i;
  622. X    Symbol *s;
  623. X
  624. X    for (i=0; keywords [i].name != (char *)0; ++i)
  625. X    {
  626. X        install (keywords [i].name, keywords [i].token, (BASE_TYPE)0);
  627. X    }
  628. X    for (i=0; consts [i].name != (char *)0; ++i)
  629. X    {
  630. X        install (consts [i].name, CONST, consts [i].cval);
  631. X    }
  632. X    for (i=0; builtins [i].name != (char *)0; ++i)
  633. X    {
  634. X        s = install (builtins [i].name, BLTIN, (BASE_TYPE)0);
  635. X        s->u.ptr = builtins [i].func;
  636. X    }
  637. X}
  638. SHAR_EOF
  639. chmod 0666 init.c || echo "restore of init.c fails"
  640. sed 's/^X//' << 'SHAR_EOF' > makefile.dos &&
  641. X
  642. X# makefile for hexcalc - works with MKS Toolkit yacc, Turbo C, and Turbo Make.
  643. X# Will work with other Unix make-like MAKEs (such as NDMAKE).
  644. X
  645. X# macros
  646. X
  647. XOBJS=hexcalc.obj init.obj bltins.obj ulpow.obj symbol.obj yylex.obj
  648. XYACC=yacc
  649. XYFLAGS=-d
  650. XCC=tcc
  651. XCFLAGS=
  652. X
  653. X# implicit rules (Turbo Make doesn't have ANY predefined implicit rules)
  654. X
  655. X.c.obj :
  656. X    $(CC) -c $<
  657. X
  658. X# MKS yacc generates inline assembler for small model Turbo C !
  659. X
  660. X.y.obj :
  661. X    $(YACC) $(YFLAGS) $<
  662. X    $(CC) $(CFLAGS) -B -c ytab.c
  663. X    mv ytab.obj $&.obj
  664. X
  665. X# dependencies
  666. X
  667. Xhexcalc.exe : $(OBJS)
  668. X    $(CC) $(CFLAGS) -ehexcalc.exe $(OBJS)
  669. X
  670. Xinit.obj : hexcalc.h ytab.h
  671. X
  672. Xyylex.obj : hexcalc.h ytab.h
  673. X
  674. Xytab.h : hexcalc.y
  675. X
  676. Xsymbol.obj : hexcalc.h
  677. X
  678. Xbltins.obj : hexcalc.h
  679. X
  680. Xulpow.obj : hexcalc.h
  681. X
  682. Xhexcalc.obj : hexcalc.h
  683. X
  684. Xclean :
  685. X    rm -f $(OBJS) *.map ytab.[ch]
  686. SHAR_EOF
  687. chmod 0666 makefile.dos || echo "restore of makefile.dos fails"
  688. sed 's/^X//' << 'SHAR_EOF' > makefile.unx &&
  689. X
  690. X# Unix makefile for hexcalc
  691. X
  692. X# macros
  693. X
  694. XOBJS=hexcalc.o init.o bltins.o ulpow.o symbol.o yylex.o
  695. XCFLAGS=-O
  696. XYFLAGS=-d
  697. X
  698. X# browser utility used to verify test results
  699. X# more(1) or pg(1) are alternatives
  700. XBROWSER=less
  701. X
  702. X# implicit rules
  703. X
  704. X.y.o:                # modify default to keep y.tab.c lying around
  705. X    $(YACC) $(YFLAGS) $<
  706. X    $(CC) $(CFLAGS) -c y.tab.c
  707. X    mv y.tab.o $@
  708. X
  709. X# dependencies
  710. X
  711. Xhexcalc : $(OBJS)
  712. X    $(CC) $(CFLAGS) -o hexcalc $(OBJS)
  713. X
  714. Xinit.o : hexcalc.h y.tab.h
  715. X
  716. Xyylex.o : hexcalc.h y.tab.h
  717. X
  718. Xy.tab.h : hexcalc.y
  719. X
  720. Xsymbol.o : hexcalc.h
  721. X
  722. Xbltins.o : hexcalc.h
  723. X
  724. Xulpow.o : hexcalc.h
  725. X
  726. Xhexcalc.o : hexcalc.h
  727. X
  728. Xtest :
  729. X    hexcalc <hctest01.txt | $(BROWSER)
  730. X    hexcalc <hctest02.txt | $(BROWSER)
  731. X
  732. Xlint :
  733. X    lint y.tab.c init.c bltins.c ulpow.c symbol.c yylex.c
  734. X
  735. Xclean :
  736. X    rm -f $(OBJS) y.tab.[ch]
  737. SHAR_EOF
  738. chmod 0666 makefile.unx || echo "restore of makefile.unx fails"
  739. sed 's/^X//' << 'SHAR_EOF' > symbol.c &&
  740. X
  741. X/*    symbol.c    hexcalc symbol table management routines
  742. X */
  743. X
  744. X#include <string.h>
  745. X#include "hexcalc.h"
  746. X
  747. X/* head ptr for the symbol table linked list */
  748. XSTATIC Symbol *symlist = (Symbol *)0;
  749. X
  750. X/******************************************************************************/
  751. X
  752. XSymbol *lookup (s)
  753. Xchar *s;
  754. X{
  755. X    Symbol *sp;
  756. X
  757. X    for (sp = symlist; sp != (Symbol *)0; sp = sp->next)
  758. X    {
  759. X        if (strcmp (sp->name, s) == 0) return sp;
  760. X    }
  761. X    return (Symbol *)0;
  762. X}
  763. X
  764. X/******************************************************************************/
  765. X
  766. Xchar *emalloc (n)
  767. Xunsigned n;
  768. X{
  769. X    void *p, *malloc();
  770. X
  771. X    if ((p = malloc (n)) == (void *)0)
  772. X    {
  773. X        execerror ("out of memory", (char *)0);
  774. X    }
  775. X    return (char *)p;
  776. X}
  777. X
  778. X/******************************************************************************/
  779. X
  780. XSymbol *install (s, t, l)    /* install s in symbol table */
  781. Xchar *s;
  782. Xint t;
  783. XBASE_TYPE l;
  784. X{
  785. X    Symbol *sp = (Symbol *)emalloc (sizeof(Symbol));
  786. X
  787. X    sp->name = (char *)emalloc (strlen (s) + 1);    /* + 1 for '\0' */
  788. X    strcpy (sp->name, s);
  789. X    sp->type = t;
  790. X    sp->u.val = l;
  791. X    sp->next = symlist;
  792. X    symlist = sp;
  793. X    return sp;
  794. X}
  795. SHAR_EOF
  796. chmod 0666 symbol.c || echo "restore of symbol.c fails"
  797. sed 's/^X//' << 'SHAR_EOF' > ulpow.c &&
  798. X
  799. X/*    ulpow -- BASE_TYPE exponentiation (no overflow detection)
  800. X *
  801. X *    Based on lpow() code distributed by Doug Gwyn
  802. X */
  803. X
  804. X#include "hexcalc.h"            /* contains BASE_TYPE typedef */
  805. X
  806. XBASE_TYPE ulpow(base, exponent)        /* returns base^exponent */
  807. XBASE_TYPE base;
  808. XBASE_TYPE exponent;
  809. X{
  810. X    BASE_TYPE result;        /* result accumulator */
  811. X
  812. X    /* handle simple special cases separately: */
  813. X    if (exponent == 0)
  814. X    {
  815. X        return 1;        /* includes 0^0 */
  816. X    }
  817. X    else if (base == 0)
  818. X    {
  819. X        return 0;        /* exp. < 0 should be EDOM */
  820. X    }
  821. X    else if (base == 1)
  822. X    {
  823. X        return 1;
  824. X    }
  825. X    else if (base == -1)
  826. X    {
  827. X#if 0    /* intended code: */
  828. X        return exponent % 2 == 0 ? 1 : -1;
  829. X#else    /* faster equivalent (suggested by Dan Levy of Teletype): */
  830. X        return (exponent & 1) == 0 ? 1 : -1;
  831. X#endif
  832. X    }
  833. X    else if (exponent < 0)
  834. X    {
  835. X        return 0;
  836. X    }
  837. X
  838. X    /* general case with exponent > 0: */
  839. X    result = 1;
  840. X    for ( ; ; )    /* LOOP INVARIANT: result*base^exponent */
  841. X    {
  842. X#if 0    /* intended code: */
  843. X        if (exponent % 2 != 0)
  844. X#else    /* faster equivalent (suggested by Dan Levy of Teletype): */
  845. X        if ((exponent & 1) != 0)
  846. X#endif
  847. X        {
  848. X            result *= base;
  849. X        }
  850. X#if 0    /* intended code: */
  851. X        if ((exponent /= 2) == 0)
  852. X#else    /* faster equivalent (suggested by Dan Levy of Teletype): */
  853. X        if ((exponent >>= 1) == 0)
  854. X#endif
  855. X        {
  856. X            break;        /* result now stable */
  857. X        }
  858. X        base *= base;
  859. X    }
  860. X
  861. X    return result;
  862. X}
  863. SHAR_EOF
  864. chmod 0666 ulpow.c || echo "restore of ulpow.c fails"
  865. sed 's/^X//' << 'SHAR_EOF' > ytab.c &&
  866. X/* C:/BIN\YACC.EXE -d hexcalc.y */
  867. X#line 1 "hexcalc.y"
  868. X
  869. X#include "hexcalc.h"
  870. Xtypedef union {
  871. X  BASE_TYPE val;    /* actual value */
  872. X  Symbol *sym;        /* symbol table pointer */
  873. X} YYSTYPE;
  874. X#define NUMBER    257
  875. X#define CONST    258
  876. X#define VAR    259
  877. X#define BLTIN    260
  878. X#define UNDEF    261
  879. X#define QUIT    262
  880. X#define HELP    263
  881. X#define CHRADIX    264
  882. X#define LSH    265
  883. X#define RSH    266
  884. X#define UNARYMINUS    267
  885. X#define POW    268
  886. Xextern int yychar, yyerrflag;
  887. Xextern YYSTYPE yyval, yylval;
  888. X#line 81
  889. X#include <stdio.h>
  890. X#include <setjmp.h>
  891. X
  892. Xchar *progname;        /* for error messages */
  893. Xint lineno = 1;
  894. Xint radix = 16;
  895. X
  896. XSTATIC char *credit =
  897. X"hexcalc 1.1 by Richard Hargrove, 25 June 1988; based on hoc3 from Kernighan and Pike";
  898. X
  899. Xjmp_buf prog_begin, prog_end;
  900. X
  901. X/******************************************************************************/
  902. X
  903. Xvoid puthelp()
  904. X{
  905. X    static char *help_text[] = {
  906. X    "Type in an expression or command. Expressions other than assignment",
  907. X    "cause the evaluated result to be output. All values are 32-bit integers.",
  908. X    "Expressions are made up of the following operands and operators:",
  909. X    "",
  910. X    "Operands: numeric literals (must begin with a digit), variables",
  911. X    "(31 chars max, initialized with assignment), and built-in functions.",
  912. X    "Built-ins:    DEC(expr)    output decimal value of expr",
  913. X    "        OCT(expr)    output octal value of expr",
  914. X    "        HEX(expr)    output hex value of expr",
  915. X    "Operators:    (  )        grouping",
  916. X    "        **        exponentiation",
  917. X    "        -  ~        unary minus, bitwise not",
  918. X    "        *  /  %        multiplication, division, modulus",
  919. X    "        +  -        addition, subtraction",
  920. X    "        <<  >>        left-shift, right-shift",
  921. X    "        &        bitwise and",
  922. X    "        ^        bitwise exclusive-or",
  923. X    "        |        bitwise or",
  924. X    "        =        assignment",
  925. X    "",
  926. X    "Commands:    help  HELP    print this message",
  927. X    "        quit  exit    terminate execution",
  928. X    "        hex dec oct    set the default radix",
  929. X    (char *)0
  930. X    };
  931. X    int i = 0;
  932. X
  933. X    while (help_text[i] != (char *)0)
  934. X    {
  935. X      puts(help_text[i++]);
  936. X    }
  937. X}
  938. X
  939. X/******************************************************************************/
  940. X
  941. Xvoid warning (s, t)    /* print warning message */
  942. Xchar *s, *t;
  943. X{
  944. X    fprintf (stderr, "%s : %s", progname, s);
  945. X    if (t != (char *)0)
  946. X    {
  947. X        fprintf (stderr, " %s", t);
  948. X    }
  949. X    fprintf (stderr, " near line %d\n", lineno);
  950. X}
  951. X
  952. X
  953. X/******************************************************************************/
  954. X
  955. Xvoid yyerror (s)    /* called for yacc syntax error */
  956. Xchar *s;
  957. X{
  958. X    warning (s, (char *)0);
  959. X}
  960. X
  961. X/******************************************************************************/
  962. X
  963. Xvoid execerror (s, t)
  964. Xchar *s, *t;
  965. X{
  966. X    warning (s, t);
  967. X    longjmp (prog_begin, 1);
  968. X}
  969. X
  970. X/******************************************************************************/
  971. X
  972. Xmain (argc, argv)
  973. Xint argc;
  974. Xchar *argv [];
  975. X{
  976. X    progname = argv [0];
  977. X    init ();
  978. X    if (setjmp (prog_end) == 0)
  979. X    {
  980. X        (void)setjmp (prog_begin);
  981. X        yyparse ();
  982. X    }
  983. X    return 0;
  984. X}
  985. Xstatic short yydef[] = {
  986. X      -1,    4,   30,   17,   16,    3,   15,   14,   13,   12, 
  987. X      11,   10,    9,    8,    7,    6,    5
  988. X};
  989. Xstatic short yyex[] = {
  990. X       0,    0,   -1,    1
  991. X};
  992. Xstatic short yyact[] = {
  993. X     -52,  -39,  -40,  -41,  -37,  -45,  -44,   -2,  -38,  -35, 
  994. X     -34,  -36,  264,  263,  262,  260,  259,  258,  257,  256, 
  995. X     126,   45,   40,   10,  -39,  -40,  -41,  -45,  -44,   -2, 
  996. X     -38,  260,  259,  258,  257,  126,   45,   40,  -31,   40, 
  997. X     -30,   61,  -46,   10,  -47,   10,  -48,   10,  -49,   10, 
  998. X     -50,  -28,  -23,  -26,  -24,  -25,  -27,  -22,  -21,  -19, 
  999. X     -20,  -29,  268,  266,  265,  124,   94,   47,   45,   43, 
  1000. X      42,   38,   37,   10,  -53,   10,  -29,  268,  -28,  -23, 
  1001. X     -42,  -26,  -24,  -25,  -27,  -22,  -21,  -19,  -20,  -29, 
  1002. X     268,  266,  265,  124,   94,   47,   45,   43,   42,   41, 
  1003. X      38,   37,  -28,  -23,  -43,  -26,  -24,  -25,  -27,  -22, 
  1004. X     -21,  -19,  -20,  -29,  268,  266,  265,  124,   94,   47, 
  1005. X      45,   43,   42,   41,   38,   37,  -28,  -23,  -26,  -24, 
  1006. X     -25,  -27,  -22,  -21,  -19,  -20,  -29,  268,  266,  265, 
  1007. X     124,   94,   47,   45,   43,   42,   38,   37,  -28,  -26, 
  1008. X     -27,  -29,  268,   47,   42,   37,  -28,  -26,  -24,  -25, 
  1009. X     -27,  -19,  -20,  -29,  268,  266,  265,   47,   45,   43, 
  1010. X      42,   37,  -28,  -23,  -26,  -24,  -25,  -27,  -19,  -20, 
  1011. X     -29,  268,  266,  265,   47,   45,   43,   42,   38,   37, 
  1012. X     -28,  -23,  -26,  -24,  -25,  -27,  -22,  -19,  -20,  -29, 
  1013. X     268,  266,  265,   94,   47,   45,   43,   42,   38,   37, 
  1014. X     -28,  -26,  -24,  -25,  -27,  -29,  268,   47,   45,   43, 
  1015. X      42,   37,   -1
  1016. X};
  1017. Xstatic short yypact[] = {
  1018. X      12,   41,   75,   77,   77,  137,   77,   77,   77,   77, 
  1019. X     152,  152,  164,  181,  200,  216,  216,  114,   31,   31, 
  1020. X      31,   31,   31,   31,   31,   31,   31,   31,   31,   31, 
  1021. X      31,   90,   62,   49,   47,   45,   43,   39,   31,   31,   31
  1022. X};
  1023. Xstatic short yygo[] = {
  1024. X     -17,  -16,  -15,  -14,  -13,  -12,  -11,  -10,   -9,   -8, 
  1025. X      -7,   -6,  -18,  -32,   -5,   -4,  -33,   40,   39,   38, 
  1026. X      30,   29,   28,   27,   26,   25,   24,   23,   22,   21, 
  1027. X      20,   19,   18,   -3,  -54,    0,   -1,   -1
  1028. X};
  1029. Xstatic short yypgo[] = {
  1030. X       0,    0,    0,   34,   16,   16,   16,   16,   16,   16, 
  1031. X      16,   16,   16,   16,   16,   16,   16,   16,   16,   16, 
  1032. X      16,   16,   36,   36,   36,   36,   36,   36,   36,   36, 
  1033. X      16,    0
  1034. X};
  1035. Xstatic short yyrlen[] = {
  1036. X       0,    0,    0,    3,    1,    3,    3,    3,    3,    3, 
  1037. X       3,    3,    3,    3,    3,    3,    2,    2,    3,    4, 
  1038. X       1,    1,    3,    3,    3,    3,    3,    0,    2,    3, 
  1039. X       1,    2
  1040. X};
  1041. X#define YYS0    50
  1042. X#define YYDELTA    23
  1043. X#define YYNPACT    41
  1044. X#define YYNDEF    17
  1045. X
  1046. X#define YYr29    0
  1047. X#define YYr30    1
  1048. X#define YYr31    2
  1049. X#define YYr9    3
  1050. X#define YYr12    4
  1051. X#define YYr15    5
  1052. X#define YYr16    6
  1053. X#define YYr17    7
  1054. X#define YYr18    8
  1055. X#define YYr19    9
  1056. X#define YYr20    10
  1057. X#define YYr21    11
  1058. X#define YYr22    12
  1059. X#define YYr23    13
  1060. X#define YYr24    14
  1061. X#define YYr25    15
  1062. X#define YYr27    16
  1063. X#define YYr28    17
  1064. X#define YYr26    18
  1065. X#define YYr14    19
  1066. X#define YYr11    20
  1067. X#define YYr10    21
  1068. X#define YYr8    22
  1069. X#define YYr7    23
  1070. X#define YYr6    24
  1071. X#define YYr5    25
  1072. X#define YYr4    26
  1073. X#define YYrACCEPT    YYr29
  1074. X#define YYrERROR    YYr30
  1075. X#define YYrLR2    YYr31
  1076. X#line 2 "yacc parser: c:/etc/yyparse.c"
  1077. X
  1078. X/*
  1079. X * Automaton to interpret LALR(1) tables.
  1080. X *
  1081. X *    Macros:
  1082. X *        yyclearin - clear the lookahead token.
  1083. X *        yyerrok - forgive a pending error
  1084. X *        YYERROR - simulate an error
  1085. X *        YYACCEPT - halt and return 0
  1086. X *        YYABORT - halt and return 1
  1087. X *        YYRETURN(value) - halt and return value.  You should use this
  1088. X *            instead of return(value).
  1089. X *        YYREAD - ensure yychar contains a lookahead token by reading
  1090. X *            one if it does not.  See also YYSYNC.
  1091. X *
  1092. X *    Preprocessor flags:
  1093. X *        YYDEBUG - includes debug code.  The parser will print
  1094. X *             a travelogue of the parse if this is defined
  1095. X *             and yydebug is non-zero.
  1096. X *        YYSSIZE - size of state and value stacks (default 150).
  1097. X *        YYSTATIC - By default, the state stack is an automatic array.
  1098. X *            If this is defined, the stack will be static.
  1099. X *            In either case, the value stack is static.
  1100. X *        YYALLOC - Dynamically allocate both the state and value stacks
  1101. X *            by calling malloc() and free().
  1102. X *        YYLR2 - defined if lookahead is needed to resolve R/R or S/R conflicts
  1103. X *        YYSYNC - if defined, yacc guarantees to fetch a lookahead token
  1104. X *            before any action, even if it doesnt need it for a decision.
  1105. X *            If YYSYNC is defined, YYREAD will never be necessary unless
  1106. X *            the user explicitly sets yychar = -1
  1107. X *
  1108. X *    Copyright (c) 1983, by the University of Waterloo
  1109. X */
  1110. X
  1111. X#ifndef YYSSIZE
  1112. X# define YYSSIZE    150
  1113. X#endif
  1114. X#ifndef    YYDEBUG
  1115. X#define    YYDEBUG    0
  1116. X#endif
  1117. X#define YYERROR        goto yyerrlabel
  1118. X#define yyerrok        yyerrflag = 0
  1119. X#define yyclearin    yychar = -1
  1120. X#define YYACCEPT    YYRETURN(0)
  1121. X#define YYABORT        YYRETURN(1)
  1122. X#ifdef YYALLOC
  1123. X# define YYRETURN(val)    { retval = (val); goto yyReturn; }
  1124. X#else
  1125. X# define YYRETURN(val)    return(val)
  1126. X#endif
  1127. X#if YYDEBUG
  1128. X/* The if..else makes this macro behave exactly like a statement */
  1129. X# define YYREAD    if (yychar < 0) {                    \
  1130. X            if ((yychar = yylex()) < 0)            \
  1131. X                yychar = 0;                \
  1132. X            if (yydebug)                    \
  1133. X                printf("read %s (%d)\n", yyptok(yychar),\
  1134. X                yychar);                \
  1135. X        } else
  1136. X#else
  1137. X# define YYREAD    if (yychar < 0) {                    \
  1138. X            if ((yychar = yylex()) < 0)            \
  1139. X                yychar = 0;                \
  1140. X        } else
  1141. X#endif
  1142. X#define YYERRCODE    256        /* value of `error' */
  1143. X#if __TURBOC__&&__SMALL__
  1144. X#define    YYQYYP    *(int *)((int)yyq + ((int)yyq-(int)yyp))
  1145. X#else
  1146. X#define    YYQYYP    yyq[yyq-yyp]
  1147. X#endif
  1148. X
  1149. XYYSTYPE    yyval,                /* $$ */
  1150. X    *yypvt,                /* $n */
  1151. X    yylval;                /* yylex() sets this */
  1152. X
  1153. Xint    yychar,                /* current token */
  1154. X    yyerrflag,            /* error flag */
  1155. X    yynerrs;            /* error count */
  1156. X
  1157. X#if YYDEBUG
  1158. Xint yydebug = YYDEBUG-0;        /* debug flag & tables */
  1159. Xextern char    *yysvar[], *yystoken[], *yyptok();
  1160. Xextern short    yyrmap[], yysmap[];
  1161. Xextern int    yynstate, yynvar, yyntoken, yynrule;
  1162. X# define yyassert(condition, msg, arg) \
  1163. X    if (!(condition)) { printf("\nyacc bug: "); printf(msg, arg); YYABORT; }
  1164. X#else /* !YYDEBUG */
  1165. X# define yyassert(condition, msg, arg)
  1166. X#endif
  1167. X
  1168. Xyyparse()
  1169. X{
  1170. X
  1171. X    register short        yyi, *yyp;    /* for table lookup */
  1172. X    register short        *yyps;        /* top of state stack */
  1173. X    register short        yystate;    /* current state */
  1174. X    register YYSTYPE    *yypv;        /* top of value stack */
  1175. X    register short        *yyq;
  1176. X    register int        yyj;
  1177. X
  1178. X#ifdef YYSTATIC
  1179. X    static short    yys[YYSSIZE + 1];
  1180. X    static YYSTYPE    yyv[YYSSIZE + 1];
  1181. X#else
  1182. X#ifdef YYALLOC
  1183. X    YYSTYPE *yyv;
  1184. X    short    *yys;
  1185. X    YYSTYPE save_yylval, save_yyval, *save_yypvt;
  1186. X    int save_yychar, save_yyerrflag, save_yynerrs;
  1187. X    int retval;
  1188. X#if 0    /* defined in <stdlib.h>*/
  1189. X    extern char    *malloc();
  1190. X#endif 0
  1191. X#else
  1192. X    short        yys[YYSSIZE + 1];
  1193. X    static YYSTYPE    yyv[YYSSIZE + 1];    /* historically static */
  1194. X#endif
  1195. X#endif
  1196. X
  1197. X#ifdef YYALLOC
  1198. X    yys = (short *) malloc((YYSSIZE + 1) * sizeof(short));
  1199. X    yyv = (YYSTYPE *) malloc((YYSSIZE + 1) * sizeof(YYSTYPE));
  1200. X    if (yys == (short *)0 || yyv == (YYSTYPE *)0) {
  1201. X        yyerror("Not enough space for parser stacks");
  1202. X        return 1;
  1203. X    }
  1204. X    save_yylval = yylval;
  1205. X    save_yyval = yyval;
  1206. X    save_yypvt = yypvt;
  1207. X    save_yychar = yychar;
  1208. X    save_yyerrflag = yyerrflag;
  1209. X    save_yynerrs = yynerrs;
  1210. X#endif
  1211. X
  1212. X    yynerrs = 0;
  1213. X    yyerrflag = 0;
  1214. X    yychar = -1;
  1215. X    yyps = yys;
  1216. X    yypv = yyv;
  1217. X    yystate = YYS0;        /* start state */
  1218. X
  1219. XyyStack:
  1220. X    yyassert((unsigned)yystate < yynstate, "state %d\n", yystate);
  1221. X    if (++yyps > &yys[YYSSIZE]) {
  1222. X        yyerror("Parser stack overflow");
  1223. X        YYABORT;
  1224. X    }
  1225. X    *yyps = yystate;    /* stack current state */
  1226. X    *++yypv = yyval;    /* ... and value */
  1227. X
  1228. X#if YYDEBUG
  1229. X    if (yydebug)
  1230. X        printf("state %d (%d), char %s (%d)\n", yysmap[yystate],
  1231. X            yystate, yyptok(yychar), yychar);
  1232. X#endif
  1233. X
  1234. X    /*
  1235. X     *    Look up next action in action table.
  1236. X     */
  1237. XyyEncore:
  1238. X#ifdef YYSYNC
  1239. X    YYREAD;
  1240. X#endif
  1241. X    if (yystate >= sizeof yypact/sizeof yypact[0])     /* simple state */
  1242. X        yyi = yystate - YYDELTA;    /* reduce in any case */
  1243. X    else {
  1244. X        if(*(yyp = &yyact[yypact[yystate]]) >= 0) {
  1245. X            /* Look for a shift on yychar */
  1246. X#ifndef YYSYNC
  1247. X            YYREAD;
  1248. X#endif
  1249. X            yyq = yyp;
  1250. X            yyi = yychar;
  1251. X#if __TURBOC__&&__SMALL__
  1252. X            /* yyi is in di, yyp is in si */
  1253. X        L01:
  1254. X            asm lodsw    /* ax = *yyp++; */
  1255. X            asm cmp yyi, ax
  1256. X            asm jl L01
  1257. X#else
  1258. X            while (yyi < *yyp++)
  1259. X                ;
  1260. X#endif
  1261. X            if (yyi == yyp[-1]) {
  1262. X                yystate = ~YYQYYP;
  1263. X#if YYDEBUG
  1264. X                if (yydebug)
  1265. X                    printf("shift %d (%d)\n", yysmap[yystate], yystate);
  1266. X#endif
  1267. X                yyval = yylval;        /* stack what yylex() set */
  1268. X                yychar = -1;        /* clear token */
  1269. X                if (yyerrflag)
  1270. X                    yyerrflag--;    /* successful shift */
  1271. X                goto yyStack;
  1272. X            }
  1273. X        }
  1274. X
  1275. X        /*
  1276. X          *    Fell through - take default action
  1277. X          */
  1278. X
  1279. X        if (yystate >= sizeof yydef /sizeof yydef[0])
  1280. X            goto yyError;
  1281. X        if ((yyi = yydef[yystate]) < 0)     { /* default == reduce? */
  1282. X                                            /* Search exception table */
  1283. X            yyassert((unsigned)~yyi < sizeof yyex/sizeof yyex[0],
  1284. X                "exception %d\n", yystate);
  1285. X            yyp = &yyex[~yyi];
  1286. X#ifndef YYSYNC
  1287. X            YYREAD;
  1288. X#endif
  1289. X            while((yyi = *yyp) >= 0 && yyi != yychar)
  1290. X                yyp += 2;
  1291. X            yyi = yyp[1];
  1292. X            yyassert(yyi >= 0,"Ex table not reduce %d\n", yyi);
  1293. X        }
  1294. X    }
  1295. X
  1296. X#ifdef YYLR2
  1297. XyyReduce:    /* reduce yyi */
  1298. X#endif
  1299. X    yyassert((unsigned)yyi < yynrule, "reduce %d\n", yyi);
  1300. X    yyj = yyrlen[yyi];
  1301. X#if YYDEBUG
  1302. X    if (yydebug) printf("reduce %d (%d), pops %d (%d)\n", yyrmap[yyi],
  1303. X        yyi, yysmap[yyps[-yyj]], yyps[-yyj]);
  1304. X#endif
  1305. X    yyps -= yyj;        /* pop stacks */
  1306. X    yypvt = yypv;        /* save top */
  1307. X    yypv -= yyj;
  1308. X    yyval = yypv[1];    /* default action $$ = $1 */
  1309. X    switch (yyi) {        /* perform semantic action */
  1310. X        
  1311. Xcase YYr4: {    /* list :  list expr '\n' */
  1312. X#line 28
  1313. X                      if (radix == 16)
  1314. X                        printf ("\t%lx\n", yypvt[-1].val);
  1315. X                      else if (radix == 10)
  1316. X                        printf ("\t%lu\n", yypvt[-1].val);
  1317. X                      else
  1318. X                        printf ("\t%lo\n", yypvt[-1].val);
  1319. X                    
  1320. X} break;
  1321. X
  1322. Xcase YYr5: {    /* list :  list HELP '\n' */
  1323. X#line 36
  1324. X puthelp(); 
  1325. X} break;
  1326. X
  1327. Xcase YYr6: {    /* list :  list QUIT '\n' */
  1328. X#line 37
  1329. X longjmp (prog_end, 1); 
  1330. X} break;
  1331. X
  1332. Xcase YYr7: {    /* list :  list CHRADIX '\n' */
  1333. X#line 38
  1334. X
  1335. X                      if (*(yypvt[-1].sym->name) == 'h')
  1336. X                        radix = 16; 
  1337. X                      else if (*(yypvt[-1].sym->name) == 'd')
  1338. X                        radix = 10; 
  1339. X                      else
  1340. X                        radix = 8; 
  1341. X                    
  1342. X} break;
  1343. X
  1344. Xcase YYr8: {    /* list :  list error '\n' */
  1345. X#line 46
  1346. X yyerrok; 
  1347. X} break;
  1348. X
  1349. Xcase YYr9: {    /* asgn :  VAR '=' expr */
  1350. X#line 48
  1351. X yyval.val = yypvt[-2].sym->u.val = yypvt[0].val; yypvt[-2].sym->type = VAR; 
  1352. X} break;
  1353. X
  1354. Xcase YYr10: {    /* expr :  NUMBER */
  1355. X#line 50
  1356. X yyval.val = yypvt[0].val; 
  1357. X} break;
  1358. X
  1359. Xcase YYr11: {    /* expr :  CONST */
  1360. X#line 51
  1361. X yyval.val = yypvt[0].sym->u.val; 
  1362. X} break;
  1363. X
  1364. Xcase YYr12: {    /* expr :  VAR */
  1365. X#line 52
  1366. X            if (yypvt[0].sym->type == UNDEF)
  1367. X                execerror ("undefined variable", yypvt[0].sym->name);
  1368. X            yyval.val = yypvt[0].sym->u.val; 
  1369. X} break;
  1370. X
  1371. Xcase YYr14: {    /* expr :  BLTIN '(' expr ')' */
  1372. X#line 57
  1373. X yyval.val = (*(yypvt[-3].sym->u.ptr))(yypvt[-1].val); 
  1374. X} break;
  1375. X
  1376. Xcase YYr15: {    /* expr :  expr LSH expr */
  1377. X#line 58
  1378. X yyval.val = yypvt[-2].val << yypvt[0].val; 
  1379. X} break;
  1380. X
  1381. Xcase YYr16: {    /* expr :  expr RSH expr */
  1382. X#line 59
  1383. X yyval.val = yypvt[-2].val >> yypvt[0].val; 
  1384. X} break;
  1385. X
  1386. Xcase YYr17: {    /* expr :  expr '|' expr */
  1387. X#line 60
  1388. X yyval.val = yypvt[-2].val | yypvt[0].val; 
  1389. X} break;
  1390. X
  1391. Xcase YYr18: {    /* expr :  expr '^' expr */
  1392. X#line 61
  1393. X yyval.val = yypvt[-2].val ^ yypvt[0].val; 
  1394. X} break;
  1395. X
  1396. Xcase YYr19: {    /* expr :  expr '&' expr */
  1397. X#line 62
  1398. X yyval.val = yypvt[-2].val & yypvt[0].val; 
  1399. X} break;
  1400. X
  1401. Xcase YYr20: {    /* expr :  expr '+' expr */
  1402. X#line 63
  1403. X yyval.val = yypvt[-2].val + yypvt[0].val; 
  1404. X} break;
  1405. X
  1406. Xcase YYr21: {    /* expr :  expr '-' expr */
  1407. X#line 64
  1408. X yyval.val = yypvt[-2].val - yypvt[0].val; 
  1409. X} break;
  1410. X
  1411. Xcase YYr22: {    /* expr :  expr '*' expr */
  1412. X#line 65
  1413. X yyval.val = yypvt[-2].val * yypvt[0].val; 
  1414. X} break;
  1415. X
  1416. Xcase YYr23: {    /* expr :  expr '/' expr */
  1417. X#line 66
  1418. X    
  1419. X            if (yypvt[0].val == 0)
  1420. X                execerror ("division by zero", (char *)0);
  1421. X            yyval.val = yypvt[-2].val / yypvt[0].val; 
  1422. X} break;
  1423. X
  1424. Xcase YYr24: {    /* expr :  expr '%' expr */
  1425. X#line 70
  1426. X    
  1427. X            if (yypvt[0].val == 0)
  1428. X                execerror ("modulo zero", (char *)0);
  1429. X            yyval.val = yypvt[-2].val % yypvt[0].val; 
  1430. X} break;
  1431. X
  1432. Xcase YYr25: {    /* expr :  expr POW expr */
  1433. X#line 74
  1434. X yyval.val = ulpow (yypvt[-2].val, yypvt[0].val); 
  1435. X} break;
  1436. X
  1437. Xcase YYr26: {    /* expr :  '(' expr ')' */
  1438. X#line 75
  1439. X yyval.val = yypvt[-1].val; 
  1440. X} break;
  1441. X
  1442. Xcase YYr27: {    /* expr :  '-' expr */
  1443. X#line 76
  1444. X yyval.val = -yypvt[0].val; 
  1445. X} break;
  1446. X
  1447. Xcase YYr28: {    /* expr :  '~' expr */
  1448. X#line 77
  1449. X yyval.val = ~ yypvt[0].val; 
  1450. X} break;
  1451. X#line 237 "yacc parser: c:/etc/yyparse.c"
  1452. X    case YYrACCEPT:
  1453. X        YYACCEPT;
  1454. X    case YYrERROR:
  1455. X        goto yyError;
  1456. X#ifdef YYLR2
  1457. X    case YYrLR2:
  1458. X#ifndef YYSYNC
  1459. X        YYREAD;
  1460. X#endif
  1461. X        yyj = 0;
  1462. X        while(yylr2[yyj] >= 0) {
  1463. X            if(yylr2[yyj] == yystate && yylr2[yyj+1] == yychar
  1464. X            && yylook(yys+1,yyps,yystate,yychar,yy2lex(),yylr2[yyj+2]))
  1465. X                    break;
  1466. X            yyj += 3;
  1467. X        }
  1468. X        if(yylr2[yyj] < 0)
  1469. X            goto yyError;
  1470. X        if(yylr2[yyj+2] < 0) {
  1471. X            yystate = ~ yylr2[yyj+2];
  1472. X            goto yyStack;
  1473. X        }
  1474. X        yyi = yylr2[yyj+2];
  1475. X        goto yyReduce;
  1476. X#endif
  1477. X    }
  1478. X
  1479. X    /*
  1480. X     *    Look up next state in goto table.
  1481. X     */
  1482. X
  1483. X    yyp = &yygo[yypgo[yyi]];
  1484. X    yyq = yyp++;
  1485. X    yyi = *yyps;
  1486. X#if    __TURBOC__ && __SMALL__
  1487. X    /* yyi is in di, yyp is in si */
  1488. XL02:
  1489. X    asm lodsw        /* ax = *yyp++; */
  1490. X    asm cmp yyi, ax
  1491. X    asm jl L02
  1492. X#else
  1493. X    while (yyi < *yyp++)
  1494. X        ;
  1495. X#endif
  1496. X    yystate = ~(yyi == *--yyp? YYQYYP: *yyq);
  1497. X    goto yyStack;
  1498. X
  1499. Xyyerrlabel:    ;        /* come here from YYERROR    */
  1500. X/*
  1501. X#pragma used yyerrlabel
  1502. X */
  1503. X    yyerrflag = 1;
  1504. X    yyps--, yypv--;
  1505. X    
  1506. XyyError:
  1507. X    switch (yyerrflag) {
  1508. X
  1509. X    case 0:        /* new error */
  1510. X        yynerrs++;
  1511. X        yyi = yychar;
  1512. X        yyerror("Syntax error");
  1513. X        if (yyi != yychar) {
  1514. X            /* user has changed the current token */
  1515. X            /* try again */
  1516. X            yyerrflag++;    /* avoid loops */
  1517. X            goto yyEncore;
  1518. X        }
  1519. X
  1520. X    case 1:        /* partially recovered */
  1521. X    case 2:
  1522. X        yyerrflag = 3;    /* need 3 valid shifts to recover */
  1523. X            
  1524. X        /*
  1525. X         *    Pop states, looking for a
  1526. X         *    shift on `error'.
  1527. X         */
  1528. X
  1529. X        for ( ; yyps > yys; yyps--, yypv--) {
  1530. X            if (*yyps >= sizeof yypact/sizeof yypact[0])
  1531. X                continue;
  1532. X            yyp = &yyact[yypact[*yyps]];
  1533. X            yyq = yyp;
  1534. X            do
  1535. X                ;
  1536. X            while (YYERRCODE < *yyp++);
  1537. X            if (YYERRCODE == yyp[-1]) {
  1538. X                yystate = ~YYQYYP;
  1539. X                goto yyStack;
  1540. X            }
  1541. X                
  1542. X            /* no shift in this state */
  1543. X#if YYDEBUG
  1544. X            if (yydebug && yyps > yys+1)
  1545. X                printf("Error recovery pops state %d (%d), uncovers %d (%d)\n",
  1546. X                    yysmap[yyps[0]], yyps[0],
  1547. X                    yysmap[yyps[-1]], yyps[-1]);
  1548. X#endif
  1549. X            /* pop stacks; try again */
  1550. X        }
  1551. X        /* no shift on error - abort */
  1552. X        break;
  1553. X
  1554. X    case 3:
  1555. X        /*
  1556. X         *    Erroneous token after
  1557. X         *    an error - discard it.
  1558. X         */
  1559. X
  1560. X        if (yychar == 0)  /* but not EOF */
  1561. X            break;
  1562. X#if YYDEBUG
  1563. X        if (yydebug)
  1564. X            printf("Error recovery discards %s (%d), ",
  1565. X                yyptok(yychar), yychar);
  1566. X#endif
  1567. X        yyclearin;
  1568. X        goto yyEncore;    /* try again in same state */
  1569. X    }
  1570. X    YYABORT;
  1571. X
  1572. X#ifdef YYALLOC
  1573. XyyReturn:
  1574. X    yylval = save_yylval;
  1575. X    yyval = save_yyval;
  1576. X    yypvt = save_yypvt;
  1577. X    yychar = save_yychar;
  1578. X    yyerrflag = save_yyerrflag;
  1579. X    yynerrs = save_yynerrs;
  1580. X    free((char *)yys);
  1581. X    free((char *)yyv);
  1582. X    return(retval);
  1583. X#endif
  1584. X}
  1585. X
  1586. X#ifdef YYLR2
  1587. Xyylook(s,rsp,state,c1,c2,i)
  1588. Xshort *s;        /* stack        */
  1589. Xshort *rsp;        /* real top of stack    */
  1590. Xint state;        /* current state    */
  1591. Xint c1;            /* current char        */
  1592. Xint c2;            /* next char        */
  1593. Xint i;            /* action S < 0, R >= 0    */
  1594. X{
  1595. X    int j;
  1596. X    short *p,*q;
  1597. X    short *sb,*st;
  1598. X#if YYDEBUG
  1599. X    if(yydebug) {
  1600. X        printf("LR2 state %d (%d) char %s (%d) lookahead %s (%d)",
  1601. X            yysmap[state],state,yyptok(c1),c1,yyptok(c2),c2);
  1602. X        if(i > 0)
  1603. X            printf("reduce %d (%d)\n", yyrmap[i], i);
  1604. X        else
  1605. X            printf("shift %d (%d)\n", yysmap[i], i);
  1606. X    }
  1607. X#endif
  1608. X    st = sb = rsp+1;
  1609. X    if(i >= 0)
  1610. X        goto reduce;
  1611. X  shift:
  1612. X    state = ~i;
  1613. X    c1 = c2;
  1614. X    if(c1 < 0)
  1615. X        return 1;
  1616. X    c2 = -1;
  1617. X
  1618. X  stack:
  1619. X      if(++st >= &s[YYSSIZE]) {
  1620. X        yyerror("Parser Stack Overflow");
  1621. X        return 0;
  1622. X    }
  1623. X    *st = state;
  1624. X    if(state >= sizeof yypact/sizeof yypact[0])
  1625. X        i = state- YYDELTA;
  1626. X    else {
  1627. X        p = &yyact[yypact[state]];
  1628. X        q = p;
  1629. X        i = c1;
  1630. X        while(i < *p++)
  1631. X            ;
  1632. X        if(i == p[-1]) {
  1633. X            state = ~q[q-p];
  1634. X            c1 = c2;
  1635. X            if(c1 < 0)
  1636. X                return 1;
  1637. X            c2 = -1;
  1638. X            goto stack;
  1639. X        }
  1640. X        if(state >= sizeof yydef/sizeof yydef[0])
  1641. X            return 0
  1642. X        if((i = yydef[state]) < 0) {
  1643. X            p = &yyex[~i];
  1644. X            while((i = *p) >= 0 && i != c1)
  1645. X                p += 2;
  1646. X            i = p[1];
  1647. X        }
  1648. X    }
  1649. X  reduce:
  1650. X      j = yyrlen[i];
  1651. X    if(st-sb >= j)
  1652. X        st -= j;
  1653. X    else {
  1654. X        rsp -= j+st-sb;
  1655. X        st = sb;
  1656. X    }
  1657. X    switch(i) {
  1658. X    case YYrERROR:
  1659. X        return 0;
  1660. X    case YYrACCEPT:
  1661. X        return 1;
  1662. X    case YYrLR2:
  1663. X        j = 0;
  1664. X        while(yylr2[j] >= 0) {
  1665. X            if(yylr2[j] == state && yylr2[j+1] == c1)
  1666. X                if((i = yylr2[j+2]) < 0)
  1667. X                    goto shift;
  1668. X                else
  1669. X                    goto reduce;
  1670. X        }
  1671. X        return 0;
  1672. X    }
  1673. X    p = &yygo[yypgo[i]];
  1674. X    q = p++;
  1675. X    i = st==sb ? *rsp : *st;
  1676. X    while(i < *p++);
  1677. X    state = ~(i == *--p? q[q-p]: *q);
  1678. X    goto stack;
  1679. X}
  1680. X#endif
  1681. X        
  1682. X#if YYDEBUG
  1683. X    
  1684. X/*
  1685. X *    Print a token legibly.
  1686. X *    This won't work if you roll your own token numbers,
  1687. X *    but I've found it useful.
  1688. X */
  1689. Xchar *
  1690. Xyyptok(i)
  1691. X{
  1692. X    static char    buf[10];
  1693. X
  1694. X    if (i >= YYERRCODE)
  1695. X        return yystoken[i-YYERRCODE];
  1696. X    if (i < 0)
  1697. X        return "";
  1698. X    if (i == 0)
  1699. X        return "$end";
  1700. X    if (i < ' ')
  1701. X        sprintf(buf, "'^%c'", i+'@');
  1702. X    else
  1703. X        sprintf(buf, "'%c'", i);
  1704. X    return buf;
  1705. X}
  1706. X#endif
  1707. X#ifdef YYDEBUG
  1708. Xchar * yystoken[] = {
  1709. X    "error",
  1710. X    "NUMBER",
  1711. X    "CONST",
  1712. X    "VAR",
  1713. X    "BLTIN",
  1714. X    "UNDEF",
  1715. X    "QUIT",
  1716. X    "HELP",
  1717. X    "CHRADIX",
  1718. X    "LSH",
  1719. X    "RSH",
  1720. X    "UNARYMINUS",
  1721. X    "POW",
  1722. X    0
  1723. X};
  1724. Xchar * yysvar[] = {
  1725. X    "$accept",
  1726. X    "expr",
  1727. X    "asgn",
  1728. X    "list",
  1729. X    0
  1730. X};
  1731. Xshort yyrmap[] = {
  1732. X      29,   30,   31,    9,   12,   15,   16,   17,   18,   19, 
  1733. X      20,   21,   22,   23,   24,   25,   27,   28,   26,   14, 
  1734. X      11,   10,    8,    7,    6,    5,    4,    1,    2,    3, 
  1735. X      13,    0
  1736. X};
  1737. Xshort yysmap[] = {
  1738. X       1,    8,   14,   16,   18,   41,   42,   43,   44,   45, 
  1739. X      46,   47,   48,   49,   50,   51,   52,   40,   36,   35, 
  1740. X      34,   33,   32,   31,   30,   29,   28,   27,   26,   21, 
  1741. X      20,   19,   13,   12,   11,   10,    9,    5,    4,    3, 
  1742. X       2,   39,   53,    6,    7,   22,   23,   24,   25,   37, 
  1743. X       0,   15,   38,   17
  1744. X};
  1745. Xint yyntoken = 27, yynvar = 4, yynstate = 54, yynrule = 32;
  1746. X#endif
  1747. SHAR_EOF
  1748. chmod 0666 ytab.c || echo "restore of ytab.c fails"
  1749. sed 's/^X//' << 'SHAR_EOF' > ytab.h &&
  1750. Xtypedef union {
  1751. X  BASE_TYPE val;    /* actual value */
  1752. X  Symbol *sym;        /* symbol table pointer */
  1753. X} YYSTYPE;
  1754. X#define NUMBER    257
  1755. X#define CONST    258
  1756. X#define VAR    259
  1757. X#define BLTIN    260
  1758. X#define UNDEF    261
  1759. X#define QUIT    262
  1760. X#define HELP    263
  1761. X#define CHRADIX    264
  1762. X#define LSH    265
  1763. X#define RSH    266
  1764. X#define UNARYMINUS    267
  1765. X#define POW    268
  1766. Xextern YYSTYPE yyval, yylval;
  1767. SHAR_EOF
  1768. chmod 0666 ytab.h || echo "restore of ytab.h fails"
  1769. sed 's/^X//' << 'SHAR_EOF' > yylex.c &&
  1770. X
  1771. X/*    yylex.c        lexical scanner for the hexcalc utility
  1772. X */
  1773. X
  1774. X#include <stdio.h>
  1775. X#include <ctype.h>
  1776. X
  1777. X#include "hexcalc.h"
  1778. X#ifdef __TURBOC__
  1779. X#include "ytab.h"
  1780. X#else
  1781. X#include "y.tab.h"
  1782. X#endif
  1783. X
  1784. Xextern int lineno;
  1785. Xextern int radix;
  1786. X
  1787. X#define MAXCHARS 31    /* number of significant chars in an identifier */
  1788. X
  1789. X/******************************************************************************/
  1790. X
  1791. Xint yylex ()
  1792. X{
  1793. X    int c;
  1794. X
  1795. X    while ((c = getchar()) == ' ' || c == '\t') /* skip whitespace */;
  1796. X    if (c == EOF) return 0;
  1797. X
  1798. X    if (radix == 8)
  1799. X    {
  1800. X        if (c >= '0' && c <= '7')
  1801. X        {
  1802. X            ungetc (c, stdin);
  1803. X            scanf ("%lo", &yylval.val);
  1804. X            return NUMBER;
  1805. X        }
  1806. X    }
  1807. X    else if (isdigit(c))
  1808. X    {
  1809. X        ungetc (c, stdin);
  1810. X        scanf (radix == 16 ? "%lx" : "%lu", &yylval.val);
  1811. X        return NUMBER;
  1812. X    }
  1813. X    if (isalpha(c))
  1814. X    {
  1815. X        Symbol *s;
  1816. X        char sbuf [MAXCHARS+1], *p = sbuf;
  1817. X
  1818. X        do 
  1819. X        {
  1820. X            if (p < sbuf+MAXCHARS) *p++ = c;
  1821. X        } 
  1822. X        while ((c = getchar()) != EOF && isalnum(c));
  1823. X        ungetc (c, stdin);
  1824. X        *p = '\0';
  1825. X        if ((s = lookup (sbuf)) == (Symbol *)0)
  1826. X        {
  1827. X            s = install (sbuf, UNDEF, (BASE_TYPE)0);
  1828. X        }
  1829. X        yylval.sym = s;
  1830. X        return s->type == UNDEF ? VAR : s->type;
  1831. X    }
  1832. X    /* handle multi-char operator tokens */
  1833. X    if ((c == '<') || (c == '>'))
  1834. X    {
  1835. X        int c2 = getchar();
  1836. X
  1837. X        if ((c == '<') && (c2 == '<'))
  1838. X        {
  1839. X            return LSH;
  1840. X        }
  1841. X        else if ((c == '>') && (c2 == '>'))
  1842. X        {
  1843. X            return RSH;
  1844. X        }
  1845. X        else
  1846. X        {
  1847. X            ungetc(c2, stdin);
  1848. X        }
  1849. X    }
  1850. X    if (c == '*')
  1851. X    {
  1852. X        int c2 = getchar();
  1853. X
  1854. X        if (c2 == '*')
  1855. X        {
  1856. X            return POW;
  1857. X        }
  1858. X        else
  1859. X        {
  1860. X            ungetc(c2, stdin);
  1861. X        }
  1862. X    }
  1863. X    if (c == '#')        /* handle comments */
  1864. X    {
  1865. X        int echo = (c = getchar()) == '#';
  1866. X
  1867. X        if (echo != 0) putchar('\t');
  1868. X        while (c != '\n')
  1869. X        {
  1870. X            if (echo != 0) putchar(c);
  1871. X            c = getchar();
  1872. X        }
  1873. X        if (echo != 0) putchar(c);
  1874. X    }
  1875. X    if (c == '\n') ++lineno;
  1876. X
  1877. X    return c;
  1878. X}
  1879. SHAR_EOF
  1880. chmod 0666 yylex.c || echo "restore of yylex.c fails"
  1881. exit 0
  1882. -------- cut here -------- cut here -------- cut here -------- cut here --------
  1883.  
  1884. richard hargrove
  1885. ...!{ihnp4 | codas | cbosgd}!killer!richardh
  1886. --------------------------------------------
  1887.