use :node; var Node = module.require('../Node').Node; fn StringLiteral(chars, column) extends Node { this.type = 'StringLiteral'; this.chars = chars; this.column = column; } StringLiteral.prototype.codegen = () -> { if !super.codegen() { return; } var elements = []; for value in this.chars { var lastElement; if typeof value == 'string' { lastElement = elements[elements.length - 1]; if lastElement?.type == 'Literal' { lastElement.value += value; } else { elements.push({ type: 'Literal', value: value }); } } else if value?.type == "StringLiteralNewLine" { lastElement = elements[elements.length - 1]; if lastElement?.type == 'Literal' { lastElement.value += value.toString(this.column - 1); } else { elements.push({ type: 'Literal', value: value.toString(this.column - 1) }); } } else { value.parent = this; elements.push(value.codegen()); } } if elements.length == 0 { return { "type": "Literal", "value": "" }; } else if elements.length == 1 { return elements[0]; } var reduced = elements.reduce((left, right) -> { return { type: 'BinaryExpression', operator: '+', left: left, right: right }; }); this.type = reduced.type; this.operator = reduced.operator; this.left = reduced.left; this.right = reduced.right; return this; }; StringLiteral.prototype.hasCallExpression = () -> false; StringLiteral.NewLine = fn (text) { this.type = "StringLiteralNewLine"; this.toString = (column) -> { var t = text.replace(/\r\n/g, '').replace(/\t/g, ' '); if t.length < column { return ''; } return t.substring(column); }; }; exports.StringLiteral = StringLiteral;