home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 332.lha / DAsm_v2.12 / src / exp.c < prev    next >
C/C++ Source or Header  |  1989-12-27  |  13KB  |  769 lines

  1.  
  2. /*
  3.  *  EXP.C
  4.  *
  5.  *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  Handle expression evaluation and addressing mode decode.
  8.  *
  9.  *  NOTE! If you use the string field in an expression you must clear
  10.  *  the SYM_MACRO and SYM_STRING bits in the flags before calling
  11.  *  freesymbollist()!
  12.  */
  13.  
  14. #include "asm.h"
  15.  
  16.  
  17. /*
  18.  *  evaluate an expression.  Figure out the addressing mode:
  19.  *
  20.  *            implied
  21.  *    #val        immediate
  22.  *    val        zero page or absolute
  23.  *    val,x        zero,x or absolute,x
  24.  *    val,y        zero,y or absolute,y
  25.  *    (val)       indirect
  26.  *    (val,x)     zero indirect x
  27.  *    (val),y     zero indirect y
  28.  *
  29.  *    exp, exp,.. LIST of expressions
  30.  *
  31.  *  an absolute may be returned as zero page
  32.  *  a relative may be returned as zero page or absolute
  33.  *
  34.  *  unary:  - ~ ! < >
  35.  *  binary: (^)(* / %)(+ -)(>> <<)(& |)(`)(&& ||)(== != < > <= >=)
  36.  *
  37.  *  values: symbol, octal, decimal, $hex, %binary, 'c "str"
  38.  *
  39.  */
  40.  
  41. #define MAXOPS    32
  42. #define MAXARGS 64
  43.  
  44. ubyte Argflags[MAXARGS];
  45. long  Argstack[MAXARGS];
  46. ubyte *Argstring[MAXARGS];
  47. short Oppri[MAXOPS];
  48. void  (*Opdis[MAXOPS]) ARGS((long, long, long, long));
  49.  
  50. uword    Argi, Opi, Lastwasop;
  51. uword    Argibase, Opibase;
  52.  
  53. SYMBOL *
  54. eval(str)
  55. register char *str;
  56. {
  57.     register SYMBOL *base, *cur;
  58.     uword oldargibase = Argibase;
  59.     uword oldopibase = Opibase;
  60.     uword scr;
  61.  
  62.     Argibase = Argi;
  63.     Opibase = Opi;
  64.     Lastwasop = 1;
  65.     base = cur = allocsymbol();
  66.  
  67.     while (*str) {
  68.     if (Xdebug)
  69.         printf("char '%c'\n", *str);
  70.     switch(*str) {
  71.     case ' ':
  72.     case '\n':
  73.         ++str;
  74.         break;
  75.     case '~':
  76.         if (Lastwasop)
  77.         doop(op_invert, 128);
  78.         else
  79.         asmerr(0,0);
  80.         ++str;
  81.         break;
  82.     case '*':
  83.         doop(op_mult, 20);
  84.         ++str;
  85.         break;
  86.     case '/':
  87.         doop(op_div, 20);
  88.         ++str;
  89.         break;
  90.     case '%':
  91.         if (Lastwasop) {
  92.         str = (char *)pushbin(str+1);
  93.         } else {
  94.         doop(op_mod, 20);
  95.         ++str;
  96.         }
  97.         break;
  98.     case '?':   /*  10      */
  99.         doop(op_question, 10);
  100.         ++str;
  101.         break;
  102.     case '+':   /*  19      */
  103.         doop(op_add, 19);
  104.         ++str;
  105.         break;
  106.     case '-':   /*  19: -   (or - unary)        */
  107.         if (Lastwasop) {
  108.         doop(op_negate, 128);
  109.         } else {
  110.         doop(op_sub, 19);
  111.         }
  112.         ++str;
  113.         break;
  114.     case '>':   /*  18: >> <<  17: > >= <= <    */
  115.         if (Lastwasop) {
  116.         doop(op_takemsb, 128);
  117.         ++str;
  118.         break;
  119.         }
  120.  
  121.         if (str[1] == '>') {
  122.         doop(op_shiftright, 18);
  123.         ++str;
  124.         } else if (str[1] == '=') {
  125.         doop(op_greatereq, 17);
  126.         ++str;
  127.         } else {
  128.         doop(op_greater, 17);
  129.         }
  130.         ++str;
  131.         break;
  132.     case '<':
  133.         if (Lastwasop) {
  134.         doop(op_takelsb, 128);
  135.         ++str;
  136.         break;
  137.         }
  138.         if (str[1] == '<') {
  139.         doop(op_shiftleft, 18);
  140.         ++str;
  141.         } else if (str[1] == '=') {
  142.         doop(op_smallereq, 17);
  143.         ++str;
  144.         } else {
  145.         doop(op_smaller, 17);
  146.         }
  147.         ++str;
  148.         break;
  149.     case '=':   /*  16: ==  (= same as ==)      */
  150.         if (str[1] == '=')
  151.         ++str;
  152.         doop(op_eqeq, 16);
  153.         ++str;
  154.         break;
  155.     case '!':   /*  16: !=                      */
  156.         if (Lastwasop) {
  157.         doop(op_not, 128);
  158.         } else {
  159.         doop(op_noteq, 16);
  160.         ++str;
  161.         }
  162.         ++str;
  163.         break;
  164.     case '&':   /*  15: &   12: &&              */
  165.         if (str[1] == '&') {
  166.         doop(op_andand, 12);
  167.         ++str;
  168.         } else {
  169.         doop(op_and, 15);
  170.         }
  171.         ++str;
  172.         break;
  173.     case '^':   /*  14: ^                       */
  174.         doop(op_xor, 14);
  175.         ++str;
  176.         break;
  177.     case '|':   /*  13: |   11: ||              */
  178.         if (str[1] == '|') {
  179.         doop(op_oror, 11);
  180.         ++str;
  181.         } else {
  182.         doop(op_or, 13);
  183.         }
  184.         ++str;
  185.         break;
  186.     case '[':   /*  eventually an argument      */
  187.         if (Opi == MAXOPS)
  188.         puts("too many ops");
  189.         else
  190.         Oppri[Opi++] = 0;
  191.         ++str;
  192.         break;
  193.     case ']':
  194.         while(Opi != Opibase && Oppri[Opi-1])
  195.         evaltop();
  196.         if (Opi != Opibase)
  197.         --Opi;
  198.         ++str;
  199.         if (Argi == Argibase) {
  200.         puts("']' error, no arg on stack");
  201.         break;
  202.         }
  203.         if (*str == 'd') {  /*  STRING CONVERSION   */
  204.         char buf[32];
  205.         ++str;
  206.         if (Argflags[Argi-1] == 0) {
  207.             sprintf(buf,"%ld",Argstack[Argi-1]);
  208.             Argstring[Argi-1] = (ubyte *)strcpy(malloc(strlen(buf)+1),buf);
  209.         }
  210.         }
  211.         break;
  212.     case '#':
  213.         cur->addrmode = AM_IMM8;
  214.         ++str;
  215.         break;
  216.     case '(':
  217.         cur->addrmode = AM_INDWORD;
  218.         ++str;
  219.         break;
  220.     case ')':
  221.         if (cur->addrmode == AM_INDWORD && str[1] == ',' && (str[2]|0x20) == 'y') {
  222.         cur->addrmode = AM_INDBYTEY;
  223.         str += 2;
  224.         }
  225.         ++str;
  226.         break;
  227.     case ',':
  228.         while(Opi != Opibase)
  229.         evaltop();
  230.         Lastwasop = 1;
  231.         scr = str[1]|0x20;    /* to lower case */
  232.         if (cur->addrmode == AM_INDWORD && scr == 'x' && !alphanum(str[2])) {
  233.         cur->addrmode = AM_INDBYTEX;
  234.         ++str;
  235.         } else if (scr == 'x' && !alphanum(str[2])) {
  236.         cur->addrmode = AM_0X;
  237.         ++str;
  238.         } else if (scr == 'y' && !alphanum(str[2])) {
  239.         cur->addrmode = AM_0Y;
  240.         ++str;
  241.         } else {
  242.         register SYMBOL *new = allocsymbol();
  243.         cur->next = new;
  244.         --Argi;
  245.         if (Argi < Argibase)
  246.             asmerr(0,0);
  247.         if (Argi > Argibase)
  248.             asmerr(0,0);
  249.         cur->value = Argstack[Argi];
  250.         cur->flags = Argflags[Argi];
  251.         if (cur->string= (ubyte *)Argstring[Argi]) {
  252.             cur->flags |= SYM_STRING;
  253.             if (Xdebug)
  254.             printf("STRING: %s\n", cur->string);
  255.         }
  256.         cur = new;
  257.         }
  258.         ++str;
  259.         break;
  260.     case '$':
  261.         str = (char *)pushhex(str+1);
  262.         break;
  263.     case '\'':
  264.         str = (char *)pushchar(str+1);
  265.         break;
  266.     case '\"':
  267.         str = (char *)pushstr(str+1);
  268.         break;
  269.     default:
  270.         if (*str == '0')
  271.         str = (char *)pushoct(str);
  272.         else {
  273.         if (*str > '0' && *str <= '9')
  274.             str = (char *)pushdec(str);
  275.         else
  276.             str = (char *)pushsymbol(str);
  277.         }
  278.         break;
  279.     }
  280.     }
  281.     while(Opi != Opibase)
  282.     evaltop();
  283.     if (Argi != Argibase) {
  284.     --Argi;
  285.     cur->value = Argstack[Argi];
  286.     cur->flags = Argflags[Argi];
  287.     if (cur->string= (ubyte *)Argstring[Argi]) {
  288.         cur->flags |= SYM_STRING;
  289.         if (Xdebug)
  290.         printf("STRING: %s\n", cur->string);
  291.     }
  292.     if (base->addrmode == 0)
  293.         base->addrmode = AM_BYTEADR;
  294.     }
  295.     if (Argi != Argibase || Opi != Opibase)
  296.     asmerr(0,0);
  297.     Argi = Argibase;
  298.     Opi  = Opibase;
  299.     Argibase = oldargibase;
  300.     Opibase = oldopibase;
  301.     return(base);
  302. }
  303.  
  304. int
  305. alphanum(c)
  306. int c;
  307. {
  308.     return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'));
  309. }
  310.  
  311. void
  312. evaltop()
  313. {
  314.     if (Xdebug)
  315.     printf("evaltop @(A,O) %d %d\n", Argi, Opi);
  316.     if (Opi <= Opibase) {
  317.     asmerr(0,0);
  318.     Opi = Opibase;
  319.     return;
  320.     }
  321.     --Opi;
  322.     if (Oppri[Opi] == 128) {
  323.     if (Argi < Argibase + 1) {
  324.         asmerr(0,0);
  325.         Argi = Argibase;
  326.         return;
  327.     }
  328.     --Argi;
  329.     (*Opdis[Opi])(Argstack[Argi], Argflags[Argi], 0, 0);
  330.     } else {
  331.     if (Argi < Argibase + 2) {
  332.         asmerr(0,0);
  333.         Argi = Argibase;
  334.         return;
  335.     }
  336.     Argi -= 2;
  337.     (*Opdis[Opi])(Argstack[Argi], Argstack[Argi+1], Argflags[Argi], Argflags[Argi+1]);
  338.     }
  339. }
  340.  
  341. void
  342. stackarg(val, flags, ptr1)
  343. long val;
  344. int flags;
  345. ubyte *ptr1;
  346. {
  347.     ubyte *str = NULL;
  348.  
  349.     if (Xdebug)
  350.     printf("stackarg %ld (@%d)\n", val, Argi);
  351.     Lastwasop = 0;
  352.     if (flags & SYM_STRING) {
  353.     register ubyte *ptr = ptr1;
  354.     register ubyte *new;
  355.     register uword len;
  356.     val = len = 0;
  357.     while (*ptr && *ptr != '\"') {
  358.         val = (val << 8) | *ptr;
  359.         ++ptr;
  360.         ++len;
  361.     }
  362.     new = malloc(len + 1);
  363.     BMov(ptr1, new, len);
  364.     new[len] = 0;
  365.     flags &= ~SYM_STRING;
  366.     str = new;
  367.     }
  368.     Argstack[Argi] = val;
  369.     Argstring[Argi] = str;
  370.     Argflags[Argi] = flags;
  371.     if (++Argi == MAXARGS) {
  372.     puts("stackarg: maxargs stacked");
  373.     Argi = Argibase;
  374.     }
  375.     while (Opi != Opibase && Oppri[Opi-1] == 128)
  376.     evaltop();
  377. }
  378.  
  379. void
  380. doop(func, pri)
  381. void (*func) ARGS((long, long, long, long));
  382. int pri;
  383. {
  384.     if (Xdebug)
  385.     puts("doop");
  386.     Lastwasop = 1;
  387.     if (Opi == Opibase || pri == 128) {
  388.     if (Xdebug)
  389.         printf("doop @ %d unary\n", Opi);
  390.     Opdis[Opi] = func;
  391.     Oppri[Opi] = pri;
  392.     ++Opi;
  393.     return;
  394.     }
  395.     while (Opi != Opibase && Oppri[Opi-1] && pri <= Oppri[Opi-1])
  396.     evaltop();
  397.     if (Xdebug)
  398.     printf("doop @ %d\n", Opi);
  399.     Opdis[Opi] = func;
  400.     Oppri[Opi] = pri;
  401.     ++Opi;
  402.     if (Opi == MAXOPS) {
  403.     puts("doop: too many operators");
  404.     Opi = Opibase;
  405.     }
  406.     return;
  407. }
  408.  
  409. void
  410. op_takelsb(v1, f1, x1, x2)
  411. long v1;
  412. long f1;
  413. long x1, x2;
  414. {
  415.     stackarg(v1 & 0xFFL, f1, NULL);
  416. }
  417.  
  418. void
  419. op_takemsb(v1, f1, x1, x2)
  420. long v1;
  421. long f1;
  422. long x1, x2;
  423. {
  424.     stackarg((v1 >> 8) & 0xFF, f1, NULL);
  425. }
  426.  
  427. void
  428. op_negate(v1, f1, x1, x2)
  429. long v1;
  430. long f1;
  431. long x1, x2;
  432. {
  433.     stackarg(-v1, f1, NULL);
  434. }
  435.  
  436. void
  437. op_invert(v1, f1, x1, x2)
  438. long v1;
  439. long f1;
  440. long x1, x2;
  441. {
  442.     stackarg(~v1, f1, NULL);
  443. }
  444.  
  445. void
  446. op_not(v1, f1, x1, x2)
  447. long v1;
  448. long f1;
  449. long x1, x2;
  450. {
  451.     stackarg((long)!v1, f1, NULL);
  452. }
  453.  
  454. void
  455. op_mult(v1, v2, f1, f2)
  456. long v1, v2;
  457. long f1, f2;
  458. {
  459.     stackarg(v1 * v2, f1|f2, NULL);
  460. }
  461.  
  462. void
  463. op_div(v1, v2, f1, f2)
  464. long v1, v2;
  465. long f1, f2;
  466. {
  467.     if (f1|f2) {
  468.     stackarg(0L, f1|f2, NULL);
  469.     return;
  470.     }
  471.     if (v2 == 0) {
  472.     puts("division by zero");
  473.     stackarg(0L, 0, NULL);
  474.     } else {
  475.     stackarg(v1 / v2, 0, NULL);
  476.     }
  477. }
  478.  
  479. void
  480. op_mod(v1, v2, f1, f2)
  481. long v1, v2;
  482. long f1, f2;
  483. {
  484.     if (f1|f2) {
  485.     stackarg(0L, f1|f2, NULL);
  486.     return;
  487.     }
  488.     if (v2 == 0)
  489.     stackarg(v1, 0, NULL);
  490.     else
  491.     stackarg(v1 % v2, 0, NULL);
  492. }
  493.  
  494. void
  495. op_question(v1, v2, f1, f2)
  496. long v1, v2;
  497. long f1, f2;
  498. {
  499.     if (f1)
  500.     stackarg(0L, f1, NULL);
  501.     else
  502.     stackarg((long)((v1) ? v2 : 0), ((v1) ? f2 : 0), NULL);
  503. }
  504.  
  505. void
  506. op_add(v1, v2, f1, f2)
  507. long v1, v2;
  508. long f1, f2;
  509. {
  510.     stackarg(v1 + v2, f1|f2, NULL);
  511. }
  512.  
  513. void
  514. op_sub(v1, v2, f1, f2)
  515. long v1, v2;
  516. long f1, f2;
  517. {
  518.     stackarg(v1 - v2, f1|f2, NULL);
  519. }
  520.  
  521. void
  522. op_shiftright(v1, v2, f1, f2)
  523. long v1, v2;
  524. long f1, f2;
  525. {
  526.     if (f1|f2)
  527.     stackarg(0L, f1|f2, NULL);
  528.     else
  529.     stackarg((long)(v1 >> v2), 0, NULL);
  530. }
  531.  
  532. void
  533. op_shiftleft(v1, v2, f1, f2)
  534. long v1, v2;
  535. long f1, f2;
  536. {
  537.     if (f1|f2)
  538.     stackarg(0L, f1|f2, NULL);
  539.     else
  540.     stackarg((long)(v1 << v2), 0, NULL);
  541. }
  542.  
  543. void
  544. op_greater(v1, v2, f1, f2)
  545. long v1, v2;
  546. long f1, f2;
  547. {
  548.     stackarg((long)(v1 > v2), f1|f2, NULL);
  549. }
  550.  
  551. void
  552. op_greatereq(v1, v2, f1, f2)
  553. long v1, v2;
  554. long f1, f2;
  555. {
  556.     stackarg((long)(v1 >= v2), f1|f2, NULL);
  557. }
  558.  
  559. void
  560. op_smaller(v1, v2, f1, f2)
  561. long v1, v2;
  562. long f1, f2;
  563. {
  564.     stackarg((long)(v1 < v2), f1|f2, NULL);
  565. }
  566.  
  567. void
  568. op_smallereq(v1, v2, f1, f2)
  569. long v1, v2;
  570. long f1, f2;
  571. {
  572.     stackarg((long)(v1 <= v2), f1|f2, NULL);
  573. }
  574.  
  575. void
  576. op_eqeq(v1, v2, f1, f2)
  577. long v1, v2;
  578. long f1, f2;
  579. {
  580.     stackarg((long)(v1 == v2), f1|f2, NULL);
  581. }
  582.  
  583. void
  584. op_noteq(v1, v2, f1, f2)
  585. long v1, v2;
  586. long f1, f2;
  587. {
  588.     stackarg((long)(v1 != v2), f1|f2, NULL);
  589. }
  590.  
  591. void
  592. op_andand(v1, v2, f1, f2)
  593. long v1, v2;
  594. long f1, f2;
  595. {
  596.     if ((!f1 && !v1) || (!f2 && !v2)) {
  597.     stackarg(0L, 0, NULL);
  598.     return;
  599.     }
  600.     stackarg(1L, f1|f2, NULL);
  601. }
  602.  
  603. void
  604. op_oror(v1, v2, f1, f2)
  605. long v1, v2;
  606. long f1, f2;
  607. {
  608.     if ((!f1 && v1) || (!f2 && v2)) {
  609.     stackarg(1L, 0, NULL);
  610.     return;
  611.     }
  612.     stackarg(0L, f1|f2, NULL);
  613. }
  614.  
  615. void
  616. op_xor(v1, v2, f1, f2)
  617. long v1, v2;
  618. long f1, f2;
  619. {
  620.     stackarg(v1^v2, f1|f2, NULL);
  621. }
  622.  
  623. void
  624. op_and(v1, v2, f1, f2)
  625. long v1, v2;
  626. long f1, f2;
  627. {
  628.     stackarg(v1&v2, f1|f2, NULL);
  629. }
  630.  
  631. void
  632. op_or(v1, v2, f1, f2)
  633. long v1, v2;
  634. long f1, f2;
  635. {
  636.     stackarg(v1|v2, f1|f2, NULL);
  637. }
  638.  
  639. ubyte *
  640. pushchar(str)
  641. ubyte *str;
  642. {
  643.     if (*str) {
  644.     stackarg((long)*str, 0, NULL);
  645.     ++str;
  646.     } else {
  647.     stackarg((long)' ', 0, NULL);
  648.     }
  649.     return((ubyte *)str);
  650. }
  651.  
  652. ubyte *
  653. pushhex(str)
  654. ubyte *str;
  655. {
  656.     register long val = 0;
  657.     for (;; ++str) {
  658.     if (*str >= '0' && *str <= '9') {
  659.         val = (val << 4) + (*str - '0');
  660.         continue;
  661.     }
  662.     if ((*str >= 'a' && *str <= 'f') || (*str >= 'A' && *str <= 'F')) {
  663.         val = (val << 4) + ((*str&0x1F) + 9);
  664.         continue;
  665.     }
  666.     break;
  667.     }
  668.     stackarg(val, 0, NULL);
  669.     return((ubyte *)str);
  670. }
  671.  
  672. ubyte *
  673. pushoct(str)
  674. ubyte *str;
  675. {
  676.     register long val = 0;
  677.     while (*str >= '0' && *str <= '7') {
  678.     val = (val << 3) + (*str - '0');
  679.     ++str;
  680.     }
  681.     stackarg(val, 0, NULL);
  682.     return((ubyte *)str);
  683. }
  684.  
  685. ubyte *
  686. pushdec(str)
  687. ubyte *str;
  688. {
  689.     register long val = 0;
  690.     while (*str >= '0' && *str <= '9') {
  691.     val = (val * 10) + (*str - '0');
  692.     ++str;
  693.     }
  694.     stackarg(val, 0, NULL);
  695.     return((ubyte *)str);
  696. }
  697.  
  698. ubyte *
  699. pushbin(str)
  700. ubyte *str;
  701. {
  702.     register long val = 0;
  703.     while (*str == '0' || *str == '1') {
  704.     val = (val << 1) | (*str - '0');
  705.     ++str;
  706.     }
  707.     stackarg(val, 0, NULL);
  708.     return((ubyte *)str);
  709. }
  710.  
  711. ubyte *
  712. pushstr(str)
  713. ubyte *str;
  714. {
  715.     stackarg(0L, SYM_STRING, str);
  716.     while (*str && *str != '\"')
  717.     ++str;
  718.     if (*str == '\"')
  719.     ++str;
  720.     return((ubyte *)str);
  721. }
  722.  
  723. ubyte *
  724. pushsymbol(str)
  725. ubyte *str;
  726. {
  727.     register SYMBOL *sym;
  728.     register ubyte *ptr;
  729.     ubyte macro = 0;
  730.  
  731.     for (ptr = str;
  732.     *ptr == '_' ||
  733.     *ptr == '.' ||
  734.     (*ptr >= 'a' && *ptr <= 'z') ||
  735.     (*ptr >= 'A' && *ptr <= 'Z') ||
  736.     (*ptr >= '0' && *ptr <= '9');
  737.     ++ptr
  738.     );
  739.     if (ptr == str) {
  740.     asmerr(9,0);
  741.     printf("char = '%c' %d (-1: %d)\n", *str, *str, *(str-1));
  742.     if (F_listfile)
  743.         fprintf(FI_listfile, "char = '%c' code %d\n", *str, *str);
  744.     return((ubyte *)str+1);
  745.     }
  746.     if (sym = findsymbol(str, ptr - str)) {
  747.     if (sym->flags & SYM_UNKNOWN)
  748.         ++Redo_eval;
  749.     if (sym->flags & SYM_MACRO) {
  750.         macro = 1;
  751.         sym = eval(sym->string);
  752.     }
  753.     if (sym->flags & SYM_STRING)
  754.         stackarg(0L, SYM_STRING, sym->string);
  755.     else
  756.         stackarg(sym->value, sym->flags & SYM_UNKNOWN, NULL);
  757.     sym->flags |= SYM_REF|SYM_MASREF;
  758.     if (macro)
  759.         freesymbollist(sym);
  760.     } else {
  761.     stackarg(0L, SYM_UNKNOWN, NULL);
  762.     sym = createsymbol(str, ptr - str);
  763.     sym->flags = SYM_REF|SYM_MASREF|SYM_UNKNOWN;
  764.     ++Redo_eval;
  765.     }
  766.     return(ptr);
  767. }
  768.  
  769.