Guest User

Untitled

a guest
Dec 17th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.81 KB | None | 0 0
  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. }
Add Comment
Please, Sign In to add comment