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:
Selfhosting Dev
2025-09-21 08:53:00 +09:00
parent ee17cfd979
commit c8063c9e41
247 changed files with 10187 additions and 23124 deletions

View File

@ -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;
}
}

View File

@ -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 '.'

View File

@ -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;
}