1: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2: * *
3: * CODEGEN.SLC Rowan Crowe <rowan#sensation'net'au> *
4: * *
5: * Simple calculator demonstration, supports addition, subtraction, *
6: * multiplication, division, and bracketing. *
7: * *
8: * This is similar to CALC.MOO supplied in COMPIxxx.ZIP downloadable via *
9: * http://www.rowan.sensation.net.au/slc.html , except that it doesn't *
10: * parse the line into an array prior to evaluating it. *
11: * *
12: * The code could still be a lot neater by not relying on using global *
13: * variables across several functions. *
14: * *
15: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16:
17: extern int itostr()
18: extern int strtoui()
19: extern int input()
20: extern int puts()
21: extern int putc()
22: extern int isdigit()
23: extern int isalpha()
24: extern int tinymeminit()
25: extern int malloc()
26: extern int free()
27: extern void abort()
28: extern int neg()
29:
30: define REG_AX 0
31: define REG_BX 1
32:
33: define OP_PUSHREG 0
34: define OP_POPREG 1
35: define OP_ADDREG 2
36: define OP_SUBREG 3
37: define OP_DIVREG 4
38: define OP_MULREG 5
39:
40: global int errno
41: global char *p
42: global int errorflag
43: global int locallabel
44:
45: int evaluate () {
46: compare()
47: }
48:
49: int compare () {
50: int t
51: add_subtract()
52: while ((*p != 0) && ((*p == '=' && *(p+1) == '=') || (*p == '<') || (*p == '>'))) {
53: if (*p == '<') {
54: p = p + 1
55: puts("\tpush\tax\n")
56: add_subtract()
57: puts("\tpop\tbx\n\tcmp\tax,bx\n\tmov\tax,-1\n")
58: t = locallabel
59: locallabel = locallabel + 1
60: puts("\tjl\tLL")
61: puts(itostr("1234567", locallabel))
62: puts("\n\tinc\tax\nLL")
63: puts(itostr("1234567", locallabel))
64: puts(":\n")
65: }
66: if (*p == '>') {
67: p = p + 1
68: puts("\tpush\tax\n")
69: add_subtract()
70: puts("\tpop\tbx\n\tcmp\tax,bx\n\tmov\tax,-1\n")
71: t = locallabel
72: locallabel = locallabel + 1
73: puts("\tjg\tLL")
74: puts(itostr("1234567", locallabel))
75: puts("\n\tinc\tax\nLL")
76: puts(itostr("1234567", locallabel))
77: puts(":\n")
78: }
79: }
80: }
81:
82: int add_subtract() {
83: divide_multiply()
84: while ((*p != 0) && ((*p == '+') || (*p == '-'))) {
85: if (*p == '+') {
86: p = p + 1
87: puts("\tpush\tax\n")
88: divide_multiply()
89: puts("\tpop\tbx\n\tadd\tax,bx\n")
90: }
91: if (*p == '-') {
92: p = p + 1
93: puts("\tpush\tax\n")
94: divide_multiply()
95: puts("\tmov\tbx,ax\n\tpop\tax\n\tsub\tax,bx\n")
96: }
97: }
98: }
99:
100: int divide_multiply() {
101: bracket()
102: while ( (*p != 0) && ( (*p == '/') || (*p == '*') ) ) {
103: if (*p == '/') {
104: p = p + 1
105: puts("\tpush\tax\n")
106: bracket()
107: puts("\tmov\tbx,ax\n\tpop\tax\n\tdiv\tbx\n")
108: }
109: if (*p == '*') {
110: p = p + 1
111: puts("\tpush\tax\n")
112: bracket()
113: puts("\tmov\tbx,ax\n\tpop\tax\n\tmul\tbx\n")
114: }
115: }
116: }
117:
118: int bracket() {
119: int rv
120:
121: remove_whitespace()
122:
123: if (isdigit(*p) || isalpha(*p)) {
124: fetchname()
125: return
126: }
127: switch(*p) {
128: case '(' {
129: p = p + 1
130: rv = add_subtract()
131: if (*p != ')') {
132: puts("syntax error: expected ')' closing bracket\n")
133: errorflag = 1
134: return 0
135: } else {
136: p = p + 1
137: remove_whitespace()
138: return rv
139: }
140: }
141: case '-' {
142: p = p + 1
143: if (isdigit(*p)) {
144: puts("-")
145: puts(fetchname())
146: }
147: }
148: case else {
149: puts("syntax error: unexpected token '")
150: putc(*p)
151: puts("'\n")
152: *p = '0'
153: errorflag = 1
154: return 0
155: }
156: }
157: }
158:
159: int fetchname() {
160: puts("\tmov\tax,")
161: while ((isdigit(*p) || isalpha(*p)) && *p != 0) {
162: putc(*p)
163: p = p + 1
164: }
165: puts("\n")
166: remove_whitespace()
167: }
168: int fetchnumber() {
169: char *tmpbuf
170: char *d
171:
172: if ((tmpbuf = malloc(20)) == -1) {
173: puts("memory allocation failed.\n")
174: abort(0)
175: }
176:
177: d = tmpbuf
178: while (isdigit(*p) && *p != 0) {
179: *d = *p
180: p = p + 1
181: d = d + 1
182: }
183: *d = 0
184: remove_whitespace()
185: free(tmpbuf)
186: puts(strtoui(tmpbuf))
187: }
188:
189: void remove_whitespace() {
190: while (*p == ' ') {
191: p = p + 1
192: }
193: }
194:
195: void add_peep(int opcode, int parm1, int parm2) {
196: }
197:
198: int main() {
199: int rv
200: char *origp
201: int exitnow
202:
203: if ((rv = tinymeminit(4096)) == -1) {
204: puts("memory init failed.\n")
205: abort(0)
206: }
207: if ((p = malloc(51)) == -1) {
208: puts("memory allocation failed.\n")
209: abort(0)
210: }
211: origp = p
212:
213: exitnow = 0
214: locallabel = 0
215: while (exitnow == 0) {
216: p = origp
217: errorflag = 0
218: puts("> ")
219: rv = input(p, 50)
220: puts("\n; ")
221: puts(p)
222: puts("\n")
223: if (*p != 0) {
224: rv = evaluate()
225: if (errorflag == 0) {
226: puts("\n")
227: }
228: } else {
229: exitnow = 1
230: }
231: }
232: puts("\nBye!\n")
233: free(p) /* ignore return value */
234: return 0
235: }
236:
237: |