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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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
  28. .filter(arg => arg.constructor.name === "Attribute")
  29. .forEach(arg => {
  30. result += ` ${arg.name}`;
  31. let compiler = new Compiler([arg.value], this.context);
  32. let attrValue = compiler.compile();
  33. if (attrValue) {
  34. result += `="${attrValue}"`;
  35. }
  36. });
  37. result += ">";
  38. node.args
  39. .filter(arg => arg.constructor.name !== "Attribute")
  40. .forEach(arg => {
  41. let compiler = new Compiler([arg], this.context);
  42. result += compiler.compile();
  43. });
  44. if (!selfClosingTags.includes(node.functionName.name)) {
  45. result += `</${node.functionName.name}>`;
  46. }
  47. return result;
  48. }
  49. lookup(identifier) {
  50. let result = this.context[identifier.name];
  51. if (!result) {
  52. throw `Undefined variable '${identifier.name}'`;
  53. }
  54. return result;
  55. }
  56. };