diff --git a/projects/nyash-wasm/pkg/README.md b/projects/nyash-wasm/pkg/README.md
index 9f453778..34b3a974 100644
--- a/projects/nyash-wasm/pkg/README.md
+++ b/projects/nyash-wasm/pkg/README.md
@@ -1,180 +1,305 @@
# ๐ฑ Nyash Programming Language
+**Next-Generation Browser-Native Programming Experience**
-**Everything is Box** - Revolutionary Programming Language
+*[๐ฏ๐ต ๆฅๆฌ่ช็ใฏใใกใ / Japanese Version](README.ja.md)*
[](#)
[](#philosophy)
[](#webassembly)
+[](projects/nyash-wasm/nyash_playground.html)
[](#license)
-## โจ Key Features
-
-- **Everything is Box Philosophy**: Every value is a unified Box object
-- **WebAssembly Ready**: Run natively in browsers with zero setup
-- **Web Integration**: Control HTML5 Canvas, DOM elements directly from code
-- **Self-Hosting**: Written in itself using revolutionary Box architecture
-- **Modern Syntax**: Clean, expressive syntax with powerful abstractions
-
-## ๐ Quick Start
-
-### Try in Browser (No Installation Required!)
-
-Open [Nyash Playground](projects/nyash-wasm/nyash_playground.html) in your browser and start coding immediately!
-
-### Local Development
-
-```bash
-# Clone the repository
-git clone https://github.com/user/nyash.git
-cd nyash
-
-# Build with Cargo
-cargo build --release
-
-# Run your first program
-./target/release/nyash examples/hello_world.nyash
-```
-
-## ๐ก Philosophy: Everything is Box
-
-Nyash revolutionizes programming by treating **everything** as a Box:
-
-```nyash
-// Traditional languages: different types, complex syntax
-// Nyash: unified Box approach
-
-greeting = new StringBox("Hello!") // Text is a Box
-number = new IntegerBox(42) // Numbers are Boxes
-display = new WebDisplayBox("output") // Even web elements are Boxes!
-
-// Everything works the same way
-display.print(greeting.toString())
-display.print("The answer is: " + number)
-```
-
-## ๐ฎ Examples
-
-### Hello World
-```nyash
-print("๐ฑ Hello, Nyash World!")
-greeting = new StringBox("Welcome to Everything is Box!")
-print(greeting.toString())
-```
-
-### Web Canvas Graphics
-```nyash
-canvas = new WebCanvasBox("my-canvas", 400, 300)
-canvas.setFillStyle("red")
-canvas.fillRect(50, 50, 100, 75)
-canvas.fillText("Nyash WebCanvas", 150, 200)
-```
-
-### Game of Life (Conway)
-```nyash
-game = new GameOfLifeBox(50, 30)
-game.randomize()
-loop (game.generation < 100) {
- game.step()
- game.display()
-}
-```
-
-## ๐ Documentation
-
-- **[Getting Started](docs/GETTING_STARTED_2025.md)** - Your first steps with Nyash
-- **[Language Guide](docs/LANGUAGE_OVERVIEW_2025.md)** - Complete language reference
-- **[Technical Architecture](docs/TECHNICAL_ARCHITECTURE_2025.md)** - Deep dive into Box philosophy
-- **[Philosophy](PHILOSOPHY.md)** - Everything is Box explained
-
-## ๐ Web Integration
-
-Nyash provides seamless browser integration:
-
-```nyash
-// Control web page elements directly
-display = new WebDisplayBox("output")
-display.setHTML("
Generated by Nyash!
")
-
-// Draw on HTML5 Canvas
-canvas = new WebCanvasBox("graphics", 800, 600)
-canvas.drawScene()
-
-// Interactive web apps in pure Nyash
-button = new WebButtonBox("click-me")
-button.onClick = new MethodBox(app, "handleClick")
-```
-
-## ๐ฏ Sample Projects
-
-Explore our curated examples:
-
-- **[Hello World](examples/hello_world.nyash)** - Basic syntax and philosophy
-- **[Simple Calculator](examples/simple_calculator.nyash)** - Math operations with Boxes
-- **[Conway's Game of Life](examples/game_of_life.nyash)** - Complex algorithms made simple
-- **[2048 Game](examples/simple_2048.nyash)** - Complete game implementation
-- **[Dice RPG](examples/app_dice_rpg.nyash)** - Turn-based battle system
-- **[Maze Generator](examples/maze_generator.nyash)** - Procedural generation
-- **[Web Canvas Demo](examples/web_canvas_demo.nyash)** - HTML5 Canvas control
-- **[Web Display Demo](examples/web_display_demo.nyash)** - DOM manipulation
-- **[Text Adventure](examples/text_adventure/)** - Multi-file project structure
-- **[Lisp Interpreter](examples/lisp/)** - Meta-programming capabilities
-
-## โก Performance & Architecture
-
-- **Rust Backend**: High-performance native execution
-- **WebAssembly Target**: Zero-overhead browser deployment
-- **Box Unification**: Simplified memory model, optimized for speed
-- **Self-Hosting**: Bootstrap compiler written in Nyash itself
-
-## ๐ Building from Source
-
-### Prerequisites
-- Rust 1.70+
-- wasm-pack (for WebAssembly builds)
-
-### Commands
-```bash
-# Native build
-cargo build --release
-
-# WebAssembly build
-wasm-pack build --target web --out-dir projects/nyash-wasm/pkg
-
-# Run tests
-cargo test
-
-# Generate documentation
-cargo doc --open
-```
-
-## ๐ค Contributing
-
-We welcome contributions! Here's how to get started:
-
-1. **Fork** the repository
-2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
-3. **Add** your changes and tests
-4. **Ensure** all tests pass (`cargo test`)
-5. **Commit** your changes (`git commit -m 'Add amazing feature'`)
-6. **Push** to your branch (`git push origin feature/amazing-feature`)
-7. **Open** a Pull Request
-
-See our [Contributing Guidelines](CONTRIBUTING.md) for detailed information.
-
-## ๐ License
-
-This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
-
-## ๐ Why Nyash?
-
-- **Unified Philosophy**: No more juggling different types and paradigms
-- **Web-First**: Built for the modern web development ecosystem
-- **Self-Documenting**: Everything is Box makes code naturally readable
-- **Performance**: Rust backend ensures native-level speed
-- **Innovation**: Revolutionary approach to programming language design
-
---
-**Everything is Box. Everything is Simple. Everything is Nyash.** ๐ฑ
+## ๐ **Try Nyash Right Now!**
-[Website](https://nyash-lang.org) โข [Documentation](docs/) โข [Examples](examples/) โข [Community](https://discord.gg/nyash)
\ No newline at end of file
+**No installation, no setup - just open and code!**
+
+๐ **[๐ฎ Launch Nyash Browser Playground](https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html)** ๐
+
+Experience features like:
+- ๐จ **Artist Collaboration Demo** - Multiple Box instances working together
+- โก **Async Computing** - Parallel processing made simple
+- ๐ฎ **Canvas Game Graphics** - Direct browser graphics programming
+- ๐ **Live Debug Visualization** - See your program's memory in real-time
+
+---
+
+## โจ **Why Nyash Changes Everything**
+
+### ๐ฏ **Memory Safety Revolution**
+```nyash
+// Traditional languages: manual memory management, crashes, security issues
+// Nyash: Everything is Box - automatic, safe, elegant
+
+static box Main {
+ init { player, enemies, canvas }
+
+ main() {
+ me.player = new PlayerBox("Hero", 100)
+ me.canvas = new WebCanvasBox("game", 800, 600)
+
+ // Memory automatically managed - no crashes, no leaks!
+ me.player.render(me.canvas)
+ return "Game running safely!"
+ }
+}
+```
+
+### ๐ **Browser-First Design**
+- **Zero Installation**: Runs directly in web browsers via WebAssembly
+- **Web APIs Built-in**: Canvas, DOM, storage - all native language features
+- **Real-time Collaboration**: Share code instantly, run anywhere
+- **Mobile Ready**: Works on phones, tablets, any modern device
+
+### ๐จ **Creative Programming Made Easy**
+```nyash
+// Create art with code - naturally!
+box Artist {
+ init { name, color }
+
+ paintMasterpiece(canvas) {
+ canvas.fillCircle(100, 100, 50, me.color)
+ canvas.fillText("Art by " + me.name, 10, 200, "24px Arial", me.color)
+ }
+}
+
+// Multiple artists collaborate
+picasso = new Artist("Picasso", "red")
+monet = new Artist("Monet", "blue")
+// Each Box maintains its own state and behavior!
+```
+
+### โก **Async Simplicity**
+```nyash
+// Parallel processing without complexity
+nowait future1 = heavyComputation(10000)
+nowait future2 = renderGraphics()
+
+// Do other work while they run...
+setupUI()
+
+// Get results when ready
+result1 = await future1
+result2 = await future2
+```
+
+---
+
+## ๐๏ธ **Revolutionary Architecture**
+
+### Everything is Box Philosophy
+Every value in Nyash is a **Box** - a unified, memory-safe container:
+
+| Traditional Languages | Nyash |
+|----------------------|-------|
+| `int x = 42;` | `x = new IntegerBox(42)` |
+| `string name = "Hello";` | `name = new StringBox("Hello")` |
+| Complex canvas setup | `canvas = new WebCanvasBox("game", 800, 600)` |
+| Manual memory management | Automatic Box lifecycle management |
+
+### Static Box Main Pattern
+```nyash
+// Clean, predictable program structure
+static box Main {
+ init { database, ui, gameState } // Declare all fields upfront
+
+ main() {
+ // Initialize in logical order
+ me.database = new DatabaseBox("save.db")
+ me.ui = new UIManagerBox()
+ me.gameState = new GameStateBox()
+
+ // Your program logic here
+ return runGameLoop()
+ }
+}
+```
+
+### Visual Debug Integration
+```nyash
+debug = new DebugBox()
+debug.startTracking()
+
+player = new PlayerBox("Hero")
+debug.trackBox(player, "Main Character")
+
+// Real-time memory visualization in browser!
+print(debug.memoryReport()) // Live stats, no debugging hell
+```
+
+---
+
+## ๐ฎ **Perfect for Creative Coding**
+
+### Game Development
+- **Built-in Canvas API**: Graphics without external libraries
+- **Input Handling**: Mouse, keyboard, touch - all native
+- **Audio Support**: SoundBox for music and effects
+- **Physics Ready**: Mathematical operations optimized
+
+### Educational Programming
+- **Visual Feedback**: See your code's effects immediately
+- **Memory Visualization**: Understand how programs work
+- **No Setup Barriers**: Students code instantly in browser
+- **Progressive Learning**: From simple scripts to complex applications
+
+### Web Applications
+- **Direct DOM Control**: WebDisplayBox manipulates HTML
+- **No Framework Needed**: Language handles web interaction natively
+- **Real-time Updates**: Changes reflect immediately
+- **Cross-Platform**: Same code, everywhere
+
+---
+
+## ๐ **Language Highlights**
+
+### Clean, Expressive Syntax
+```nyash
+// Object-oriented programming made natural
+box Player {
+ init { name, health, inventory }
+
+ Player(playerName) {
+ me.name = playerName
+ me.health = 100
+ me.inventory = new ArrayBox()
+ }
+
+ takeDamage(amount) {
+ me.health = me.health - amount
+ if me.health <= 0 {
+ me.respawn()
+ }
+ }
+
+ respawn() {
+ me.health = 100
+ print(me.name + " respawned!")
+ }
+}
+```
+
+### Powerful Operators
+```nyash
+// Natural language operators for clarity
+isAlive = health > 0 and not poisoned
+canCast = mana >= spellCost or hasItem("Magic Ring")
+gameOver = playerDead or timeUp
+
+// Mathematical operations built-in
+distance = sqrt((x2 - x1)^2 + (y2 - y1)^2)
+angle = atan2(deltaY, deltaX)
+```
+
+### Generic Programming
+```nyash
+// Type-safe generic containers
+box Container {
+ init { value }
+
+ Container(item) { me.value = item }
+ getValue() { return me.value }
+}
+
+numbers = new Container(42)
+texts = new Container("Hello")
+```
+
+---
+
+## ๐ ๏ธ **Getting Started**
+
+### Browser Development (Recommended)
+```bash
+# 1. Clone repository
+git clone https://github.com/moe-charm/nyash.git
+cd nyash
+
+# 2. Build WebAssembly version
+cd projects/nyash-wasm
+./build.sh
+
+# 3. Open playground in browser
+# Open nyash_playground.html in any modern browser
+```
+
+### Native Development
+
+#### Linux/WSL
+```bash
+# Build native version
+cargo build --release
+
+# Run programs locally
+./target/release/nyash program.nyash
+
+# Try examples
+./target/release/nyash test_async_demo.nyash
+./target/release/nyash app_dice_rpg.nyash
+```
+
+#### ๐ช Windows (Cross-compile)
+```bash
+# Install cross-compiler
+cargo install cargo-xwin
+
+# Build Windows executable
+cargo xwin build --target x86_64-pc-windows-msvc --release
+
+# Generated executable (916KB)
+target/x86_64-pc-windows-msvc/release/nyash.exe
+```
+
+---
+
+## ๐ค **Contributing**
+
+Nyash is open source and welcomes contributions!
+
+- **Issues**: Report bugs, request features
+- **Pull Requests**: Code improvements, new examples
+- **Documentation**: Help improve guides and examples
+- **Community**: Share your Nyash creations!
+
+## ๐ **License**
+
+MIT License - Free for personal and commercial use.
+
+---
+
+## ๐ **Links**
+
+- **[๐ฎ Try Now - Browser Playground](https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html)**
+- **[๐ Documentation](docs/)**
+- **[๐ฏ Examples](examples/)**
+- **[๐ฌ Community Discussion](https://github.com/moe-charm/nyash/discussions)**
+
+## ๐จโ๐ป **Creator**
+
+**Moe Charm** - Programming Language Designer & Developer
+- ๐ GitHub: [@moe-charm](https://github.com/moe-charm)
+- ๐ฆ Twitter/X: [@CharmNexusCore](https://x.com/CharmNexusCore)
+- โ Support Development: [coff.ee/moecharmde6](http://coff.ee/moecharmde6)
+
+*Creating innovative programming languages with AI assistance and dedication ๐ค*
+
+---
+
+## ๐ค **Support the Project**
+
+Nyash is developed with cutting-edge AI collaboration!
+
+If you enjoy Nyash and want to support continued development:
+
+**โ [Support Development](http://coff.ee/moecharmde6)** - Help fuel innovation!
+
+*Powered by Claude Code - Advanced AI development tools aren't free! ๐ค*
+
+Your support helps maintain the project, develop new features, and continue pushing the boundaries of programming language design. Every contribution makes a difference! ๐
+
+---
+
+*Built with โค๏ธ, ๐ค Claude Code, and the Everything is Box philosophy*
+
+**Nyash - Where every value is a Box, and every Box tells a story.**
\ No newline at end of file
diff --git a/projects/nyash-wasm/pkg/nyash_rust_bg.wasm b/projects/nyash-wasm/pkg/nyash_rust_bg.wasm
index 428c7757..3a7f1cd2 100644
Binary files a/projects/nyash-wasm/pkg/nyash_rust_bg.wasm and b/projects/nyash-wasm/pkg/nyash_rust_bg.wasm differ
diff --git a/src/box_factory/builtin.rs b/src/box_factory/builtin.rs
index 97b7dd36..99698660 100644
--- a/src/box_factory/builtin.rs
+++ b/src/box_factory/builtin.rs
@@ -9,8 +9,66 @@ use super::BoxFactory;
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox};
use crate::interpreter::RuntimeError;
use crate::boxes::*;
+use crate::method_box::MethodBox;
+use crate::boxes::p2p_box::TransportKind;
+use crate::boxes::math_box::RangeBox;
use std::collections::HashMap;
+/// Group switches to control which builtin types are registered
+#[derive(Debug, Clone, Copy)]
+pub struct BuiltinGroups {
+ pub basic: bool, // String, Integer, Bool, Float, Null
+ pub container: bool, // Array, Map, Result, Buffer
+ pub utility: bool, // Math, Random, Time, Debug
+ pub io: bool, // Console, Sound
+ pub network: bool, // Socket, HTTP*
+ pub text: bool, // Regex, JSON
+ pub misc: bool, // Stream, Range, Method, Intent, Error
+ pub native: bool, // DateTime, Timer, Egui (cfg-gated)
+ pub wasm: bool, // Web* (cfg-gated)
+}
+
+impl Default for BuiltinGroups {
+ fn default() -> Self {
+ Self {
+ basic: true,
+ container: true,
+ utility: true,
+ io: true,
+ network: true,
+ text: true,
+ misc: true,
+ native: true,
+ wasm: true,
+ }
+ }
+}
+
+impl BuiltinGroups {
+ /// Native full preset (default): all groups enabled
+ pub fn native_full() -> Self { Self::default() }
+
+ /// Native minimal preset: disable network-related boxes
+ pub fn native_minimal() -> Self {
+ Self { network: false, ..Self::default() }
+ }
+
+ /// WASM playground preset: enable core features, disable native/network/io
+ /// - native: false (no DateTimeBox/TimerBox/Egui)
+ /// - io: false (no ConsoleBox/SoundBox)
+ /// - network: false (no Socket/HTTP/P2P)
+ /// - wasm: true (enable Web* boxes)
+ pub fn wasm_playground() -> Self {
+ Self {
+ native: false,
+ io: false,
+ network: false,
+ wasm: true,
+ ..Self::default()
+ }
+ }
+}
+
type BoxCreator = Box]) -> Result, RuntimeError> + Send + Sync>;
/// Factory for all built-in Box types
@@ -20,22 +78,33 @@ pub struct BuiltinBoxFactory {
}
impl BuiltinBoxFactory {
- /// Create a new factory with all built-in types registered
+ /// Create a new factory with default (all) groups registered
pub fn new() -> Self {
- let mut factory = Self {
- creators: HashMap::new(),
- };
-
- // Register all built-in Box types
- factory.register_basic_types();
- factory.register_container_types();
- factory.register_utility_types();
- factory.register_io_types();
+ Self::new_with_groups(BuiltinGroups::default())
+ }
+
+ /// Create a new factory with group-based registration control
+ pub fn new_with_groups(groups: BuiltinGroups) -> Self {
+ let mut factory = Self { creators: HashMap::new() };
+
+ if groups.basic { factory.register_basic_types(); }
+ if groups.container { factory.register_container_types(); }
+ if groups.utility { factory.register_utility_types(); }
+ if groups.io { factory.register_io_types(); }
+ if groups.network { factory.register_network_types(); }
+ if groups.text { factory.register_text_types(); }
+ if groups.misc { factory.register_misc_types(); }
+
+ // Platform-specific sets
#[cfg(not(target_arch = "wasm32"))]
- factory.register_native_types();
+ {
+ if groups.native { factory.register_native_types(); }
+ }
#[cfg(target_arch = "wasm32")]
- factory.register_wasm_types();
-
+ {
+ if groups.wasm { factory.register_wasm_types(); }
+ }
+
factory
}
@@ -140,6 +209,16 @@ impl BuiltinBoxFactory {
Ok(Box::new(MapBox::new()))
});
+ // BufferBox
+ self.register("BufferBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("BufferBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(BufferBox::new()))
+ });
+
// ResultBox
self.register("ResultBox", |args| {
if args.len() != 1 {
@@ -217,6 +296,183 @@ impl BuiltinBoxFactory {
Ok(Box::new(SoundBox::new()))
});
}
+
+ /// Register networking-related types (sockets, HTTP)
+ fn register_network_types(&mut self) {
+ // SocketBox
+ self.register("SocketBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("SocketBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(SocketBox::new()))
+ });
+
+ // HTTPClientBox
+ self.register("HTTPClientBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("HTTPClientBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(HttpClientBox::new()))
+ });
+
+ // HTTPServerBox
+ self.register("HTTPServerBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("HTTPServerBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(HTTPServerBox::new()))
+ });
+
+ // HTTPRequestBox
+ self.register("HTTPRequestBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("HTTPRequestBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(HTTPRequestBox::new()))
+ });
+
+ // HTTPResponseBox
+ self.register("HTTPResponseBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("HTTPResponseBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(HTTPResponseBox::new()))
+ });
+
+ // P2PBox
+ self.register("P2PBox", |args| {
+ if args.len() != 2 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("P2PBox constructor expects 2 arguments (node_id, transport_type), got {}", args.len()),
+ });
+ }
+ let node_id = args[0].to_string_box().value;
+ let transport_str = args[1].to_string_box().value;
+ let transport_kind = transport_str.parse::()
+ .map_err(|e| RuntimeError::InvalidOperation { message: e })?;
+ Ok(Box::new(P2PBox::new(node_id, transport_kind)))
+ });
+ }
+
+ /// Register text/format related types (Regex, JSON)
+ fn register_text_types(&mut self) {
+ // RegexBox
+ self.register("RegexBox", |args| {
+ if args.len() != 1 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("RegexBox constructor expects 1 argument, got {}", args.len()),
+ });
+ }
+ let pattern = args[0].to_string_box().value;
+ match RegexBox::new(&pattern) {
+ Ok(regex_box) => Ok(Box::new(regex_box)),
+ Err(e) => Err(RuntimeError::InvalidOperation { message: format!("Invalid regex pattern: {}", e) }),
+ }
+ });
+
+ // JSONBox
+ self.register("JSONBox", |args| {
+ if args.len() != 1 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("JSONBox constructor expects 1 argument, got {}", args.len()),
+ });
+ }
+ let json_str = args[0].to_string_box().value;
+ match JSONBox::from_str(&json_str) {
+ Ok(json_box) => Ok(Box::new(json_box)),
+ Err(e) => Err(RuntimeError::InvalidOperation { message: format!("Invalid JSON: {}", e) }),
+ }
+ });
+ }
+
+ /// Register various utility types not covered elsewhere
+ fn register_misc_types(&mut self) {
+ // StreamBox
+ self.register("StreamBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("StreamBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(StreamBox::new()))
+ });
+
+ // TimerBox (native only)
+ #[cfg(not(target_arch = "wasm32"))]
+ {
+ self.register("TimerBox", |args| {
+ if !args.is_empty() {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("TimerBox constructor expects 0 arguments, got {}", args.len()),
+ });
+ }
+ Ok(Box::new(TimerBox::new()))
+ });
+ }
+
+ // RangeBox
+ self.register("RangeBox", |args| {
+ if args.len() < 2 || args.len() > 3 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("RangeBox constructor expects 2-3 arguments, got {}", args.len()),
+ });
+ }
+ let start = args[0].to_string_box().value.parse::().map_err(|_| RuntimeError::TypeError { message: "RangeBox constructor requires integer arguments".to_string() })?;
+ let end = args[1].to_string_box().value.parse::().map_err(|_| RuntimeError::TypeError { message: "RangeBox constructor requires integer arguments".to_string() })?;
+ let step = if args.len() == 3 {
+ args[2].to_string_box().value.parse::().map_err(|_| RuntimeError::TypeError { message: "RangeBox constructor requires integer arguments".to_string() })?
+ } else { 1 };
+ Ok(Box::new(RangeBox::new(start, end, step)))
+ });
+
+ // MethodBox
+ self.register("MethodBox", |args| {
+ if args.len() != 2 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("MethodBox constructor expects 2 arguments (instance, method_name), got {}", args.len()),
+ });
+ }
+ let instance = args[0].clone_box();
+ let method_name = args[1].to_string_box().value;
+ Ok(Box::new(MethodBox::new(instance, method_name)))
+ });
+
+ // IntentBox
+ self.register("IntentBox", |args| {
+ if args.len() != 2 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("IntentBox constructor expects 2 arguments (name, payload), got {}", args.len()),
+ });
+ }
+ let name = args[0].to_string_box().value;
+ // Try parse payload as JSON, fallback to string
+ let payload_str = args[1].to_string_box().value;
+ let payload = match serde_json::from_str::(&payload_str) {
+ Ok(json) => json,
+ Err(_) => serde_json::Value::String(payload_str),
+ };
+ Ok(Box::new(IntentBox::new(name, payload)))
+ });
+
+ // ErrorBox (Exception)
+ self.register("ErrorBox", |args| {
+ let message = match args.get(0) {
+ Some(arg) => arg.to_string_box().value,
+ None => String::new(),
+ };
+ Ok(Box::new(crate::exception_box::ErrorBox::new(&message)))
+ });
+ }
/// Register native-only types
#[cfg(not(target_arch = "wasm32"))]
@@ -264,8 +520,38 @@ impl BuiltinBoxFactory {
})
}
});
-
- // Additional WASM types can be registered here
+
+ // WebConsoleBox
+ self.register("WebConsoleBox", |args| {
+ if args.len() != 1 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("WebConsoleBox constructor expects 1 argument (element_id), got {}", args.len()),
+ });
+ }
+ if let Some(id_str) = args[0].as_any().downcast_ref::() {
+ Ok(Box::new(crate::boxes::WebConsoleBox::new(id_str.value.clone())))
+ } else {
+ Err(RuntimeError::TypeError {
+ message: "WebConsoleBox constructor requires string element_id argument".to_string(),
+ })
+ }
+ });
+
+ // WebCanvasBox
+ self.register("WebCanvasBox", |args| {
+ if args.len() != 3 {
+ return Err(RuntimeError::InvalidOperation {
+ message: format!("WebCanvasBox constructor expects 3 arguments (canvas_id, width, height), got {}", args.len()),
+ });
+ }
+
+ let canvas_id = args[0].to_string_box().value;
+ let width = args[1].to_string_box().value.parse::()
+ .map_err(|_| RuntimeError::TypeError { message: "WebCanvasBox width must be integer".to_string() })?;
+ let height = args[2].to_string_box().value.parse::()
+ .map_err(|_| RuntimeError::TypeError { message: "WebCanvasBox height must be integer".to_string() })?;
+ Ok(Box::new(crate::boxes::WebCanvasBox::new(canvas_id, width, height)))
+ });
}
/// Register a Box creator function
@@ -305,4 +591,4 @@ macro_rules! register_builtins {
$factory.register($box_name, $creator_fn);
)*
};
-}
\ No newline at end of file
+}
diff --git a/src/boxes/mod.rs b/src/boxes/mod.rs
index ce975d89..e2ff6347 100644
--- a/src/boxes/mod.rs
+++ b/src/boxes/mod.rs
@@ -131,8 +131,7 @@ pub mod http_server_box;
// P2P้ไฟกBox็พค (NEW! - Completely rewritten)
pub mod intent_box;
-// Temporarily commented out until transport/messaging import issues are fixed
-// pub mod p2p_box;
+pub mod p2p_box;
// null้ขๆฐใๅใจใฏในใใผใ
pub use null_box::{NullBox, null};
@@ -153,5 +152,4 @@ pub use http_server_box::HTTPServerBox;
// P2P้ไฟกBoxใฎๅใจใฏในใใผใ
pub use intent_box::IntentBox;
-// Temporarily commented out until transport/messaging import issues are fixed
-// pub use p2p_box::P2PBox;
\ No newline at end of file
+pub use p2p_box::P2PBox;
diff --git a/src/boxes/p2p_box.rs b/src/boxes/p2p_box.rs
index 159776b0..63fe7568 100644
--- a/src/boxes/p2p_box.rs
+++ b/src/boxes/p2p_box.rs
@@ -37,8 +37,7 @@
use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase};
use crate::boxes::IntentBox;
-use crate::transport::{Transport, InProcessTransport, TransportError};
-use crate::messaging::IntentHandler;
+use crate::transport::{Transport, InProcessTransport};
use std::any::Any;
use std::sync::RwLock;
use std::collections::HashMap;
@@ -135,6 +134,7 @@ impl P2PBox {
let mut handlers = self.handlers.write().unwrap();
handlers.insert(intent_str, handler);
Box::new(BoolBox::new(true))
+ }
/// ใใผใใๅฐ้ๅฏ่ฝใใใงใใฏ
pub fn is_reachable(&self, node_id: Box) -> Box {
let node_str = node_id.to_string_box().value;
@@ -208,4 +208,4 @@ impl std::fmt::Display for P2PBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.fmt_box(f)
}
-}
\ No newline at end of file
+}
diff --git a/src/interpreter/core.rs b/src/interpreter/core.rs
index f240060c..41578d44 100644
--- a/src/interpreter/core.rs
+++ b/src/interpreter/core.rs
@@ -256,6 +256,33 @@ impl NyashInterpreter {
runtime,
}
}
+
+ /// ใฐใซใผใๆงๆใๆๅฎใใฆๆฐใใใคใณใฟใผใใชใฟใผใไฝๆ
+ pub fn new_with_groups(groups: crate::box_factory::builtin::BuiltinGroups) -> Self {
+ let shared = SharedState::new();
+
+ use crate::box_factory::user_defined::UserDefinedBoxFactory;
+ let udf = Arc::new(UserDefinedBoxFactory::new(shared.clone()));
+ let runtime = NyashRuntimeBuilder::new()
+ .with_builtin_groups(groups)
+ .with_factory(udf)
+ .build();
+
+ let mut shared = shared; // ๅฏๅคๅ
+ shared.box_declarations = runtime.box_declarations.clone();
+
+ Self {
+ shared,
+ local_vars: HashMap::new(),
+ outbox_vars: HashMap::new(),
+ control_flow: ControlFlow::None,
+ current_constructor_context: None,
+ evaluation_stack: Vec::new(),
+ invalidated_ids: Arc::new(Mutex::new(HashSet::new())),
+ stdlib: None,
+ runtime,
+ }
+ }
/// ๅ
ฑๆ็ถๆ
ใใๆฐใใใคใณใฟใผใใชใฟใผใไฝๆ๏ผ้ๅๆๅฎ่ก็จ๏ผ
pub fn with_shared(shared: SharedState) -> Self {
@@ -280,6 +307,31 @@ impl NyashInterpreter {
runtime,
}
}
+
+ /// ๅ
ฑๆ็ถๆ
๏ผใฐใซใผใๆงๆใๆๅฎใใฆๆฐใใใคใณใฟใผใใชใฟใผใไฝๆ๏ผ้ๅๆๅฎ่ก็จ๏ผ
+ pub fn with_shared_and_groups(shared: SharedState, groups: crate::box_factory::builtin::BuiltinGroups) -> Self {
+ use crate::box_factory::user_defined::UserDefinedBoxFactory;
+ let udf = Arc::new(UserDefinedBoxFactory::new(shared.clone()));
+ let runtime = NyashRuntimeBuilder::new()
+ .with_builtin_groups(groups)
+ .with_factory(udf)
+ .build();
+
+ let mut shared = shared; // ๅฏๅคๅ
+ shared.box_declarations = runtime.box_declarations.clone();
+
+ Self {
+ shared,
+ local_vars: HashMap::new(),
+ outbox_vars: HashMap::new(),
+ control_flow: ControlFlow::None,
+ current_constructor_context: None,
+ evaluation_stack: Vec::new(),
+ invalidated_ids: Arc::new(Mutex::new(HashSet::new())),
+ stdlib: None,
+ runtime,
+ }
+ }
/// ASTใๅฎ่ก
pub fn execute(&mut self, ast: ASTNode) -> Result, RuntimeError> {
diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs
index c05af308..80cf096c 100644
--- a/src/interpreter/mod.rs
+++ b/src/interpreter/mod.rs
@@ -7,7 +7,7 @@
// Import all necessary dependencies
use crate::ast::{ASTNode, CatchClause};
-use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, ArrayBox, ResultBox, ErrorBox, BoxCore};
+use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, ErrorBox, BoxCore};
use crate::boxes::FutureBox;
use crate::instance_v2::InstanceBox;
use crate::channel_box::ChannelBox;
diff --git a/src/interpreter/objects.rs b/src/interpreter/objects.rs
index a8ce64f0..d614b6c5 100644
--- a/src/interpreter/objects.rs
+++ b/src/interpreter/objects.rs
@@ -26,12 +26,32 @@ impl NyashInterpreter {
match nyash_args {
Ok(args) => {
- // Try unified registry
- use super::super::runtime::get_global_unified_registry;
- let registry = get_global_unified_registry();
+ // Handle generics: if user-defined and type arguments provided, specialize declaration
+ let mut target_class = class.to_string();
+ let user_defined_exists = {
+ let box_decls = self.shared.box_declarations.read().unwrap();
+ box_decls.contains_key(class)
+ };
+ if user_defined_exists && !type_arguments.is_empty() {
+ let generic_decl = {
+ let box_decls = self.shared.box_declarations.read().unwrap();
+ box_decls.get(class).cloned()
+ };
+ if let Some(generic_decl) = generic_decl {
+ // Validate and specialize
+ self.validate_generic_arguments(&generic_decl, type_arguments)?;
+ let specialized = self.specialize_generic_class(&generic_decl, type_arguments)?;
+ target_class = specialized.name.clone();
+ // Insert specialized declaration so registry can create it
+ let mut box_decls = self.shared.box_declarations.write().unwrap();
+ box_decls.insert(target_class.clone(), specialized);
+ }
+ }
+
+ // Try unified registry (use interpreter's runtime registry to include user-defined boxes)
+ let registry = self.runtime.box_registry.clone();
let registry_lock = registry.lock().unwrap();
-
- match registry_lock.create_box(class, &args) {
+ match registry_lock.create_box(&target_class, &args) {
Ok(box_instance) => {
// Check if this is a user-defined box that needs constructor execution
@@ -41,7 +61,7 @@ impl NyashInterpreter {
// Check if we have a box declaration for this class
let (box_decl_opt, constructor_opt) = {
let box_decls = self.shared.box_declarations.read().unwrap();
- if let Some(box_decl) = box_decls.get(class) {
+ if let Some(box_decl) = box_decls.get(&target_class) {
// Find the birth constructor (unified constructor system)
let birth_key = format!("birth/{}", arguments.len());
let constructor = box_decl.constructors.get(&birth_key).cloned();
@@ -64,7 +84,7 @@ impl NyashInterpreter {
return Ok(box_instance);
} else {
return Err(RuntimeError::InvalidOperation {
- message: format!("No constructor found for {} with {} arguments", class, arguments.len()),
+ message: format!("No constructor found for {} with {} arguments", target_class, arguments.len()),
});
}
}
@@ -74,19 +94,19 @@ impl NyashInterpreter {
return Ok(box_instance);
},
Err(e) => {
- eprintln!("๐ Unified registry failed for {}: {}", class, e);
- // Fall through to legacy match statement
+ // Stop here: use unified registry result as source of truth
+ return Err(e);
}
}
},
Err(e) => {
- eprintln!("๐ Argument evaluation failed: {}", e);
- // Fall through to legacy match statement which will re-evaluate args
+ // Argument evaluation failed; propagate error
+ return Err(e);
}
}
- // ๐ง Legacy implementation (will be removed in Phase 9.78e)
- eprintln!("๐ Falling back to legacy match statement for: {}", class);
+ // Unified registry is authoritative; legacy implementation removed
+ return Err(RuntimeError::UndefinedClass { name: class.to_string() });
// Try basic type constructors first
if let Ok(basic_box) = self.create_basic_box(class, arguments) {
@@ -103,7 +123,8 @@ impl NyashInterpreter {
unreachable!("Basic type {} should have been handled by create_basic_box()", class);
}
- /* Basic types are now handled by create_basic_box() - keeping for reference
+ /* Basic types are now handled by create_basic_box() - keeping for reference */
+ /*
"IntegerBox" => {
// IntegerBoxใฏๅผๆฐ1ๅ๏ผๆดๆฐๅค๏ผใงไฝๆ
if arguments.len() != 1 {
@@ -195,6 +216,7 @@ impl NyashInterpreter {
});
}
}
+ */
"MathBox" => {
// MathBoxใฏๅผๆฐใชใใงไฝๆ
if !arguments.is_empty() {
diff --git a/src/interpreter/objects_basic_constructors.rs b/src/interpreter/objects_basic_constructors.rs
index 79fe7d8e..a22370e1 100644
--- a/src/interpreter/objects_basic_constructors.rs
+++ b/src/interpreter/objects_basic_constructors.rs
@@ -5,8 +5,8 @@ use crate::ast::ASTNode;
use crate::box_trait::*;
use crate::interpreter::core::{NyashInterpreter as Interpreter, RuntimeError};
use crate::boxes::FloatBox;
-use crate::NullBox;
-use crate::MapBox;
+use crate::boxes::null_box::NullBox;
+use crate::boxes::map_box::MapBox;
impl Interpreter {
/// Create basic type boxes (StringBox, IntegerBox, BoolBox, etc.)
@@ -154,4 +154,4 @@ impl Interpreter {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/lib.rs b/src/lib.rs
index e51d0d78..947abbe0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,6 +7,8 @@
// ๐ WebAssembly support
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
+#[cfg(target_arch = "wasm32")]
+use crate::box_factory::builtin::BuiltinGroups;
pub mod box_trait;
pub mod boxes;
@@ -109,7 +111,7 @@ impl NyashWasm {
console_error_panic_hook::set_once();
// Create interpreter with browser-specific setup
- let interpreter = NyashInterpreter::new();
+ let interpreter = NyashInterpreter::new_with_groups(BuiltinGroups::wasm_playground());
// Register browser-specific boxes
// ConsoleBox is available as a constructor: console = new ConsoleBox()
diff --git a/src/runner.rs b/src/runner.rs
index ace7b7b8..b02504d7 100644
--- a/src/runner.rs
+++ b/src/runner.rs
@@ -15,7 +15,8 @@ use nyash_rust::{
mir::{MirCompiler, MirPrinter, MirInstruction},
backend::VM,
};
-use nyash_rust::runtime::NyashRuntime;
+use nyash_rust::runtime::{NyashRuntime, NyashRuntimeBuilder};
+use nyash_rust::box_factory::builtin::BuiltinGroups;
use nyash_rust::interpreter::SharedState;
use nyash_rust::box_factory::user_defined::UserDefinedBoxFactory;
use nyash_rust::core::model::BoxDeclaration as CoreBoxDecl;
@@ -226,7 +227,7 @@ impl NyashRunner {
eprintln!("๐ DEBUG: Creating interpreter...");
// Execute the AST
- let mut interpreter = NyashInterpreter::new();
+ let mut interpreter = NyashInterpreter::new_with_groups(BuiltinGroups::native_full());
eprintln!("๐ DEBUG: Starting execution...");
match interpreter.execute(ast) {
Ok(result) => {
@@ -321,7 +322,9 @@ impl NyashRunner {
// Prepare runtime and collect Box declarations for VM user-defined types
let runtime = {
- let rt = NyashRuntime::new();
+ let rt = NyashRuntimeBuilder::new()
+ .with_builtin_groups(BuiltinGroups::native_full())
+ .build();
self.collect_box_declarations(&ast, &rt);
// Register UserDefinedBoxFactory backed by the same declarations
let mut shared = SharedState::new();
@@ -643,7 +646,7 @@ impl NyashRunner {
let start = std::time::Instant::now();
for _ in 0..self.config.iterations {
if let Ok(ast) = NyashParser::parse_from_string(test_code) {
- let mut interpreter = NyashInterpreter::new();
+ let mut interpreter = NyashInterpreter::new_with_groups(BuiltinGroups::native_full());
let _ = interpreter.execute(ast);
}
}
@@ -866,7 +869,7 @@ fn demo_interpreter_system() {
match NyashParser::parse_from_string(simple_code) {
Ok(ast) => {
- let mut interpreter = NyashInterpreter::new();
+ let mut interpreter = NyashInterpreter::new_with_groups(BuiltinGroups::native_full());
match interpreter.execute(ast) {
Ok(result) => {
println!(" โ
Result: {}", result.to_string_box().value);
@@ -891,7 +894,7 @@ fn demo_interpreter_system() {
match NyashParser::parse_from_string(expr_code) {
Ok(ast) => {
- let mut interpreter = NyashInterpreter::new();
+ let mut interpreter = NyashInterpreter::new_with_groups(BuiltinGroups::native_full());
match interpreter.execute(ast) {
Ok(result) => {
println!(" โ
Result: {}", result.to_string_box().value);
diff --git a/src/runtime/nyash_runtime.rs b/src/runtime/nyash_runtime.rs
index 92cd73a9..e12c0525 100644
--- a/src/runtime/nyash_runtime.rs
+++ b/src/runtime/nyash_runtime.rs
@@ -8,7 +8,7 @@ use std::sync::{Arc, Mutex, RwLock};
use crate::core::model::BoxDeclaration;
use crate::box_factory::{UnifiedBoxRegistry, BoxFactory};
-use crate::box_factory::builtin::BuiltinBoxFactory;
+use crate::box_factory::builtin::{BuiltinBoxFactory, BuiltinGroups};
#[cfg(feature = "plugins")]
use crate::box_factory::plugin::PluginBoxFactory;
@@ -34,11 +34,12 @@ impl NyashRuntime {
pub struct NyashRuntimeBuilder {
box_registry: Option>>,
box_declarations: Option>>>,
+ builtin_groups: Option,
}
impl NyashRuntimeBuilder {
pub fn new() -> Self {
- Self { box_registry: None, box_declarations: None }
+ Self { box_registry: None, box_declarations: None, builtin_groups: None }
}
/// Inject a BoxFactory implementation directly into a private registry
@@ -60,19 +61,40 @@ impl NyashRuntimeBuilder {
}
pub fn build(self) -> NyashRuntime {
+ let registry = match self.box_registry {
+ Some(reg) => reg,
+ None => match self.builtin_groups {
+ Some(groups) => create_registry_with_groups(groups),
+ None => create_default_registry(),
+ }
+ };
+
NyashRuntime {
- box_registry: self.box_registry.unwrap_or_else(|| create_default_registry()),
+ box_registry: registry,
box_declarations: self.box_declarations.unwrap_or_else(|| Arc::new(RwLock::new(HashMap::new()))),
}
}
}
fn create_default_registry() -> Arc> {
+ create_registry_with_groups(BuiltinGroups::default())
+}
+
+fn create_registry_with_groups(groups: BuiltinGroups) -> Arc> {
let mut registry = UnifiedBoxRegistry::new();
- registry.register(Arc::new(BuiltinBoxFactory::new()));
+ registry.register(Arc::new(BuiltinBoxFactory::new_with_groups(groups)));
#[cfg(feature = "plugins")]
{
registry.register(Arc::new(PluginBoxFactory::new()));
}
Arc::new(Mutex::new(registry))
}
+
+impl NyashRuntimeBuilder {
+ /// Configure which builtin groups are registered in the registry.
+ /// If a custom box_registry is already provided, this setting is ignored.
+ pub fn with_builtin_groups(mut self, groups: BuiltinGroups) -> Self {
+ self.builtin_groups = Some(groups);
+ self
+ }
+}
diff --git a/src/transport/inprocess.rs b/src/transport/inprocess.rs
index 70ce5050..1a141ae8 100644
--- a/src/transport/inprocess.rs
+++ b/src/transport/inprocess.rs
@@ -24,6 +24,17 @@ pub struct InProcessTransport {
receive_callback: Arc>>>,
}
+impl std::fmt::Debug for InProcessTransport {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("InProcessTransport")
+ .field("node_id", &self.node_id)
+ .field("bus", &"MessageBus")
+ .field("endpoint", &"BusEndpoint")
+ .field("receive_callback", &"")
+ .finish()
+ }
+}
+
impl InProcessTransport {
/// ๆฐใใInProcessTransportใไฝๆ
pub fn new(node_id: String) -> Self {
diff --git a/src/transport/mod.rs b/src/transport/mod.rs
index 9162770e..58a427c1 100644
--- a/src/transport/mod.rs
+++ b/src/transport/mod.rs
@@ -34,7 +34,7 @@ pub enum TransportError {
}
/// Abstract transport trait for different communication methods
-pub trait Transport: Send + Sync {
+pub trait Transport: Send + Sync + std::fmt::Debug {
/// Get the node ID of this transport
fn node_id(&self) -> &str;