Permalink
Browse files

implement || and &&

  • Loading branch information...
1 parent 69b0210 commit 6a24c33cd9adf61a4a33ba85cb60c208adc9edff @jlongster committed Nov 6, 2013
Showing with 136 additions and 14 deletions.
  1. +53 −12 src/compiler.js
  2. +63 −2 test/asm/primitives.js
  3. +20 −0 test/asm/primitives.ljs
View
65 src/compiler.js
@@ -46,6 +46,7 @@
const NewExpression = T.NewExpression;
const UpdateExpression = T.UpdateExpression;
const LogicalExpression = T.LogicalExpression;
+ const IfStatement = T.IfStatement;
const ForStatement = T.ForStatement;
const BlockStatement = T.BlockStatement;
const CatchClause = T.CatchClause;
@@ -581,7 +582,7 @@
if(this === Types.voidTy) {
return other === Types.voidTy;
}
-
+
if (other instanceof PrimitiveType ||
other instanceof PointerType) {
return true;
@@ -711,7 +712,7 @@
check(decl.init, ('Global variable ' + quote(decl.id) +
' must have an initializer'));
check(decl.init instanceof Literal,
- 'Global variable ' + quote(decl.id) +
+ 'Global variable ' + quote(decl.id) +
' must be a constant literal');
logger.pop();
}
@@ -748,14 +749,54 @@
FunctionDeclaration.prototype.transform = function (o) {
o = extend(o);
o.scope = this.frame;
-
+
assert(this.body instanceof BlockStatement);
this.body.body = compileList(this.body.body, o);
this.frame.close();
return cast(this, this.decltype.reflect(o));
};
+ IfStatement.prototype.transformNode = function(o) {
+ if(o.asmjs &&
+ this.test instanceof LogicalExpression &&
+ (this.test.operator == '&&' || this.test.operator == '||')) {
+ var test = this.test;
+ var tmp = o.scope.freshTemp(Types.i32ty, test.loc);
+ var code = [new ExpressionStatement(
+ new AssignmentExpression(tmp, '=', literal(0))
+ )];
+
+ var assignTrue = new BlockStatement([
+ new ExpressionStatement(new AssignmentExpression(tmp, '=', literal(1)))
+ ]);
+
+ if(test.operator == '&&') {
+ code.push(new IfStatement(
+ test.left,
+ new BlockStatement([new IfStatement(
+ test.right,
+ assignTrue
+ )])
+ ).transform(o));
+ }
+ else if(test.operator == '||') {
+ code.push(new BlockStatement([
+ new IfStatement(test.left, assignTrue).transform(o),
+ new IfStatement(test.right, assignTrue).transform(o)
+ ]));
+ }
+
+ code.push(new BlockStatement([new IfStatement(
+ tmp,
+ this.consequent,
+ this.alternate
+ )]));
+
+ return new BlockStatement(code);
+ }
+ };
+
ForStatement.prototype.transform = function (o) {
o = extend(o);
o.scope = this.scope;
@@ -847,7 +888,7 @@
var transformed = [];
for(var i=0; i<decls.length; i++) {
- if((decl = decls[i].transform(o))) {
+ if((decl = decls[i].transform(o))) {
transformed.push(decl);
}
}
@@ -934,7 +975,7 @@
}
var assn = (new AssignmentExpression(left, "=", right, this.init.loc)).transform(o);
-
+
if(this.global) {
this.id = assn.left;
this.init = assn.right;
@@ -1549,7 +1590,7 @@
variable.name != 'this' &&
node.parameters.indexOf(variable) === -1) {
-
+
var decl = new VariableDeclarator(new Identifier(variable.name),
new Literal((ty && ty.defaultValue) || 0));
@@ -1592,7 +1633,7 @@
for (var i = 0, j = params.length; i < j; i++) {
var p = params[i];
var ty = p.type;
-
+
if(!ty) {
continue;
}
@@ -1638,7 +1679,7 @@
var frameSize = frame.frameSize;
if(frameSize) {
var allocStack = new AssignmentExpression(
- frame.realSP(), "=",
+ frame.realSP(), "=",
forceType(new BinaryExpression("-", forceType(frame.realSP()), literal(frameSize)),
Types.i32ty)
);
@@ -1818,7 +1859,7 @@
var exprList = [assn];
if(o.asmjs && frameSize) {
var restoreStack = new AssignmentExpression(
- scope.frame.realSP(), "=",
+ scope.frame.realSP(), "=",
forceType(
new BinaryExpression(
"+", forceType(scope.frame.realSP()), literal(frameSize)
@@ -1920,7 +1961,7 @@
function extractExterns(node) {
var externs = [];
- if(node instanceof Program) {
+ if(node instanceof Program) {
for(var i=0; i<node.body.length; i++) {
var expr = node.body[i];
@@ -1993,7 +2034,7 @@
// Pass 1.
logger.info("Pass 1");
types = resolveAndLintTypes(node, types || clone(Types.builtinTypes));
- var o = { types: types, name: name, logger: _logger, memcheck: false,
+ var o = { types: types, name: name, logger: _logger, memcheck: false,
asmjs: options.asmjs, warn: warningOptions(options) };
// Pass 2.
@@ -2009,7 +2050,7 @@
node = node.lower(o);
return {
- externs: externs,
+ externs: externs,
node: T.flatten(node)
};
}
View
65 test/asm/primitives.js
@@ -59,7 +59,7 @@ var asm = (function (global, env, buffer) {
var globalSP = 64;
function main() {
- var _ = 0, x = 0, y = 0, z = 0.0, w = 0.0, i = 0, $SP = 0;
+ var _ = 0, _$1 = 0, _$2 = 0, _$3 = 0, _$4 = 0, x = 0, y = 0, z = 0.0, w = 0.0, i = 0, $SP = 0;
U4[1] = totalSize - 64;
U4[0] = 4;
assertEqual(1, 1);
@@ -87,6 +87,67 @@ function main() {
assertEqual(z / w, 0.85);
assertEqual(z * w, 30.6);
assertEqual(z * +(x | 0), 40.8);
+ x = 5;
+ if ((x | 0) > 3) {
+ x = 10;
+ }
+ assertEqual(x | 0, 10);
+ x = 5;
+ {
+ _ = 0;
+ {
+ _$1 = 0;
+ if ((x | 0 | 0 | 0) > 3) {
+ if ((x | 0 | 0 | 0) < 10) {
+ _$1 = 1;
+ }
+ }
+ {
+ if (_$1) {
+ if (1) {
+ _ = 1;
+ }
+ }
+ }
+ }
+ {
+ if (_) {
+ x = 15;
+ }
+ }
+ }
+ x = 5;
+ y = 6;
+ {
+ _$2 = 0;
+ {
+ {
+ _$3 = 0;
+ {
+ if ((x | 0 | 0 | 0) > 1) {
+ _$3 = 1;
+ }
+ if ((y | 0 | 0 | 0) > 10) {
+ _$3 = 1;
+ }
+ }
+ {
+ if (_$3) {
+ _$2 = 1;
+ }
+ }
+ }
+ if (0) {
+ _$2 = 1;
+ }
+ }
+ {
+ if (_$2) {
+ x = 15;
+ }
+ }
+ }
+ assertEqual(x | 0, 15);
x = 0;
y = 1;
while ((x | 0) < 10) {
@@ -95,7 +156,7 @@ function main() {
}
assertEqual(y | 0, 1024);
y = 1;
- for (i = 0; (i | 0) < 10; _ = i, i = (i | 0) + 1 | 0, _) {
+ for (i = 0; (i | 0) < 10; _$4 = i, i = (i | 0) + 1 | 0, _$4) {
y = imul(y, 2) | 0;
}
assertEqual(y | 0, 1024);
View
20 test/asm/primitives.ljs
@@ -38,6 +38,26 @@ function void main() {
// mixing ints and doubles coerces everything to doubles
assertEqual(z * x, 40.8);
+ // if
+ x = 5;
+ if(x > 3) {
+ x = 10;
+ }
+ assertEqual(x, 10);
+
+ // conditionals
+ x = 5;
+ if(x > 3 && x < 10 && 1) {
+ x = 15;
+ }
+
+ x = 5;
+ y = 6;
+ if(x > 1 || y > 10 || 0) {
+ x = 15;
+ }
+ assertEqual(x, 15);
+
// while loop
x = 0;
y = 1;

0 comments on commit 6a24c33

Please sign in to comment.