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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. this.result += `<${node.functionName}${
  19. attributes.length ? ' ' : ''
  20. }${attributes.join(' ')}>${content}</${node.functionName}>`
  21. } else if (node.type === 'string') {
  22. this.result += node.content
  23. } else if (node.type === 'identifier') {
  24. this.result += this.lookup(node.name)
  25. } else if (node.type === 'each') {
  26. const symbol = node.symbol.value
  27. const subject = this.lookup(node.subject.name)
  28. subject.forEach(item => {
  29. let context = {}
  30. context[symbol] = item
  31. const compiler = new Compiler([node.body], context)
  32. this.result += compiler.compile()
  33. })
  34. }
  35. })
  36. return this.result.trim()
  37. }
  38. compileAttribute(attribute) {
  39. if (attribute.type === 'string') {
  40. return attribute.content
  41. } else if (attribute.type === 'identifier') {
  42. return this.lookup(attribute.name)
  43. }
  44. }
  45. lookup(name) {
  46. return this.context[name]
  47. }
  48. }