A templating language that looks like Lisp and compiles to HTML
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

compiler.js 2.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. const util = require('util')
  2. const selfClosingTags = require('./util/selfClosingTags')
  3. module.exports = class Compiler {
  4. constructor(tree, context) {
  5. this.tree = tree
  6. this.context = context
  7. this.pos = 0
  8. this.result = ''
  9. this.standardLibrary = {
  10. cond: function(predicate, left, right) {
  11. if (predicate) {
  12. let compiler = new Compiler([left], this.context)
  13. return compiler.compile()
  14. } else {
  15. let compiler = new Compiler([right], this.context)
  16. return compiler.compile()
  17. }
  18. },
  19. }
  20. }
  21. compile() {
  22. this.tree.forEach(node => {
  23. switch (node.constructor.name) {
  24. case 'Application':
  25. this.result += this.application(node)
  26. break;
  27. case 'String':
  28. this.result += node.value;
  29. break;
  30. case 'Identifier':
  31. this.result += this.lookup(node)
  32. break;
  33. }
  34. })
  35. return this.result
  36. }
  37. application(node) {
  38. if (this.standardLibrary[node.functionName.name]) {
  39. return this.standardLibrary[node.functionName.name](...node.args)
  40. }
  41. return this.htmlElement(node)
  42. }
  43. htmlElement(node) {
  44. let result = `<${node.functionName.name}`
  45. node.args.filter(arg => arg.constructor.name === 'Attribute').forEach(arg => {
  46. result += ` ${arg.name}`
  47. let compiler = new Compiler([arg.value], this.context)
  48. let attrValue = compiler.compile()
  49. if (attrValue) {
  50. result += `="${attrValue}"`
  51. }
  52. })
  53. result += '>'
  54. node.args.filter(arg => arg.constructor.name !== 'Attribute').forEach(arg => {
  55. let compiler = new Compiler([arg], this.context)
  56. result += compiler.compile()
  57. })
  58. if (!selfClosingTags.includes(node.functionName.name)) {
  59. result += `</${node.functionName.name}>`
  60. }
  61. return result
  62. }
  63. lookup(identifier) {
  64. let result = this.context[identifier.name]
  65. if (!result) {
  66. throw `Undefined variable '${identifier.name}'`
  67. }
  68. return result
  69. }
  70. currentNode() {
  71. return this.tree[this.pos]
  72. }
  73. }