|
|
1.1 ! root 1: /* ! 2: * The typedef rvalue defines the basic entity upon which bc ! 3: * operates. ! 4: */ ! 5: ! 6: typedef struct { ! 7: mint mantissa; ! 8: int scale; ! 9: } rvalue; ! 10: ! 11: ! 12: /* ! 13: * The typedef array defines the concept of an array of rvalues. ! 14: */ ! 15: ! 16: typedef struct { ! 17: rvalue *avalue; ! 18: int size; ! 19: } array; ! 20: ! 21: ! 22: /* ! 23: * The typedef bcstate is used to hold the state of the bc- ! 24: * pseudo machine which should be restored when returning from ! 25: * a function call. ! 26: */ ! 27: ! 28: typedef struct { ! 29: union code *spc; /* pc to return to */ ! 30: union stkent *sfp, /* frame pointer to return to */ ! 31: *stos; /* stack pointer to return to */ ! 32: } bcstate; ! 33: ! 34: ! 35: /* ! 36: * The typedef stkent defines the union used for run-time stack ! 37: * entries. ! 38: */ ! 39: ! 40: typedef union stkent { ! 41: rvalue rvalue, ! 42: *lvalue; ! 43: array *alvalue; ! 44: bcstate bcstate; ! 45: } stkent; ! 46: ! 47: ! 48: /* ! 49: * The typedef opcode is the list of opcodes for the hypothetical ! 50: * bc-machine. ! 51: */ ! 52: ! 53: #define LOAD 0 /* ! 54: * Convert TOS from an l_value to an r_value. ! 55: */ ! 56: #define LIBASE 1 ! 57: #define LOBASE 2 ! 58: #define LSCALE 3 /* ! 59: * Push the r_value of the special variable ibase ! 60: * (resp. obase, scale). ! 61: */ ! 62: #define STORE 4 /* ! 63: * Store the r_value TOS at the l_value ! 64: * TOS[-1]. Leave the r_value on the stack ! 65: * but remove the l_value. ! 66: */ ! 67: #define SIBASE 5 ! 68: #define SOBASE 6 ! 69: #define SSCALE 7 /* ! 70: * Copy the r_value in TOS into ibase (rep. obase, ! 71: * scale). Also, check to see that the value is ! 72: * acceptable. ! 73: */ ! 74: #define POP 8 /* ! 75: * Throw away the r_value TOS. ! 76: */ ! 77: #define PRVAL 9 /* ! 78: * Push the r_value corresponding to the l_value TOS ! 79: * onto the stack. Note that the old TOS is left ! 80: * on the stack. ! 81: */ ! 82: #define PGLSC 10 ! 83: #define PLOSC 11 /* ! 84: * Push the l_value of a global (local) scalar onto ! 85: * the stack. The address (resp. stack frame offset) ! 86: * of the scalar follows the opcode. ! 87: */ ! 88: #define PLISC 12 /* Push the l_value of a literal scalar onto the ! 89: * stack. The address of the scalar follows the ! 90: * the opcode. Distinguished from PGLSC so literal ! 91: * storage space can be recovered, otherwise the same. ! 92: */ ! 93: #define PGLAE 13 ! 94: #define PLOAE 14 /* ! 95: * Push the l_value of a global (local) array ! 96: * element onto the stack. The address (resp. stack ! 97: * frame offset) of the array follows the opcode ! 98: * and TOS is the subscript. Note that the subscript ! 99: * is first removed from the stack. ! 100: */ ! 101: #define PGLAR 15 ! 102: #define PLOAR 16 /* ! 103: * Push the l_value of a global (local) array onto ! 104: * the stack. The address (resp. stack fram offset) ! 105: * of the array follows the opcode. (Used to pass ! 106: * an entire array as a function argument.) ! 107: */ ! 108: #define STOP 17 /* ! 109: * Stop interpreting bc-machine pseudo-instructions ! 110: * and return. This is only used at the end of ! 111: * the code compiled for immediate execution. ! 112: */ ! 113: #define CALL 18 /* ! 114: * Call the function whoose dictionary entry ! 115: * is pointed to by the word following this ! 116: * opcode. The number of arguments is contained ! 117: * in the word following that. ! 118: * Just before the CALL, the stack looks like: ! 119: * TOS-> last parameter ! 120: * ... ! 121: * first parameter ! 122: * rest of stack ! 123: * and just after the CALL, it looks like: ! 124: * TOS-> state to return to ! 125: * last automatic variable ! 126: * ... ! 127: * first automatic variable ! 128: * last parameter ! 129: * ... ! 130: * FRAME-> first parameter ! 131: * rest of stack ! 132: */ ! 133: #define RETURN 19 /* ! 134: * Return from the function whoose dictionary entry ! 135: * is pointed to by the word following this opcode. ! 136: * Just before the RETURN, the stack looks like: ! 137: * TOS-> r_value to return ! 138: * state to return to ! 139: * last automatic variable ! 140: * ... ! 141: * first automatic variable ! 142: * last parameter ! 143: * ... ! 144: * FRAME-> first parameter ! 145: * rest of stack ! 146: * Just after the RETURN, the stack looks like: ! 147: * TOS-> r_value returned ! 148: * rest of stack ! 149: * Note that all prameters and automatic variables ! 150: * must be freed and removed from the stack. ! 151: */ ! 152: #define INC 20 ! 153: #define DEC 21 /* ! 154: * Add 1 (resp. -1) to the r_value TOS. ! 155: */ ! 156: #define PRNUM 22 /* ! 157: * Print the r_value TOS and then remove it from ! 158: * the stack. ! 159: */ ! 160: #define PRSTR 23 /* ! 161: * Print the string whose address follows this ! 162: * opcode. Note that no newline is added. ! 163: */ ! 164: #define PRNL 24 /* ! 165: * Print a new line character. ! 166: */ ! 167: ! 168: #define LENGTH 25 ! 169: #define SCALE 26 ! 170: #define SQRT 27 /* ! 171: * Replace the r_value TOS with its length in bytes, ! 172: * scale factor, or square root respectively. ! 173: */ ! 174: #define ADD 28 ! 175: #define SUB 29 ! 176: #define MUL 30 ! 177: #define DIV 31 ! 178: #define REM 32 ! 179: #define EXP 33 /* ! 180: * Replace the r_values TOS and TOS[-1] with ! 181: * TOS + TOS[-1] (resp. TOS - TOS[-1], TOS * TOS[-1], ! 182: * TOS / TOS[-1], TOS % TOS[-1], TOS ^ TOS[-1]). ! 183: */ ! 184: #define NEG 34 /* ! 185: * Replace the r_value TOS with -TOS. ! 186: */ ! 187: #define BRALW 35 ! 188: #define BRNEV 36 /* ! 189: * Branch always (respectively never). The new ! 190: * pc will be the address of the following code ! 191: * item plus its contents. ! 192: */ ! 193: #define BRLT 37 ! 194: #define BRLE 38 ! 195: #define BREQ 39 ! 196: #define BRGE 40 ! 197: #define BRGT 41 ! 198: #define BRNE 42 /* ! 199: * Branch if the r_value TOS[-1] is less than ! 200: * (respectively less or equal, equal, ! 201: * greater or equal, greater and unequal) ! 202: * then the r_value TOS. Note that both TOS and ! 203: * TOS[-1] are removed from the stack. ! 204: */ ! 205: #define EXIT 43 /* Exit from bc, used to be immediately done ! 206: * whether quit appeared in a conditional, ! 207: * function definition or anywhere whatsoever. ! 208: */ ! 209: typedef int opcode; ! 210: ! 211: /* ! 212: * The typedef code is the type of entry in the array of ! 213: * pseudo-code which the pseudo-machine executes. ! 214: */ ! 215: ! 216: typedef union code { ! 217: int opcode; ! 218: int address; /* relative code address */ ! 219: rvalue *lvalue; /* global scalar or constant */ ! 220: array *alvalue; /* global array */ ! 221: char *svalue; /* string */ ! 222: int ivalue; /* stack offset and misc. counts */ ! 223: struct dicent *dvalue; /* function name */ ! 224: } code;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.