A templating language that looks like Lisp and compiles to HTML
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.

lexer.js 1.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. const tokenTypes = {
  2. OPAREN: '(',
  3. CPAREN: ')',
  4. KEYWORD: 'keyword',
  5. QUOTE: '"',
  6. LITERAL: 'literal',
  7. ATTRIBUTE: 'attribute',
  8. EOF: 'eof',
  9. }
  10. const scan = source => {
  11. pos = 0
  12. line = 1
  13. tokens = []
  14. while (pos < source.length) {
  15. if (source[pos].match(/\(/)) {
  16. tokens.push({
  17. type: tokenTypes.OPAREN,
  18. line: line,
  19. })
  20. pos++
  21. } else if (source[pos].match(/\)/)) {
  22. tokens.push({
  23. type: tokenTypes.CPAREN,
  24. line: line,
  25. })
  26. pos++
  27. } else if (source[pos].match(/['"]/)) {
  28. tokens.push({
  29. type: tokenTypes.QUOTE,
  30. line: line,
  31. })
  32. pos++
  33. } else if (source[pos].match(/:/)) {
  34. let value = /:([^()'"\s]+)/.exec(source)[1].trim()
  35. tokens.push({
  36. type: tokenTypes.ATTRIBUTE,
  37. line: line,
  38. value: value,
  39. })
  40. pos += value.length + 1 // the +1 is to account for the colon
  41. } else if (source[pos].match(/\n/)) {
  42. line++
  43. pos++
  44. } else if (source[pos].match(/\s/)) {
  45. pos++
  46. } else {
  47. let value = /[^()"':]+/.exec(source.slice(pos))[0]
  48. tokens.push({
  49. type: tokenTypes.LITERAL,
  50. line: line,
  51. value: value.trim(),
  52. })
  53. pos += value.length
  54. }
  55. }
  56. tokens.push({
  57. type: tokenTypes.EOF,
  58. line: line,
  59. })
  60. return tokens
  61. }
  62. module.exports = {
  63. scan: scan,
  64. tokenTypes: tokenTypes,
  65. }