|
|
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.