refactor: Extract basic type constructors from execute_new function
- Create objects_basic_constructors.rs with create_basic_box() method - Handle StringBox, IntegerBox, BoolBox, ArrayBox, NullBox, FloatBox, MapBox - Reduce execute_new function complexity by delegating basic types - Start decomposing 875-line function into manageable modules - All tests pass successfully
This commit is contained in:
@ -34,6 +34,7 @@ mod expressions;
|
||||
mod statements;
|
||||
mod functions;
|
||||
mod objects;
|
||||
mod objects_basic_constructors;
|
||||
mod io;
|
||||
mod methods;
|
||||
mod math_methods;
|
||||
|
||||
@ -88,22 +88,22 @@ impl NyashInterpreter {
|
||||
// 🚧 Legacy implementation (will be removed in Phase 9.78e)
|
||||
eprintln!("🔍 Falling back to legacy match statement for: {}", class);
|
||||
|
||||
// 組み込みBox型のチェック
|
||||
// Try basic type constructors first
|
||||
if let Ok(basic_box) = self.create_basic_box(class, arguments) {
|
||||
return Ok(basic_box);
|
||||
}
|
||||
|
||||
// 組み込みBox型のチェック (基本型以外)
|
||||
eprintln!("🔍 Starting built-in Box type checks...");
|
||||
match class {
|
||||
// Basic Box constructors (CRITICAL - these were missing!)
|
||||
"StringBox" => {
|
||||
// StringBoxは引数1個(文字列値)で作成
|
||||
if arguments.len() != 1 {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("StringBox constructor expects 1 argument, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
let value = self.execute_expression(&arguments[0])?;
|
||||
let string_value = value.to_string_box().value;
|
||||
let string_box = Box::new(StringBox::new(string_value)) as Box<dyn NyashBox>;
|
||||
return Ok(string_box);
|
||||
// Basic types are handled by create_basic_box() above
|
||||
"StringBox" | "IntegerBox" | "BoolBox" | "ArrayBox" | "ResultBox" |
|
||||
"ErrorBox" | "NullBox" | "FloatBox" | "MapBox" => {
|
||||
// These are handled by create_basic_box(), should not reach here
|
||||
unreachable!("Basic type {} should have been handled by create_basic_box()", class);
|
||||
}
|
||||
|
||||
/* Basic types are now handled by create_basic_box() - keeping for reference
|
||||
"IntegerBox" => {
|
||||
// IntegerBoxは引数1個(整数値)で作成
|
||||
if arguments.len() != 1 {
|
||||
|
||||
157
src/interpreter/objects_basic_constructors.rs
Normal file
157
src/interpreter/objects_basic_constructors.rs
Normal file
@ -0,0 +1,157 @@
|
||||
//! Basic type constructors for execute_new
|
||||
//! Handles StringBox, IntegerBox, BoolBox, ArrayBox, etc.
|
||||
|
||||
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;
|
||||
|
||||
impl Interpreter {
|
||||
/// Create basic type boxes (StringBox, IntegerBox, BoolBox, etc.)
|
||||
pub(super) fn create_basic_box(
|
||||
&mut self,
|
||||
class: &str,
|
||||
arguments: &[ASTNode]
|
||||
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
match class {
|
||||
"StringBox" => {
|
||||
// StringBoxは引数1個(文字列値)で作成
|
||||
if arguments.len() != 1 {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("StringBox constructor expects 1 argument, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
|
||||
let value = self.execute_expression(&arguments[0])?;
|
||||
if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
|
||||
return Ok(Box::new(StringBox::new(s.value.clone())));
|
||||
} else if let Some(i) = value.as_any().downcast_ref::<IntegerBox>() {
|
||||
return Ok(Box::new(StringBox::new(i.value.to_string())));
|
||||
} else if let Some(b) = value.as_any().downcast_ref::<BoolBox>() {
|
||||
return Ok(Box::new(StringBox::new(b.value.to_string())));
|
||||
} else {
|
||||
return Ok(Box::new(StringBox::new(value.to_string_box().value)));
|
||||
}
|
||||
}
|
||||
|
||||
"IntegerBox" => {
|
||||
// IntegerBoxは引数1個(整数値)で作成
|
||||
if arguments.len() != 1 {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("IntegerBox constructor expects 1 argument, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
|
||||
let value = self.execute_expression(&arguments[0])?;
|
||||
if let Some(i) = value.as_any().downcast_ref::<IntegerBox>() {
|
||||
return Ok(Box::new(IntegerBox::new(i.value)));
|
||||
} else if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
|
||||
match s.value.parse::<i64>() {
|
||||
Ok(n) => return Ok(Box::new(IntegerBox::new(n))),
|
||||
Err(_) => return Err(RuntimeError::TypeError {
|
||||
message: format!("Cannot convert '{}' to integer", s.value),
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
return Err(RuntimeError::TypeError {
|
||||
message: "IntegerBox constructor requires integer or string argument".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
"BoolBox" => {
|
||||
// BoolBoxは引数1個(ブール値)で作成
|
||||
if arguments.len() != 1 {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("BoolBox constructor expects 1 argument, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
|
||||
let value = self.execute_expression(&arguments[0])?;
|
||||
if let Some(b) = value.as_any().downcast_ref::<BoolBox>() {
|
||||
return Ok(Box::new(BoolBox::new(b.value)));
|
||||
} else if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
|
||||
let val = match s.value.as_str() {
|
||||
"true" => true,
|
||||
"false" => false,
|
||||
_ => return Err(RuntimeError::TypeError {
|
||||
message: format!("Cannot convert '{}' to boolean", s.value),
|
||||
}),
|
||||
};
|
||||
return Ok(Box::new(BoolBox::new(val)));
|
||||
} else {
|
||||
return Err(RuntimeError::TypeError {
|
||||
message: "BoolBox constructor requires boolean or string argument".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
"ArrayBox" => {
|
||||
// ArrayBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("ArrayBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
return Ok(Box::new(ArrayBox::new()));
|
||||
}
|
||||
|
||||
"NullBox" => {
|
||||
// NullBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("NullBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
return Ok(Box::new(NullBox::new()));
|
||||
}
|
||||
|
||||
"MapBox" => {
|
||||
// MapBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("MapBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
let map_box = Box::new(MapBox::new()) as Box<dyn NyashBox>;
|
||||
return Ok(map_box);
|
||||
}
|
||||
|
||||
"FloatBox" => {
|
||||
// FloatBoxは引数1個(浮動小数点数値)で作成
|
||||
if arguments.len() != 1 {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("FloatBox constructor expects 1 argument, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
|
||||
let value = self.execute_expression(&arguments[0])?;
|
||||
if let Some(f) = value.as_any().downcast_ref::<FloatBox>() {
|
||||
return Ok(Box::new(FloatBox::new(f.value)));
|
||||
} else if let Some(i) = value.as_any().downcast_ref::<IntegerBox>() {
|
||||
return Ok(Box::new(FloatBox::new(i.value as f64)));
|
||||
} else if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
|
||||
match s.value.parse::<f64>() {
|
||||
Ok(n) => return Ok(Box::new(FloatBox::new(n))),
|
||||
Err(_) => return Err(RuntimeError::TypeError {
|
||||
message: format!("Cannot convert '{}' to float", s.value),
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
return Err(RuntimeError::TypeError {
|
||||
message: "FloatBox constructor requires float, integer, or string argument".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
// Not a basic type
|
||||
Err(RuntimeError::TypeError {
|
||||
message: format!("Not a basic type: {}", class),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
83
src/interpreter/objects_non_basic_constructors.rs
Normal file
83
src/interpreter/objects_non_basic_constructors.rs
Normal file
@ -0,0 +1,83 @@
|
||||
//! Non-basic type constructors for execute_new
|
||||
//! Handles MathBox, ConsoleBox, GUI boxes, Network boxes, etc.
|
||||
|
||||
use crate::ast::ASTNode;
|
||||
use crate::box_trait::*;
|
||||
use crate::interpreter::core::{NyashInterpreter as Interpreter, RuntimeError};
|
||||
use crate::boxes::math_box::MathBox;
|
||||
use crate::boxes::random_box::RandomBox;
|
||||
use crate::boxes::sound_box::SoundBox;
|
||||
use crate::boxes::debug_box::DebugBox;
|
||||
|
||||
impl Interpreter {
|
||||
/// Create non-basic type boxes (MathBox, ConsoleBox, GUI/Network boxes, etc.)
|
||||
pub(super) fn create_non_basic_box(
|
||||
&mut self,
|
||||
class: &str,
|
||||
arguments: &[ASTNode]
|
||||
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
match class {
|
||||
"MathBox" => {
|
||||
// MathBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("MathBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
let math_box = Box::new(MathBox::new()) as Box<dyn NyashBox>;
|
||||
return Ok(math_box);
|
||||
}
|
||||
|
||||
"ConsoleBox" => {
|
||||
// ConsoleBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("ConsoleBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
let console_box = Box::new(crate::box_trait::ConsoleBox::new()) as Box<dyn NyashBox>;
|
||||
return Ok(console_box);
|
||||
}
|
||||
|
||||
"RandomBox" => {
|
||||
// RandomBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("RandomBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
let random_box = Box::new(RandomBox::new()) as Box<dyn NyashBox>;
|
||||
return Ok(random_box);
|
||||
}
|
||||
|
||||
"SoundBox" => {
|
||||
// SoundBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("SoundBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
let sound_box = Box::new(SoundBox::new()) as Box<dyn NyashBox>;
|
||||
return Ok(sound_box);
|
||||
}
|
||||
|
||||
"DebugBox" => {
|
||||
// DebugBoxは引数なしで作成
|
||||
if !arguments.is_empty() {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("DebugBox constructor expects 0 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
let debug_box = Box::new(DebugBox::new()) as Box<dyn NyashBox>;
|
||||
return Ok(debug_box);
|
||||
}
|
||||
|
||||
_ => {
|
||||
// Not a non-basic type handled here
|
||||
Err(RuntimeError::TypeError {
|
||||
message: format!("Not a non-basic type handled in this method: {}", class),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user