Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GET TO THE CHOPVAR

Matt Steele
November 03, 2015

GET TO THE CHOPVAR

Writing an ArnoldC-to-Javascript compiler in Javascript

Have you ever wanted to invent your own programming language and run it in the browser? Well, you can! Write your own compiler! Or a transpiler, or whatever the cool kids are calling them these days. No formal knowledge of compilers is required.
In this talk, I'll show you how to use tools like Jison to build a compiler that targets JavaScript as a runtime. You can even generate Source Maps, so you can debug against your original code in the browser.
We'll then put it to use by writing a compiler for the greatest programming language of all time: ArnoldC.

Matt Steele

November 03, 2015
Tweet

More Decks by Matt Steele

Other Decks in Programming

Transcript

  1. HEY CHRISTMAS TREE foo YOU SET US UP 0 HEY

    CHRISTMAS TREE bar YOU SET US UP 1 foo = 0 bar = 1
  2. HEY CHRISTMAS TREE foo YOU SET US UP @I LIED

    HEY CHRISTMAS TREE bar YOU SET US UP @NO PROBLEMO foo = false bar = true
  3. a = (4 + b) * 2 GET TO THE

    CHOPPER a HERE IS MY INVITATION 4 GET UP b YOU'RE FIRED 2 ENOUGH TALK
  4. LISTEN TO ME VERY CAREFULLY fn TALK TO THE HAND

    "inside a function" HASTA LA VISTA, BABY DO IT NOW fn Functions
  5. LISTEN TO ME VERY CAREFULLY addFive I NEED YOUR CLOTHES

    YOUR BOOTS AND YOUR MOTORCYCLE num GET TO THE CHOPPER sum HERE IS MY INVITATION num GET UP 5 ENOUGH TALK TALK TO THE HAND sum HASTA LA VISTA, BABY DO IT NOW addFive 8
  6. LISTEN TO ME VERY CAREFULLY addFive I NEED YOUR CLOTHES

    YOUR BOOTS AND YOUR MOTORCYCLE num GIVE THESE PEOPLE AIR GET TO THE CHOPPER sum HERE IS MY INVITATION sum GET UP 5 ENOUGH TALK I'll BE BACK sum HASTA LA VISTA, BABY GET YOUR ASS TO MARS result DO IT NOW addFive 8 TALK TO THE HAND result
  7. #include<stdio.h> int main() { printf("Hello World\n"); return 0; } .section

    __TEXT,__text,regular,pure_instructions .macosx_version_min 10, 10 .globl _main .align 4, 0x90 _main: ## @main .cfi_startproc ## BB#0: pushq %rbp Ltmp0: .cfi_def_cfa_offset 16 Ltmp1: .cfi_offset %rbp, -16 movq %rsp, %rbp Ltmp2: .cfi_def_cfa_register %rbp leaq L_str(%rip), %rdi callq _puts xorl %eax, %eax popq %rbp retq .cfi_endproc .section __TEXT,__cstring,cstring_literals L_str: ## @str .asciz "Hello World" .subsections_via_symbols GCC
  8. ☕ math = root: Math.sqrt square: square cube: (x) ->

    x * square x math = { root: Math.sqrt, square: square, cube: function(x) { return x * square(x); } };
  9. [ . ; +a ; E introducinga - new 'language:

    i forautomatic 2 c- programming 5 f J ! 2 - 1' F m G-'- i m m d - D I V I S I O N OF SPERRY RAND CORPORATION http://www.computerhistory.org/collections/catalog/102646140
  10. UNIQUE SAVINGS f &he vm "FLOW-MATXC Virtually Eliminates Your Cading

    Load Your skilled programmers are freed from olerialstrudgery tcs do more creative work. FLOW-Mamc M t o smpbis'of the p r o g r m k g effort from detailed coding to problem definitionandsystem*amlysh,Slashesdrasticallythe time required to program new or aItered UNIVAC applications. Drastically Reduces Training Time In just a few days, users can be trained in the basic characteristics of the UNIVAC system and in the FLOW- MATIC method of ~roaamrnin~. - - With 0 FLOW-MATIC, it is not necessary to have a large staff of trained program- mers. The more complicated, time-con- suming training in techniques of com- puter coding need be taught only to those few people selected to become highly skilled career programmers.
  11. UNIQUE SAVINGS f &he vm "FLOW-MATXC Virtually Eliminates Your Cading

    Load Your skilled programmers are freed from olerialstrudgery tcs do more creative work. FLOW-Mamc M t o smpbis'of the p r o g r m k g effort from detailed coding to problem definitionandsystem*amlysh,Slashesdrasticallythe time required to program new or aItered UNIVAC applications. Drastically Reduces Training Time In just a few days, users can be trained in the basic characteristics of the UNIVAC system and in the FLOW- MATIC method of ~roaamrnin~. - - With 0 FLOW-MATIC, it is not necessary to have a large staff of trained program- mers. The more complicated, time-con- suming training in techniques of com- puter coding need be taught only to those few people selected to become highly skilled career programmers. SAVINGS f &he vm W-MATXC Virtually Eliminates Your Cading Load Your skilled programmers are freed from olerialstrudgery tcs do more creative work. FLOW-Mamc M t o smpbis'of the p r o g r m k g effort from detailed coding to problem definitionandsystem*amlysh,Slashesdrasticallythe time required to program new or aItered UNIVAC applications.
  12. UNIQUE SAVINGS f &he vm "FLOW-MATXC Virtually Eliminates Your Cading

    Load Your skilled programmers are freed from olerialstrudgery tcs do more creative work. FLOW-Mamc M t o smpbis'of the p r o g r m k g effort from detailed coding to problem definitionandsystem*amlysh,Slashesdrasticallythe time required to program new or aItered UNIVAC applications. Drastically Reduces Training Time In just a few days, users can be trained in the basic characteristics of the UNIVAC system and in the FLOW- MATIC method of ~roaamrnin~. - - With 0 FLOW-MATIC, it is not necessary to have a large staff of trained program- mers. The more complicated, time-con- suming training in techniques of com- puter coding need be taught only to those few people selected to become highly skilled career programmers.
  13. UNIQUE SAVINGS f &he vm "FLOW-MATXC Virtually Eliminates Your Cading

    Load Your skilled programmers are freed from olerialstrudgery tcs do more creative work. FLOW-Mamc M t o smpbis'of the p r o g r m k g effort from detailed coding to problem definitionandsystem*amlysh,Slashesdrasticallythe time required to program new or aItered UNIVAC applications. Drastically Reduces Training Time In just a few days, users can be trained in the basic characteristics of the UNIVAC system and in the FLOW- MATIC method of ~roaamrnin~. - - With 0 FLOW-MATIC, it is not necessary to have a large staff of trained program- mers. The more complicated, time-con- suming training in techniques of com- puter coding need be taught only to those few people selected to become highly skilled career programmers. Drastically Reduces Training Time In just a few days, users can be trained in the basic characteristics of the UNIVAC system and in the FLOW- MATIC method of ~roaamrnin~. - - With 0 FLOW-MATIC, it is not necessary to have a large staff of trained program- mers. The more complicated, time-con- suming training in techniques of com- puter coding need be taught only to those few people selected to become highly skilled career programmers.
  14. Lexical Analysis GET TO THE CHOPPER a HERE IS MY

    INVITATION 4 GET UP b YOU'RE FIRED 2 ENOUGH TALK
  15. Lexical Analysis GET TO THE CHOPPER a HERE IS MY

    INVITATION 4 GET UP b YOU'RE FIRED 2 ENOUGH TALK
  16. GET TO THE CHOPPER a HERE IS MY INVITATION 4

    GET UP b YOU'RE FIRED 2 ENOUGH TALK KEYWORD_ASSIGN_VARIABLE VARIABLE KEYWORD_SET_VALUE INTEGER KEYWORD_PLUS_OPERATOR VARIABLE KEYWORD_MULTIPLICATION_OPERATOR INTEGER KEYWORD_END_ASSIGN_VARIABLE
  17. GET TO THE CHOPPER a HERE IS MY INVITATION 4

    GET UP b YOU'RE FIRED 2 ENOUGH TALK
  18. GET TO THE CHOPPER a 4 HERE IS MY INVITATION

    assignment operation GET UP b YOU'RE FIRED 2 initial value operation
  19. VARIABLE INTEGER SET_VALUE assignment operation PLUS_ OPERATOR VARIABLE MULTIPLICATION_ OPERATOR

    INTEGER initial value operation Abstract Syntax Tree ASSIGN_VARIABLE
  20. var a = 4; a = a + b; a

    + a * 2; let a = ((4 + b) * 2);
  21. var fs = require("fs"); var jison = require("jison"); var bnf

    = fs.readFileSync("grammar.jison", "utf8"); var parser = new jison.Parser(bnf); var transpiled = parser.parse(input);
  22. var fs = require("fs"); var jison = require("jison"); var bnf

    = fs.readFileSync("grammar.jison", "utf8"); var parser = new jison.Parser(bnf); var transpiled = parser.parse(input); "grammar.jison"
  23. grammar.jison %lex /* lexical grammar */ %% /* Lexer */

    /lex %% /* language grammar */ /* Parser / Translate */
  24. %lex %% \s+ /* skip whitespaces */ "IT'S SHOWTIME" return

    'BEGIN_MAIN' "YOU HAVE BEEN TERMINATED" return 'END_MAIN' \-?[0-9]+ return 'NUMBER' "TALK TO THE HAND" return 'PRINT' "@I LIED" return 'FALSE' "@NO PROBLEMO" return 'TRUE' "HEY CHRISTMAS TREE" return 'DECLARE_INT' "YOU SET US UP" return 'SET_INITIAL_VALUE' "GET TO THE CHOPPER" return 'BEGIN_ASSIGN' "ENOUGH TALK" return 'END_ASSIGN' "HERE IS MY INVITATION" return 'SET_VALUE' "GET UP" return 'PLUS' "GET DOWN" return 'MINUS' "YOU'RE FIRED" return 'MULTIPLY' "HE HAD TO SPLIT" return 'DIVIDE' "I LET HIM GO" return 'MODULO' "YOU ARE NOT YOU YOU ARE ME" return 'EQUAL' "LET OFF SOME STEAM BENNET" return 'GREATER' "CONSIDER THAT A DIVORCE" return 'OR' "KNOCK KNOCK" return 'AND'
  25. Expression : Expression PLUS Expression | Expression MINUS Expression |

    Expression TIMES Expression | Expression DIVIDE Expression | Expression EXP Expression | LEFT_PAREN Expression RIGHT_PAREN | NUMBER | E | PI ; Language Grammar
  26. Translating to JavaScript Expression : Expression PLUS Expression { js

    code to execute } | Expression MINUS Expression { js code to execute } | Expression TIMES Expression { js code to execute } | Expression DIVIDE Expression { js code to execute } | LEFT_PAREN Expression RIGHT_PAREN { js code to execute }
  27. Translating to JavaScript Expression : Expression PLUS Expression { $$

    = $1 + $3; } | Expression MINUS Expression { $$ = new MinusOperator($1, $3); } | Expression TIMES Expression { $$ = new Operator($1, '*', $3); } | Expression DIVIDE Expression { $$ = new Operator($2, $1, $3); } | LEFT_PAREN Expression RIGHT_PAREN { $$ = $2; }
  28. Translating to JavaScript Expression : Expression PLUS Expression { $$

    = $1 + $3; } | Expression MINUS Expression { $$ = new MinusOperator($1, $3); } | Expression TIMES Expression { $$ = new Operator($1, '*', $3); } | Expression DIVIDE Expression { $$ = new Operator($2, $1, $3); } | LEFT_PAREN Expression RIGHT_PAREN { $$ = $2; }
  29. Translating to JavaScript Expression : Expression PLUS Expression { $$

    = $1 + $3; } | Expression MINUS Expression { $$ = new MinusOperator($1, $3); } | Expression TIMES Expression { $$ = new Operator($1, '*', $3); } | Expression DIVIDE Expression { $$ = new Operator($2, $1, $3); } | LEFT_PAREN Expression RIGHT_PAREN { $$ = $2; }
  30. Translating to JavaScript Expression : Expression PLUS Expression { $$

    = $1 + $3; } | Expression MINUS Expression { $$ = new MinusOperator($1, $3); } | Expression TIMES Expression { $$ = new Operator($1, '*', $3); } | Expression DIVIDE Expression { $$ = new Operator($2, $1, $3); } | LEFT_PAREN Expression RIGHT_PAREN { $$ = $2; }
  31. Expression : Expression MINUS Expression { $$ = new yy.MinusOperator($1,

    $3); } ; bnf.jison var yy = { MinusOperator: function(first, second) { return first + ' - ' + second; } }; module.exports = yy; ast.js
  32. Expression : Expression MINUS Expression { $$ = new yy.MinusOperator($1,

    $3); } ; bnf.jison var yy = { MinusOperator: function(first, second) { return first + ' - ' + second; } }; module.exports = yy; ast.js var parser = new jison.Parser(bnf); parser.yy = require('./ast'); transpiler.js
  33. program : methods BEGIN_MAIN statements END_MAIN methods EOF { return

    $1 .concat($5) .concat(new yy.MainExpression($3, @2, @4)); } ; statements : statements statement { $$ = $1.concat($2); } | { $$ = []; } ;
  34. program : methods BEGIN_MAIN statements END_MAIN methods EOF { return

    $1 .concat($5) .concat(new yy.MainExpression($3, @2, @4)); } ; statements : statements statement { $$ = $1.concat($2); } | { $$ = []; } ;
  35. program : methods BEGIN_MAIN statements END_MAIN methods EOF { return

    $1 .concat($5) .concat(new yy.MainExpression($3, @2, @4)); } ; statements : statements statement { $$ = $1.concat($2); } | { $$ = []; } ;
  36. program : methods BEGIN_MAIN statements END_MAIN methods EOF { return

    $1 .concat($5) .concat(new yy.MainExpression($3, @2, @4)); } ; statements : statements statement { $$ = $1.concat($2); } | { $$ = []; } ;
  37. statement : PRINT integer { $$ = new yy.PrintExpression(@1, $2);

    } | DECLARE_INT variable SET_INITIAL_VALUE integer { $$ = new yy.IntDeclarationExpression(@1, $2, $4); } | BEGIN_ASSIGN variable SET_VALUE integer END_ASSIGN { $$ = new yy.AssignmentExpression(@1, $2, $4, []);} | BEGIN_ASSIGN variable SET_VALUE integer ops END_ASSIGN { $$ = new yy.AssignmentExpression(@1, $2, $4, $5);} | IF integer statements END_IF { $$ = new yy.IfExpression(@1, $2, $3, [], @4); } | IF integer statements else statements END_IF { $$ = new yy.IfExpression(@1, $2, $3, $5, @6, $4); } | WHILE variable statements END_WHILE { $$ = new yy.WhileExpression(@1, $2, $3, @4); } | method_call { $$ = $1; } | ASSIGN_FROM_CALL variable method_call { $$ = new yy.AssignmentFromCallExpression(@1, $2, $3); } | RETURN integer { $$ = new yy.ReturnExpression(@1, $2); } ;
  38. statement : PRINT integer { $$ = new yy.PrintExpression(@1, $2);

    } | DECLARE_INT variable SET_INITIAL_VALUE integer { $$ = new yy.IntDeclarationExpression(@1, $2, $4); } | BEGIN_ASSIGN variable SET_VALUE integer END_ASSIGN { $$ = new yy.AssignmentExpression(@1, $2, $4, []);} | BEGIN_ASSIGN variable SET_VALUE integer ops END_ASSIGN { $$ = new yy.AssignmentExpression(@1, $2, $4, $5);} | IF integer statements END_IF { $$ = new yy.IfExpression(@1, $2, $3, [], @4); } | IF integer statements else statements END_IF { $$ = new yy.IfExpression(@1, $2, $3, $5, @6, $4); } | WHILE variable statements END_WHILE { $$ = new yy.WhileExpression(@1, $2, $3, @4); } | method_call { $$ = $1; } | ASSIGN_FROM_CALL variable method_call { $$ = new yy.AssignmentFromCallExpression(@1, $2, $3); } | RETURN integer { $$ = new yy.ReturnExpression(@1, $2); } ;
  39. class PrintExpression extends AstNode { constructor(position, value) { super(position.first_line, position.first_column);

    this.value = value; } compile() { return 'console.log( ' + this.value.compile() + ' );\n'; } }
  40. class AstNode { constructor(line, column) { this.line = line; this.column

    = column; } compile() { //Abstract } } class PrintExpression extends AstNode { constructor(position, value) { super(position.first_line, position.first_column); this.value = value; } compile() { return 'console.log( ' + this.value.compile() + ' );\n'; } }
  41. class AstNode { constructor(line, column) { this.line = line; this.column

    = column; } compile() { //Abstract } } class PrintExpression extends AstNode { constructor(position, value) { super(position.first_line, position.first_column); this.value = value; } compile() { return 'console.log( ' + this.value.compile() + ' );\n'; } }
  42. class PrintExpression extends AstNode { constructor(position, value) { super(position.first_line, position.first_column);

    this.value = value; } compile() { return 'console.log( ' + this.value.compile() + ' );\n'; } }
  43. class AstNode { constructor(line, column) { this.line = line; this.column

    = column; } compile() { //Abstract } } class PrintExpression extends AstNode { constructor(position, value) { super(position.first_line, position.first_column); this.value = value; } compile() { return 'console.log( ' + this.value.compile() + ' );\n'; } }
  44. class MainExpression extends AstNode { constructor(statements, startPosition, endPosition) { //

    etc etc } compile(indent, fileName) { return this._sn('(function() {\n') .add(this.statements.map(function (child) { return child.compile(); })) .add('}());\n')); } }
  45. var fs = require("fs"); var jison = require("jison"); var bnf

    = fs.readFileSync("grammar.jison", "utf8"); var parser = new jison.Parser(bnf); return parser.parse(input); CLI
  46. var fs = require("fs"); var jison = require("jison"); var bnf

    = fs.readFileSync("grammar.jison", "utf8"); var parser = new jison.Parser(bnf); return parser.parse(input); CLI
  47. var multiple = divisible(n, 3); if (multiple) { console.log( "Fizz"

    ); } else { var multiple = divisible(n, 5); if (multiple) { console.log( "Buzz" ); } else { console.log( n ); } } } } }()); }()); //# sourceMappingURL=fizzbuzz.arnoldc.js.map
  48. var multiple = divisible(n, 3); if (multiple) { console.log( "Fizz"

    ); } else { var multiple = divisible(n, 5); if (multiple) { console.log( "Buzz" ); } else { console.log( n ); } } } } }()); }()); //# sourceMappingURL=fizzbuzz.arnoldc.js.map
  49. {"version":3,"sources":["fizzbuzz.arnoldc"],"names": [],"mappings":";;CA2CA,SAA4B,MAA5B,EACqD,QADrD,EAEqD,OAFrD;GAII,IAAmB,QAAnB,GACgB,CADhB;GAEA,IAAmB,SAAnB,GACgB,CADhB;GAEA,IAAm B,OAAnB,GACgB,CADhB;GAEA,IAAmB,QAAnB,KACwB,QACtB,GAAgB,OAFlB;GAAA,UAAmB,QAAnB,mBAAmB,QAAnB,GAAmB,QAAnB;GAAmB,QAAnB,cAAmB,QAAnB ;GAIA,IAAmB,OAAnB,KACwB,OACtB,GAAa,QAFf;GAAA,UAAmB,OAAnB,mBAAmB,OAAnB,GAAmB,OAAnB;GAAmB,OAAnB,cAAmB,OAAnB;GAIA,IAAmB,SAAnB,KAC wB,QACxB,GAAS,OAFT;GAAA,UAAmB,SAAnB,mBAAmB,SAAnB,GAAmB,SAAnB;GAAmB,SAAnB,cAAmB,SAAnB;GAIF,OAAa,SAAb;CACF;CAEA,SAA4B,SAA5B,EACm D,QADnD,EAEmD,OAFnD;GAKA,IAAmB,MAAnB,GACc,CADd;GAEA,IAAqB,MAArB,GACU,MAAV,CAAiB,QAAjB,EAA0B,OAA1B;GAEA,IAAmB,MAAnB,GACc,CADd;G AEA,IAAmB,MAAnB,KACsB,MACtB,IAA2B,CAF3B;GAAA,UAAmB,MAAnB,mBAAmB,MAAnB,GAAmB,MAAnB;GAAmB,MAAnB,cAAmB,MAAnB;GAKA,OAAa,MAAb;CACA; CAtFA;GAEA,IAAmB,aAAnB,GACc,IADd;GAEA,IAAmB,CAAnB,GACc,CADd;GAEA,IAAmB,QAAnB,GACc,IADd;GAGA,OAAa,aAAb;KACA,IAAmB,CAAnB,KACsB,C ACtB,GAAO,CAFP;KAAA,UAAmB,CAAnB,mBAAmB,CAAnB,GAAmB,CAAnB;KAAmB,CAAnB,cAAmB,CAAnB;KAKA,IAAmB,aAAnB,KACsB,GACtB,GAA0B,CAF1B;KAAA ,UAAmB,aAAnB,mBAAmB,aAAnB,GAAmB,aAAnB;KAAmB,aAAnB,cAAmB,aAAnB;KAKA,IAAqB,QAArB,GACU,SAAV,CAAoB,CAApB,EAAsB,EAAtB;KACA,IAAgC,QA

    AhC;OACA,aAAiB,UAAjB;KADA;KAEA;OACA,IAAqB,QAArB,GACU,SAAV,CAAoB,CAApB,EAAsB,CAAtB;OACA,IAAgC,QAAhC;SACA,aAAiB,MAAjB;OADA;OAEA; SACA,IAAqB,QAArB,GACU,SAAV,CAAoB,CAApB,EAAsB,CAAtB;SACA,IAAgC,QAAhC;WACA,aAAiB,MAAjB;SADA;SAEA;WACA,aAAiB,CAAjB;SACA;OACA;KACA ;GACA;CAEA","file":"fizzbuzz.arnoldc.js.map","sourcesContent":["IT'S SHOWTIME\n\nHEY CHRISTMAS TREE isLessThan100\nYOU SET US UP @NO PROBLEMO\nHEY CHRISTMAS TREE n\nYOU SET US UP 0\nHEY CHRISTMAS TREE multiple\nYOU SET US UP @NO PROBLEMO\n\nSTICK AROUND isLessThan100\nGET TO THE CHOPPER n\nHERE IS MY INVITATION n\nGET UP 1\nENOUGH TALK\n\nGET TO THE CHOPPER isLessThan100\nHERE IS MY INVITATION 100\nLET OFF SOME STEAM BENNET n\nENOUGH TALK\n\nGET YOUR ASS TO MARS multiple\nDO IT NOW divisible n 15\nBECAUSE I'M GOING TO SAY PLEASE multiple\nTALK TO THE HAND \"FizzBuzz\"\nBULLSHIT\nGET YOUR ASS TO MARS multiple\nDO IT NOW divisible n 3\nBECAUSE I'M GOING TO SAY PLEASE multiple\nTALK TO THE HAND \"Fizz\"\nBULLSHIT\nGET YOUR ASS TO MARS multiple\nDO IT NOW divisible n 5\nBECAUSE I'M GOING TO SAY PLEASE multiple\nTALK TO THE HAND \"Buzz\"\nBULLSHIT\nTALK TO THE HAND n\nYOU HAVE NO RESPECT FOR LOGIC\nYOU HAVE NO RESPECT FOR LOGIC\nYOU HAVE NO RESPECT FOR LOGIC\nCHILL\n\nYOU HAVE BEEN TERMINATED\n\nLISTEN TO ME VERY CAREFULLY modulo\n I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE dividend\n I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE divisor\n GIVE THESE PEOPLE AIR\n HEY CHRISTMAS TREE quotient\n YOU SET US UP 0\n HEY CHRISTMAS TREE remainder\n YOU SET US UP 0\n HEY CHRISTMAS TREE product\n YOU SET US UP 0\n GET TO THE CHOPPER quotient\n HERE IS MY INVITATION dividend\n HE HAD TO SPLIT divisor\n ENOUGH TALK\n GET TO THE CHOPPER product\n HERE IS MY INVITATION divisor\n YOU'RE FIRED quotient\n ENOUGH TALK\n GET TO THE CHOPPER remainder\n HERE IS MY INVITATION dividend\n GET DOWN product\n ENOUGH TALK\n I'LL BE BACK remainder\nHASTA LA VISTA, BABY\n\nLISTEN TO ME VERY CAREFULLY divisible\nI NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE dividend\nI NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE divisor\nGIVE THESE PEOPLE AIR\n\nHEY CHRISTMAS TREE result\nYOU SET US UP 0\nGET YOUR ASS TO MARS result\nDO IT NOW modulo dividend divisor\n\nHEY CHRISTMAS TREE isZero\nYOU SET US UP 0\nGET TO THE CHOPPER isZero \nHERE IS MY INVITATION result\nYOU ARE NOT YOU YOU ARE ME 0\nENOUGH TALK\n\nI'LL BE BACK isZero\nHASTA LA VISTA, BABY\n"]}
  50. var sourceNode = require('source-map').SourceNode; var AdditionOperation = function(first, second) {

    return new SourceNode( line, column, source, `${first} + ${second}` ); }; ast.js
  51. class AstNode { _sn(indent, fileName, chunk) { return new SourceNode(this.line,

    this.column, fileName, '') .add(indentNode(indent)) .add(chunk); } compile(indent, fileName) { //Abstract } }
  52. class AstNode { _sn(indent, fileName, chunk) { return new SourceNode(this.line,

    this.column, fileName, '') .add(indentNode(indent)) .add(chunk); } compile(indent, fileName) { //Abstract } } class MainExpression extends AstNode { compile(indent, fileName) { return this._sn(indent, fileName, '(function() {\n') .add(this.statements.map(function (child) { return child.compile(indent + 1, fileName); })) .add(indentNode(indent)) .add(new SourceNode(this.endLine, this.endColumn, fileName, '}());\n')); } }