UNPKG

futurescript

Version:

A functional style, but highly readable language that compiles to JavaScript.

251 lines (227 loc) 7.62 kB
import * as $tools from "./tools.mjs"; import * as $lex from "./lex.mjs"; import * as $node from "./node.mjs"; import * as $base from "./expression-base.mjs"; import * as $pattern from "./pattern.mjs"; import * as $print from "./print.mjs"; import {JsBuilder as J} from "./js-builder.mjs"; export class PlusExpression extends $base.BinaryExpression { bareCompile() { return [this.x.compile(), "+", this.y.compile()]; } } PlusExpression.sign = $lex.Plus; export class MinusExpression extends $base.BinaryExpression { bareCompile() { return [this.x.compile(), "-", this.y.compile()]; } } MinusExpression.sign = $lex.Minus; export class TimesExpression extends $base.BinaryExpression { bareCompile() { return [this.x.compile(), "*", this.y.compile()]; } } TimesExpression.sign = $lex.Times; export class OverExpression extends $base.BinaryExpression { bareCompile() { return [this.x.compile(), "/", this.y.compile()]; } } OverExpression.sign = $lex.Over; export class BinaryCompareExpression extends $base.BinaryExpression { static patternsAndCaptures() { return [ [[$pattern.tokensExcept([ $lex.Equal, $lex.NotEqual, $lex.LessThan, $lex.GreaterThan, $lex.LessThanOrEqual, $lex.GreaterThanOrEqual ]), this.sign, $pattern.tokensExcept([ $lex.Equal, $lex.NotEqual, $lex.LessThan, $lex.GreaterThan, $lex.LessThanOrEqual, $lex.GreaterThanOrEqual ])], [0, 2]] ]; } } export class EqualExpression extends BinaryCompareExpression { bareCompile() { return [this.x.compile(), "===", this.y.compile()]; } } EqualExpression.sign = $lex.Equal; export class NotEqualExpression extends BinaryCompareExpression { bareCompile() { return [this.x.compile(), "!==", this.y.compile()]; } } NotEqualExpression.sign = $lex.NotEqual; export class LessThanExpression extends BinaryCompareExpression { bareCompile() { return [this.x.compile(), "<", this.y.compile()]; } } LessThanExpression.sign = $lex.LessThan; export class GreaterThanExpression extends BinaryCompareExpression { bareCompile() { return [this.x.compile(), ">", this.y.compile()]; } } GreaterThanExpression.sign = $lex.GreaterThan; export class LessThanOrEqualExpression extends BinaryCompareExpression { bareCompile() { return [this.x.compile(), "<=", this.y.compile()]; } } LessThanOrEqualExpression.sign = $lex.LessThanOrEqual; export class GreaterThanOrEqualExpression extends BinaryCompareExpression { bareCompile() { return [this.x.compile(), ">=", this.y.compile()]; } } GreaterThanOrEqualExpression.sign = $lex.GreaterThanOrEqual; export class ChainedCompareExpression extends $base.Expression { constructor(chain) { super(); this.chain = chain; } static patternsAndCaptures() { return [ [[$pattern.tokens, token => $tools.instanceof(token, [ $lex.Equal, $lex.LessThan, $lex.LessThanOrEqual ]), $pattern.tokens, token => $tools.instanceof(token, [ $lex.Equal, $lex.LessThan, $lex.LessThanOrEqual ]), $pattern.tokens], [0, 1, 2, 3, 4]], [[$pattern.tokens, token => $tools.instanceof(token, [ $lex.Equal, $lex.GreaterThan, $lex.GreaterThanOrEqual ]), $pattern.tokens, token => $tools.instanceof(token, [ $lex.Equal, $lex.GreaterThan, $lex.GreaterThanOrEqual ]), $pattern.tokens], [0, 1, 2, 3, 4]] ]; } static applyMatch(match, lex) { let convert = lexPart => { let token = lexPart.token(); if (token instanceof $lex.Equal) { return new $node.Equal().setLexPart(lexPart); } else if (token instanceof $lex.LessThan) { return new $node.LessThan().setLexPart(lexPart); } else if (token instanceof $lex.GreaterThan) { return new $node.GreaterThan().setLexPart(lexPart); } else if (token instanceof $lex.LessThanOrEqual) { return new $node.LessThanOrEqual().setLexPart(lexPart); } else if (token instanceof $lex.GreaterThanOrEqual) { return new $node.GreaterThanOrEqual().setLexPart(lexPart); } }; return new this( new $node.Arr([ this.build(lex.part(match[0])), convert(lex.part(match[1])), this.build(lex.part(match[2])), convert(lex.part(match[3])), this.build(lex.part(match[4])) ]) ); } bareCompile() { let convert = operator => { if (operator instanceof $node.Equal) { return "0"; } else if (operator instanceof $node.NotEqual) { return "1"; } else if (operator instanceof $node.LessThan) { return "2"; } else if (operator instanceof $node.GreaterThan) { return "3"; } else if (operator instanceof $node.LessThanOrEqual) { return "4"; } else if (operator instanceof $node.GreaterThanOrEqual) { return "5"; } }; let chain = this.chain.value; this.getRoot().predefinedLib.chainedCompare = true; return [ "chainedCompare_" + $node.antiConflictString + "(", chain[0].compile(), "," + convert(chain[1]) + ",", chain[2].compile(), "," + convert(chain[3]) + ",", chain[4].compile(), ")" ]; } } export class OrExpression extends $base.BinaryExpression { bareCompile() { return [this.x.compile(), "||", this.y.compile()]; } } OrExpression.sign = $lex.Or; export class AndExpression extends $base.BinaryExpression { bareCompile() { return [this.x.compile(), "&&", this.y.compile()]; } } AndExpression.sign = $lex.And; export class NotExpression extends $base.UnaryExpression { bareCompile() { return ["!", this.x.compile()]; } } NotExpression.sign = $lex.Not; export class PositiveExpression extends $base.UnaryExpression { bareCompile() { return ["+", this.x.compile()]; } } PositiveExpression.sign = $lex.Positive; export class NegativeExpression extends $base.UnaryExpression { bareCompile() { return ["-", this.x.compile()]; } } NegativeExpression.sign = $lex.Negative; export class RemExpression extends $base.BinaryExpression { bareCompile() { return [this.x.compile(), "%", this.y.compile()]; } } RemExpression.sign = $lex.Rem; export class ModExpression extends $base.BinaryExpression { bareCompile() { this.getRoot().predefinedLib.mod = true; return ["mod_" + $node.antiConflictString + "(", this.x.compile(), ",", this.y.compile(), ")"]; } } ModExpression.sign = $lex.Mod; export class PowerExpression extends $base.BinaryExpression { bareCompile() { return ["Math.pow(", this.x.compile(), ",", this.y.compile(), ")"]; } } PowerExpression.sign = $lex.Power;