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.

compiler.js 1.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. const selfClosingTags = require('./util/selfClosingTags')
  2. module.exports = class Compiler {
  3. constructor(tree, context) {
  4. this.tree = tree
  5. this.context = context
  6. this.pos = 0
  7. this.result = ''
  8. }
  9. compile() {
  10. this.tree.forEach(node => {
  11. switch (node.constructor.name) {
  12. case 'Application':
  13. this.result += this.application(node)
  14. break;
  15. case 'Identifier':
  16. this.result += this.lookup(node)
  17. break;
  18. case 'String':
  19. this.result += node.value;
  20. break;
  21. }
  22. })
  23. return this.result
  24. }
  25. application(node) {
  26. let result = `<${node.functionName.name}`
  27. node.args.filter(arg => arg.constructor.name === 'Attribute').forEach(arg => {
  28. result += ` ${arg.name}`
  29. let compiler = new Compiler([arg.value], this.context)
  30. let attrValue = compiler.compile()
  31. if (attrValue) {
  32. result += `="${attrValue}"`
  33. }
  34. })
  35. result += '>'
  36. node.args.filter(arg => arg.constructor.name !== 'Attribute').forEach(arg => {
  37. let compiler = new Compiler([arg], this.context)
  38. result += compiler.compile()
  39. })
  40. if (!selfClosingTags.includes(node.functionName.name)) {
  41. result += `</${node.functionName.name}>`
  42. }
  43. return result
  44. }
  45. lookup(identifier) {
  46. let result = this.context[identifier.name]
  47. if (!result) {
  48. throw `Undefined variable '${identifier.name}'`
  49. }
  50. return result
  51. }
  52. }