Advertisement
Guest User

Untitled

a guest
Apr 18th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const ops = {
  2.     '+': {Op: Add, Args: 2},
  3.     '-': {Op: Subtract, Args: 2},
  4.     '*': {Op: Multiply, Args: 2},
  5.     '/': {Op: Divide, Args: 2},
  6.     'negate': {Op: Negate, Args: 1},
  7. };
  8.  
  9. function ParsePrefixError(msg) {
  10.     this.message = msg;
  11.     this.name = "ParsePrefixError";
  12. }
  13.  
  14. ParsePrefixError.prototype = Error.prototype;
  15.  
  16. let expression = "";
  17. let pos = 0;
  18.  
  19. const checkPos = () => pos < expression.length;
  20.  
  21. const isLetter = (c) => /\w/.test(c);
  22.  
  23. const isDigit = (c) => /\d/.test(c);
  24.  
  25. const isWhiteSpace = (c) => /\s/.test(c);
  26.  
  27. const next = () => {
  28.     pos++;
  29. };
  30.  
  31. const curChar = () => expression.charAt(pos);
  32.  
  33. function skipSpaces() {
  34.     while (checkPos() && isWhiteSpace(curChar())) {
  35.         next();
  36.     }
  37. }
  38.  
  39. function getNumber() {
  40.     let number = "";
  41.     while (checkPos() && (isDigit(curChar()) || curChar() === '-')) {
  42.         number += curChar();
  43.         next();
  44.     }
  45.     skipSpaces();
  46.     return number;
  47. }
  48.  
  49. function getConst(number) {
  50.     try {
  51.         return new Const(parseInt(number));
  52.     } catch (Error) {
  53.         throw new ParsePrefixError("Illegal constant at index " +
  54.             (pos - number.length() + 1) + "\n" + number + "\n");
  55.     }
  56. }
  57.  
  58. function getVariable() {
  59.     let identifier = "";
  60.     while (checkPos() && isLetter(curChar())) {
  61.         identifier += curChar();
  62.         next();
  63.     }
  64.     if (!identifier in vars) {
  65.         throw new ParsePrefixError("Unknown identifier name at pos : " +
  66.             (pos - identifier.length) + " " + identifier);
  67.     }
  68.     skipSpaces();
  69.     return Variable(identifier);
  70. }
  71.  
  72. function getFunctionParam() {
  73.     let functionName = "";
  74.     while (!(/\(/.test(curChar()) || isWhiteSpace(curChar()))) {
  75.         functionName += curChar();
  76.         next();
  77.     }
  78.     if (!functionName in ops) {
  79.         throw new ParsePrefixError("Unknown function name at pos : " +
  80.             (pos - functionName.length) + " " + functionName);
  81.     }
  82.     skipSpaces();
  83.     const func = ops[functionName]["Op"];
  84.     const argsCnt = ops[functionName]["Args"];
  85.     return [func, argsCnt];
  86. }
  87.  
  88. function parseInBrackets() {
  89.     if (checkPos()) {
  90.         next();
  91.         skipSpaces();
  92.         if (isDigit(curChar())) {
  93.             return getConst(getNumber());
  94.         } else if (isLetter(curChar())) {
  95.             return getVariable();
  96.         } else {
  97.             let curOperands = [];
  98.             const params = getFunctionParam();
  99.             const func = params[0];
  100.             const argsCnt = params[1];
  101.             if (curChar() === ')') {
  102.                 throw new ParsePrefixError("Missing operands at pos : " + pos);
  103.             } else if (isDigit(curChar())) {
  104.                 curOperands.push(getConst(getNumber()));
  105.             } else if (isLetter(curChar())) {
  106.                 curOperands.push(getVariable());
  107.             } else if (/\(/.test(curChar())) {
  108.                 curOperands.push(parseInBrackets());
  109.             }
  110.             if (curOperands.length !== argsCnt) {
  111.                 throw new ParsePrefixError("Unexpected number of arguments");
  112.             } else {
  113.                 return func(curOperands);
  114.             }
  115.         }
  116.     }
  117. }
  118.  
  119. const parsePrefix = function (expr) {
  120.     expression = expr;
  121.     return parseInBrackets();
  122. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement