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.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. module.exports = class Compiler {
  2. constructor(tree, context) {
  3. this.tree = tree
  4. this.context = context
  5. this.result = ''
  6. }
  7. compile() {
  8. this.tree.forEach(node => {
  9. if (node.type === 'functionCall') {
  10. const attributes = node.args.map(
  11. arg =>
  12. `${arg.attributeName}="${this.compileAttribute(
  13. arg.attributeValue,
  14. )}"`,
  15. )
  16. const compiler = new Compiler(node.subtree, this.context)
  17. const content = compiler.compile()
  18. if (node.functionName) {
  19. this.result += `<${node.functionName}${
  20. attributes.length ? ' ' : ''
  21. }${attributes.join(' ')}>${content}</${node.functionName}>`
  22. } else {
  23. this.result += content
  24. }
  25. } else if (node.type === 'string') {
  26. this.result += node.content
  27. } else if (node.type === 'identifier') {
  28. this.result += this.lookup(node.name)
  29. } else if (node.type === 'each') {
  30. const symbol = node.symbol.value
  31. const subject = this.lookup(node.subject.name)
  32. subject.forEach(item => {
  33. let context = {}
  34. context[symbol] = item
  35. const compiler = new Compiler([node.body], context)
  36. this.result += compiler.compile()
  37. })
  38. }
  39. })
  40. return this.result.trim()
  41. }
  42. compileAttribute(attribute) {
  43. if (attribute.type === 'string') {
  44. return attribute.content
  45. } else if (attribute.type === 'identifier') {
  46. return this.lookup(attribute.name)
  47. }
  48. }
  49. lookup(name) {
  50. return this.context[name]
  51. }
  52. }