221 lines
6.9 KiB
JavaScript
221 lines
6.9 KiB
JavaScript
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 : '';
|
|
}
|
|
}
|