pyvm: split op handlers into ops_core/ops_box/ops_ctrl; add ops_flow + intrinsic; delegate vm.py without behavior change
net-plugin: modularize constants (consts.rs) and sockets (sockets.rs); remove legacy commented socket code; fix unused imports mir: move instruction unit tests to tests/mir_instruction_unit.rs (file lean-up); no semantic changes runner/pyvm: ensure using pre-strip; misc docs updates Build: cargo build ok; legacy cfg warnings remain as before
This commit is contained in:
@ -52,8 +52,18 @@ pub trait ParserUtils {
|
||||
|
||||
/// NEWLINEトークンをスキップ
|
||||
fn skip_newlines(&mut self) {
|
||||
while matches!(self.current_token().token_type, TokenType::NEWLINE) && !self.is_at_end() {
|
||||
self.advance();
|
||||
let allow_sc = std::env::var("NYASH_PARSER_ALLOW_SEMICOLON").ok().map(|v| {
|
||||
let lv = v.to_ascii_lowercase();
|
||||
lv == "1" || lv == "true" || lv == "on"
|
||||
}).unwrap_or(false);
|
||||
loop {
|
||||
let is_nl = matches!(self.current_token().token_type, TokenType::NEWLINE);
|
||||
let is_sc = allow_sc && matches!(self.current_token().token_type, TokenType::SEMICOLON);
|
||||
if (is_nl || is_sc) && !self.is_at_end() {
|
||||
self.advance();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,44 @@ impl NyashParser {
|
||||
let mut expr = self.expr_parse_primary()?;
|
||||
|
||||
loop {
|
||||
// Phase 2: expression-level postfix catch/cleanup
|
||||
// Example: foo(bar) catch(Type e) { ... } cleanup { ... }
|
||||
// Guarded by Stage-3 gate to avoid surprising Stage-2 programs.
|
||||
if crate::config::env::expr_postfix_catch()
|
||||
&& (self.match_token(&TokenType::CATCH) || self.match_token(&TokenType::CLEANUP))
|
||||
{
|
||||
use crate::ast::{CatchClause, Span};
|
||||
// Parse optional single catch, then optional cleanup
|
||||
let mut catch_clauses: Vec<CatchClause> = Vec::new();
|
||||
if self.match_token(&TokenType::CATCH) {
|
||||
self.advance(); // consume 'catch'
|
||||
self.consume(TokenType::LPAREN)?;
|
||||
let (exception_type, exception_var) = self.parse_catch_param()?;
|
||||
self.consume(TokenType::RPAREN)?;
|
||||
let catch_body = self.parse_block_statements()?;
|
||||
catch_clauses.push(CatchClause {
|
||||
exception_type,
|
||||
variable_name: exception_var,
|
||||
body: catch_body,
|
||||
span: Span::unknown(),
|
||||
});
|
||||
}
|
||||
let finally_body = if self.match_token(&TokenType::CLEANUP) {
|
||||
self.advance(); // consume 'cleanup'
|
||||
Some(self.parse_block_statements()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
expr = ASTNode::TryCatch {
|
||||
try_body: vec![expr],
|
||||
catch_clauses,
|
||||
finally_body,
|
||||
span: Span::unknown(),
|
||||
};
|
||||
// Postfix catch/cleanup binds at the end of a call/chain. Stop further chaining.
|
||||
break;
|
||||
}
|
||||
if self.match_token(&TokenType::DOT) {
|
||||
self.advance(); // consume '.'
|
||||
|
||||
|
||||
@ -196,6 +196,11 @@ impl NyashParser {
|
||||
let mut statements = Vec::new();
|
||||
let mut _statement_count = 0;
|
||||
|
||||
let allow_sc = std::env::var("NYASH_PARSER_ALLOW_SEMICOLON").ok().map(|v| {
|
||||
let lv = v.to_ascii_lowercase();
|
||||
lv == "1" || lv == "true" || lv == "on"
|
||||
}).unwrap_or(false);
|
||||
|
||||
while !self.is_at_end() {
|
||||
// EOF tokenはスキップ
|
||||
if matches!(self.current_token().token_type, TokenType::EOF) {
|
||||
@ -203,7 +208,9 @@ impl NyashParser {
|
||||
}
|
||||
|
||||
// NEWLINE tokenはスキップ(文の区切りとして使用)
|
||||
if matches!(self.current_token().token_type, TokenType::NEWLINE) {
|
||||
if matches!(self.current_token().token_type, TokenType::NEWLINE)
|
||||
|| (allow_sc && matches!(self.current_token().token_type, TokenType::SEMICOLON))
|
||||
{
|
||||
self.advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user