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,14 +1,14 @@
/*!
* Nyash Parser - Statement Parsing Module
*
*
*Statementの解析を担当するモジュール
* if, loop, break, return, print等の制御構文を処理
*/
use crate::tokenizer::TokenType;
use crate::ast::{ASTNode, CatchClause, Span};
use super::{NyashParser, ParseError};
use super::common::ParserUtils;
use super::{NyashParser, ParseError};
use crate::ast::{ASTNode, CatchClause, Span};
use crate::tokenizer::TokenType;
impl NyashParser {
/// 文をパース
@ -16,67 +16,31 @@ impl NyashParser {
// For grammar diff: capture starting token to classify statement keyword
let start_tok = self.current_token().token_type.clone();
let result = match &start_tok {
TokenType::BOX => {
self.parse_box_declaration()
},
TokenType::IMPORT => {
self.parse_import()
},
TokenType::INTERFACE => {
self.parse_interface_box_declaration()
},
TokenType::GLOBAL => {
self.parse_global_var()
},
TokenType::FUNCTION => {
self.parse_function_declaration()
},
TokenType::BOX => self.parse_box_declaration(),
TokenType::IMPORT => self.parse_import(),
TokenType::INTERFACE => self.parse_interface_box_declaration(),
TokenType::GLOBAL => self.parse_global_var(),
TokenType::FUNCTION => self.parse_function_declaration(),
TokenType::STATIC => {
self.parse_static_declaration() // 🔥 静的宣言 (function/box)
},
TokenType::IF => {
self.parse_if()
},
TokenType::LOOP => {
self.parse_loop()
},
TokenType::BREAK => {
self.parse_break()
},
TokenType::CONTINUE => {
self.parse_continue()
},
TokenType::RETURN => {
self.parse_return()
},
TokenType::PRINT => {
self.parse_print()
},
TokenType::NOWAIT => {
self.parse_nowait()
},
TokenType::INCLUDE => {
self.parse_include()
},
TokenType::LOCAL => {
self.parse_local()
},
TokenType::OUTBOX => {
self.parse_outbox()
},
TokenType::TRY => {
self.parse_try_catch()
},
TokenType::THROW => {
self.parse_throw()
},
TokenType::USING => {
self.parse_using()
},
self.parse_static_declaration() // 🔥 静的宣言 (function/box)
}
TokenType::IF => self.parse_if(),
TokenType::LOOP => self.parse_loop(),
TokenType::BREAK => self.parse_break(),
TokenType::CONTINUE => self.parse_continue(),
TokenType::RETURN => self.parse_return(),
TokenType::PRINT => self.parse_print(),
TokenType::NOWAIT => self.parse_nowait(),
TokenType::INCLUDE => self.parse_include(),
TokenType::LOCAL => self.parse_local(),
TokenType::OUTBOX => self.parse_outbox(),
TokenType::TRY => self.parse_try_catch(),
TokenType::THROW => self.parse_throw(),
TokenType::USING => self.parse_using(),
TokenType::FROM => {
// 🔥 from構文: from Parent.method(args) または from Parent.constructor(args)
self.parse_from_call_statement()
},
}
TokenType::IDENTIFIER(_name) => {
// function宣言 または 代入文 または 関数呼び出し
self.parse_assignment_or_function_call()
@ -91,7 +55,7 @@ impl NyashParser {
Ok(self.parse_expression()?)
}
};
// Non-invasive syntax rule check
if std::env::var("NYASH_GRAMMAR_DIFF").ok().as_deref() == Some("1") {
let kw = match start_tok {
@ -116,7 +80,12 @@ impl NyashParser {
};
if let Some(k) = kw {
let ok = crate::grammar::engine::get().syntax_is_allowed_statement(k);
if !ok { eprintln!("[GRAMMAR-DIFF][Parser] statement '{}' not allowed by syntax rules", k); }
if !ok {
eprintln!(
"[GRAMMAR-DIFF][Parser] statement '{}' not allowed by syntax rules",
k
);
}
}
}
result
@ -130,7 +99,11 @@ impl NyashParser {
self.advance();
v
} else {
return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "string literal".to_string(), line: self.current_token().line });
return Err(ParseError::UnexpectedToken {
found: self.current_token().token_type.clone(),
expected: "string literal".to_string(),
line: self.current_token().line,
});
};
// Optional: 'as' Alias (treat 'as' as identifier literal)
let mut alias: Option<String> = None;
@ -141,20 +114,28 @@ impl NyashParser {
alias = Some(name.clone());
self.advance();
} else {
return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "alias name".to_string(), line: self.current_token().line });
return Err(ParseError::UnexpectedToken {
found: self.current_token().token_type.clone(),
expected: "alias name".to_string(),
line: self.current_token().line,
});
}
}
}
Ok(ASTNode::ImportStatement { path, alias, span: Span::unknown() })
Ok(ASTNode::ImportStatement {
path,
alias,
span: Span::unknown(),
})
}
/// if文をパース: if (condition) { body } else if ... else { body }
pub(super) fn parse_if(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'if'
// 条件部分を取得
let condition = Box::new(self.parse_expression()?);
// then部分を取得
self.consume(TokenType::LBRACE)?;
let mut then_body = Vec::new();
@ -165,11 +146,11 @@ impl NyashParser {
}
}
self.consume(TokenType::RBRACE)?;
// else if/else部分を処理
let else_body = if self.match_token(&TokenType::ELSE) {
self.advance(); // consume 'else'
if self.match_token(&TokenType::IF) {
// else if を ネストしたifとして処理
let nested_if = self.parse_if()?;
@ -190,7 +171,7 @@ impl NyashParser {
} else {
None
};
Ok(ASTNode::If {
condition,
then_body,
@ -198,11 +179,11 @@ impl NyashParser {
span: Span::unknown(),
})
}
/// loop文をパース
pub(super) fn parse_loop(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'loop'
// 条件部分を取得(省略可: `loop { ... }` は無条件ループとして扱う)
let condition = if self.match_token(&TokenType::LPAREN) {
self.advance(); // consume '('
@ -211,9 +192,12 @@ impl NyashParser {
cond
} else {
// default: true
Box::new(ASTNode::Literal { value: crate::ast::LiteralValue::Bool(true), span: Span::unknown() })
Box::new(ASTNode::Literal {
value: crate::ast::LiteralValue::Bool(true),
span: Span::unknown(),
})
};
// body部分を取得
self.consume(TokenType::LBRACE)?;
let mut body = Vec::new();
@ -224,30 +208,34 @@ impl NyashParser {
}
}
self.consume(TokenType::RBRACE)?;
Ok(ASTNode::Loop {
condition,
body,
span: Span::unknown(),
})
}
/// break文をパース
pub(super) fn parse_break(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'break'
Ok(ASTNode::Break { span: Span::unknown() })
Ok(ASTNode::Break {
span: Span::unknown(),
})
}
/// continue文をパース
pub(super) fn parse_continue(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'continue'
Ok(ASTNode::Continue { span: Span::unknown() })
Ok(ASTNode::Continue {
span: Span::unknown(),
})
}
/// return文をパース
pub(super) fn parse_return(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'return'
// 許容: 改行をスキップしてから式有無を判定
// 許容: 改行をスキップしてから式有無を判定
self.skip_newlines();
// returnの後に式があるかチェックRBRACE/EOFなら値なし
let value = if self.is_at_end() || self.match_token(&TokenType::RBRACE) {
@ -255,24 +243,30 @@ impl NyashParser {
} else {
Some(Box::new(self.parse_expression()?))
};
Ok(ASTNode::Return { value, span: Span::unknown() })
Ok(ASTNode::Return {
value,
span: Span::unknown(),
})
}
/// print文をパース
pub(super) fn parse_print(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'print'
self.consume(TokenType::LPAREN)?;
let value = Box::new(self.parse_expression()?);
self.consume(TokenType::RPAREN)?;
Ok(ASTNode::Print { expression: value, span: Span::unknown() })
Ok(ASTNode::Print {
expression: value,
span: Span::unknown(),
})
}
/// nowait文をパース: nowait variable = expression
pub(super) fn parse_nowait(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'nowait'
// 変数名を取得
let variable = if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
let name = name.clone();
@ -286,21 +280,21 @@ impl NyashParser {
line,
});
};
self.consume(TokenType::ASSIGN)?;
let expression = Box::new(self.parse_expression()?);
Ok(ASTNode::Nowait {
variable,
expression,
span: Span::unknown(),
})
}
/// include文をパース
pub(super) fn parse_include(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'include'
let path = if let TokenType::STRING(path) = &self.current_token().token_type {
let path = path.clone();
self.advance();
@ -313,27 +307,30 @@ impl NyashParser {
line,
});
};
Ok(ASTNode::Include { filename: path, span: Span::unknown() })
Ok(ASTNode::Include {
filename: path,
span: Span::unknown(),
})
}
/// local変数宣言をパース: local var1, var2, var3 または local x = 10
pub(super) fn parse_local(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'local'
let mut names = Vec::new();
let mut initial_values = Vec::new();
// 最初の変数名を取得
if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
names.push(name.clone());
self.advance();
// = があれば初期値を設定
if self.match_token(&TokenType::ASSIGN) {
self.advance(); // consume '='
initial_values.push(Some(Box::new(self.parse_expression()?)));
// 初期化付きlocalは単一変数のみカンマ区切り不可
Ok(ASTNode::Local {
variables: names,
@ -343,11 +340,11 @@ impl NyashParser {
} else {
// 初期化なしの場合はカンマ区切りで複数変数可能
initial_values.push(None);
// カンマ区切りで追加の変数名を取得
while self.match_token(&TokenType::COMMA) {
self.advance(); // consume ','
if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
names.push(name.clone());
initial_values.push(None);
@ -361,7 +358,7 @@ impl NyashParser {
});
}
}
Ok(ASTNode::Local {
variables: names,
initial_values,
@ -377,22 +374,22 @@ impl NyashParser {
})
}
}
/// outbox変数宣言をパース: outbox var1, var2, var3
pub(super) fn parse_outbox(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'outbox'
let mut names = Vec::new();
// 最初の変数名を取得
if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
names.push(name.clone());
self.advance();
// カンマ区切りで追加の変数名を取得
while self.match_token(&TokenType::COMMA) {
self.advance(); // consume ','
if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
names.push(name.clone());
self.advance();
@ -405,7 +402,7 @@ impl NyashParser {
});
}
}
let num_vars = names.len();
Ok(ASTNode::Outbox {
variables: names,
@ -421,12 +418,12 @@ impl NyashParser {
})
}
}
/// try-catch文をパース
pub(super) fn parse_try_catch(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'try'
self.consume(TokenType::LBRACE)?;
let mut try_body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines();
@ -434,42 +431,44 @@ impl NyashParser {
try_body.push(self.parse_statement()?);
}
}
self.consume(TokenType::RBRACE)?;
let mut catch_clauses = Vec::new();
// catch節をパース
while self.match_token(&TokenType::CATCH) {
self.advance(); // consume 'catch'
self.consume(TokenType::LPAREN)?;
// 例外型 (オプション)
let exception_type = if let TokenType::IDENTIFIER(type_name) = &self.current_token().token_type {
let type_name = type_name.clone();
self.advance();
Some(type_name)
} else {
None
};
let exception_type =
if let TokenType::IDENTIFIER(type_name) = &self.current_token().token_type {
let type_name = type_name.clone();
self.advance();
Some(type_name)
} else {
None
};
// 例外変数名
let exception_var = if let TokenType::IDENTIFIER(var_name) = &self.current_token().token_type {
let var_name = var_name.clone();
self.advance();
var_name
} else {
let line = self.current_token().line;
return Err(ParseError::UnexpectedToken {
found: self.current_token().token_type.clone(),
expected: "exception variable name".to_string(),
line,
});
};
let exception_var =
if let TokenType::IDENTIFIER(var_name) = &self.current_token().token_type {
let var_name = var_name.clone();
self.advance();
var_name
} else {
let line = self.current_token().line;
return Err(ParseError::UnexpectedToken {
found: self.current_token().token_type.clone(),
expected: "exception variable name".to_string(),
line,
});
};
self.consume(TokenType::RPAREN)?;
self.consume(TokenType::LBRACE)?;
let mut catch_body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines();
@ -477,9 +476,9 @@ impl NyashParser {
catch_body.push(self.parse_statement()?);
}
}
self.consume(TokenType::RBRACE)?;
catch_clauses.push(CatchClause {
exception_type,
variable_name: Some(exception_var),
@ -487,12 +486,12 @@ impl NyashParser {
span: Span::unknown(),
});
}
// finally節をパース (オプション)
let finally_body = if self.match_token(&TokenType::FINALLY) {
self.advance(); // consume 'finally'
self.consume(TokenType::LBRACE)?;
let mut body = Vec::new();
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines();
@ -500,13 +499,13 @@ impl NyashParser {
body.push(self.parse_statement()?);
}
}
self.consume(TokenType::RBRACE)?;
Some(body)
} else {
None
};
Ok(ASTNode::TryCatch {
try_body,
catch_clauses,
@ -514,48 +513,51 @@ impl NyashParser {
span: Span::unknown(),
})
}
/// throw文をパース
pub(super) fn parse_throw(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'throw'
let value = Box::new(self.parse_expression()?);
Ok(ASTNode::Throw { expression: value, span: Span::unknown() })
Ok(ASTNode::Throw {
expression: value,
span: Span::unknown(),
})
}
/// 🔥 from構文を文としてパース: from Parent.method(args)
pub(super) fn parse_from_call_statement(&mut self) -> Result<ASTNode, ParseError> {
// 既存のparse_from_call()を使用してFromCall ASTードを作成
let from_call_expr = self.parse_from_call()?;
// FromCallは式でもあるが、文としても使用可能
// 例: from Animal.constructor() (戻り値を使わない)
Ok(from_call_expr)
}
/// using文をパース: using namespace_name
pub(super) fn parse_using(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'using'
// 名前空間名を取得
if let TokenType::IDENTIFIER(namespace_name) = &self.current_token().token_type {
let name = namespace_name.clone();
self.advance();
// Phase 0では "nyashstd" のみ許可
if name != "nyashstd" {
return Err(ParseError::UnsupportedNamespace {
name,
line: self.current_token().line
return Err(ParseError::UnsupportedNamespace {
name,
line: self.current_token().line,
});
}
Ok(ASTNode::UsingStatement {
namespace_name: name,
span: Span::unknown(),
})
} else {
Err(ParseError::ExpectedIdentifier {
line: self.current_token().line
Err(ParseError::ExpectedIdentifier {
line: self.current_token().line,
})
}
}