class VTepLInterpreter { constructor(parser, core) { this.parser = parser; this.data = []; this.content = ''; this.core = core; } async render(data) { let self = this; self.data = data; let newData = await self.interpreter(self.parser.parsed); self.data = []; return newData[0]; } // This stuff is slow as fuck xD Optimize parser to create faster interpreter async interpreter(parsed, index = 0) { let self = this; let types = VParserTypes; let tplCont = ''; for (let i = index; i < parsed.length; i++) { let item = parsed[i], content = item.content; switch (item.type) { case types.content: tplCont += content; break; case types.variable: tplCont += self.getVariable(content) break; case types.assign: let data = content.split("="), key = data.shift(); self.setVariable(data.join("=").trim().replace(/"/g, ""), key.trim()); break; case types.forEach: let d = await this.handleForEach(item, parsed, i); i = d[0]; tplCont += d[1]; break; case types.for: let fd = await this.handleFor(item, parsed, i); i = fd[0]; tplCont += fd[1]; break; case types.if: let id = await this.handleIf(item, parsed, i); i = id[0]; tplCont += id[1]; break; case types.include: tplCont += await this.handleInclude(item); break; case types.ifEnd: tplCont += content; return [tplCont, i]; case types.forEnd: tplCont += content; return [tplCont, i]; default: console.warn("Invalid Type found"); break; } } return [tplCont, parsed.length]; } getVariable(variable, isEqualCheck = false) { variable = variable.toString(); if (!isEqualCheck) { let v = variable.split("=="); if (v.length > 1) { return this.getEqual(v[0].trim(), v[1].trim()); } v = variable.split("??"); if (v.length > 1) { return this.getBool(v[0].trim(), v[1].trim()); } v = variable.split("?"); if (v.length > 1) { return this.getIsDefined(v[0].trim(), v[1].trim()); } v = variable.split("||"); if (v.length > 1) { return this.getDefault(v[0].trim(), v[1].trim()); } } if (this.data[variable]) { return this.data[variable]; } let split = variable.split("."), prevVar = this.data; for (let i = 0; i < split.length; i++) { prevVar = prevVar[split[i]] || prevVar; } if (typeof prevVar === 'string') { return prevVar; } if (typeof prevVar === 'number') { return prevVar.toString(); } if (typeof prevVar === 'boolean') { return prevVar.toString(); } return ''; } getEqual(variable1, variable2) { let split = variable2.split("?"); let var1 = this.getVariable(variable1, true); let var2 = this.getVariable(split[0].trim(), true); if (split.length > 1) { let newSplit = split[1].split(":"); let right = newSplit[1] || ''; return var1 === var2 ? newSplit[0].trim() : right.trim(); } return var1 === var2 ? 'true' : 'false'; } setVariable(value, variable) { let c = this.getVariable(value); if (c !== '') { value = c; } this.data[variable] = value; } async handleForEach(item, parsed, i) { let content = item.content.split(" as "); let root = this.getVariable(content[0].trim()); let addTo = 0, isInvalid = false; if (root === '') { isInvalid = true; root = {invalid: "true"}; } if (typeof root === 'string') { root = JSON.parse(root); } if (Array.isArray(root) && root.length === 0) { root.push(""); isInvalid = true; } let d = Object.keys(root), raw = '', varContent = content[1].trim().split(","); for (let x of d) { if (varContent.length === 2) { this.setVariable(x, varContent[1]); } this.setVariable(root[x], varContent[0]); let data = await this.interpreter(parsed, i + 1); addTo = data[1]; raw += data[0]; } if (isInvalid) { raw = ''; } return [addTo, raw]; } async handleInclude(item) { let split = item.content.split(";"), name = split.shift(), data = {}; await this.core.loadTemplate(name); for (let item of split) { let d = item.split("="), index = d.shift(), dat = d.join("="); if (!dat.startsWith("\"") && !dat.startsWith("\'")) { dat = this.getVariable(dat); } else { if (dat.startsWith("\"")) { dat = dat.replace(/"/g, ""); } else { dat = dat.replace(/'/g, ""); } } data[index] = dat; } return await this.core.renderOn(name, data); } async handleFor(item, parsed, ind) { let content = item.content.split(" as "), addTo = 0, count = content[0].trim().split(".."), max = parseInt(count[1]), min = parseInt(count[0]), newContent = ''; for (let i = min; i < max; i++) { this.setVariable(i.toString(), content[1]); let data = await this.interpreter(parsed, ind + 1); addTo = data[1]; newContent += data[0]; } return [addTo, newContent]; } async handleIf(item, parsed, i) { let data = await this.interpreter(parsed, i + 1); return [data[1], data[0]]; } getIsDefined(variable, value) { return this.getVariable(variable, true) !== '' ? value : ''; } getDefault(variable, value) { let vars = this.getVariable(variable, true); return vars !== '' ? vars : value; } getBool(variable, value) { return this.getVariable(variable, true) ? value : ''; } }