daily pastebin goal
85%
SHARE
TWEET

Untitled

a guest Dec 17th, 2018 55 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Calc
  2. // ----
  3. //
  4. // A dumb/simple embeddable dsl for performing simple calculations in javascript
  5. //
  6. // e.g. ($area % 0.96) x 1.05 units 0.96
  7. //      $area x 0.05
  8. //      (2 x $centreline_length) x (2 x $width)
  9. //
  10. // calc     ::== exp 'units' unitlist
  11. // unitlist ::== number ',' unitlist | number
  12. // exp      ::== '(' exp ')'
  13. //          ::== exp '%' exp
  14. //          ::== exp 'x' exp
  15. //          ::== exp '+' exp
  16. //          ::== exp '-' exp
  17. //          ::== value
  18. // value    ::== number  
  19. //          ::== ref
  20.  
  21. var Calc = {};
  22. (function () {
  23.     var TokenTypes,
  24.         SIMPLE_TOKENS,
  25.         KEYWORDS,
  26.         PATTERNS,
  27.         tokenize,
  28.         readToken;
  29.  
  30.     TokenTypes = {
  31.         OPEN_PAREN: 'OPEN_PAREN',
  32.         CLOSE_PAREN: 'CLOSE_PAREN',
  33.         NUMBER: 'NUMBER',
  34.         REFERENCE: 'REFERENCE',
  35.         DIVIDE_OP: 'DIVIDE_OP',
  36.         MULTIPLY_OP: 'MULTIPLY_OP',
  37.         ADD_OP: 'ADD_OP',
  38.         SUBTRACT_OP: 'SUBTRACT_OP',
  39.         UNITS_KW: 'UNIT_KW',
  40.         COMMA: 'COMMA'
  41.     };
  42.  
  43.     SIMPLE_TOKENS = {
  44.         '%': TokenTypes.DIVIDE_OP,
  45.         'x': TokenTypes.MULTIPLY_OP,
  46.         ',': TokenTypes.COMMA,
  47.         '+': TokenTypes.ADD_OP,
  48.         '-': TokenTypes.SUBTRACT_OP,
  49.         '(': TokenTypes.OPEN_PAREN,
  50.         ')': TokenTypes.CLOSE_PAREN
  51.     };
  52.  
  53.     PATTERNS = {
  54.         NUMBER: /^-?(0|([1-9]\d*))(\.\d+)?((e|E)(\+|\-)\d+)?/,
  55.         REFERENCE: /^\$(\w+)/
  56.     };
  57.  
  58.     KEYWORDS = {
  59.         UNIT_KW: 'units'
  60.     };
  61.  
  62.     Calc.tokenize = tokenize = function (str) {
  63.         var tokens = [], i;
  64.         for (i = 0; i < str.length; i = readToken(tokens, str, i)) { }
  65.         return tokens;
  66.     };
  67.  
  68.     readToken = function (tokens, str, i) {
  69.         var char, head, match, key, end;
  70.         char = str[i];
  71.  
  72.         if (char == ' ' || char == '\t' || char == '\n') {
  73.             return i + 1;
  74.         }
  75.  
  76.         if (char in SIMPLE_TOKENS) {
  77.             tokens.push({ type: SIMPLE_TOKENS[char] });
  78.             return i + 1;
  79.         }
  80.  
  81.         head = str.slice(i);
  82.  
  83.         for (key in KEYWORDS) if (KEYWORDS.hasOwnProperty(key)) {
  84.             end = i + KEYWORDS[key].length;
  85.             match = str.slice(i, end);
  86.  
  87.             if (match === KEYWORDS[key]) {
  88.                 tokens.push({ type: TokenTypes[key] });
  89.                 return end;
  90.             }
  91.         }
  92.  
  93.         for (key in PATTERNS) if (PATTERNS.hasOwnProperty(key)) {
  94.             match = PATTERNS[key].exec(head);
  95.  
  96.             if (match) {
  97.                 tokens.push({ type: TokenTypes[key], value: match[0]});
  98.                 return i + match[0].length;
  99.             }
  100.         }
  101.  
  102.         throw new Error("Couldn't tokenize " + str + " @ " + i + "'" + char + "'");
  103.     };
  104. }.call(null));
  105. if (typeof module !== 'undefined' && module.exports) {
  106.     module.exports = Calc;
  107. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top