nadesiko3 3.6.26 → 3.6.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +5 -4
  2. package/batch/command.txt +65 -6
  3. package/core/package.json +1 -1
  4. package/core/src/nako_ast.mts +2 -0
  5. package/core/src/nako_gen.mjs +56 -0
  6. package/core/src/nako_gen.mts +54 -0
  7. package/core/src/nako_josi_list.mjs +1 -0
  8. package/core/src/nako_josi_list.mts +1 -0
  9. package/core/src/nako_lex_rules.mjs +1 -0
  10. package/core/src/nako_lex_rules.mts +1 -0
  11. package/core/src/nako_parser3.mjs +32 -0
  12. package/core/src/nako_parser3.mts +33 -0
  13. package/core/src/nako_prepare.mjs +7 -2
  14. package/core/src/nako_prepare.mts +7 -2
  15. package/core/src/nako_token.mts +1 -0
  16. package/core/test/basic_test.mjs +22 -0
  17. package/core/test/calc_test.mjs +16 -0
  18. package/package.json +3 -3
  19. package/release/_hash.txt +32 -32
  20. package/release/_script-tags.txt +33 -33
  21. package/release/command.json +1 -1
  22. package/release/command.json.js +1 -1
  23. package/release/command_cnako3.json +1 -1
  24. package/release/command_list.json +1 -1
  25. package/release/edit_main.js +9 -9
  26. package/release/edit_main.js.map +3 -3
  27. package/release/editor.js +9 -9
  28. package/release/plugin_markup.js +39 -39
  29. package/release/plugin_markup.js.map +4 -4
  30. package/release/version.js +1 -1
  31. package/release/version_main.js +1 -1
  32. package/release/version_main.js.map +1 -1
  33. package/release/wnako3.js +55 -54
  34. package/release/wnako3.js.map +3 -3
  35. package/release/wnako3webworker.js +37 -36
  36. package/release/wnako3webworker.js.map +3 -3
  37. package/src/nako_version.mjs +2 -2
  38. package/src/nako_version.mts +2 -2
  39. package/src/plugin_browser_dom_basic.mjs +4 -1
  40. package/src/plugin_browser_dom_basic.mts +4 -1
  41. package/src/plugin_browser_dom_parts.mjs +80 -28
  42. package/src/plugin_browser_dom_parts.mts +94 -34
package/README.md CHANGED
@@ -138,12 +138,13 @@ Google Colabでなでしこのビルドテストできます。
138
138
  ## なでしこの開発履歴
139
139
 
140
140
  「なでしこ3」の開発は2017年に始まり、以後コツコツとバージョンアップを続けています。
141
- 「誰でも簡単プログラマー」の目標を実現するために、これからも頑張ります。
141
+ 「誰でも簡単プログラマー」の目標を実現するために開発を続けます。
142
142
 
143
- - (2024/07/22) v.3.6.11でcoreに分割した開発用リポジトリを再び本家に統合
144
- - (2024/07/04) v3.6.8で、バンドルツールを`webpack`から`esbuild`に変更(#1690)
143
+ - (2024-07-22) v.3.6.11でcoreに分割した開発用リポジトリを再び本家に統合
144
+ - (2024-07-04) v3.6.8で、バンドルツールを`webpack`から`esbuild`に変更(#1690)
145
+ - (2024-05-02) v3.6.2で、プラグイン用APIを一新、なでしこの変数管理をObjectからMapに変更(#1638)
145
146
  - (2022-05-19) v3.3.18でJavaScriptからTypeScriptへ変更。言語コアを別リポジトリcoreに移動
146
- - (2022-04-20) v3.3.2を公開(モジュール構造をCommonJSESModuleへ変更/asyncFnの実装)
147
+ - (2022-04-20) v3.3.2を公開(モジュール構造をCommonJSからESModuleへ変更/非同期関数asyncFnの実装)
147
148
  - (2021-04-09) v3.2.1を公開
148
149
  - (2020-04-24) v3.1.2を公開
149
150
  - (2017-12-29) v3.0.19を公開(無名関数の「には」構文の実装など)
package/batch/command.txt CHANGED
@@ -830,6 +830,71 @@
830
830
 
831
831
 
832
832
  ■plugin_electron_node(拡張プラグイン,enako)
833
+ ●システム定数
834
+ | 定数 | Eアプリ | | app | Eあぷり | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L196
835
+ | 定数 | IPCメイン | | ipcMain | IPCめいん | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L197
836
+ ●Electronアプリ
837
+ | 関数 | アプリID設定 | APPIDに/APPIDを | アプリIDを設定する | あぷりIDせってい | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L203
838
+ | 関数 | QUIT | | Electronのアプリを終了する | QUIT | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L212
839
+ | 関数 | 終了 | | Electronのアプリを終了する | しゅうりょう | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L221
840
+ | 関数 | 強制終了 | CODEで | Electronのアプリを強制終了する | きょうせいしゅうりょう | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L230
841
+ | 関数 | 再起動予約 | POPTSで | アプリが終了した際に自動的に起動する | さいきどうよやく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L239
842
+ | 関数 | Eアプリ準備完了 | | アプリの準備が完了していれば真を返す | Eあぷりじゅんびかんりょう | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L251
843
+ | 関数 | Eアプリ準備完了時 | CALLBACKで | アプリの準備が完了した際に呼び去られる処理を登録する | Eあぷりじゅんびかんりょうしたとき | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L259
844
+ | 関数 | Eアプリフォーカス獲得 | | アプリがフォーカスの獲得を試みる | Eあぷりふぉーかすかくとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L270
845
+ | 関数 | Eアプリバージョン取得 | | package.jsonで設定しているアプリのバージョンを返す | Eあぷりばーじょんしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L279
846
+ | 関数 | Eアプリ名取得 | | package.jsonで設定しているアプリの名前(name,productName)を返す | Eあぷりめいしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L287
847
+ ●ElectronのBrowserWindow
848
+ | 関数 | ブラウザウインドウ作成 | POPTSで/POPTSから | オプションに従いブラウザウインドウを作成して返す | ぶらうざういんどうさくせい | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L296
849
+ | 関数 | ブラウザ読込 | WINにPURLから/WINへPURLを | ウインドウに指定のURLから読み込みを行う | ぶらうざよみこみ | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L325
850
+ | 関数 | 全ウインドウ数取得 | | アプリに存在する全てのWindowの数を返す | ぜんういんどうすうしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L340
851
+ | 関数 | フォーカスウインドウ取得 | | フォーカスを獲得しているWindowを返す | ふぉーかすういんどうしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L348
852
+ | 関数 | ウインドウ再読込 | WINを | 指定したウインドウの再読み込みを行う | ういんどうさいよみこみ | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L356
853
+ | 関数 | ウインドウ表示 | WINを/WINの | 指定したウインドウを表示状態にする | ういんどうひょうじ | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L365
854
+ | 関数 | 開発ツールトグル | WINを/WINの | 指定したウインドウの開発者ツールの表示状態をトグルする | かいはつつーるとぐる | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L374
855
+ | 関数 | メニュー設定 | WINにMENUを | menuをウインドウのメニューに設定する | めにゅーせってい | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L383
856
+ ●Electronのメニュー
857
+ | 関数 | アプリメニュー設定 | MENUを | menuをアプリのメインメニューに設定する | あぷりめにゅーせってい | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L393
858
+ | 関数 | アプリメニュー取得 | | アプリのメインメニューに取得して返す | あぷりめにゅーしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L411
859
+ | 関数 | メニュー一括作成 | TEMPLATEから | メニューをテンプレートから一括作成し作成したメニューを返す | めにゅーいっかつさくせい | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L427
860
+ | 関数 | メニューポップアップ開 | MENUをPOPTSで | メニューをポップアップメニューとして開く | めにゅーぽっぷあっぷひらく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L450
861
+ | 関数 | メニューポップアップ閉 | MENUをWINの | ポップアップメニューとして開かれたこのメニューを閉じる | めにゅーぽっぷあっぷとじる | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L462
862
+ | 関数 | メニューアイテム追加 | MENUにITEMを | メニューにメニュー項目を追加する | めにゅーあいてむついか | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L472
863
+ | 関数 | メニュー項目追加 | MENUにITEMを | メニューにメニュー項目を追加する | めにゅーこうもくついか | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L481
864
+ | 関数 | メニューアイテム挿入 | MENUのPOSにITEMを | メニューの指定位置にメニュー項目を挿入する | めにゅーあいてむそうにゅう | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L490
865
+ | 関数 | メニュー項目挿入 | MENUのPOSにITEMを | メニューの指定位置にメニュー項目を挿入する | めにゅーこうもくそうにゅう | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L499
866
+ | 関数 | メニューアイテム取得 | MENUからIDを/IDの | メニューから指定したIDを持つメニューアイテムを返す | めにゅーあいてむしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L508
867
+ | 関数 | メニューIDクリック時 | CALLBACKでMENUのIDを | メニューから指定したIDを持つ項目をクリックした時の処理を登録する | めにゅーIDくりっくしたとき | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L516
868
+ | 関数 | メニュー項目作成 | POPTSから/POPTSの | メニュー項目を作成して返す | めにゅーこうもくさくせい | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L526
869
+ ●Electronのイベント処理
870
+ | 関数 | 発生時 | CALLBACKでOBJのTYPE | 対象にて指定のイベントが発生した時の処理を登録する | はっせいしたとき | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L550
871
+ | 関数 | 単発発生時 | CALLBACKでOBJのTYPE | 対象にて指定のイベントが発生した時の処理を登録する。イベント発生時に自動削除される | たんぱつはっせいしたとき | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L563
872
+ | 関数 | 呼出時 | CALLBACKでOBJのTYPE | 対象にて指定のInvoke呼び出しを受けた時の処理を登録する(evt, ...args) | よびだされたとき | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L572
873
+ | 関数 | 呼出 | OBJのTYPEARGSで/TYPEを | 対象のInvokeを呼び出す | よびだす | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L581
874
+ ●Electronのshell
875
+ ●Electronのdialog
876
+ | 関数 | ファイル選択 | WINにPOPTSで | ファイルを選択するダイアログを表示して結果を返す(非同期関数) | ふぁいるせんたく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L601
877
+ | 関数 | フォルダ選択 | WINにPOPTSで | フォルダを選択するダイアログを表示して結果を返す(非同期関数) | ふぉるだせんたく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L612
878
+ | 関数 | 保存ファイル選択 | WINにOPTSで | ファイルを保存するためのダイアログを表示して結果を返す(非同期関数) | ほぞんふぁいるせんたく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L623
879
+ ●Electronのscreen
880
+ | 関数 | カーソル絶対位置取得 | | マウスポインタの絶対位置をDIPポイント単位で返す | かーそるぜったいいちしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L632
881
+ | 関数 | 主モニター取得 | | 主画面に指定されているモニターのDisplayを返す | しゅもにたーしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L640
882
+ | 関数 | 全モニター取得 | | 全てのモニターをDisplayの配列で返す | ぜんもにたーしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L648
883
+ | 関数 | 付近モニター取得 | Pの/Pから | 指定した点に最も近いモニターのDisplayを返す | ふきんもにたーしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L656
884
+ | 関数 | 該当モニター取得 | Rの/Rから | 指定した矩形に最も近いモニターのDisplayを返す | がいとうもにたーしゅとく | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L665
885
+ | 関数 | PX2DIP点変換 | Pの/Pから | Pointを物理的な単位からDIP単位に変換して返す | PX2DIPてんへんかん | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L674
886
+ | 関数 | DIP2PX点変換 | Pの/Pから | PointをDIP単位から物理的な単位に変換して返す | DIP2PXてんへんかん | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L683
887
+ | 関数 | PX2DIP矩形変換 | RのWINで/Rから | Rectangleを物理的な単位からDIP単位に変換して返す。DPIは指定したウインドウと相対的に計算する | PX2DIPくけいへんかん | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L692
888
+ | 関数 | DIP2PXP矩形変換 | RのWINで/Rから | RectangleをDIP単位から物理的な単位に変換して返す。DPIは指定したウインドウと相対的に計算する | DIP2PXくけいへんかん | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L701
889
+ ●Electronのユーザ用IPC通信
890
+ | 関数 | データ受信時 | CALLBACKで | レンダラからのデータ送信を受けた時の処理を登録する(evt, key, msg) | でーたじゅしんしたとき | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L711
891
+ | 関数 | データ呼出時 | CALLBACKで/CALLBACKの | レンダラからの呼び出しを受けた時の処理を登録する(evt, key, msg) | でーたよびだされたとき | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L720
892
+ | 関数 | データ送信 | OBJにKEYでDATAを | レンダラにデータを送信する(webContent, key, data) | でーたそうしん | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L729
893
+ | 関数 | データ呼出 | OBJにKEYでDATAを | レンダラにデータを呼び出す(webContent, key, data) | でーたよびだし | https://github.com/kujirahand/nadesiko3electron/blob/master/src/plugin_electron_node.mjs#L738
894
+ ●ElectronのNode側の標準機能セット
895
+
896
+
897
+ ■nadesiko3-toml(拡張プラグイン,wnako,cnako)
833
898
  ●PHP定数
834
899
  ●PHPシステム
835
900
  ●PDO
@@ -837,9 +902,3 @@
837
902
  ●KUDB
838
903
 
839
904
 
840
- ■nadesiko3-toml(拡張プラグイン,wnako,cnako)
841
- ●TOML
842
- | 関数 | TOMLデコード | Sを/Sの/Sから | TOML文字列をオブジェクトにデコードして返す | TOMLでこーど | https://github.com/kujirahand/nadesiko3-toml/blob/master/src/nadesiko3-toml.js#L27
843
- | 関数 | TOMLエンコード | Sを/Sから/Sの | オブジェクトをTOML文字列にエンコードする | TOMLえんこーど | https://github.com/kujirahand/nadesiko3-toml/blob/master/src/nadesiko3-toml.js#L35
844
-
845
-
package/core/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nadesiko3core",
3
- "version": "3.6.26",
3
+ "version": "3.6.28",
4
4
  "description": "Japanese Programming Language Nadesiko v3 core",
5
5
  "main": "index.mjs",
6
6
  "type": "module",
@@ -31,6 +31,7 @@ export type NodeType = 'nop'
31
31
  | 'break'
32
32
  | 'def_test'
33
33
  | 'let'
34
+ | 'let_prop' // #1793
34
35
  | 'let_array'
35
36
  | 'json_array'
36
37
  | 'json_obj'
@@ -50,6 +51,7 @@ export type NodeType = 'nop'
50
51
  | 'def_local_var'
51
52
  | 'def_local_varlist'
52
53
  | 'ref_array' // 配列参照
54
+ | 'ref_prop' // #1793 (プロパティ参照)
53
55
  | 'require'
54
56
  | 'performance_monitor'
55
57
  | 'speed_mode'
@@ -464,6 +464,12 @@ export class NakoGen {
464
464
  case 'let':
465
465
  code += this.convLet(node);
466
466
  break;
467
+ case 'let_prop':
468
+ code += this.convLetProp(node);
469
+ break;
470
+ case 'ref_prop':
471
+ code += this.convRefProp(node);
472
+ break;
467
473
  case 'inc':
468
474
  code += this.convInc(node);
469
475
  break;
@@ -977,6 +983,17 @@ export class NakoGen {
977
983
  }
978
984
  return code;
979
985
  }
986
+ convRefProp(node) {
987
+ const name = this._convGen(node.name, true);
988
+ const list = node.index;
989
+ if (!list || list.length <= 0) {
990
+ throw NakoSyntaxError.fromNode('プロパティがありません。', node);
991
+ }
992
+ const prop = list[0].value;
993
+ const code = `( (function(){ if (${name}.__getProp) { return ${name}.__getProp('${prop}', __self) } ` +
994
+ `else { return ${name}['${prop}'] } })() )`;
995
+ return code;
996
+ }
980
997
  convLetArray(node) {
981
998
  const id = this.loopId++;
982
999
  const valueNode = node.blocks[0];
@@ -1746,6 +1763,45 @@ export class NakoGen {
1746
1763
  }
1747
1764
  return ';' + this.convLineno(node, false) + code + '\n';
1748
1765
  }
1766
+ // プロパティへの代入式 (#1793)
1767
+ convLetProp(node) {
1768
+ if (!node.index || node.index.length == 0) {
1769
+ throw NakoSyntaxError.fromNode('代入する先のプロパティ名がありません。', node);
1770
+ }
1771
+ if (!node.blocks || node.blocks.length == 0) {
1772
+ throw NakoSyntaxError.fromNode('代入する値がありません。', node);
1773
+ }
1774
+ const astProp = node.index[0];
1775
+ const astValue = node.blocks[0];
1776
+ let prop = '';
1777
+ if (astProp) {
1778
+ prop = astProp.value;
1779
+ }
1780
+ else {
1781
+ throw NakoSyntaxError.fromNode('代入する先のプロパティ名がありません。', node);
1782
+ }
1783
+ let value = null;
1784
+ // 値のプログラムを生成
1785
+ if (astValue) {
1786
+ value = this._convGen(astValue, true);
1787
+ }
1788
+ else {
1789
+ throw NakoSyntaxError.fromNode('代入する値がありません。', node);
1790
+ }
1791
+ // 変数名
1792
+ const name = node.name;
1793
+ const res = this.findVar(name, value);
1794
+ let code = '/*[convLetProp]*/';
1795
+ // 変数が存在しないとき
1796
+ if (res === null) {
1797
+ throw NakoSyntaxError.fromNode(`変数『${name}』が見当たりません。`, node);
1798
+ }
1799
+ // プロパティへの代入式を作る
1800
+ const propVar = `${res.js}['${prop}']`;
1801
+ code += `if (typeof ${res.js}.__setProp === 'function') { ${res.js}.__setProp('${prop}', ${value}, __self); } `;
1802
+ code += `else { ${propVar} = ${value} };`;
1803
+ return ';' + this.convLineno(node, false) + code + '\n';
1804
+ }
1749
1805
  convDefLocalVar(node) {
1750
1806
  const astValue = node.blocks[0];
1751
1807
  let value = '0';
@@ -540,6 +540,12 @@ export class NakoGen {
540
540
  case 'let':
541
541
  code += this.convLet(node as AstLet)
542
542
  break
543
+ case 'let_prop':
544
+ code += this.convLetProp(node as AstLet)
545
+ break
546
+ case 'ref_prop':
547
+ code += this.convRefProp(node as AstLet)
548
+ break
543
549
  case 'inc':
544
550
  code += this.convInc(node as AstBlocks)
545
551
  break
@@ -1053,6 +1059,19 @@ export class NakoGen {
1053
1059
  return code
1054
1060
  }
1055
1061
 
1062
+ convRefProp (node: Ast): string {
1063
+ const name = this._convGen(node.name as Ast, true)
1064
+ const list: Ast[] | undefined = node.index
1065
+ if (!list || list.length <= 0) {
1066
+ throw NakoSyntaxError.fromNode('プロパティがありません。', node)
1067
+ }
1068
+ const prop = (list[0] as AstStrValue).value
1069
+ const code =
1070
+ `( (function(){ if (${name}.__getProp) { return ${name}.__getProp('${prop}', __self) } ` +
1071
+ `else { return ${name}['${prop}'] } })() )`
1072
+ return code
1073
+ }
1074
+
1056
1075
  convLetArray (node: AstLetArray): string {
1057
1076
  const id = this.loopId++
1058
1077
  const valueNode: Ast = node.blocks[0]
@@ -1811,6 +1830,41 @@ export class NakoGen {
1811
1830
  return ';' + this.convLineno(node, false) + code + '\n'
1812
1831
  }
1813
1832
 
1833
+ // プロパティへの代入式 (#1793)
1834
+ convLetProp(node: AstLet): string {
1835
+ if (!node.index || node.index.length == 0) { throw NakoSyntaxError.fromNode('代入する先のプロパティ名がありません。', node) }
1836
+ if (!node.blocks || node.blocks.length == 0) { throw NakoSyntaxError.fromNode('代入する値がありません。', node) }
1837
+ const astProp = node.index[0]
1838
+ const astValue = node.blocks[0]
1839
+ let prop = ''
1840
+ if (astProp) {
1841
+ prop = (astProp as AstStrValue).value
1842
+ } else {
1843
+ throw NakoSyntaxError.fromNode('代入する先のプロパティ名がありません。', node)
1844
+ }
1845
+ let value = null
1846
+ // 値のプログラムを生成
1847
+ if (astValue) {
1848
+ value = this._convGen(astValue, true)
1849
+ } else {
1850
+ throw NakoSyntaxError.fromNode('代入する値がありません。', node)
1851
+ }
1852
+
1853
+ // 変数名
1854
+ const name: string = node.name
1855
+ const res = this.findVar(name, value)
1856
+ let code = '/*[convLetProp]*/'
1857
+ // 変数が存在しないとき
1858
+ if (res === null) {
1859
+ throw NakoSyntaxError.fromNode(`変数『${name}』が見当たりません。`, node)
1860
+ }
1861
+ // プロパティへの代入式を作る
1862
+ const propVar = `${res.js}['${prop}']`
1863
+ code += `if (typeof ${res.js}.__setProp === 'function') { ${res.js}.__setProp('${prop}', ${value}, __self); } `
1864
+ code += `else { ${propVar} = ${value} };`
1865
+ return ';' + this.convLineno(node, false) + code + '\n'
1866
+ }
1867
+
1814
1868
  convDefLocalVar(node: AstDefVar): string {
1815
1869
  const astValue = node.blocks[0]
1816
1870
  let value = '0'
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * 助詞の一覧
3
3
  */
4
+ // 基本的な助詞の一覧
4
5
  export const josiList = [
5
6
  'について', 'くらい', 'なのか', 'までを', 'までの', 'による',
6
7
  'とは', 'から', 'まで', 'だけ', 'より', 'ほど', 'など',
@@ -2,6 +2,7 @@
2
2
  * 助詞の一覧
3
3
  */
4
4
 
5
+ // 基本的な助詞の一覧
5
6
  export const josiList: string[] = [
6
7
  'について', 'くらい', 'なのか', 'までを', 'までの', 'による',
7
8
  'とは', 'から', 'まで', 'だけ', 'より', 'ほど', 'など',
@@ -81,6 +81,7 @@ export const rules = [
81
81
  { name: ')', pattern: /^\)/, readJosi: true },
82
82
  { name: '|', pattern: /^\|/ },
83
83
  { name: '??', pattern: /^\?\?/ }, // 「表示」のエイリアス #1745
84
+ { name: '$', pattern: /^\$/ }, // #1793 プロパティアクセス
84
85
  { name: 'string', pattern: /^🌿/, cbParser: src => cbString('🌿', '🌿', src) },
85
86
  { name: 'string_ex', pattern: /^🌴/, cbParser: src => cbString('🌴', '🌴', src) },
86
87
  { name: 'string_ex', pattern: /^「/, cbParser: src => cbString('「', '」', src) },
@@ -101,6 +101,7 @@ export const rules: NakoLexRule[] = [
101
101
  { name: ')', pattern: /^\)/, readJosi: true },
102
102
  { name: '|', pattern: /^\|/ },
103
103
  { name: '??', pattern: /^\?\?/ }, // 「表示」のエイリアス #1745
104
+ { name: '$', pattern: /^\$/ }, // #1793 プロパティアクセス
104
105
  { name: 'string', pattern: /^🌿/, cbParser: src => cbString('🌿', '🌿', src) },
105
106
  { name: 'string_ex', pattern: /^🌴/, cbParser: src => cbString('🌴', '🌴', src) },
106
107
  { name: 'string_ex', pattern: /^「/, cbParser: src => cbString('「', '」', src) },
@@ -1789,6 +1789,25 @@ export class NakoParser extends NakoParserBase {
1789
1789
  throw NakoSyntaxError.fromNode(`${this.nodeToStr(word, { depth: 1 }, false)}への代入文で計算式に以下の書き間違いがあります。\n${err.message}`, map);
1790
1790
  }
1791
1791
  }
1792
+ // プロパティ代入文 (#1793)
1793
+ if (this.check2(['word', '$', 'word', 'eq']) || this.check2(['word', '$', 'string', 'eq'])) {
1794
+ const word = this.peek();
1795
+ if (this.accept(['word', '$', 'word', 'eq', this.yCalc]) || this.accept(['word', '$', 'string', 'eq', this.yCalc])) {
1796
+ const nameToken = this.getVarName(this.y[0]);
1797
+ const propToken = this.y[2];
1798
+ const valueToken = this.y[4];
1799
+ return {
1800
+ type: 'let_prop',
1801
+ name: nameToken.value,
1802
+ index: [propToken],
1803
+ blocks: [valueToken],
1804
+ josi: '',
1805
+ ...map,
1806
+ end: this.peekSourceMap()
1807
+ };
1808
+ }
1809
+ throw NakoSyntaxError.fromNode(`${this.nodeToStr(word, { depth: 1 }, false)}への代入文の計算式に書き間違いがあります。`, map);
1810
+ }
1792
1811
  // let_array ?
1793
1812
  if (this.check2(['word', '@'])) {
1794
1813
  const la = this.yLetArrayAt(map);
@@ -2581,6 +2600,19 @@ export class NakoParser extends NakoParserBase {
2581
2600
  }
2582
2601
  return ast;
2583
2602
  }
2603
+ // word$prop
2604
+ if (word.josi === '' && (this.check2(['$', 'word']) || this.check2(['$', 'string']))) {
2605
+ this.get(); // skip '$'
2606
+ const prop = this.get();
2607
+ return {
2608
+ type: 'ref_prop', // プロパティ参照
2609
+ name: word,
2610
+ index: [prop],
2611
+ josi: prop.josi,
2612
+ ...map,
2613
+ end: this.peekSourceMap()
2614
+ };
2615
+ }
2584
2616
  return word; // Token to Ast
2585
2617
  }
2586
2618
  return null;
@@ -1556,6 +1556,25 @@ export class NakoParser extends NakoParserBase {
1556
1556
  throw NakoSyntaxError.fromNode(`${this.nodeToStr(word, { depth: 1 }, false)}への代入文で計算式に以下の書き間違いがあります。\n${err.message}`, map)
1557
1557
  }
1558
1558
  }
1559
+ // プロパティ代入文 (#1793)
1560
+ if (this.check2(['word', '$', 'word', 'eq']) || this.check2(['word', '$', 'string', 'eq'])) {
1561
+ const word = this.peek()
1562
+ if (this.accept(['word', '$', 'word', 'eq', this.yCalc]) || this.accept(['word', '$', 'string', 'eq', this.yCalc])) {
1563
+ const nameToken = this.getVarName(this.y[0])
1564
+ const propToken = this.y[2]
1565
+ const valueToken = this.y[4]
1566
+ return {
1567
+ type: 'let_prop',
1568
+ name: (nameToken as AstStrValue).value,
1569
+ index: [propToken],
1570
+ blocks: [valueToken],
1571
+ josi: '',
1572
+ ...map,
1573
+ end: this.peekSourceMap()
1574
+ } as AstLet
1575
+ }
1576
+ throw NakoSyntaxError.fromNode(`${this.nodeToStr(word, { depth: 1 }, false)}への代入文の計算式に書き間違いがあります。`, map)
1577
+ }
1559
1578
 
1560
1579
  // let_array ?
1561
1580
  if (this.check2(['word', '@'])) {
@@ -2291,6 +2310,20 @@ export class NakoParser extends NakoParserBase {
2291
2310
  if (ast.index && ast.index.length === 0) { throw NakoSyntaxError.fromNode(`配列『${word.value}』アクセスで指定ミス`, word) }
2292
2311
  return ast
2293
2312
  }
2313
+
2314
+ // word$prop
2315
+ if (word.josi === '' && (this.check2(['$', 'word']) || this.check2(['$', 'string']))) {
2316
+ this.get() // skip '$'
2317
+ const prop = this.get() as Token
2318
+ return {
2319
+ type: 'ref_prop', // プロパティ参照
2320
+ name: word,
2321
+ index: [prop as Ast],
2322
+ josi: prop.josi,
2323
+ ...map,
2324
+ end: this.peekSourceMap()
2325
+ }
2326
+ }
2294
2327
  return word as any // Token to Ast
2295
2328
  }
2296
2329
  return null
@@ -118,10 +118,15 @@ export class NakoPrepare {
118
118
  // 読点は「,」に変換する (#877)
119
119
  [0x3001, ','], // 読点 --- JSON記法で「,」と「、」を区別したいので読点は変換しないことに。(#276)
120
120
  [0xFF0C, ','], // 読点 ',' 論文などで利用、ただし句点はドットと被るので変換しない (#735)
121
- [0x2716, '*'], // ×の絵文字 (#1183)
121
+ [0x2715, '*'], // ✕の絵文字 (#1781) @see https://ja.wikipedia.org/wiki/%C3%97#%E7%AC%A6%E5%8F%B7%E4%BD%8D%E7%BD%AE
122
+ [0x2716, '*'], // ✖の絵文字 (#1183)
123
+ [0x2717, '*'], // ✗の絵文字 (#1781)
124
+ [0x2718, '*'], // ✘の絵文字 (#1781)
125
+ [0x274C, '*'], // ❌の絵文字 (#1781) CROSS MARK
122
126
  [0x2795, '+'], // +の絵文字 (#1183)
123
127
  [0x2796, '-'], // -の絵文字 (#1183)
124
- [0x2797, '÷'] // ÷の絵文字 (#1183)
128
+ [0x2797, '÷'], // ÷の絵文字 (#1183)
129
+ [0x1F7F0, '='] //🟰の絵文字(#1781)
125
130
  ]);
126
131
  }
127
132
  // 一文字だけ変換
@@ -134,10 +134,15 @@ export class NakoPrepare {
134
134
  // 読点は「,」に変換する (#877)
135
135
  [0x3001, ','], // 読点 --- JSON記法で「,」と「、」を区別したいので読点は変換しないことに。(#276)
136
136
  [0xFF0C, ','], // 読点 ',' 論文などで利用、ただし句点はドットと被るので変換しない (#735)
137
- [0x2716, '*'], // ×の絵文字 (#1183)
137
+ [0x2715, '*'], // ✕の絵文字 (#1781) @see https://ja.wikipedia.org/wiki/%C3%97#%E7%AC%A6%E5%8F%B7%E4%BD%8D%E7%BD%AE
138
+ [0x2716, '*'], // ✖の絵文字 (#1183)
139
+ [0x2717, '*'], // ✗の絵文字 (#1781)
140
+ [0x2718, '*'], // ✘の絵文字 (#1781)
141
+ [0x274C, '*'], // ❌の絵文字 (#1781) CROSS MARK
138
142
  [0x2795, '+'], // +の絵文字 (#1183)
139
143
  [0x2796, '-'], // -の絵文字 (#1183)
140
- [0x2797, '÷'] // ÷の絵文字 (#1183)
144
+ [0x2797, '÷'], // ÷の絵文字 (#1183)
145
+ [0x1F7F0, '='] //🟰の絵文字(#1781)
141
146
  ])
142
147
  }
143
148
 
@@ -102,6 +102,7 @@ export type TokenType = '?'
102
102
  | '」' // error - エラーチェックのため
103
103
  | '』' // error - エラーチェックのため
104
104
  | '??' // 「表示」のエイリアス
105
+ | '$' // プロパティアクセス
105
106
 
106
107
  // トークン
107
108
  export interface Token {
@@ -372,4 +372,26 @@ describe('basic', async () => {
372
372
  await cmp('constructor=10;constructorを表示', '10')
373
373
  await cmp('super=10;superを表示', '10')
374
374
  })
375
+ it('オブジェクトを手軽に設定する-通常(#1793)', async () => {
376
+ await cmp('A={"幅":30};A$幅=50;A$幅を表示', '50')
377
+ await cmp('A={"高":30};A$高さ=50;A$高さを表示', '50') // 送り仮名の省略
378
+ })
379
+ it('オブジェクトを手軽に設定する-プロパティ関数(#1793)', async () => {
380
+ // プロパティの値を取得して10倍にして返す
381
+ await cmp(
382
+ '『 (function(prop, sys){ return this[prop] * 10 })』をJS実行してF_GETに代入。\n' +
383
+ '『 (function(prop, val, sys){ this[prop] = val })』をJS実行してF_SETに代入。\n' +
384
+ 'A={"幅": 3, "__setProp": F_SET, "__getProp": F_GET};\n' +
385
+ 'A$幅=5; A$幅を表示', '50')
386
+ // 値を10倍にして格納
387
+ await cmp(
388
+ '『 (function(prop, sys){ return this[prop] })』をJS実行してF_GETに代入。\n' +
389
+ '『 (function(prop, val, sys){ this[prop] = val*10 })』をJS実行してF_SETに代入。\n' +
390
+ 'A={"幅": 3, "__setProp": F_SET, "__getProp": F_GET};\n' +
391
+ 'A$幅=5; A$幅を表示', '50')
392
+ })
393
+ it('オブジェクトを手軽に設定する-文字列 (#1793)', async () => {
394
+ await cmp('A={"幅":30};A$"幅"=50;A$"幅"を表示', '50')
395
+ await cmp('A={"高":30};A$"高"=50;A$"高"を表示', '50') // 送り仮名の省略
396
+ })
375
397
  })
@@ -237,4 +237,20 @@ describe('calc_test.js', async () => {
237
237
  await cmp('123456789012345678901234567890123456789n>>60nを表示', '107081695084215790682')
238
238
  })
239
239
 
240
+ it('似たフォント問題:なでしこ3で「✕」で掛け算させる #1781', async () => {
241
+ // multiple
242
+ await cmp('(2*3)を表示', '6')
243
+ await cmp('(2✕3)を表示', '6') // 0x2715
244
+ await cmp('(2✖3)を表示', '6') // 0x2716
245
+ await cmp('(2✗3)を表示', '6') // 0x2717
246
+ await cmp('(2✘3)を表示', '6') // 0x2718
247
+ await cmp('(2❌3)を表示', '6') // 0x274C
248
+ // others
249
+ await cmp('(2➕3)を表示', '5')
250
+ await cmp('(20➖3)を表示', '17')
251
+ await cmp('(21÷3)を表示', '7')
252
+ await cmp('(21➗3)を表示', '7')
253
+ await cmp('(20➖3)を表示', '17')
254
+ await cmp('A🟰3;Aを表示', '3')
255
+ })
240
256
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nadesiko3",
3
- "version": "3.6.26",
3
+ "version": "3.6.28",
4
4
  "description": "Japanese Programming Language",
5
5
  "type": "module",
6
6
  "main": "src/index.mjs",
@@ -140,7 +140,7 @@
140
140
  "style-loader": "^4.0.0",
141
141
  "stylelint": "^16.4.0",
142
142
  "testdouble": "^3.20.2",
143
- "typescript": "^5.5.3",
143
+ "typescript": "^5.6.3",
144
144
  "typescript-eslint": "^8.0.0",
145
145
  "url-loader": "^4.1.1",
146
146
  "util": "^0.12.5"
@@ -150,7 +150,7 @@
150
150
  "fs-extra": "^11.2.0",
151
151
  "html": "^1.0.0",
152
152
  "iconv-lite": "^0.6.3",
153
- "marked": "^14.0.0",
153
+ "marked": "^15.0.0",
154
154
  "node-fetch": "^3.3.2",
155
155
  "opener": "^1.5.2",
156
156
  "shell-quote": "^1.8.1"