lispToMmix/js/lexer.js

180 lines
4.2 KiB
JavaScript
Raw Normal View History

2022-10-14 19:30:47 +02:00
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];
}