chore(fmt): add legacy stubs and strip trailing whitespace to unblock cargo fmt
This commit is contained in:
@ -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(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user