bkc
Version:
:dog: If there are no dogs in Heaven, then when I die I want to go where they went.
167 lines (166 loc) • 5.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const error_1 = require("../execute/error");
const instant_1 = require("../execute/instant");
const list_1 = require("../execute/list");
const check_1 = require("../util/check");
const combineStartedToEnd = (list) => {
return {
type: 'str',
va: list.join(' '),
};
};
const combineString = (args) => {
let started = false;
let temp = [];
const re = [];
loop: for (let i of args) {
if (i.type === 'comstart') {
started = true;
temp.push(i.va.substring(1, i.va.length));
continue loop;
}
if (i.type === 'comend') {
if (started) {
started = false;
temp.push(i.va.substring(0, i.va.length - 1));
re.push(combineStartedToEnd(temp));
temp = [];
}
continue loop;
}
if (started) {
if (i.type === 'str' || i.type === 'var' || i.type === 'emp' || i.type === 'num') {
temp.push(i.va);
}
else {
throw error_1.error(error_1.ERROR_CODE.STRING_COMBINE_FAILED);
}
}
else {
re.push(i);
}
}
return re;
};
const parseArg = (arg) => {
const regExpString = /(^'([A-Z]|[a-z]|[0-9])*'$)|(^'([A-Z]|[a-z]|[0-9])*'$)/;
const regExpVariable = /^(_|[A-Z]|[a-z])(_|[A-Z]|[a-z]|[0-9])*$/;
const regExpNumber = /^[0-9]+(.[0-9]+)?$/;
const regExpExpression = /^(=|\+|-|\*|\/|<|>|<=|>=|==|!=)$/;
const regExpArgument = /^('|'|_|[A-Z]|[a-z]|[0-9])(('|'|_|[A-Z]|[a-z]|[0-9])*,('|'|_|[A-Z]|[a-z]|[0-9])+)+$/;
const regExpEmpty = /^$/;
const regExpCombineable = /^'([A-Z]|[a-z]|[0-9])*$/;
const regExpCombineend = /^([A-Z]|[a-z]|[0-9])*'$/;
if (regExpString.test(arg)) {
return {
type: 'str',
va: arg.substring(1, arg.length - 1),
};
}
else if (regExpArgument.test(arg)) {
return {
type: 'arg',
va: arg.split(',').map((value) => parseArg(value)),
};
}
else if (regExpVariable.test(arg)) {
return {
type: 'var',
va: arg,
};
}
else if (regExpNumber.test(arg)) {
return {
type: 'num',
va: parseFloat(arg),
};
}
else if (regExpExpression.test(arg)) {
return {
type: 'exp',
va: arg,
};
}
else if (regExpCombineable.test(arg)) {
return {
type: 'comstart',
va: arg,
};
}
else if (regExpCombineend.test(arg)) {
return {
type: 'comend',
va: arg,
};
}
else if (regExpEmpty.test(arg)) {
return {
type: 'emp',
va: arg,
};
}
else {
return {
type: 'err',
va: arg,
};
}
};
const ast = (code, optionsE) => {
const options = check_1.fixOption(optionsE);
const regExpEnter = /\r\n|\r|\n|&/;
const splited = code.split(regExpEnter).filter((line) => Boolean(line.trim())).map((line) => line.trim());
const vars = [];
return splited.map((value) => {
let dots = value.split(' ').map((dot) => dot.trim());
let command = dots.shift() || 'skip';
let type = 'error';
if (command === 'var') {
const testShift = dots.shift();
if (testShift) {
command = testShift;
if (list_1.internalList.indexOf(testShift) !== -1
|| options.externals.map((external) => external.command).indexOf(testShift) !== -1
|| options.instants.map((instants) => instants.command).indexOf(testShift) !== -1
|| options.vars.map((singleVar) => singleVar.name).indexOf(testShift) !== -1
|| list_1.reservedWordList.indexOf(testShift) !== -1
|| instant_1.instantList.indexOf(testShift) !== -1) {
type = 'error';
}
else {
vars.push(command);
type = 'assign';
}
}
}
else if (command === 'if') {
type = 'if';
}
else if (command === 'for') {
type = 'for';
}
else if (command === 'end') {
type = 'end';
}
else if (vars.indexOf(command) !== -1) {
type = 'assign';
}
else if (command === 'skip') {
type = 'skip';
}
else if (command === '#') {
type = 'skip';
}
else {
type = 'command';
}
const re = {
type,
val: (type === 'skip') ? 'skip' : command,
args: (type === 'skip') ? [] : combineString(dots.map(parseArg)),
};
return re;
});
};
exports.default = ast;