chore(fmt): add legacy stubs and strip trailing whitespace to unblock cargo fmt

This commit is contained in:
Selfhosting Dev
2025-09-17 07:43:07 +09:00
parent fcf8ce1f3c
commit adbb0201a9
385 changed files with 35622 additions and 15004 deletions

View File

@ -1,22 +1,22 @@
/*!
* Box Definition Parser Module
*
*
* Box宣言box, interface box, static boxの解析を担当
* Nyashの中核概念「Everything is Box」を実現する重要モジュール
*/
use crate::tokenizer::TokenType;
use crate::ast::{ASTNode, Span};
use crate::parser::{NyashParser, ParseError};
use crate::parser::common::ParserUtils;
use crate::must_advance;
use crate::parser::common::ParserUtils;
use crate::parser::{NyashParser, ParseError};
use crate::tokenizer::TokenType;
use std::collections::HashMap;
impl NyashParser {
/// box宣言をパース: box Name { fields... methods... }
pub fn parse_box_declaration(&mut self) -> Result<ASTNode, ParseError> {
self.consume(TokenType::BOX)?;
let name = if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
let name = name.clone();
self.advance();
@ -29,19 +29,19 @@ impl NyashParser {
line,
});
};
// 🔥 ジェネリクス型パラメータのパース (<T, U>)
let type_parameters = if self.match_token(&TokenType::LESS) {
self.advance(); // consume '<'
let mut params = Vec::new();
while !self.match_token(&TokenType::GREATER) && !self.is_at_end() {
must_advance!(self, _unused, "generic type parameter parsing");
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
params.push(param.clone());
self.advance();
if self.match_token(&TokenType::COMMA) {
self.advance();
self.skip_newlines();
@ -54,18 +54,18 @@ impl NyashParser {
});
}
}
self.consume(TokenType::GREATER)?; // consume '>'
params
} else {
Vec::new()
};
// 🚀 Multi-delegation support: "from Parent1, Parent2, ..."
let extends = if self.match_token(&TokenType::FROM) {
self.advance(); // consume 'from'
let mut parents = Vec::new();
// Parse first parent (required)
if let TokenType::IDENTIFIER(parent) = &self.current_token().token_type {
parents.push(parent.clone());
@ -77,12 +77,12 @@ impl NyashParser {
line: self.current_token().line,
});
}
// Parse additional parents (optional)
while self.match_token(&TokenType::COMMA) {
self.advance(); // consume ','
self.skip_newlines();
if let TokenType::IDENTIFIER(parent) = &self.current_token().token_type {
parents.push(parent.clone());
self.advance();
@ -94,21 +94,22 @@ impl NyashParser {
});
}
}
parents
} else {
Vec::new()
};
// implementsキーワードのチェック
// TODO: TokenType::IMPLEMENTS is not defined in current version
let implements = if false { // self.match_token(&TokenType::IMPLEMENTS) {
let implements = if false {
// self.match_token(&TokenType::IMPLEMENTS) {
self.advance(); // consume 'implements'
let mut interfaces = Vec::new();
loop {
must_advance!(self, _unused, "interface implementation parsing");
if let TokenType::IDENTIFIER(interface) = &self.current_token().token_type {
interfaces.push(interface.clone());
self.advance();
@ -119,51 +120,51 @@ impl NyashParser {
line: self.current_token().line,
});
}
if self.match_token(&TokenType::COMMA) {
self.advance();
} else {
break;
}
}
interfaces
} else {
Vec::new()
};
self.consume(TokenType::LBRACE)?;
self.skip_newlines(); // ブレース後の改行をスキップ
let mut fields = Vec::new();
let mut methods = HashMap::new();
let mut public_fields: Vec<String> = Vec::new();
let mut private_fields: Vec<String> = Vec::new();
let mut constructors = HashMap::new();
let mut init_fields = Vec::new();
let mut weak_fields = Vec::new(); // 🔗 Track weak fields
let mut weak_fields = Vec::new(); // 🔗 Track weak fields
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines(); // ループ開始時に改行をスキップ
// RBRACEに到達していればループを抜ける
if self.match_token(&TokenType::RBRACE) {
break;
}
// initブロックの処理initメソッドではない場合のみ
if self.match_token(&TokenType::INIT) && self.peek_token() != &TokenType::LPAREN {
self.advance(); // consume 'init'
self.consume(TokenType::LBRACE)?;
// initブロック内のフィールド定義を読み込み
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines();
if self.match_token(&TokenType::RBRACE) {
break;
}
// Check for weak modifier
let is_weak = if self.match_token(&TokenType::WEAK) {
self.advance(); // consume 'weak'
@ -171,14 +172,14 @@ impl NyashParser {
} else {
false
};
if let TokenType::IDENTIFIER(field_name) = &self.current_token().token_type {
init_fields.push(field_name.clone());
if is_weak {
weak_fields.push(field_name.clone()); // 🔗 Add to weak fields list
}
self.advance();
// カンマがあればスキップ
if self.match_token(&TokenType::COMMA) {
self.advance();
@ -186,72 +187,78 @@ impl NyashParser {
} else {
// 不正なトークンがある場合はエラー
return Err(ParseError::UnexpectedToken {
expected: if is_weak { "field name after 'weak'" } else { "field name" }.to_string(),
expected: if is_weak {
"field name after 'weak'"
} else {
"field name"
}
.to_string(),
found: self.current_token().token_type.clone(),
line: self.current_token().line,
});
}
}
self.consume(TokenType::RBRACE)?;
continue;
}
// overrideキーワードをチェック
let mut is_override = false;
if self.match_token(&TokenType::OVERRIDE) {
is_override = true;
self.advance();
}
// initトークンをメソッド名として特別処理
if self.match_token(&TokenType::INIT) && self.peek_token() == &TokenType::LPAREN {
let field_or_method = "init".to_string();
self.advance(); // consume 'init'
// コンストラクタとして処理
if self.match_token(&TokenType::LPAREN) {
// initは常にコンストラクタ
if is_override {
return Err(ParseError::UnexpectedToken {
expected: "method definition, not constructor after override keyword".to_string(),
expected: "method definition, not constructor after override keyword"
.to_string(),
found: TokenType::INIT,
line: self.current_token().line,
});
}
// コンストラクタの処理
self.advance(); // consume '('
let mut params = Vec::new();
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
must_advance!(self, _unused, "constructor parameter parsing");
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
params.push(param.clone());
self.advance();
}
if self.match_token(&TokenType::COMMA) {
self.advance();
}
}
self.consume(TokenType::RPAREN)?;
self.consume(TokenType::LBRACE)?;
let mut body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
must_advance!(self, _unused, "constructor body parsing");
self.skip_newlines();
if self.match_token(&TokenType::RBRACE) {
break;
}
body.push(self.parse_statement()?);
}
self.consume(TokenType::RBRACE)?;
let constructor = ASTNode::FunctionDeclaration {
name: field_or_method.clone(),
params: params.clone(),
@ -260,60 +267,61 @@ impl NyashParser {
is_override: false, // コンストラクタは常に非オーバーライド
span: Span::unknown(),
};
// 🔥 init/引数数 形式でキーを作成(インタープリターと一致させる)
let constructor_key = format!("{}/{}", field_or_method, params.len());
constructors.insert(constructor_key, constructor);
continue;
}
}
// packキーワードの処理ビルトインBox継承用
if self.match_token(&TokenType::PACK) && self.peek_token() == &TokenType::LPAREN {
let field_or_method = "pack".to_string();
self.advance(); // consume 'pack'
// packは常にコンストラクタ
if is_override {
return Err(ParseError::UnexpectedToken {
expected: "method definition, not constructor after override keyword".to_string(),
expected: "method definition, not constructor after override keyword"
.to_string(),
found: TokenType::PACK,
line: self.current_token().line,
});
}
// packコンストラクタの処理
self.advance(); // consume '('
let mut params = Vec::new();
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
must_advance!(self, _unused, "pack parameter parsing");
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
params.push(param.clone());
self.advance();
}
if self.match_token(&TokenType::COMMA) {
self.advance();
}
}
self.consume(TokenType::RPAREN)?;
self.consume(TokenType::LBRACE)?;
let mut body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
must_advance!(self, _unused, "pack body parsing");
self.skip_newlines();
if self.match_token(&TokenType::RBRACE) {
break;
}
body.push(self.parse_statement()?);
}
self.consume(TokenType::RBRACE)?;
let constructor = ASTNode::FunctionDeclaration {
name: field_or_method.clone(),
params: params.clone(),
@ -322,59 +330,60 @@ impl NyashParser {
is_override: false, // packは常に非オーバーライド
span: Span::unknown(),
};
// 🔥 pack/引数数 形式でキーを作成(インタープリターと一致させる)
let constructor_key = format!("{}/{}", field_or_method, params.len());
constructors.insert(constructor_key, constructor);
continue;
}
// birthキーワードの処理生命を与えるコンストラクタ
if self.match_token(&TokenType::BIRTH) && self.peek_token() == &TokenType::LPAREN {
let field_or_method = "birth".to_string();
self.advance(); // consume 'birth'
// birthは常にコンストラクタ
if is_override {
return Err(ParseError::UnexpectedToken {
expected: "method definition, not constructor after override keyword".to_string(),
expected: "method definition, not constructor after override keyword"
.to_string(),
found: TokenType::BIRTH,
line: self.current_token().line,
});
}
// birthコンストラクタの処理
self.advance(); // consume '('
let mut params = Vec::new();
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
must_advance!(self, _unused, "birth parameter parsing");
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
params.push(param.clone());
self.advance();
}
if self.match_token(&TokenType::COMMA) {
self.advance();
}
}
self.consume(TokenType::RPAREN)?;
self.consume(TokenType::LBRACE)?;
let mut body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
must_advance!(self, _unused, "birth body parsing");
self.skip_newlines();
if self.match_token(&TokenType::RBRACE) {
break;
}
body.push(self.parse_statement()?);
}
self.consume(TokenType::RBRACE)?;
let constructor = ASTNode::FunctionDeclaration {
name: field_or_method.clone(),
params: params.clone(),
@ -383,13 +392,13 @@ impl NyashParser {
is_override: false, // birthは常に非オーバーライド
span: Span::unknown(),
};
// 🔥 birth/引数数 形式でキーを作成(インタープリターと一致させる)
let constructor_key = format!("{}/{}", field_or_method, params.len());
constructors.insert(constructor_key, constructor);
continue;
}
// 🚨 birth()統一システム: Box名コンストラクタ無効化
// Box名と同じ名前のコンストラクタは禁止birth()のみ許可)
if let TokenType::IDENTIFIER(id) = &self.current_token().token_type {
@ -401,13 +410,13 @@ impl NyashParser {
});
}
}
// 通常のフィールド名またはメソッド名を読み取り
if let TokenType::IDENTIFIER(field_or_method) = &self.current_token().token_type {
let field_or_method = field_or_method.clone();
self.advance();
// 可視性:
// 可視性:
// - public { ... } / private { ... } ブロック
// - public name: Type 単行P0: 型はパースのみ、意味付けは後段)
if field_or_method == "public" || field_or_method == "private" {
@ -419,12 +428,18 @@ impl NyashParser {
if let TokenType::IDENTIFIER(fname) = &self.current_token().token_type {
let fname = fname.clone();
// ブロックに追加
if field_or_method == "public" { public_fields.push(fname.clone()); } else { private_fields.push(fname.clone()); }
if field_or_method == "public" {
public_fields.push(fname.clone());
} else {
private_fields.push(fname.clone());
}
// 互換性のため、全体fieldsにも追加
fields.push(fname);
self.advance();
// カンマ/改行をスキップ
if self.match_token(&TokenType::COMMA) { self.advance(); }
if self.match_token(&TokenType::COMMA) {
self.advance();
}
self.skip_newlines();
continue;
}
@ -440,62 +455,79 @@ impl NyashParser {
continue;
} else if matches!(self.current_token().token_type, TokenType::IDENTIFIER(_)) {
// 単行形式: public name[: Type]
let fname = if let TokenType::IDENTIFIER(n) = &self.current_token().token_type { n.clone() } else { unreachable!() };
let fname =
if let TokenType::IDENTIFIER(n) = &self.current_token().token_type {
n.clone()
} else {
unreachable!()
};
self.advance();
if self.match_token(&TokenType::COLON) {
self.advance(); // consume ':'
// 型名識別子を受理して破棄P0
// 型名識別子を受理して破棄P0
if let TokenType::IDENTIFIER(_ty) = &self.current_token().token_type {
self.advance();
} else {
return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "type name".to_string(), line: self.current_token().line });
return Err(ParseError::UnexpectedToken {
found: self.current_token().token_type.clone(),
expected: "type name".to_string(),
line: self.current_token().line,
});
}
}
if field_or_method == "public" { public_fields.push(fname.clone()); } else { private_fields.push(fname.clone()); }
if field_or_method == "public" {
public_fields.push(fname.clone());
} else {
private_fields.push(fname.clone());
}
fields.push(fname);
self.skip_newlines();
continue;
} else {
// public/private の後に '{' でも識別子でもない
return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "'{' or field name".to_string(), line: self.current_token().line });
return Err(ParseError::UnexpectedToken {
found: self.current_token().token_type.clone(),
expected: "'{' or field name".to_string(),
line: self.current_token().line,
});
}
}
// メソッドかフィールドかを判定
if self.match_token(&TokenType::LPAREN) {
// メソッド定義
self.advance(); // consume '('
let mut params = Vec::new();
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
must_advance!(self, _unused, "method parameter parsing");
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
params.push(param.clone());
self.advance();
}
if self.match_token(&TokenType::COMMA) {
self.advance();
}
}
self.consume(TokenType::RPAREN)?;
self.consume(TokenType::LBRACE)?;
let mut body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
must_advance!(self, _unused, "method body parsing");
self.skip_newlines();
if self.match_token(&TokenType::RBRACE) {
break;
}
body.push(self.parse_statement()?);
}
self.consume(TokenType::RBRACE)?;
let method = ASTNode::FunctionDeclaration {
name: field_or_method.clone(),
params,
@ -504,14 +536,14 @@ impl NyashParser {
is_override,
span: Span::unknown(),
};
methods.insert(field_or_method, method);
} else {
// フィールド定義P0: 型注釈 name: Type を受理して破棄)
let fname = field_or_method;
if self.match_token(&TokenType::COLON) {
self.advance(); // consume ':'
// 型名識別子を許可P0は保持せず破棄
// 型名識別子を許可P0は保持せず破棄
if let TokenType::IDENTIFIER(_ty) = &self.current_token().token_type {
self.advance();
}
@ -526,14 +558,14 @@ impl NyashParser {
});
}
}
self.consume(TokenType::RBRACE)?;
// 🔥 Override validation
for parent in &extends {
self.validate_override_methods(&name, parent, &methods)?;
}
Ok(ASTNode::BoxDeclaration {
name,
fields,
@ -542,7 +574,7 @@ impl NyashParser {
methods,
constructors,
init_fields,
weak_fields, // 🔗 Add weak fields to AST
weak_fields, // 🔗 Add weak fields to AST
is_interface: false,
extends,
implements,
@ -552,12 +584,12 @@ impl NyashParser {
span: Span::unknown(),
})
}
/// interface box宣言をパース: interface box Name { methods... }
pub fn parse_interface_box_declaration(&mut self) -> Result<ASTNode, ParseError> {
self.consume(TokenType::INTERFACE)?;
self.consume(TokenType::BOX)?;
let name = if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
let name = name.clone();
self.advance();
@ -570,48 +602,48 @@ impl NyashParser {
line,
});
};
self.consume(TokenType::LBRACE)?;
self.skip_newlines(); // ブレース後の改行をスキップ
let mut methods = HashMap::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines(); // ループ開始時に改行をスキップ
if let TokenType::IDENTIFIER(method_name) = &self.current_token().token_type {
let method_name = method_name.clone();
self.advance();
// インターフェースメソッドはシグネチャのみ
if self.match_token(&TokenType::LPAREN) {
self.advance(); // consume '('
let mut params = Vec::new();
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
params.push(param.clone());
self.advance();
}
if self.match_token(&TokenType::COMMA) {
self.advance();
}
}
self.consume(TokenType::RPAREN)?;
// インターフェースメソッドは実装なし空のbody
let method_decl = ASTNode::FunctionDeclaration {
name: method_name.clone(),
params,
body: vec![], // 空の実装
is_static: false, // インターフェースメソッドは通常静的でない
body: vec![], // 空の実装
is_static: false, // インターフェースメソッドは通常静的でない
is_override: false, // デフォルトは非オーバーライド
span: Span::unknown(),
};
methods.insert(method_name, method_decl);
// メソッド宣言後の改行をスキップ
self.skip_newlines();
} else {
@ -631,9 +663,9 @@ impl NyashParser {
});
}
}
self.consume(TokenType::RBRACE)?;
Ok(ASTNode::BoxDeclaration {
name,
fields: vec![], // インターフェースはフィールドなし
@ -641,14 +673,14 @@ impl NyashParser {
private_fields: vec![],
methods,
constructors: HashMap::new(), // インターフェースにコンストラクタなし
init_fields: vec![], // インターフェースにinitブロックなし
weak_fields: vec![], // 🔗 インターフェースにweak fieldsなし
is_interface: true, // インターフェースフラグ
extends: vec![], // 🚀 Multi-delegation: Changed from None to vec![]
init_fields: vec![], // インターフェースにinitブロックなし
weak_fields: vec![], // 🔗 インターフェースにweak fieldsなし
is_interface: true, // インターフェースフラグ
extends: vec![], // 🚀 Multi-delegation: Changed from None to vec![]
implements: vec![],
type_parameters: Vec::new(), // 🔥 インターフェースではジェネリクス未対応
is_static: false, // インターフェースは非static
static_init: None, // インターフェースにstatic initなし
is_static: false, // インターフェースは非static
static_init: None, // インターフェースにstatic initなし
span: Span::unknown(),
})
}

View File

@ -1,6 +1,6 @@
/*!
* Dependency Analysis Helpers
*
*
* Static box依存関係の解析と循環依存検出
*/
@ -10,18 +10,25 @@ use std::collections::{HashMap, HashSet};
impl NyashParser {
/// Static初期化ブロック内の文から依存関係を抽出
pub(super) fn extract_dependencies_from_statements(&self, statements: &[ASTNode]) -> HashSet<String> {
pub(super) fn extract_dependencies_from_statements(
&self,
statements: &[ASTNode],
) -> HashSet<String> {
let mut dependencies = HashSet::new();
for stmt in statements {
self.extract_dependencies_from_ast(stmt, &mut dependencies);
}
dependencies
}
/// AST内から静的Box参照を再帰的に検出
pub(super) fn extract_dependencies_from_ast(&self, node: &ASTNode, dependencies: &mut HashSet<String>) {
pub(super) fn extract_dependencies_from_ast(
&self,
node: &ASTNode,
dependencies: &mut HashSet<String>,
) {
match node {
ASTNode::FieldAccess { object, .. } => {
// Math.PI のような参照を検出
@ -46,7 +53,12 @@ impl NyashParser {
ASTNode::UnaryOp { operand, .. } => {
self.extract_dependencies_from_ast(operand, dependencies);
}
ASTNode::If { condition, then_body, else_body, .. } => {
ASTNode::If {
condition,
then_body,
else_body,
..
} => {
self.extract_dependencies_from_ast(condition, dependencies);
for stmt in then_body {
self.extract_dependencies_from_ast(stmt, dependencies);
@ -57,7 +69,9 @@ impl NyashParser {
}
}
}
ASTNode::Loop { condition, body, .. } => {
ASTNode::Loop {
condition, body, ..
} => {
self.extract_dependencies_from_ast(condition, dependencies);
for stmt in body {
self.extract_dependencies_from_ast(stmt, dependencies);
@ -73,26 +87,26 @@ impl NyashParser {
}
}
}
/// 循環依存検出
pub fn check_circular_dependencies(&self) -> Result<(), ParseError> {
// すべてのstatic boxに対して循環検出を実行
let all_boxes: Vec<_> = self.static_box_dependencies.keys().cloned().collect();
for box_name in &all_boxes {
let mut visited = HashSet::new();
let mut stack = Vec::new();
if self.has_cycle_dfs(box_name, &mut visited, &mut stack)? {
// 循環を文字列化
let cycle_str = stack.join(" -> ");
return Err(ParseError::CircularDependency { cycle: cycle_str });
}
}
Ok(())
}
/// DFSで循環依存を検出
fn has_cycle_dfs(
&self,
@ -105,15 +119,15 @@ impl NyashParser {
stack.push(current.to_string()); // 循環を完成させる
return Ok(true);
}
// 既に訪問済みで循環がなければスキップ
if visited.contains(current) {
return Ok(false);
}
visited.insert(current.to_string());
stack.push(current.to_string());
// 依存先をチェック
if let Some(dependencies) = self.static_box_dependencies.get(current) {
for dep in dependencies {
@ -122,23 +136,31 @@ impl NyashParser {
}
}
}
stack.pop();
Ok(false)
}
/// Override メソッドの検証
pub(super) fn validate_override_methods(&self, child_name: &str, parent_name: &str, methods: &HashMap<String, ASTNode>) -> Result<(), ParseError> {
pub(super) fn validate_override_methods(
&self,
child_name: &str,
parent_name: &str,
methods: &HashMap<String, ASTNode>,
) -> Result<(), ParseError> {
// 現時点では簡単な検証のみ
// TODO: 親クラスのメソッドシグネチャとの比較
for (method_name, method_ast) in methods {
if let ASTNode::FunctionDeclaration { is_override, .. } = method_ast {
if *is_override {
// 将来的にここで親クラスのメソッドが存在するかチェック
eprintln!("🔍 Validating override method '{}' in '{}' from '{}'", method_name, child_name, parent_name);
eprintln!(
"🔍 Validating override method '{}' in '{}' from '{}'",
method_name, child_name, parent_name
);
}
}
}
Ok(())
}
}
}

View File

@ -1,12 +1,12 @@
/*!
* Parser Declarations Module
*
*
* 宣言Declarationの解析を担当するモジュール群
* Box定義、関数定義、use文などの宣言を処理
*/
pub mod box_definition;
pub mod static_box;
pub mod dependency_helpers;
pub mod static_box;
// Re-export commonly used items

View File

@ -1,20 +1,20 @@
/*!
* Static Box Definition Parser
*
*
* static box宣言と関連ヘルパー関数
*/
use crate::tokenizer::TokenType;
use crate::ast::{ASTNode, Span};
use crate::parser::{NyashParser, ParseError};
use crate::parser::common::ParserUtils;
use crate::parser::{NyashParser, ParseError};
use crate::tokenizer::TokenType;
use std::collections::HashMap;
impl NyashParser {
/// static box宣言をパース: static box Name { ... }
pub fn parse_static_box(&mut self) -> Result<ASTNode, ParseError> {
self.consume(TokenType::BOX)?;
let name = if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
let name = name.clone();
self.advance();
@ -27,17 +27,17 @@ impl NyashParser {
line,
});
};
// 🔥 ジェネリクス型パラメータのパース (<T, U>)
let type_parameters = if self.match_token(&TokenType::LESS) {
self.advance(); // consume '<'
let mut params = Vec::new();
loop {
if let TokenType::IDENTIFIER(param_name) = &self.current_token().token_type {
params.push(param_name.clone());
self.advance();
if self.match_token(&TokenType::COMMA) {
self.advance(); // consume ','
} else {
@ -52,24 +52,24 @@ impl NyashParser {
});
}
}
self.consume(TokenType::GREATER)?; // consume '>'
params
} else {
Vec::new()
};
// from句のパースMulti-delegation- static boxでもデリゲーション可能 🚀
let extends = if self.match_token(&TokenType::FROM) {
self.advance(); // consume 'from'
let mut parent_list = Vec::new();
loop {
if let TokenType::IDENTIFIER(parent_name) = &self.current_token().token_type {
parent_list.push(parent_name.clone());
self.advance();
if self.match_token(&TokenType::COMMA) {
self.advance(); // consume ','
} else {
@ -84,23 +84,23 @@ impl NyashParser {
});
}
}
parent_list
} else {
Vec::new()
};
// interface句のパースインターフェース実装- static boxでもinterface実装可能
let implements = if self.match_token(&TokenType::INTERFACE) {
self.advance(); // consume 'interface'
let mut interface_list = Vec::new();
loop {
if let TokenType::IDENTIFIER(interface_name) = &self.current_token().token_type {
interface_list.push(interface_name.clone());
self.advance();
if self.match_token(&TokenType::COMMA) {
self.advance(); // consume ','
} else {
@ -115,35 +115,35 @@ impl NyashParser {
});
}
}
interface_list
} else {
vec![]
};
self.consume(TokenType::LBRACE)?;
self.skip_newlines(); // ブレース後の改行をスキップ
let mut fields = Vec::new();
let mut methods = HashMap::new();
let constructors = HashMap::new();
let mut init_fields = Vec::new();
let mut weak_fields = Vec::new(); // 🔗 Track weak fields for static box
let mut weak_fields = Vec::new(); // 🔗 Track weak fields for static box
let mut static_init = None;
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines(); // ループ開始時に改行をスキップ
// RBRACEに到達していればループを抜ける
if self.match_token(&TokenType::RBRACE) {
break;
}
// 🔥 static { } ブロックの処理
if self.match_token(&TokenType::STATIC) {
self.advance(); // consume 'static'
self.consume(TokenType::LBRACE)?;
let mut static_body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines();
@ -151,25 +151,25 @@ impl NyashParser {
static_body.push(self.parse_statement()?);
}
}
self.consume(TokenType::RBRACE)?;
static_init = Some(static_body);
continue;
}
// initブロックの処理
if self.match_token(&TokenType::INIT) {
self.advance(); // consume 'init'
self.consume(TokenType::LBRACE)?;
// initブロック内のフィールド定義を読み込み
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines();
if self.match_token(&TokenType::RBRACE) {
break;
}
// Check for weak modifier
let is_weak = if self.match_token(&TokenType::WEAK) {
self.advance(); // consume 'weak'
@ -177,14 +177,14 @@ impl NyashParser {
} else {
false
};
if let TokenType::IDENTIFIER(field_name) = &self.current_token().token_type {
init_fields.push(field_name.clone());
if is_weak {
weak_fields.push(field_name.clone()); // 🔗 Add to weak fields list
}
self.advance();
// カンマがあればスキップ
if self.match_token(&TokenType::COMMA) {
self.advance();
@ -192,41 +192,46 @@ impl NyashParser {
} else {
// 不正なトークンがある場合はエラー
return Err(ParseError::UnexpectedToken {
expected: if is_weak { "field name after 'weak'" } else { "field name" }.to_string(),
expected: if is_weak {
"field name after 'weak'"
} else {
"field name"
}
.to_string(),
found: self.current_token().token_type.clone(),
line: self.current_token().line,
});
}
}
self.consume(TokenType::RBRACE)?;
continue;
}
if let TokenType::IDENTIFIER(field_or_method) = &self.current_token().token_type {
let field_or_method = field_or_method.clone();
self.advance();
// メソッド定義か?
if self.match_token(&TokenType::LPAREN) {
// メソッド定義
self.advance(); // consume '('
let mut params = Vec::new();
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
params.push(param.clone());
self.advance();
}
if self.match_token(&TokenType::COMMA) {
self.advance();
}
}
self.consume(TokenType::RPAREN)?;
self.consume(TokenType::LBRACE)?;
let mut body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines();
@ -234,18 +239,18 @@ impl NyashParser {
body.push(self.parse_statement()?);
}
}
self.consume(TokenType::RBRACE)?;
let method = ASTNode::FunctionDeclaration {
name: field_or_method.clone(),
params,
body,
is_static: false, // static box内のメソッドは通常メソッド
is_static: false, // static box内のメソッドは通常メソッド
is_override: false, // デフォルトは非オーバーライド
span: Span::unknown(),
};
methods.insert(field_or_method, method);
} else {
// フィールド定義
@ -259,17 +264,19 @@ impl NyashParser {
});
}
}
self.consume(TokenType::RBRACE)?;
// 🔥 Static初期化ブロックから依存関係を抽出
if let Some(ref init_stmts) = static_init {
let dependencies = self.extract_dependencies_from_statements(init_stmts);
self.static_box_dependencies.insert(name.clone(), dependencies);
self.static_box_dependencies
.insert(name.clone(), dependencies);
} else {
self.static_box_dependencies.insert(name.clone(), std::collections::HashSet::new());
self.static_box_dependencies
.insert(name.clone(), std::collections::HashSet::new());
}
Ok(ASTNode::BoxDeclaration {
name,
fields,
@ -278,13 +285,13 @@ impl NyashParser {
methods,
constructors,
init_fields,
weak_fields, // 🔗 Add weak fields to static box construction
weak_fields, // 🔗 Add weak fields to static box construction
is_interface: false,
extends,
implements,
type_parameters,
is_static: true, // 🔥 static boxフラグを設定
static_init, // 🔥 static初期化ブロック
is_static: true, // 🔥 static boxフラグを設定
static_init, // 🔥 static初期化ブロック
span: Span::unknown(),
})
}