You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.1 KiB

4 years ago
  1. var tokenize = require('../tokenizer');
  2. var TokenStream = require('../common/TokenStream');
  3. var tokenStream = new TokenStream();
  4. var astToTokens = {
  5. decorator: function(handlers) {
  6. var curNode = null;
  7. var prev = { len: 0, node: null };
  8. var nodes = [prev];
  9. var buffer = '';
  10. return {
  11. children: handlers.children,
  12. node: function(node) {
  13. var tmp = curNode;
  14. curNode = node;
  15. handlers.node.call(this, node);
  16. curNode = tmp;
  17. },
  18. chunk: function(chunk) {
  19. buffer += chunk;
  20. if (prev.node !== curNode) {
  21. nodes.push({
  22. len: chunk.length,
  23. node: curNode
  24. });
  25. } else {
  26. prev.len += chunk.length;
  27. }
  28. },
  29. result: function() {
  30. return prepareTokens(buffer, nodes);
  31. }
  32. };
  33. }
  34. };
  35. function prepareTokens(str, nodes) {
  36. var tokens = [];
  37. var nodesOffset = 0;
  38. var nodesIndex = 0;
  39. var currentNode = nodes ? nodes[nodesIndex].node : null;
  40. tokenize(str, tokenStream);
  41. while (!tokenStream.eof) {
  42. if (nodes) {
  43. while (nodesIndex < nodes.length && nodesOffset + nodes[nodesIndex].len <= tokenStream.tokenStart) {
  44. nodesOffset += nodes[nodesIndex++].len;
  45. currentNode = nodes[nodesIndex].node;
  46. }
  47. }
  48. tokens.push({
  49. type: tokenStream.tokenType,
  50. value: tokenStream.getTokenValue(),
  51. index: tokenStream.tokenIndex, // TODO: remove it, temporary solution
  52. balance: tokenStream.balance[tokenStream.tokenIndex], // TODO: remove it, temporary solution
  53. node: currentNode
  54. });
  55. tokenStream.next();
  56. // console.log({ ...tokens[tokens.length - 1], node: undefined });
  57. }
  58. return tokens;
  59. }
  60. module.exports = function(value, syntax) {
  61. if (typeof value === 'string') {
  62. return prepareTokens(value, null);
  63. }
  64. return syntax.generate(value, astToTokens);
  65. };