nadesiko3
Version:
Japanese Programming Language
133 lines (132 loc) • 4.46 kB
JavaScript
import { NakoColors } from './nako_colors.mjs';
/**
* コンパイルされたなでしこのプログラムで、グローバル空間のthisが指すオブジェクト
*/
export class NakoGlobal {
/**
* @param compiler
* @param gen
*/
constructor(compiler, gen, guid = 0) {
this.guid = guid;
this.lastJSCode = '';
// ユーザーのプログラムから編集される変数
this.__locals = new Map();
this.__varslist = [
compiler.newVaiables(compiler.__varslist[0]), // system
compiler.newVaiables(compiler.__varslist[1]), // global
compiler.newVaiables(compiler.__varslist[2]) // local [2][3][4][5] ...
];
this.numFailures = 0;
this.index = 0;
this.nextIndex = -1;
this.__code = [];
this.__callstack = [];
this.__stack = [];
this.__labels = [];
this.__genMode = gen.genMode;
// バージョン情報の引き継ぎ
this.version = compiler.version;
this.coreVersion = compiler.coreVersion;
// PluginSystemとdestroy()から参照するため
this.__module = { ...compiler.__module }; // shallow copy
this.pluginfiles = { ...compiler.getPluginfiles() };
// PluginWorkerでユーザー定義関数のJavaScriptコードをworkerのコンパイラのインスタンスへコピーするため
this.gen = gen;
// 以下のメソッドで使うため
this.logger = compiler.getLogger();
this.compiler = compiler;
this.josiList = compiler.josiList;
this.reservedWords = compiler.reservedWords;
}
clearLog() {
this.__varslist[0].set('表示ログ', '');
}
get log() {
let s = this.__varslist[0].get('表示ログ');
s = s.replace(/\s+$/, '');
return s;
}
/**
* システム変数を設定する
* @param name システム変数名
* @param value 設定したい値
*/
__setSysVar(name, value) {
this.__varslist[0].set(name, value);
}
/**
* システム変数を取得する
* @param name システム変数名
* @returns システム変数の値
*/
__getSysVar(name) {
return this.__varslist[0].get(name);
}
/**
* 「ナデシコ」命令のためのメソッド
*/
runEx(code, fname, opts, preCode = '') {
// スコープを共有して実行
opts.preCode = preCode;
opts.nakoGlobal = this;
return this.compiler.runSync(code, fname, opts);
}
async runAsync(code, fname, opts, preCode = '') {
// スコープを共有して実行
opts.preCode = preCode;
opts.nakoGlobal = this;
return await this.compiler.runAsync(code, fname, opts);
}
/**
* テスト実行のためのメソッド
* @param {{ name: string, f: () => void }[]} tests
*/
_runTests(tests) {
let text = `${NakoColors.color.bold}テストの実行結果${NakoColors.color.reset}\n`;
let pass = 0;
let numFailures = 0;
for (const t of tests) {
try {
t.f();
text += `${NakoColors.color.green}✔${NakoColors.color.reset} ${t.name}\n`;
pass++;
}
catch (err) {
text += `${NakoColors.color.red}☓${NakoColors.color.reset} ${t.name}: ${err.message}\n`;
numFailures++;
}
}
if (numFailures > 0) {
text += `${NakoColors.color.green}成功 ${pass}件 ${NakoColors.color.red}失敗 ${numFailures}件`;
}
else {
text += `${NakoColors.color.green}成功 ${pass}件`;
}
this.numFailures = numFailures;
this.logger.stdout(text);
}
/**
* 毎プラグインの「!クリア」関数を実行
*/
clearPlugins() {
// 実行している関数をすべて終了させる
// プラグインのクリア関数を呼び出す
const clearName = '!クリア';
for (const pname in this.pluginfiles) {
const po = this.__module[pname];
if (po[clearName] && po[clearName].fn) {
po[clearName].fn(this);
}
}
}
/**
* 各種リセット処理
*/
reset() {
this.clearPlugins();
}
destroy() {
this.reset();
}
}