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 == '"') { buffer += c; if (!inC) finishBuff(); inStr = false; } else { buffer += c; } continue; } if (c == '"') { inStr = true; buffer += c; 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 ((data instanceof LISPstring)&&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]; }