Skip to content

Commit 6894408

Browse files
committed
Implement relations
1 parent 59e1e44 commit 6894408

File tree

3 files changed

+303
-11
lines changed

3 files changed

+303
-11
lines changed

cradle.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function getChar() {
2222
stdin.pause();
2323
stdin.setRawMode(false);
2424
look = c.toString();
25+
stdin.removeAllListeners('error');
2526
return deferred.resolve();
2627
});
2728
stdin.once('error', function(err) {

expressions.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ function divide() {
8585
emitLn('DIVS D1,D0');
8686
});
8787
}
88+
8889
function termTail() {
8990
let nextChar = look();
9091
if (nextChar === '*' || nextChar === '/') {

withBooleanExpressions.js

Lines changed: 301 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
'use strict';
22

3-
const cradle = require('./cradle');
3+
const cradle = require('./cradle'),
4+
q = require('q');
45

56
const look = cradle.look,
67
expected = cradle.expected,
8+
getName = cradle.getName,
79
getChar = cradle.getChar,
10+
getNum = cradle.getNum,
811
init = cradle.init,
912
emitLn = cradle.emitLn,
10-
match = cradle.match;
13+
match = cradle.match,
14+
isAlpha = cradle.isAlpha;
1115

1216

1317
function isBoolean(c) {
@@ -54,19 +58,63 @@ function boolExpression() {
5458
});
5559
}
5660

61+
62+
63+
5764
function boolTerm() {
58-
let nextChar = look();
59-
if (!isBoolean(nextChar)) return expected('Boolean Literal');
60-
return getBoolean()
61-
.then((myBool) => {
62-
if (myBool) {
63-
emitLn('MOVE #-1,D0')
64-
} else {
65-
emitLn('CLR D0');
66-
}
65+
function boolTermInner() {
66+
let nextChar = look();
67+
if (nextChar === '&') {
68+
emitLn('MOVE D0,-(SP)');
69+
return match('&')
70+
.then(() => {
71+
return notFactor();
72+
})
73+
.then(() => {
74+
emitLn('AND (SP)+,D0');
75+
return boolTermInner();
76+
});
77+
}
78+
}
79+
return notFactor()
80+
.then(() => {
81+
return boolTermInner();
6782
});
6883
}
6984

85+
86+
function boolFactor() {
87+
let nextChar = look();
88+
if (isBoolean(nextChar)) {
89+
return getBoolean()
90+
.then((myBool) => {
91+
if (myBool) {
92+
emitLn('MOVE #-1,D0')
93+
} else {
94+
emitLn('CLR D0');
95+
}
96+
});
97+
} else {
98+
return relation();
99+
}
100+
}
101+
102+
function notFactor() {
103+
let nextChar = look();
104+
105+
if (nextChar === '!') {
106+
return match('!')
107+
.then(() => {
108+
return boolFactor();
109+
})
110+
.then(() => {
111+
emitLn('EOR #-1,D0');
112+
});
113+
} else {
114+
return boolFactor();
115+
}
116+
}
117+
70118
function isOrOp(c) {
71119
return c === '|' || c === '~';
72120
}
@@ -91,11 +139,253 @@ function boolXor() {
91139
})
92140
}
93141

142+
function isRelOp(c) {
143+
return c === '=' || c === '#' || c === '<' || c === '>';
144+
}
145+
146+
function equals() {
147+
return match('=')
148+
.then(() => {
149+
return expression();
150+
})
151+
.then(() => {
152+
emitLn('CMP (SP)+,D0');
153+
emitLn('SEQ D0');
154+
});
155+
}
156+
157+
function notEquals() {
158+
return match('#')
159+
.then(() => {
160+
return expression();
161+
})
162+
.then(() => {
163+
emitLn('CMP (SP)+,D0');
164+
emitLn('SNE D0');
165+
});
166+
}
167+
168+
function less() {
169+
return match('<')
170+
.then(() => {
171+
return expression();
172+
})
173+
.then(() => {
174+
emitLn('CMP (SP)+,D0');
175+
emitLn('SGE D0');
176+
});
177+
}
178+
179+
function greater() {
180+
return match('>')
181+
.then(() => {
182+
return expression();
183+
})
184+
.then(() => {
185+
emitLn('CMP (SP)+,D0');
186+
emitLn('SLE D0');
187+
});
188+
}
189+
190+
function relation() {
191+
return expression()
192+
.then(() => {
193+
let nextChar = look();
194+
if (isRelOp(nextChar)) {
195+
emitLn('MOVE D0,-(SP)');
196+
let nextStep;
197+
switch(nextChar) {
198+
case '=':
199+
nextStep = equals;
200+
break;
201+
case '#':
202+
nextStep = notEquals;
203+
break;
204+
case '<':
205+
nextStep = less;
206+
break;
207+
case '>':
208+
nextStep = greater;
209+
break;
210+
}
211+
return nextStep()
212+
.then(() => {
213+
emitLn('TST D0');
214+
});
215+
}
216+
});
217+
}
218+
219+
function expression() {
220+
let nextChar = look();
221+
return q()
222+
.then(() => {
223+
if (isAddOp(nextChar)) {
224+
emitLn('CLR D0')
225+
} else {
226+
return term();
227+
}
228+
})
229+
.then(() => {
230+
return expressionTail();
231+
});
232+
}
233+
234+
function expressionTail() {
235+
let nextChar = look();
236+
if (isAddOp(nextChar)) {
237+
emitLn('MOVE D0,-(SP)');
238+
return q()
239+
.then(() => {
240+
let nextChar = look();
241+
switch(nextChar) {
242+
case '+':
243+
return add();
244+
case '-':
245+
return subtract();
246+
}
247+
})
248+
.then(() => {
249+
return expressionTail();
250+
});
251+
} else {
252+
return;
253+
}
254+
}
255+
256+
function isAddOp(c) {
257+
return (c === '+' || c === '-')
258+
}
259+
260+
function term() {
261+
return factor()
262+
.then(() => {
263+
return termTail();
264+
});
265+
}
266+
267+
function divide() {
268+
return match('/')
269+
.then(() => {
270+
return factor()
271+
})
272+
.then(() => {
273+
emitLn('MOVE (SP)+,D1');
274+
emitLn('DIVS D1,D0');
275+
});
276+
}
277+
function termTail() {
278+
let nextChar = look();
279+
if (nextChar === '*' || nextChar === '/') {
280+
emitLn('MOVE D0,-(SP)');
281+
return q()
282+
.then(() => {
283+
let nextChar = look();
284+
switch(nextChar) {
285+
case '*':
286+
return multiply();
287+
case '/':
288+
return divide();
289+
}
290+
})
291+
.then(() => {
292+
return termTail();
293+
});
294+
} else {
295+
return;
296+
}
297+
}
298+
299+
function multiply() {
300+
return match('*')
301+
.then(() => {
302+
return factor()
303+
})
304+
.then(() => {
305+
emitLn('MULS (SP)+,D0');
306+
});
307+
}
308+
309+
function divide() {
310+
return match('/')
311+
.then(() => {
312+
return factor()
313+
})
314+
.then(() => {
315+
emitLn('MOVE (SP)+,D1');
316+
emitLn('DIVS D1,D0');
317+
});
318+
}
319+
320+
function factor() {
321+
let nextChar = look();
322+
if (nextChar === '(') {
323+
return match('(')
324+
.then(() => {
325+
return expression();
326+
})
327+
.then(() => {
328+
return match(')');
329+
});
330+
} else if (isAlpha(nextChar)) {
331+
return ident();
332+
} else {
333+
return getNum()
334+
.then((num) => {
335+
emitLn('MOVE #' + num + ',D0');
336+
});
337+
}
338+
}
339+
340+
function add() {
341+
return match('+')
342+
.then(() => {
343+
return term();
344+
})
345+
.then(() => {
346+
emitLn('ADD (SP)+,D0');
347+
});
348+
}
349+
350+
function subtract() {
351+
return match('-')
352+
.then(() => {
353+
return term()
354+
})
355+
.then(() => {
356+
emitLn('SUB (SP)+,D0');
357+
emitLn('NEG D0');
358+
});
359+
}
360+
361+
function ident() {
362+
return getName()
363+
.then((name) => {
364+
let nextChar = look();
365+
if (nextChar === '(') {
366+
return match('(')
367+
.then(() => {
368+
return match(')');
369+
})
370+
.then(() => {
371+
emitLn('BSR ' + name);
372+
});
373+
} else {
374+
emitLn('MOVE ' + name + '(PC),D0');
375+
}
376+
});
377+
}
378+
379+
380+
94381

95382
init()
96383
.then(() => {
97384
return boolExpression();
98385
})
386+
.then(() => {
387+
emitLn('END START');
388+
})
99389
.catch((err) => {
100390
console.log(err.stack);
101391
})

0 commit comments

Comments
 (0)