UNPKG

mollu-lang-web

Version:
400 lines (399 loc) 19.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.runRepl = exports.run = void 0; var token_1 = require("./token"); var io_1 = require("./io"); var error_1 = require("./error"); var repl_1 = require("./repl"); var vartable = []; var labeltable = []; var calc_idx = 0; function calc(tokenlist) { return __awaiter(this, void 0, void 0, function () { var isvalue, value, i, temp, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: isvalue = true; value = 0; i = calc_idx; _b.label = 1; case 1: if (!(i < tokenlist.length)) return [3 /*break*/, 16]; if (!isvalue) return [3 /*break*/, 13]; temp = 0; _a = tokenlist[i].type; switch (_a) { case 'var_value': return [3 /*break*/, 2]; case 'positive_one': return [3 /*break*/, 3]; case 'positive_ten': return [3 /*break*/, 4]; case 'negative_one': return [3 /*break*/, 5]; case 'negative_ten': return [3 /*break*/, 6]; case 'input_number': return [3 /*break*/, 7]; case 'input_character': return [3 /*break*/, 9]; } return [3 /*break*/, 11]; case 2: { temp = vartable[tokenlist[i].str.length - 1]; if (temp === undefined) temp = 0; return [3 /*break*/, 12]; } _b.label = 3; case 3: temp = 1; return [3 /*break*/, 12]; case 4: temp = 10; return [3 /*break*/, 12]; case 5: temp = -1; return [3 /*break*/, 12]; case 6: temp = -10; return [3 /*break*/, 12]; case 7: return [4 /*yield*/, (0, io_1.input_number)()]; case 8: temp = _b.sent(); return [3 /*break*/, 12]; case 9: return [4 /*yield*/, (0, io_1.input_character)()]; case 10: temp = _b.sent(); return [3 /*break*/, 12]; case 11: (0, error_1.throwerror)(tokenlist[i].info, '', 0); _b.label = 12; case 12: if (i === calc_idx) value += temp; else if (tokenlist[i - 1].type == 'add') value += temp; else if (tokenlist[i - 1].type == 'sub') value -= temp; else if (tokenlist[i - 1].type == 'mul') value *= temp; else if (tokenlist[i - 1].type == 'div') value /= temp; return [3 /*break*/, 14]; case 13: switch (tokenlist[i].type) { case 'add': case 'sub': case 'mul': case 'div': break; default: calc_idx = i - 1; return [2 /*return*/, value]; } _b.label = 14; case 14: isvalue = !isvalue; _b.label = 15; case 15: i++; return [3 /*break*/, 1]; case 16: calc_idx = tokenlist.length - 1; return [2 /*return*/, value]; } }); }); } function run(tokenlist) { return __awaiter(this, void 0, void 0, function () { var comment, i, _a, temp, value, temp, value, togo, condition, value, value; return __generator(this, function (_b) { switch (_b.label) { case 0: comment = 0; i = 0; _b.label = 1; case 1: if (!(i < tokenlist.length)) return [3 /*break*/, 14]; if ((0, error_1.isErrorOccurred)()) return [3 /*break*/, 14]; switch (tokenlist[i].type) { case 'line_comment': if (comment == 0) comment = 1; break; case 'line_feed': if (comment == 1) comment = 0; break; case 'block_comment_start': if (comment == 0) comment = 2; break; case 'block_comment_end': if (comment == 2) comment = 0; break; } if (comment != 0) return [3 /*break*/, 13]; _a = tokenlist[i].type; switch (_a) { case 'assign': return [3 /*break*/, 2]; case 'jump_equal': return [3 /*break*/, 4]; case 'jump_less': return [3 /*break*/, 4]; case 'jump_greater': return [3 /*break*/, 4]; case 'define_label': return [3 /*break*/, 6]; case 'output_number': return [3 /*break*/, 7]; case 'output_character': return [3 /*break*/, 9]; case 'line_comment': return [3 /*break*/, 11]; case 'line_feed': return [3 /*break*/, 11]; case 'block_comment_start': return [3 /*break*/, 11]; case 'block_comment_end': return [3 /*break*/, 11]; } return [3 /*break*/, 12]; case 2: temp = tokenlist[i].str.length; ++i; calc_idx = i; return [4 /*yield*/, calc(tokenlist)]; case 3: value = _b.sent(); i = calc_idx; vartable[temp - 3] = value; return [3 /*break*/, 13]; case 4: if (i + 2 >= tokenlist.length) { (0, error_1.throwerror)(tokenlist[i].info, "", 0); return [3 /*break*/, 13]; } temp = tokenlist[i].type; ++i; calc_idx = i; return [4 /*yield*/, calc(tokenlist)]; case 5: value = _b.sent(); i = calc_idx; ++i; if (tokenlist[i].type == 'label') { togo = labeltable[tokenlist[i].str.length - 4]; if (togo < 0) { (0, error_1.throwerror)(tokenlist[i].info, "", 0); } condition = false; if (temp == 'jump_equal') condition = (value == 0); else if (temp == 'jump_less') condition = (value < 0); else if (temp == 'jump_greater') condition = (value > 0); if (condition) { i = togo; } } else { (0, error_1.throwerror)(tokenlist[i].info, "", 0); } return [3 /*break*/, 13]; case 6: { labeltable[tokenlist[i].str.length - 4] = i; return [3 /*break*/, 13]; } _b.label = 7; case 7: ++i; calc_idx = i; return [4 /*yield*/, calc(tokenlist)]; case 8: value = _b.sent(); i = calc_idx; (0, io_1.output_number)(value); return [3 /*break*/, 13]; case 9: ++i; calc_idx = i; return [4 /*yield*/, calc(tokenlist)]; case 10: value = _b.sent(); i = calc_idx; (0, io_1.output_character)(value); return [3 /*break*/, 13]; case 11: return [3 /*break*/, 13]; case 12: (0, error_1.throwerror)(tokenlist[i].info, "", 0); _b.label = 13; case 13: i++; return [3 /*break*/, 1]; case 14: return [2 /*return*/]; } }); }); } exports.run = run; function runRepl(code) { return __awaiter(this, void 0, void 0, function () { var tl, _a, temp, value, temp, value, togo, condition, value, value; return __generator(this, function (_b) { switch (_b.label) { case 0: if (code === 'exit' || code === 'exit()') { repl_1.repl.endRepl(); return [2 /*return*/]; } tl = (0, token_1.tokenize)(code); repl_1.repl.repl_tokenlist = repl_1.repl.repl_tokenlist.concat(tl); _b.label = 1; case 1: if (!(repl_1.repl.repl_idx < repl_1.repl.repl_tokenlist.length)) return [3 /*break*/, 14]; if ((0, error_1.isErrorOccurred)() || !repl_1.repl.isRepl()) return [3 /*break*/, 14]; switch (repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].type) { case 'line_comment': if (repl_1.repl.repl_comment == 0) repl_1.repl.repl_comment = 1; break; case 'line_feed': if (repl_1.repl.repl_comment == 1) repl_1.repl.repl_comment = 0; break; case 'block_comment_start': if (repl_1.repl.repl_comment == 0) repl_1.repl.repl_comment = 2; break; case 'block_comment_end': if (repl_1.repl.repl_comment == 2) repl_1.repl.repl_comment = 0; break; } if (repl_1.repl.repl_comment != 0) return [3 /*break*/, 13]; _a = repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].type; switch (_a) { case 'assign': return [3 /*break*/, 2]; case 'jump_equal': return [3 /*break*/, 4]; case 'jump_less': return [3 /*break*/, 4]; case 'jump_greater': return [3 /*break*/, 4]; case 'define_label': return [3 /*break*/, 6]; case 'output_number': return [3 /*break*/, 7]; case 'output_character': return [3 /*break*/, 9]; case 'line_comment': return [3 /*break*/, 11]; case 'line_feed': return [3 /*break*/, 11]; case 'block_comment_start': return [3 /*break*/, 11]; case 'block_comment_end': return [3 /*break*/, 11]; } return [3 /*break*/, 12]; case 2: temp = repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].str.length; ++repl_1.repl.repl_idx; calc_idx = repl_1.repl.repl_idx; return [4 /*yield*/, calc(repl_1.repl.repl_tokenlist)]; case 3: value = _b.sent(); repl_1.repl.repl_idx = calc_idx; vartable[temp - 3] = value; return [3 /*break*/, 13]; case 4: if (repl_1.repl.repl_idx + 2 >= repl_1.repl.repl_tokenlist.length) { (0, error_1.throwerror)(repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].info, "", 0); return [3 /*break*/, 13]; } temp = repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].type; ++repl_1.repl.repl_idx; calc_idx = repl_1.repl.repl_idx; return [4 /*yield*/, calc(repl_1.repl.repl_tokenlist)]; case 5: value = _b.sent(); repl_1.repl.repl_idx = calc_idx; ++repl_1.repl.repl_idx; if (repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].type == 'label') { togo = labeltable[repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].str.length - 4]; if (togo < 0) { (0, error_1.throwerror)(repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].info, "", 0); } condition = false; if (temp == 'jump_equal') condition = (value == 0); else if (temp == 'jump_less') condition = (value < 0); else if (temp == 'jump_greater') condition = (value > 0); if (condition) { repl_1.repl.repl_idx = togo; } } else { (0, error_1.throwerror)(repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].info, "", 0); } return [3 /*break*/, 13]; case 6: { labeltable[repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].str.length - 4] = repl_1.repl.repl_idx; return [3 /*break*/, 13]; } _b.label = 7; case 7: ++repl_1.repl.repl_idx; calc_idx = repl_1.repl.repl_idx; return [4 /*yield*/, calc(repl_1.repl.repl_tokenlist)]; case 8: value = _b.sent(); repl_1.repl.repl_idx = calc_idx; (0, io_1.output_number)(value); return [3 /*break*/, 13]; case 9: ++repl_1.repl.repl_idx; calc_idx = repl_1.repl.repl_idx; return [4 /*yield*/, calc(repl_1.repl.repl_tokenlist)]; case 10: value = _b.sent(); repl_1.repl.repl_idx = calc_idx; (0, io_1.output_character)(value); return [3 /*break*/, 13]; case 11: return [3 /*break*/, 13]; case 12: (0, error_1.throwerror)(repl_1.repl.repl_tokenlist[repl_1.repl.repl_idx].info, "", 0); _b.label = 13; case 13: repl_1.repl.repl_idx++; return [3 /*break*/, 1]; case 14: return [2 /*return*/]; } }); }); } exports.runRepl = runRepl;