123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- const util = require('util')
- const selfClosingTags = require('./util/selfClosingTags')
-
- module.exports = class Compiler {
- constructor(tree, context) {
- this.tree = tree
- this.context = context
- this.pos = 0
- this.result = ''
- this.standardLibrary = {
- cond: function(predicate, left, right) {
- if (predicate) {
- let compiler = new Compiler([left], this.context)
- return compiler.compile()
- } else {
- let compiler = new Compiler([right], this.context)
- return compiler.compile()
- }
- },
- }
- }
-
- compile() {
- this.tree.forEach(node => {
- switch (node.constructor.name) {
- case 'Application':
- this.result += this.application(node)
- break;
- case 'String':
- this.result += node.value;
- break;
- case 'Identifier':
- this.result += this.lookup(node)
- break;
- }
- })
-
- return this.result
- }
-
- application(node) {
- if (this.standardLibrary[node.functionName.name]) {
- return this.standardLibrary[node.functionName.name](...node.args)
- }
-
- return this.htmlElement(node)
- }
-
- htmlElement(node) {
- let result = `<${node.functionName.name}`
-
- node.args.filter(arg => arg.constructor.name === 'Attribute').forEach(arg => {
- result += ` ${arg.name}`
-
- let compiler = new Compiler([arg.value], this.context)
- let attrValue = compiler.compile()
-
- if (attrValue) {
- result += `="${attrValue}"`
- }
- })
-
- result += '>'
-
- node.args.filter(arg => arg.constructor.name !== 'Attribute').forEach(arg => {
- let compiler = new Compiler([arg], this.context)
- result += compiler.compile()
- })
-
- if (!selfClosingTags.includes(node.functionName.name)) {
- result += `</${node.functionName.name}>`
- }
-
- return result
- }
-
- lookup(identifier) {
- let result = this.context[identifier.name]
-
- if (!result) {
- throw `Undefined variable '${identifier.name}'`
- }
-
- return result
- }
-
- currentNode() {
- return this.tree[this.pos]
- }
- }
|