diff --git a/Cargo.toml b/Cargo.toml index 76b16167..3e8352fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,50 +9,110 @@ repository = "https://github.com/user/nyash" keywords = ["language", "interpreter", "box", "memory-safe", "rust"] categories = ["development-tools::parsing", "interpreters"] +# Default features - minimal CLI only +[features] +default = ["cli"] +cli = [] +gui = ["dep:egui", "dep:eframe", "dep:egui_extras", "dep:image"] +gui-examples = ["gui"] +all-examples = ["gui-examples"] + [lib] name = "nyash_rust" path = "src/lib.rs" crate-type = ["cdylib", "rlib"] +# Main CLI binary - always available [[bin]] name = "nyash" path = "src/main.rs" +# GUI examples - only built with gui-examples feature [[bin]] name = "simple_notepad" path = "examples/simple_notepad.rs" +required-features = ["gui-examples"] [[bin]] name = "nyash_notepad" path = "examples/simple_notepad_v2.rs" +required-features = ["gui-examples"] [[bin]] name = "nyash_notepad_ascii" path = "examples/simple_notepad_ascii.rs" +required-features = ["gui-examples"] [[bin]] name = "debug_notepad" path = "examples/debug_notepad.rs" +required-features = ["gui-examples"] [[bin]] name = "nyash_notepad_jp" path = "examples/nyash_notepad_jp.rs" +required-features = ["gui-examples"] [[bin]] name = "nyash_explorer" path = "examples/nyash_explorer.rs" +required-features = ["gui-examples"] [[bin]] name = "nyash_explorer_icons" path = "examples/nyash_explorer_with_icons.rs" - -[[example]] -name = "visual_node_prototype" -path = "development/egui_research/experiments/visual_node_prototype.rs" +required-features = ["gui-examples"] [[bin]] name = "test_icon_extraction" path = "examples/test_icon_extraction.rs" +required-features = ["gui-examples"] + +# Examples for development - only available as examples, not bins +[[example]] +name = "gui_simple_notepad" +path = "examples/simple_notepad.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_simple_notepad_v2" +path = "examples/simple_notepad_v2.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_simple_notepad_ascii" +path = "examples/simple_notepad_ascii.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_debug_notepad" +path = "examples/debug_notepad.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_nyash_notepad_jp" +path = "examples/nyash_notepad_jp.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_nyash_explorer" +path = "examples/nyash_explorer.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_nyash_explorer_with_icons" +path = "examples/nyash_explorer_with_icons.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_test_icon_extraction" +path = "examples/test_icon_extraction.rs" +required-features = ["gui-examples"] + +[[example]] +name = "gui_visual_node_prototype" +path = "development/egui_research/experiments/visual_node_prototype.rs" +required-features = ["gui-examples"] @@ -90,11 +150,11 @@ wasm-bindgen = "0.2" console_error_panic_hook = "0.1" js-sys = "0.3" -# GUI フレームワーク -egui = "0.29" -eframe = { version = "0.29", default-features = false, features = ["default_fonts", "glow"] } -egui_extras = { version = "0.29", features = ["image"] } -image = { version = "0.25", features = ["png", "ico"] } +# GUI フレームワーク - only when gui feature is enabled +egui = { version = "0.29", optional = true } +eframe = { version = "0.29", default-features = false, features = ["default_fonts", "glow"], optional = true } +egui_extras = { version = "0.29", features = ["image"], optional = true } +image = { version = "0.25", features = ["png", "ico"], optional = true } # Windows API [target.'cfg(windows)'.dependencies] diff --git a/local_tests/basic_math.nyash b/local_tests/basic_math.nyash new file mode 100644 index 00000000..fcf68afd --- /dev/null +++ b/local_tests/basic_math.nyash @@ -0,0 +1,13 @@ +// Basic arithmetic test +local a, b, c, d, flag +a = 10 +b = 20 +c = a + b +print("10 + 20 = " + c) + +d = c * 2 +print("30 * 2 = " + d) + +// Boolean test +flag = true +print("Flag is: " + flag) \ No newline at end of file diff --git a/local_tests/simple_hello.nyash b/local_tests/simple_hello.nyash new file mode 100644 index 00000000..23039fbf --- /dev/null +++ b/local_tests/simple_hello.nyash @@ -0,0 +1,12 @@ +// Simple Hello World test +print("Hello, Nyash!") + +local greeting +greeting = new StringBox("Welcome to Nyash!") +print(greeting.toString()) + +local numbers +numbers = new IntegerBox(42) +local result +result = numbers + 8 +print("42 + 8 = " + result) \ No newline at end of file diff --git a/local_tests/static_main.nyash b/local_tests/static_main.nyash new file mode 100644 index 00000000..1e5a29e7 --- /dev/null +++ b/local_tests/static_main.nyash @@ -0,0 +1,15 @@ +// Static box Main pattern - current working syntax +static box Main { + init { console, result } + + main() { + me.console = new ConsoleBox() + me.console.log("Hello from Static Main!") + + local temp + temp = 42 + me.result = temp + + return "Main completed!" + } +} \ No newline at end of file diff --git a/src/boxes/egui_box.rs b/src/boxes/egui_box.rs index 1d0a0a5f..2fbf70e0 100644 --- a/src/boxes/egui_box.rs +++ b/src/boxes/egui_box.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "gui")] + /*! 🖼️ EguiBox - デスクトップGUIアプリBox * Everything is Box哲学によるGUIフレームワーク統合 * 「なんでもBoxにできる」化け物言語の第一歩! diff --git a/src/boxes/mod.rs b/src/boxes/mod.rs index c7cec7e9..82388999 100644 --- a/src/boxes/mod.rs +++ b/src/boxes/mod.rs @@ -74,7 +74,7 @@ pub mod console_box; pub mod web; // GUI Box(条件付きコンパイル) -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "gui", not(target_arch = "wasm32")))] pub mod egui_box; // 共通で使う型とトレイトを再エクスポート @@ -95,7 +95,7 @@ pub use map_box::MapBox; pub use console_box::ConsoleBox; // EguiBoxの再エクスポート(非WASM環境のみ) -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "gui", not(target_arch = "wasm32")))] pub use egui_box::EguiBox; // Web Box群の再エクスポート(WASM環境のみ) diff --git a/src/interpreter/box_methods.rs b/src/interpreter/box_methods.rs index c2766a06..1ed040b8 100644 --- a/src/interpreter/box_methods.rs +++ b/src/interpreter/box_methods.rs @@ -144,7 +144,7 @@ impl NyashInterpreter { // DebugBox methods moved to system_methods.rs /// EguiBoxのメソッド呼び出しを実行(非WASM環境のみ) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] pub(super) fn execute_egui_method(&mut self, _egui_box: &crate::boxes::EguiBox, method: &str, arguments: &[ASTNode]) -> Result, RuntimeError> { // 引数を評価 diff --git a/src/interpreter/expressions.rs b/src/interpreter/expressions.rs index cf890634..bdbc44af 100644 --- a/src/interpreter/expressions.rs +++ b/src/interpreter/expressions.rs @@ -459,7 +459,7 @@ impl NyashInterpreter { // } // EguiBox method calls (非WASM環境のみ) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] if let Some(egui_box) = obj_value.as_any().downcast_ref::() { return self.execute_egui_method(egui_box, method, arguments); } @@ -849,14 +849,19 @@ impl NyashInterpreter { } // 🔥 ビルトインBoxかチェック - let is_builtin = matches!(parent, - "IntegerBox" | "StringBox" | "BoolBox" | "ArrayBox" | "MapBox" | - "FileBox" | "ResultBox" | "FutureBox" | "ChannelBox" | "MathBox" | - "TimeBox" | "DateTimeBox" | "TimerBox" | "RandomBox" | "SoundBox" | - "DebugBox" | "MethodBox" | "NullBox" | "ConsoleBox" | "FloatBox" | - "BufferBox" | "RegexBox" | "JSONBox" | "StreamBox" | "HTTPClientBox" | - "IntentBox" | "P2PBox" | "EguiBox" - ); + let mut builtin_boxes = vec![ + "IntegerBox", "StringBox", "BoolBox", "ArrayBox", "MapBox", + "FileBox", "ResultBox", "FutureBox", "ChannelBox", "MathBox", + "TimeBox", "DateTimeBox", "TimerBox", "RandomBox", "SoundBox", + "DebugBox", "MethodBox", "NullBox", "ConsoleBox", "FloatBox", + "BufferBox", "RegexBox", "JSONBox", "StreamBox", "HTTPClientBox", + "IntentBox", "P2PBox" + ]; + + #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] + builtin_boxes.push("EguiBox"); + + let is_builtin = builtin_boxes.contains(&parent); if is_builtin { // ビルトインBoxの場合、ロックを解放してからメソッド呼び出し diff --git a/src/interpreter/objects.rs b/src/interpreter/objects.rs index b03c5e88..c8dcc383 100644 --- a/src/interpreter/objects.rs +++ b/src/interpreter/objects.rs @@ -214,7 +214,7 @@ impl NyashInterpreter { // let p2p_box = Box::new(crate::boxes::P2PBox::new(node_id, intent_box)) as Box; // return Ok(p2p_box); // } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] "EguiBox" => { // EguiBoxは引数なしで作成(GUIアプリケーション用) if !arguments.is_empty() { @@ -860,9 +860,9 @@ impl NyashInterpreter { let is_web_box = false; // GUI専用Box(非WASM環境のみ) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] let is_gui_box = matches!(type_name, "EguiBox"); - #[cfg(target_arch = "wasm32")] + #[cfg(not(all(feature = "gui", not(target_arch = "wasm32"))))] let is_gui_box = false; is_builtin || is_web_box || is_gui_box || @@ -916,14 +916,19 @@ impl NyashInterpreter { // 親クラスの継承チェーンを再帰的に解決 (Multi-delegation) 🚀 for parent_name in &box_decl.extends { // 🔥 ビルトインBoxかチェック - let is_builtin = matches!(parent_name.as_str(), - "IntegerBox" | "StringBox" | "BoolBox" | "ArrayBox" | "MapBox" | - "FileBox" | "ResultBox" | "FutureBox" | "ChannelBox" | "MathBox" | - "TimeBox" | "DateTimeBox" | "TimerBox" | "RandomBox" | "SoundBox" | - "DebugBox" | "MethodBox" | "NullBox" | "ConsoleBox" | "FloatBox" | - "BufferBox" | "RegexBox" | "JSONBox" | "StreamBox" | "HTTPClientBox" | - "IntentBox" | "P2PBox" | "EguiBox" - ); + let mut builtin_boxes = vec![ + "IntegerBox", "StringBox", "BoolBox", "ArrayBox", "MapBox", + "FileBox", "ResultBox", "FutureBox", "ChannelBox", "MathBox", + "TimeBox", "DateTimeBox", "TimerBox", "RandomBox", "SoundBox", + "DebugBox", "MethodBox", "NullBox", "ConsoleBox", "FloatBox", + "BufferBox", "RegexBox", "JSONBox", "StreamBox", "HTTPClientBox", + "IntentBox", "P2PBox" + ]; + + #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] + builtin_boxes.push("EguiBox"); + + let is_builtin = builtin_boxes.contains(&parent_name.as_str()); if is_builtin { // ビルトインBoxの場合、フィールドやメソッドは継承しない