You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.2 KiB
JavaScript

const KEYWORDS = [
"let",
"for",
"print",
"input",
"//"
];
const TYPES = [
"int",
"float",
"string",
"bool"
];
const PATTERNS = [
"asgn": [ "ident", "eq", "expr" ],
"let": [ "type", "ident", "eq?", "expr" ],
];
class UnexpectedTokenError extends SyntaxError {
constructor (expectedTokens, token, line, col) {
const expected = expectedTokens.map((t) => `"${t}"`).join(", ");
super(`Expected ${expected} but got ${token}`);
this.lineNumber = line;
this.columnNumber = col;
}
}
class UnexpectedEndOfInputError {
constructor (line, col) {
super(`Unexpected end of input at ${line}:${col}.`);
}
}
const inPath = Deno.args[0];
const dec = new TextDecoder("utf-8);
const raw = Deno.readFile(inPath);
const input = dec.decode(raw);
const lines = input.split("\n");
let tree = [];
let stack = [];
let ctx = "";
// keyword, ident, type, num, string, op, group, eof
let expectedTokens = ["keyword", "ident"];
let tokenType = null;
// ` `, `{`, `}`
let delim = " ";
let token = "";
let idents = [];
for (let line = 0; line < lines.length; line++) {
const currentLine = lines[line];
for (let col = 0; col < currentLine.length; col++) {
if (currentLine[col] === delim) {
tokenType = null;
const tokenHandlers = {
"keyword": () => {
if (KEYWORDS.includes(token)) {
stack.push(token);
tokenType = "keyword";
}
},
"ident": () => {
if (idents.includes(token)) {
stack.push(token);
idents.push(token);
tokenType = "ident";
}
},
};
for (type in expectedTokens) {
tokenHandlers[type]();
if (tokenType !== null) {
break;
}
}
if (!expectedTokens.includes(tokenType)) {
throw new UnexpectedTokenError(expectedTokens, token, line, col);
} else {
switch (tokenType) {
case "keyword":
switch (token) {
case "let":
ctx = patterns["let"];
expectedToken = "ident";
delim = " ";
break;
}
break;
case "ident":
} else {
token.push(line[j]);
}
switch (mode) {
case "keyword": {
const keyword = line.split(" ")[0];
if (KEYWORDS.includes(keyword)) {
stack.push(keyword);
} else {
throw new UnknownKeywordError(keyword, i, 0);