Advertisement
Guest User

Aphid.alx

a guest
Apr 18th, 2015
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. namespace Components.Aphid;
  2. token AphidTokenType;
  3. base AphidExpression;
  4. node AphidNodeType;
  5. parser AphidParser;
  6.  
  7. ////////////////////////////////////////////////////////////////
  8. // Types
  9. ////////////////////////////////////////////////////////////////
  10. BinaryOperatorExpression = { LeftOperand, AphidTokenType Operator, RightOperand };
  11. UnaryOperatorExpression = { AphidTokenType Operator, Operand, opt bool IsPostfix };
  12. CallExpression = { FunctionExpression, opt list Args };
  13. TernaryOperatorExpression = { AphidTokenType Operator, FirstOperand, SecondOperand, ThirdOperand };
  14. ArrayAccessExpression = { ArrayExpression, KeyExpression };
  15. IdentifierExpression = { string Identifier, opt list IdentifierExpression Attributes };
  16. IfExpression = { Condition, list Body, list ElseBody };
  17. DynamicMemberExpression = { foo foo };
  18. ExtendExpression = { string ExtendType, ObjectExpression Object };
  19. ForEachExpression = { foo foo };
  20. ForExpression = { foo foo };
  21. WhileExpression = { foo foo };
  22. DoWhileExpression = { foo foo };
  23. LoadScriptExpression = { FileExpression };
  24. LoadLibraryExpression = { LibraryExpression };
  25. TryExpression = { list TryBody, IdentifierExpression CatchArg, list CatchBody, list FinallyBody };
  26. SwitchExpression = { foo foo };
  27. SwitchCase = { foo foo };
  28. StringExpression = { foo foo };
  29. ObjectExpression = { foo };
  30. ArrayExpression = { foo };
  31. FunctionExpression = { foo };
  32. PartialFunctionExpression = { foo };
  33. PatternMatchingExpression = { foo };
  34. PatternExpression = { foo };
  35. NumberExpression = { decimal Value, };
  36.  
  37. ////////////////////////////////////////////////////////////////
  38. // Macros
  39. ////////////////////////////////////////////////////////////////
  40. Delim = macro(@(_left, _value, _right) {
  41.     Match(_left);
  42.     _value;
  43.     Match(_right);
  44. });
  45.  
  46. Parens = macro(@(_value) { Delim(LeftParenthesis, _value, RightParenthesis); });
  47.  
  48. Prefix = macro(@(_token, _value) {
  49.     Match(_token);
  50.     _value;
  51. });
  52.  
  53. TakeToken = macro(@(_var) {
  54.     _var = TokenType;
  55.     NextToken;
  56. });
  57.  
  58. SkipThen = macro(@(_retVal) {
  59.     @() {
  60.         NextToken;
  61.         ret _retVal;
  62.     };
  63. });
  64.  
  65. ThenSkip = macro(@(_retVal) {
  66.     @() {
  67.         exp = _retVal;
  68.         NextToken;
  69.         ret exp;
  70.     };
  71. });
  72.  
  73. ParseBinOpExp = macro(@(_parse, _ops) {
  74.     @() {
  75.         operand = _parse();
  76.  
  77.         while (_ops) {
  78.             TakeToken(op);
  79.             operand = BinaryOperatorExpression(operand, op, _parse());
  80.         }
  81.  
  82.         ret operand;
  83.     };
  84. });
  85.  
  86. ////////////////////////////////////////////////////////////////
  87. // Functions
  88. ////////////////////////////////////////////////////////////////
  89. root list Parse = @() {
  90.     expressionSequence;
  91.     NextToken;
  92.     while (!None) expressionSequence += ParseStatement();
  93.  
  94.     ret expressionSequence;
  95. };
  96.  
  97. ParseStatement = _ParseStatement(true);
  98. ParseSingleStatement = _ParseStatement(false);
  99.  
  100. _ParseStatement = macro(@(_requireEos) {
  101.     @() {
  102.         exp;
  103.    
  104.         // Todo add support for $ op
  105.         switch (TokenType) {
  106.             ifKeyword: exp ParseIfExpression;
  107.             forKeyword: exp ParseForExpression;
  108.             whileKeyword: exp ParseWhileExpression;
  109.            
  110.             doKeyword: {
  111.                 exp ParseDoWhileExpression;
  112.                 MatchEos(_requireEos);
  113.             }
  114.  
  115.             extendKeyword: exp ParseExtendExpression;
  116.             tryKeyword: exp ParseTryExpression;
  117.             switchKeyword: exp ParseSwitchExpression;
  118.            
  119.             default:  {
  120.                 exp ParseExpression;
  121.                 MatchEos(_requireEos);
  122.             }
  123.         }
  124.  
  125.         ret exp;
  126.     };
  127. });
  128.  
  129. MatchEos = macro(@(_requireEos) { if (_requireEos) EndOfStatement; });
  130. ParseExpression = @() ParseAssignmentExpression();
  131.  
  132. ParseAssignmentExpression = ParseBinOpExp(
  133.     ParsePipelineExpression,
  134.     AssignmentOperator |
  135.     PlusEqualOperator |
  136.     MinusEqualOperator |
  137.     MultiplicationEqualOperator |
  138.     DivisionEqualOperator |
  139.     ModulusEqualOperator |
  140.     BinaryAndEqualOperator |
  141.     OrEqualOperator |
  142.     XorEqualOperator |
  143.     ShiftLeftEqualOperator |
  144.     ShiftRightEqualOperator);
  145.  
  146. ParsePipelineExpression = ParseBinOpExp(ParseQueryExpression, PipelineOperator);
  147.  
  148. ParseQueryExpression = @() {
  149.     exp ParseRangeExpression;
  150.     inQuery = true;
  151.  
  152.     do {
  153.         switch (TokenType) {
  154.             AggregateOperator,
  155.             AnyOperator,  
  156.             SelectManyOperator,
  157.             SelectOperator,
  158.             WhereOperator: {
  159.                 TakeToken(t);
  160.                 exp = BinaryOperatorExpression(exp, t, ParseRangeExpression());
  161.             }
  162.  
  163.             DistinctOperator: {
  164.                 exp = UnaryOperatorExpression(TokenType, exp);
  165.                 NextToken;
  166.             }
  167.  
  168.             default: inQuery = false;
  169.         }
  170.     } while(inQuery);
  171.  
  172.     ret exp;
  173. };
  174.  
  175. ParseRangeExpression = ParseBinOpExp(ParseConditionalExpression, RangeOperator);
  176.  
  177. ParseConditionalExpression = @() {
  178.     exp ParseLogicalExpression;
  179.  
  180.     if (ConditionalOperator) {
  181.         NextToken;
  182.         trueExpression ParseExpression;
  183.         ColonOperator;
  184.         falseExpression ParseExpression;
  185.  
  186.         ret TernaryOperatorExpression(
  187.             ConditionalOperator,
  188.             exp,
  189.             trueExpression,
  190.             falseExpression);
  191.     } else {
  192.         ret exp;
  193.     }
  194. };
  195.  
  196. ParseLogicalExpression = ParseBinOpExp(ParseComparisonExpression, AndOperator | OrOperator);
  197.  
  198. ParseComparisonExpression = ParseBinOpExp(
  199.     ParsePostfixUnaryOperationExpression,
  200.     EqualityOperator |
  201.     NotEqualOperator |
  202.     LessThanOperator |
  203.     LessThanOrEqualOperator |
  204.     GreaterThanOperator |
  205.     GreaterThanOrEqualOperator);
  206.  
  207. ParsePostfixUnaryOperationExpression = @() {
  208.     term = ParseBinaryOrExpression();
  209.  
  210.     switch (TokenType) {
  211.         IncrementOperator, DecrementOperator: {
  212.             TakeToken(op);
  213.  
  214.             ret UnaryOperatorExpression(op, term, true);
  215.         }
  216.  
  217.         default: ret term;
  218.     }
  219. };
  220.  
  221. ParseBinaryOrExpression = ParseBinOpExp(ParseXorExpression, BinaryOrOperator);
  222. ParseXorExpression = ParseBinOpExp(ParseBinaryAndExpression, XorOperator);
  223. ParseBinaryAndExpression = ParseBinOpExp(ParseShiftExpression, BinaryAndOperator);
  224. ParseShiftExpression = ParseBinOpExp(ParseAdditionExpression, ShiftLeft | ShiftRight);
  225. ParseAdditionExpression = ParseBinOpExp(ParseTermExpression, AdditionOperator | MinusOperator);
  226.  
  227. ParseTermExpression = ParseBinOpExp(
  228.     ParsePrefixUnaryOperatorExpression,
  229.     MultiplicationOperator | DivisionOperator | ModulusOperator);
  230.  
  231. ParsePrefixUnaryOperatorExpression = @() {
  232.     switch (TokenType) {
  233.         AdditionOperator,
  234.         MinusOperator,
  235.         NotOperator,
  236.         IncrementOperator,
  237.         DecrementOperator,
  238.         MultiplicationOperator,
  239.         ComplementOperator: {
  240.             TakeToken(t);
  241.                        
  242.             ret UnaryOperatorExpression(t, ParseArrayAccessExpression());
  243.         }
  244.  
  245.         default: ret ParseArrayAccessExpression();
  246.     }
  247. };
  248.  
  249. ParseArrayAccessExpression = @() {
  250.     exp ParseCallExpression;
  251.  
  252.     while (LeftBracket) {
  253.         NextToken;
  254.         key ParseExpression;
  255.         RightBracket;
  256.         exp = ArrayAccessExpression(exp, key);
  257.     }
  258.  
  259.     ret exp;
  260. };
  261.  
  262. ParseCall = macro(@(_parseFunc) {
  263.     @() {
  264.         function = _parseFunc();
  265.  
  266.         while (LeftParenthesis) {
  267.             NextToken;
  268.        
  269.             if (RightParenthesis) {
  270.                 NextToken;
  271.                 function = CallExpression(function);
  272.             } else {
  273.                 args ParseTuple;
  274.                 RightParenthesis;
  275.                 function = CallExpression(function, args);
  276.             }
  277.         }
  278.  
  279.         ret function;
  280.     };
  281. });
  282.  
  283. ParseCallBody = macro(@(_func) {
  284.     while (LeftParenthesis) {
  285.         NextToken;
  286.        
  287.         if (RightParenthesis) {
  288.             NextToken;
  289.             _func = CallExpression(_func);
  290.         } else {
  291.             args = ParseTuple();
  292.             RightParenthesis;
  293.             _func = CallExpression(_func, args);
  294.         }
  295.     }
  296. });
  297.  
  298. ParseCallExpression = ParseCall(ParseMemberExpression);
  299.  
  300. ParseMemberExpression = @() {
  301.     factor ParseFactorCallExpression;
  302.  
  303.     while (MemberOperator) {
  304.         NextToken;
  305.         exp;
  306.  
  307.         switch (TokenType) {
  308.             Identifier: {
  309.                 exp = IdentifierExpression(Lexeme);
  310.                 NextToken;
  311.             }
  312.  
  313.             String: exp ParseStringExpression;
  314.  
  315.             LeftBrace: {
  316.                 NextToken;
  317.                 exp = DynamicMemberExpression(ParseExpression());
  318.                 RightBrace;
  319.             }
  320.  
  321.             default: {
  322.                 // Todo: exception handling
  323.                 //throw new AphidParserException(_currentToken);
  324.             }
  325.         }
  326.  
  327.         factor = BinaryOperatorExpression(factor, MemberOperator, exp);
  328.         ParseCallBody(factor);     
  329.  
  330.         if (definedKeyword) {
  331.             NextToken;
  332.  
  333.             ret UnaryOperatorExpression(definedKeyword, factor, true);
  334.         }
  335.     }
  336.  
  337.     ret factor;
  338. };
  339.  
  340. ParseFactorCallExpression = ParseCall(ParseFactorExpression);
  341. ParseStringExpression = Lexeme |> StringExpression |> ThenSkip;
  342. ParseFactorExpression = @() { };
  343.  
  344. IdentifierExpression ParseIdentifierExpression = @() {
  345.     exp = IdentifierExpression(Lexeme);
  346.     NextToken;
  347.  
  348.     if (Identifier) {
  349.         id = exp;
  350.         // Add support for [] instead of 'list IdentifierExpression', infer type
  351.         attrs = list IdentifierExpression;
  352.  
  353.         do {
  354.             attrs += id;
  355.             id = IdentifierExpression(Lexeme);
  356.             NextToken;
  357.         } while (Identifier);
  358.  
  359.         exp = IdentifierExpression(id.Identifier, attrs);
  360.     }
  361.  
  362.     ret exp;
  363. };
  364.  
  365. ParseUnaryExpression = @() {
  366.     TakeToken(t);
  367.  
  368.     ret UnaryOperatorExpression(t, ParseExpression());
  369. };
  370.  
  371. ParseCondition = @() {
  372.     Parens(condition ParseExpression);
  373.    
  374.     ret condition;
  375. };
  376.  
  377. ParseIfExpression = @() {
  378.     NextToken;
  379.     condition ParseCondition;
  380.     body ParseBlock;
  381.     list elseBody;
  382.  
  383.     if (elseKeyword)
  384.     {
  385.         NextToken;
  386.         elseBody ParseBlock;
  387.     }
  388.  
  389.     ret IfExpression(condition, body, elseBody);
  390. };
  391.  
  392. _ParseBlock = macro(@(_parseStatement) {
  393.     @() {
  394.         statements;
  395.  
  396.         if (LeftBrace) {
  397.             NextToken;
  398.             while (!RightBrace) statements += ParseStatement();
  399.             NextToken;
  400.         } else {
  401.             statements += _parseStatement();
  402.         }
  403.  
  404.         ret statements;
  405.     };
  406. });
  407.  
  408. list ParseBlock = _ParseBlock(ParseStatement);
  409. list ParseSingleBlock = _ParseBlock(ParseSingleStatement);
  410.  
  411. // Todo: infer return type and cast if necessary.
  412. // Todo: Extend expression should probably accept IdExp to support attributes
  413. ParseExtendExpression = SkipThen(
  414.     ExtendExpression(ParseIdentifierExpression().Identifier, ParseObjectExpression()));
  415.  
  416. // Todo: support empty objects
  417.  
  418. ParseForExpression = @() {
  419.     NextToken;
  420.     LeftParenthesis;
  421.     initOrElement ParseExpression;
  422.  
  423.     if (inKeyword) {
  424.         NextToken;
  425.         collection ParseExpression;
  426.         RightParenthesis;
  427.         body ParseBlock;
  428.  
  429.         ret ForEachExpression(collection, initOrElement, body);
  430.     } else {
  431.         EndOfStatement;
  432.         condition ParseExpression;
  433.         EndOfStatement;
  434.         afterthought ParseExpression;
  435.         RightParenthesis;
  436.         body ParseBlock;
  437.  
  438.         ret ForExpression(initOrElement, condition, afterthought, body);
  439.     }
  440. };
  441.  
  442. ParseWhileExpression = SkipThen(WhileExpression(ParseCondition(), ParseBlock()));
  443.  
  444. ParseDoWhileExpression = @() {
  445.     NextToken;
  446.     body ParseBlock;
  447.     Prefix(whileKeyword, Parens(condition ParseExpression));
  448.  
  449.     ret DoWhileExpression(condition, body);
  450. };
  451.  
  452. list ParseTuple = @() {
  453.     tuple;
  454.  
  455.     while (true) {
  456.         tuple += ParseExpression();
  457.  
  458.         if (Comma) NextToken;
  459.         else ret tuple;
  460.     }
  461. };
  462.  
  463. ParseLoadScriptExpression = SkipThen(LoadScriptExpression(ParseExpression()));
  464. ParseLoadLibraryExpression = SkipThen(LoadLibraryExpression(ParseExpression()));
  465.  
  466. // Todo: fix now that var decls work
  467. ParseTryExpression = @() {
  468.     NextToken;
  469.     tryBody ParseBlock;
  470.     IdentifierExpression catchArg;
  471.     list catchBody;          
  472.     list finallyBody;
  473.  
  474.     switch (TokenType) {
  475.         catchKeyword: {
  476.             NextToken;
  477.             Parens(catchArg ParseIdentifierExpression);
  478.             catchBody ParseBlock;
  479.  
  480.             if (finallyKeyword) {
  481.                 NextToken;
  482.                 finallyBody ParseBlock;
  483.             }
  484.         }
  485.  
  486.         finallyKeyword: {
  487.             NextToken;
  488.             finallyBody ParseBlock;
  489.         }
  490.  
  491.         default: {
  492.             ret null;
  493.             // Todo: add parser throw
  494.         }
  495.     }
  496.  
  497.     ret TryExpression(tryBody, catchArg, catchBody, finallyBody);
  498. };
  499.  
  500. ParseSwitchExpression = @() {
  501.     NextToken;
  502.     Parens(exp ParseExpression);
  503.     LeftBrace;
  504.     cases = list SwitchCase;
  505.     list defaultCase;
  506.  
  507.     while (!RightBrace) {
  508.         if (!defaultKeyword) {
  509.             caseTuple ParseTuple;
  510.             ColonOperator;
  511.             block ParseBlock;
  512.             cases += SwitchCase(caseTuple, block);
  513.         } else {
  514.             NextToken;
  515.             ColonOperator;
  516.             defaultCase ParseBlock;
  517.         }
  518.     }
  519.  
  520.     NextToken;
  521.  
  522.     ret SwitchExpression(exp, cases, defaultCase);
  523. };
  524.  
  525. ParseObjectExpression = @() { };
  526.  
  527. ObjectExpression ParseObjectExpression = @() {
  528.     NextToken;
  529.     inNode = true;
  530.     childNodes = list BinaryOperatorExpression;
  531.  
  532.     while (inNode) {
  533.         switch (TokenType) {
  534.             Identifier: {
  535.                 childNodes += ParseKeyValuePairExpression();
  536.                 switch (TokenType) {
  537.                     Comma: NextToken;
  538.                     RightBrace: {
  539.                         NextToken;
  540.                         inNode = false;
  541.                     }
  542.                     default: {
  543.                         // Todo: error
  544.                     }
  545.                 }
  546.             }
  547.             RightBrace: {
  548.                 NextToken;
  549.                 inNode = false;
  550.             }
  551.             default: {
  552.                 // Todo: error
  553.             }
  554.         }
  555.     }
  556.  
  557.     ret ObjectExpression(childNodes);
  558. };
  559.  
  560. ParseArrayExpression = @() {
  561.     NextToken;
  562.     inNode = true;
  563.     childNodes = list AphidExpression;
  564.  
  565.     if (!RightBracket) {
  566.         while (inNode) {
  567.             childNodes += ParseExpression();
  568.  
  569.             switch (TokenType) {
  570.                 Comma: {
  571.                     NextToken;
  572.  
  573.                     if (RightBracket) {
  574.                         NextToken;
  575.                         inNode = false;
  576.                     }
  577.                 }
  578.                 RightBracket: {
  579.                     NextToken;
  580.                     inNode = false;
  581.                 }
  582.                 default: {
  583.                     // Todo: error
  584.                 }
  585.             }
  586.         }
  587.     } else {
  588.         NextToken;
  589.     }
  590.  
  591.     ret ArrayExpression(childNodes);
  592. };
  593.  
  594. BinaryOperatorExpression ParseKeyValuePairExpression = @() {
  595.     id ParseIdentifierExpression;
  596.     exp;
  597.  
  598.     if (ColonOperator || AssignmentOperator) {
  599.         NextToken;
  600.         exp ParseExpression;
  601.     } else {
  602.         exp = id;
  603.     }
  604.  
  605.     ret BinaryOperatorExpression(id, ColonOperator, exp);
  606. };
  607.  
  608. ParseNumberExpression = @(){
  609.     exp = NumberExpression(decimal.Parse(Lexeme));
  610.     NextToken;
  611.    
  612.     ret exp;
  613. };
  614.  
  615. ParseFunctionExpression = @() {
  616.     exp;
  617.     body;
  618.     args;
  619.     argExp;
  620.     NextToken;
  621.  
  622.     switch (TokenType) {
  623.         LeftParenthesis: {
  624.             NextToken;
  625.  
  626.             if (!RightParenthesis) {
  627.                 while (true) {
  628.                     if (Identifier) {
  629.                         id ParseIdentifierExpression;
  630.                         argExp = id;
  631.  
  632.                         if (AssignmentOperator) {
  633.                             TakeToken(op);
  634.                             argExp = BinaryOperatorExpression(id, op, ParseExpression());
  635.                         }
  636.  
  637.                         args += argExp;
  638.  
  639.                         if (Comma) NextToken;
  640.                         else break;
  641.                     } else {
  642.                         // Todo: error
  643.                     }
  644.                 }
  645.             }
  646.  
  647.             RightParenthesis;
  648.             isSingleLine = TokenType != LeftBrace;
  649.             block = ParseSingleBlock();
  650.  
  651.             if (isSingleLine && UseImplicitReturns) {
  652.                 body += UnaryOperatorExpression(retKeyword, block[0]);
  653.             } else {
  654.                 body = block;
  655.             }
  656.  
  657.             exp = FunctionExpression(args, body);
  658.         }
  659.  
  660.         default: exp = PartialFunctionExpression(ParseCallExpression());
  661.     }
  662.  
  663.     ret exp;
  664. };
  665.  
  666. ParsePatternMatchingExpression2 = @() {
  667.     NextToken;
  668.     patterns;
  669.     Parens(testExp ParseExpression);
  670.     System.Convert.ToInt64(_currentToken.Lexeme.Substring(2), 16);
  671.     ret null;
  672. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement