180 lines
No EOL
4.2 KiB
JavaScript
180 lines
No EOL
4.2 KiB
JavaScript
export class LISPstring extends String {
|
|
#l;
|
|
#c;
|
|
constructor(string, line, char) {
|
|
super(string);
|
|
this.#l = line;
|
|
this.#c = char;
|
|
}
|
|
get lineCount() {
|
|
return this.#l;
|
|
}
|
|
get charCount() {
|
|
return this.#l;
|
|
}
|
|
get pos() {
|
|
return [this.#l, this.#c];
|
|
}
|
|
}
|
|
|
|
export class LISPcmd extends Array {
|
|
#l;
|
|
#c;
|
|
|
|
constructor(code, line, char) {
|
|
var childs = cutCmd(code, line, char);
|
|
|
|
super(...childs);
|
|
this.#l = line;
|
|
this.#c = char;
|
|
}
|
|
get lineCount() {
|
|
return this.#l;
|
|
}
|
|
get charCount() {
|
|
return this.#l;
|
|
}
|
|
get pos() {
|
|
return [this.#l, this.#c];
|
|
}
|
|
get array(){
|
|
return new Array(...this);
|
|
}
|
|
}
|
|
|
|
export function error(msg, l = null, c = null) {
|
|
var out = "Error"
|
|
if (l != null && c != null) out += ` in line ${l} and character ${c}`;
|
|
out += ": " + msg;
|
|
console.log("\x1b[31m", out, "\x1b[0m");
|
|
process.exit(1);
|
|
}
|
|
|
|
var lispSeperator = [" ", ":", "\n"];
|
|
|
|
function cutCmd(code, line, chars) {
|
|
if (!code.startsWith("(")) return ["", error("Compiler Error", line, chars)];
|
|
|
|
if (!code.endsWith(")")) return ["", error("Compiler Error", line, chars)];
|
|
|
|
code = code.substring(1, code.length - 1);
|
|
|
|
var countLinesBegin = line;
|
|
var countCharsBegin = chars;
|
|
|
|
var countLines = line;
|
|
var countChars = chars;
|
|
var inC = 0;
|
|
var wasinC = false;
|
|
var inStr = 0;
|
|
var buffer = "";
|
|
var i = 0;
|
|
var out = [];
|
|
|
|
function finishBuff() {
|
|
out.push(
|
|
wasinC ?
|
|
new LISPcmd(buffer.trim(), countLinesBegin, countCharsBegin)
|
|
:
|
|
new LISPstring(buffer.trim(), countLinesBegin, countCharsBegin)
|
|
);
|
|
countLinesBegin = countLines;
|
|
countCharsBegin = countChars;
|
|
buffer = "";
|
|
wasinC = false;
|
|
}
|
|
|
|
for (var i = 0; i < code.length; i++) {
|
|
|
|
countChars++;
|
|
//console.log(code,countLines,countChars);
|
|
let c = code[i];
|
|
if (!inC && !inStr) {
|
|
countLinesBegin = countLines;
|
|
countCharsBegin = countChars;
|
|
}
|
|
if (c == "\\") {
|
|
buffer += code[++i];
|
|
continue;
|
|
}
|
|
if (inStr) {
|
|
if (c == "\n") {
|
|
countLines++;
|
|
countChars = 0;
|
|
} else if (c == '"') {
|
|
if (!inC) finishBuff();
|
|
inStr = false;
|
|
} else {
|
|
buffer += c;
|
|
}
|
|
continue;
|
|
}
|
|
if (c == '"') {
|
|
inStr = true;
|
|
continue;
|
|
}
|
|
if (c == ";" && !inC) {
|
|
while (code[++i] != "\n") { }
|
|
countLines++;
|
|
countChars = 0;
|
|
continue;
|
|
}
|
|
if (c == "\n") {
|
|
countLines++;
|
|
countChars = 0;
|
|
}
|
|
if (/*(c == " "||c=="\n")*/lispSeperator.includes(c) && !inC) {
|
|
if (buffer.trim() != "") {
|
|
finishBuff();
|
|
}
|
|
continue;
|
|
}
|
|
if (c == "(") {
|
|
if (!inC && buffer.trim() != "") {
|
|
finishBuff();
|
|
}
|
|
inC++;
|
|
wasinC = true;
|
|
}
|
|
if (c == ")") {
|
|
inC--;
|
|
if (inC < 0) error("Closing braket to much!", countLines, countChars);
|
|
if (!inC) {
|
|
buffer += c;
|
|
finishBuff();
|
|
continue;
|
|
}
|
|
}
|
|
buffer += c;
|
|
|
|
}
|
|
if (inStr) error("Missing closing quotation mark!", countLines, countChars);
|
|
if (inC) error("Missing closing braket!", countLines, countChars);
|
|
|
|
if (buffer.trim() != "") finishBuff();
|
|
|
|
return out;
|
|
}
|
|
|
|
|
|
export function createType(data) {
|
|
if (data == "true") {
|
|
return ["bool", 1];
|
|
}
|
|
if (data == "false") {
|
|
return ["bool", 0];
|
|
}
|
|
/*if (data == "NaN") {
|
|
return ["num", NaN];
|
|
}*/
|
|
/*if(typeof data == "string"&&data.startsWith('"') && data.endsWith('"')){
|
|
return ["str", data.slice(1,-1)];
|
|
}*/
|
|
if ((data instanceof LISPstring) && !isNaN(data)) {
|
|
return ["num", Number(data)];
|
|
}
|
|
if (data instanceof LISPcmd) {
|
|
return ["code", data];
|
|
}
|
|
return ["var", data];
|
|
} |