use :node;
var Node = module.require('./Node').Node;
fn CaseClause(tests, body)
extends Node { this.type = 'CaseClause'; this.body = body; this.body.parent = this; this.tests = tests; if this.tests? { for test in this.tests { test.parent = this; } }
}
CaseClause.prototype.codegen = (branchFallthrough) -> {
if !super.codegen() { return; } if !this.tests? and !branchFallthrough { return this.body.codegen(); } this.type = "IfStatement"; this.switchCase = true; var rangeError = false; if this.tests? { for test in this.tests { var equalsToDiscriminant; if test.type == "Range" { var fromCheck; if test.start { fromCheck = { "type": "BinaryExpression", "operator": ">=", "left": this.parent.discriminant, "right": test.start }; } var toCheck; if test.to { toCheck = { "type": "BinaryExpression", "operator": "<" + ("=" if test.operator == ".." else ""), "left": this.parent.discriminant, "right": test.to }; } if fromCheck && toCheck { equalsToDiscriminant = { "type": "LogicalExpression", "operator": "&&", "left": fromCheck, "right": toCheck }; } else if fromCheck || toCheck { equalsToDiscriminant = fromCheck ?? toCheck; } else { rangeError = test; break; } } else if test.type == "ArrayExpression" { test = test.codegen(); equalsToDiscriminant = { "type": "BinaryExpression", "operator": ">=", "left": { "type": "MemberExpression", "computed": false, "object": this.parent.discriminant, "property": { "type": "Identifier", "name": "length" } }, "right": { "type": "Literal", "value": test.elements.length } }; for element, i in test.elements { if element? { equalsToDiscriminant = { "type": "LogicalExpression", "operator": "&&", "left": equalsToDiscriminant, "right": { "type": "BinaryExpression", "operator": "===", "left": { "type": "MemberExpression", "computed": true, "object": this.parent.discriminant, "property": { "type": "Literal", "value": i } }, "right": element } }; } } } else { equalsToDiscriminant = { "type": "BinaryExpression", "operator": "===", "left": this.parent.discriminant, "right": test.codegen() }; } if !this.test { this.test = equalsToDiscriminant; } else { this.test = { "type": "LogicalExpression", "operator": "||", "left": this.test, "right": equalsToDiscriminant }; } } } if rangeError { Node.getErrorManager().error({ type: "EmptyRange", message: "empty range in case clause is disallowed.", loc: rangeError.loc }); return null; } this.consequent = this.body.codegen(); if branchFallthrough { var fallthroughTest = { "type": "BinaryExpression", "left": this.parent.fallthroughId, "operator": "<", "right": { "type": "Literal", "value": 2 } }; if !this.tests? { this.test = fallthroughTest; } else { this.test = { "type": "LogicalExpression", "operator": "&&", "left": fallthroughTest, "right": this.test }; } } this.alternate = null; return this;
};
exports.CaseClause = CaseClause;