aiscript-dev / aiscript

🔋 A lightweight scripting language runing on JavaScript
https://aiscript-dev.github.io/aiscript/
MIT License
186 stars 33 forks source link

ホストが標準関数を上書きできるようにしたい #671

Open FineArchs opened 5 months ago

FineArchs commented 5 months ago

https://github.com/aiscript-dev/aiscript/blob/38f36ef2cef10ecc7620db9f0f3d46c92d23abc6/src/interpreter/index.ts#L50-L54 ここの...consts,を一番下にすればホストが同名の関数を提供することで既存の関数を上書きできるようになるはずなのでそうしたい

syuilo commented 5 months ago

上書きしたいのはなぜ?

FineArchs commented 5 months ago

関数にバグやパフォーマンス上の問題があった時に自力救済ができるというのと、 ユースケース次第では一部の関数の使用を禁止したい場合があるかもしれないので、そういう場合にメッセージを出す関数で上書きするなどの処置が取れるといいかなと思っています

uzmoi commented 2 months ago

stdをデフォルトから分離して、ホスト側がプリセット的なものを選択してconstsと一緒にインタプリタに渡すようにしてもいいなと思いました。 使わないデフォルトの実装をtree-shakingで落とせるのと、#45 とかで信頼できる環境でだけデフォルト実装を使う関数とかが入ったときに、上書きし忘れとかアップデートで増えた新しい関数の上書きし忘れとかを防げるので。

FineArchs commented 2 months ago

同パッケージ内でも、ファイルを分けてお互いに参照しない状態にすればtree-shakingは効きましたっけ?

uzmoi commented 2 months ago

ファイル分けてなくても変数が参照されていなければ効きますね。 例えば以下のようにすればstdPresetAllUnsafe:functionの実装は参照されていないので消えます。

// aiscript.ts
export const stdPresetSafe = {
  'Safe:function': FN_NATIVE(/* implements */),
};
export const stdPresetAll = {
  ...stdPresetSafe,
  'Unsafe:function': FN_NATIVE(/* implements */),
};

export class Interpreter {
  constructor(consts, options) {
    // ...
  }
  // ...
}

// host.ts
import { Interpleter, stdPresetSafe } from './aiscript';
const interpreter = new Interpreter(stdPresetSafe);
uzmoi commented 2 months ago

すいません、駄目な気がして試したらファイル分けてなくてもは嘘でした。 ファイル分けてれば効きます。 ファイル分けない場合は関数にすれば効きます。

export const stdPresetSafe = () => ({
  'Safe:function': FN_NATIVE(/* implements */),
});
export const stdPresetAll = () => ({
  ...stdPresetSafe(),
  'Unsafe:function': FN_NATIVE(/* implements */),
});