chore(fmt): add legacy stubs and strip trailing whitespace to unblock cargo fmt
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, BinaryOperator, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_bit_or(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -10,7 +10,12 @@ impl NyashParser {
|
||||
let operator = BinaryOperator::BitOr;
|
||||
self.advance();
|
||||
let right = self.expr_parse_bit_xor()?;
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -21,7 +26,12 @@ impl NyashParser {
|
||||
let operator = BinaryOperator::BitXor;
|
||||
self.advance();
|
||||
let right = self.expr_parse_bit_and()?;
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -32,9 +42,13 @@ impl NyashParser {
|
||||
let operator = BinaryOperator::BitAnd;
|
||||
self.advance();
|
||||
let right = self.expr_parse_equality()?;
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, Span};
|
||||
use crate::must_advance;
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
#[inline]
|
||||
fn is_sugar_enabled() -> bool { crate::parser::sugar_gate::is_enabled() }
|
||||
fn is_sugar_enabled() -> bool {
|
||||
crate::parser::sugar_gate::is_enabled()
|
||||
}
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_call(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -70,12 +72,20 @@ impl NyashParser {
|
||||
});
|
||||
}
|
||||
self.advance(); // consume '?.'
|
||||
// ident then optional call
|
||||
// ident then optional call
|
||||
let name = match &self.current_token().token_type {
|
||||
TokenType::IDENTIFIER(s) => { let v = s.clone(); self.advance(); v }
|
||||
TokenType::IDENTIFIER(s) => {
|
||||
let v = s.clone();
|
||||
self.advance();
|
||||
v
|
||||
}
|
||||
_ => {
|
||||
let line = self.current_token().line;
|
||||
return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "identifier after '?.'".to_string(), line });
|
||||
return Err(ParseError::UnexpectedToken {
|
||||
found: self.current_token().token_type.clone(),
|
||||
expected: "identifier after '?.'".to_string(),
|
||||
line,
|
||||
});
|
||||
}
|
||||
};
|
||||
let access = if self.match_token(&TokenType::LPAREN) {
|
||||
@ -85,23 +95,39 @@ impl NyashParser {
|
||||
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
|
||||
must_advance!(self, _unused, "safe method call arg parsing");
|
||||
arguments.push(self.parse_expression()?);
|
||||
if self.match_token(&TokenType::COMMA) { self.advance(); }
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RPAREN)?;
|
||||
ASTNode::MethodCall { object: Box::new(expr.clone()), method: name, arguments, span: Span::unknown() }
|
||||
ASTNode::MethodCall {
|
||||
object: Box::new(expr.clone()),
|
||||
method: name,
|
||||
arguments,
|
||||
span: Span::unknown(),
|
||||
}
|
||||
} else {
|
||||
// field access
|
||||
ASTNode::FieldAccess { object: Box::new(expr.clone()), field: name, span: Span::unknown() }
|
||||
ASTNode::FieldAccess {
|
||||
object: Box::new(expr.clone()),
|
||||
field: name,
|
||||
span: Span::unknown(),
|
||||
}
|
||||
};
|
||||
|
||||
// Wrap with peek: peek expr { null => null, else => access(expr) }
|
||||
expr = ASTNode::PeekExpr {
|
||||
scrutinee: Box::new(expr.clone()),
|
||||
arms: vec![(crate::ast::LiteralValue::Null, ASTNode::Literal { value: crate::ast::LiteralValue::Null, span: Span::unknown() })],
|
||||
arms: vec![(
|
||||
crate::ast::LiteralValue::Null,
|
||||
ASTNode::Literal {
|
||||
value: crate::ast::LiteralValue::Null,
|
||||
span: Span::unknown(),
|
||||
},
|
||||
)],
|
||||
else_expr: Box::new(access),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
|
||||
} else if self.match_token(&TokenType::LPAREN) {
|
||||
// 関数呼び出し: function(args) または 一般式呼び出し: (callee)(args)
|
||||
self.advance(); // consume '('
|
||||
@ -109,23 +135,43 @@ impl NyashParser {
|
||||
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
|
||||
must_advance!(self, _unused, "function call argument parsing");
|
||||
arguments.push(self.parse_expression()?);
|
||||
if self.match_token(&TokenType::COMMA) { self.advance(); }
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RPAREN)?;
|
||||
|
||||
if let ASTNode::Variable { name, .. } = expr.clone() {
|
||||
expr = ASTNode::FunctionCall { name, arguments, span: Span::unknown() };
|
||||
expr = ASTNode::FunctionCall {
|
||||
name,
|
||||
arguments,
|
||||
span: Span::unknown(),
|
||||
};
|
||||
} else {
|
||||
expr = ASTNode::Call { callee: Box::new(expr), arguments, span: Span::unknown() };
|
||||
expr = ASTNode::Call {
|
||||
callee: Box::new(expr),
|
||||
arguments,
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
} else if self.match_token(&TokenType::QUESTION) {
|
||||
let nt = self.peek_token();
|
||||
let is_ender = matches!(nt,
|
||||
TokenType::NEWLINE | TokenType::EOF | TokenType::RPAREN | TokenType::COMMA | TokenType::RBRACE
|
||||
let is_ender = matches!(
|
||||
nt,
|
||||
TokenType::NEWLINE
|
||||
| TokenType::EOF
|
||||
| TokenType::RPAREN
|
||||
| TokenType::COMMA
|
||||
| TokenType::RBRACE
|
||||
);
|
||||
if !is_ender { break; }
|
||||
if !is_ender {
|
||||
break;
|
||||
}
|
||||
self.advance();
|
||||
expr = ASTNode::QMarkPropagate { expression: Box::new(expr), span: Span::unknown() };
|
||||
expr = ASTNode::QMarkPropagate {
|
||||
expression: Box::new(expr),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
#[inline]
|
||||
fn is_sugar_enabled() -> bool { crate::parser::sugar_gate::is_enabled() }
|
||||
fn is_sugar_enabled() -> bool {
|
||||
crate::parser::sugar_gate::is_enabled()
|
||||
}
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_coalesce(&mut self) -> Result<ASTNode, ParseError> {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, BinaryOperator, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_equality(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -15,11 +15,25 @@ impl NyashParser {
|
||||
self.advance();
|
||||
let right = self.expr_parse_comparison()?;
|
||||
if std::env::var("NYASH_GRAMMAR_DIFF").ok().as_deref() == Some("1") {
|
||||
let name = match operator { BinaryOperator::Equal=>"eq", BinaryOperator::NotEqual=>"ne", _=>"cmp" };
|
||||
let name = match operator {
|
||||
BinaryOperator::Equal => "eq",
|
||||
BinaryOperator::NotEqual => "ne",
|
||||
_ => "cmp",
|
||||
};
|
||||
let ok = crate::grammar::engine::get().syntax_is_allowed_binop(name);
|
||||
if !ok { eprintln!("[GRAMMAR-DIFF][Parser] binop '{}' not allowed by syntax rules", name); }
|
||||
if !ok {
|
||||
eprintln!(
|
||||
"[GRAMMAR-DIFF][Parser] binop '{}' not allowed by syntax rules",
|
||||
name
|
||||
);
|
||||
}
|
||||
}
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -40,9 +54,13 @@ impl NyashParser {
|
||||
};
|
||||
self.advance();
|
||||
let right = self.expr_parse_range()?;
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, BinaryOperator, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_factor(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -19,13 +19,26 @@ impl NyashParser {
|
||||
self.advance();
|
||||
let right = self.parse_unary()?;
|
||||
if std::env::var("NYASH_GRAMMAR_DIFF").ok().as_deref() == Some("1") {
|
||||
let name = match operator { BinaryOperator::Multiply=>"mul", BinaryOperator::Divide=>"div", _=>"mod" };
|
||||
let name = match operator {
|
||||
BinaryOperator::Multiply => "mul",
|
||||
BinaryOperator::Divide => "div",
|
||||
_ => "mod",
|
||||
};
|
||||
let ok = crate::grammar::engine::get().syntax_is_allowed_binop(name);
|
||||
if !ok { eprintln!("[GRAMMAR-DIFF][Parser] binop '{}' not allowed by syntax rules", name); }
|
||||
if !ok {
|
||||
eprintln!(
|
||||
"[GRAMMAR-DIFF][Parser] binop '{}' not allowed by syntax rules",
|
||||
name
|
||||
);
|
||||
}
|
||||
}
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, BinaryOperator, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_or(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -12,9 +12,16 @@ impl NyashParser {
|
||||
let right = self.expr_parse_and()?;
|
||||
if std::env::var("NYASH_GRAMMAR_DIFF").ok().as_deref() == Some("1") {
|
||||
let ok = crate::grammar::engine::get().syntax_is_allowed_binop("or");
|
||||
if !ok { eprintln!("[GRAMMAR-DIFF][Parser] binop 'or' not allowed by syntax rules"); }
|
||||
if !ok {
|
||||
eprintln!("[GRAMMAR-DIFF][Parser] binop 'or' not allowed by syntax rules");
|
||||
}
|
||||
}
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -27,9 +34,16 @@ impl NyashParser {
|
||||
let right = self.expr_parse_equality()?;
|
||||
if std::env::var("NYASH_GRAMMAR_DIFF").ok().as_deref() == Some("1") {
|
||||
let ok = crate::grammar::engine::get().syntax_is_allowed_binop("and");
|
||||
if !ok { eprintln!("[GRAMMAR-DIFF][Parser] binop 'and' not allowed by syntax rules"); }
|
||||
if !ok {
|
||||
eprintln!("[GRAMMAR-DIFF][Parser] binop 'and' not allowed by syntax rules");
|
||||
}
|
||||
}
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
pub(crate) mod ternary;
|
||||
pub(crate) mod coalesce;
|
||||
pub(crate) mod logic;
|
||||
pub(crate) mod bit;
|
||||
pub(crate) mod compare;
|
||||
pub(crate) mod range;
|
||||
pub(crate) mod term;
|
||||
pub(crate) mod shift;
|
||||
pub(crate) mod factor;
|
||||
pub(crate) mod call;
|
||||
pub(crate) mod coalesce;
|
||||
pub(crate) mod compare;
|
||||
pub(crate) mod factor;
|
||||
pub(crate) mod logic;
|
||||
pub(crate) mod primary;
|
||||
pub(crate) mod range;
|
||||
pub(crate) mod shift;
|
||||
pub(crate) mod term;
|
||||
pub(crate) mod ternary;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::ast::{ASTNode, LiteralValue, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, Span, LiteralValue};
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_primary(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -23,10 +23,15 @@ impl NyashParser {
|
||||
crate::must_advance!(self, _unused, "array literal element parsing");
|
||||
let el = self.parse_expression()?;
|
||||
elems.push(el);
|
||||
if self.match_token(&TokenType::COMMA) { self.advance(); }
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RBRACK)?;
|
||||
Ok(ASTNode::ArrayLiteral { elements: elems, span: Span::unknown() })
|
||||
Ok(ASTNode::ArrayLiteral {
|
||||
elements: elems,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::LBRACE => {
|
||||
let sugar_on = crate::parser::sugar_gate::is_enabled()
|
||||
@ -38,39 +43,111 @@ impl NyashParser {
|
||||
self.advance();
|
||||
let mut entries: Vec<(String, ASTNode)> = Vec::new();
|
||||
let sugar_level = std::env::var("NYASH_SYNTAX_SUGAR_LEVEL").ok();
|
||||
let ident_key_on = std::env::var("NYASH_ENABLE_MAP_IDENT_KEY").ok().as_deref() == Some("1") || sugar_level.as_deref() == Some("full");
|
||||
let ident_key_on = std::env::var("NYASH_ENABLE_MAP_IDENT_KEY").ok().as_deref()
|
||||
== Some("1")
|
||||
|| sugar_level.as_deref() == Some("full");
|
||||
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
|
||||
let key = match &self.current_token().token_type {
|
||||
TokenType::STRING(s) => { let v = s.clone(); self.advance(); v }
|
||||
TokenType::IDENTIFIER(id) if ident_key_on => { let v = id.clone(); self.advance(); v }
|
||||
TokenType::STRING(s) => {
|
||||
let v = s.clone();
|
||||
self.advance();
|
||||
v
|
||||
}
|
||||
TokenType::IDENTIFIER(id) if ident_key_on => {
|
||||
let v = id.clone();
|
||||
self.advance();
|
||||
v
|
||||
}
|
||||
_ => {
|
||||
let line = self.current_token().line;
|
||||
return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: if ident_key_on { "string or identifier key in map literal".to_string() } else { "string key in map literal".to_string() }, line });
|
||||
return Err(ParseError::UnexpectedToken {
|
||||
found: self.current_token().token_type.clone(),
|
||||
expected: if ident_key_on {
|
||||
"string or identifier key in map literal".to_string()
|
||||
} else {
|
||||
"string key in map literal".to_string()
|
||||
},
|
||||
line,
|
||||
});
|
||||
}
|
||||
};
|
||||
self.consume(TokenType::COLON)?;
|
||||
let value_expr = self.parse_expression()?;
|
||||
entries.push((key, value_expr));
|
||||
if self.match_token(&TokenType::COMMA) { self.advance(); }
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RBRACE)?;
|
||||
Ok(ASTNode::MapLiteral { entries, span: Span::unknown() })
|
||||
Ok(ASTNode::MapLiteral {
|
||||
entries,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::INCLUDE => self.parse_include(),
|
||||
TokenType::STRING(s) => {
|
||||
let value = s.clone();
|
||||
self.advance();
|
||||
Ok(ASTNode::Literal {
|
||||
value: LiteralValue::String(value),
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::NUMBER(n) => {
|
||||
let value = *n;
|
||||
self.advance();
|
||||
Ok(ASTNode::Literal {
|
||||
value: LiteralValue::Integer(value),
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::FLOAT(f) => {
|
||||
let value = *f;
|
||||
self.advance();
|
||||
Ok(ASTNode::Literal {
|
||||
value: LiteralValue::Float(value),
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::TRUE => {
|
||||
self.advance();
|
||||
Ok(ASTNode::Literal {
|
||||
value: LiteralValue::Bool(true),
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::FALSE => {
|
||||
self.advance();
|
||||
Ok(ASTNode::Literal {
|
||||
value: LiteralValue::Bool(false),
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::NULL => {
|
||||
self.advance();
|
||||
Ok(ASTNode::Literal {
|
||||
value: LiteralValue::Null,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::INCLUDE => { self.parse_include() }
|
||||
TokenType::STRING(s) => { let value = s.clone(); self.advance(); Ok(ASTNode::Literal { value: LiteralValue::String(value), span: Span::unknown() }) }
|
||||
TokenType::NUMBER(n) => { let value = *n; self.advance(); Ok(ASTNode::Literal { value: LiteralValue::Integer(value), span: Span::unknown() }) }
|
||||
TokenType::FLOAT(f) => { let value = *f; self.advance(); Ok(ASTNode::Literal { value: LiteralValue::Float(value), span: Span::unknown() }) }
|
||||
TokenType::TRUE => { self.advance(); Ok(ASTNode::Literal { value: LiteralValue::Bool(true), span: Span::unknown() }) }
|
||||
TokenType::FALSE => { self.advance(); Ok(ASTNode::Literal { value: LiteralValue::Bool(false), span: Span::unknown() }) }
|
||||
TokenType::NULL => { self.advance(); Ok(ASTNode::Literal { value: LiteralValue::Null, span: Span::unknown() }) }
|
||||
TokenType::THIS => {
|
||||
if std::env::var("NYASH_DEPRECATE_THIS").ok().as_deref() == Some("1") {
|
||||
eprintln!("[deprecate:this] 'this' is deprecated; use 'me' instead (line {})", self.current_token().line);
|
||||
eprintln!(
|
||||
"[deprecate:this] 'this' is deprecated; use 'me' instead (line {})",
|
||||
self.current_token().line
|
||||
);
|
||||
}
|
||||
self.advance();
|
||||
Ok(ASTNode::Me { span: Span::unknown() })
|
||||
Ok(ASTNode::Me {
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::ME => {
|
||||
self.advance();
|
||||
Ok(ASTNode::Me {
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
TokenType::ME => { self.advance(); Ok(ASTNode::Me { span: Span::unknown() }) }
|
||||
TokenType::NEW => {
|
||||
self.advance();
|
||||
if let TokenType::IDENTIFIER(class_name) = &self.current_token().token_type {
|
||||
@ -80,10 +157,23 @@ impl NyashParser {
|
||||
if self.match_token(&TokenType::LESS) {
|
||||
self.advance();
|
||||
loop {
|
||||
if let TokenType::IDENTIFIER(tn) = &self.current_token().token_type { type_arguments.push(tn.clone()); self.advance(); }
|
||||
else { let line = self.current_token().line; return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "type argument".to_string(), line }); }
|
||||
if self.match_token(&TokenType::COMMA) { self.advance(); continue; }
|
||||
self.consume(TokenType::GREATER)?; break;
|
||||
if let TokenType::IDENTIFIER(tn) = &self.current_token().token_type {
|
||||
type_arguments.push(tn.clone());
|
||||
self.advance();
|
||||
} else {
|
||||
let line = self.current_token().line;
|
||||
return Err(ParseError::UnexpectedToken {
|
||||
found: self.current_token().token_type.clone(),
|
||||
expected: "type argument".to_string(),
|
||||
line,
|
||||
});
|
||||
}
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
continue;
|
||||
}
|
||||
self.consume(TokenType::GREATER)?;
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::LPAREN)?;
|
||||
@ -91,49 +181,108 @@ impl NyashParser {
|
||||
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
|
||||
crate::must_advance!(self, _unused, "new expression argument parsing");
|
||||
arguments.push(self.parse_expression()?);
|
||||
if self.match_token(&TokenType::COMMA) { self.advance(); }
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RPAREN)?;
|
||||
Ok(ASTNode::New { class, arguments, type_arguments, span: Span::unknown() })
|
||||
Ok(ASTNode::New {
|
||||
class,
|
||||
arguments,
|
||||
type_arguments,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
} else {
|
||||
let line = self.current_token().line;
|
||||
Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "class name".to_string(), line })
|
||||
Err(ParseError::UnexpectedToken {
|
||||
found: self.current_token().token_type.clone(),
|
||||
expected: "class name".to_string(),
|
||||
line,
|
||||
})
|
||||
}
|
||||
}
|
||||
TokenType::FROM => { self.parse_from_call() }
|
||||
TokenType::FROM => self.parse_from_call(),
|
||||
TokenType::IDENTIFIER(name) => {
|
||||
let parent = name.clone();
|
||||
self.advance();
|
||||
if self.match_token(&TokenType::DoubleColon) {
|
||||
self.advance();
|
||||
let method = match &self.current_token().token_type {
|
||||
TokenType::IDENTIFIER(m) => { let s=m.clone(); self.advance(); s }
|
||||
TokenType::INIT => { self.advance(); "init".to_string() }
|
||||
TokenType::PACK => { self.advance(); "pack".to_string() }
|
||||
TokenType::BIRTH => { self.advance(); "birth".to_string() }
|
||||
_ => { let line = self.current_token().line; return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "method name".to_string(), line }); }
|
||||
TokenType::IDENTIFIER(m) => {
|
||||
let s = m.clone();
|
||||
self.advance();
|
||||
s
|
||||
}
|
||||
TokenType::INIT => {
|
||||
self.advance();
|
||||
"init".to_string()
|
||||
}
|
||||
TokenType::PACK => {
|
||||
self.advance();
|
||||
"pack".to_string()
|
||||
}
|
||||
TokenType::BIRTH => {
|
||||
self.advance();
|
||||
"birth".to_string()
|
||||
}
|
||||
_ => {
|
||||
let line = self.current_token().line;
|
||||
return Err(ParseError::UnexpectedToken {
|
||||
found: self.current_token().token_type.clone(),
|
||||
expected: "method name".to_string(),
|
||||
line,
|
||||
});
|
||||
}
|
||||
};
|
||||
self.consume(TokenType::LPAREN)?;
|
||||
let mut arguments = Vec::new();
|
||||
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
|
||||
crate::must_advance!(self, _unused, "Parent::method call argument parsing");
|
||||
arguments.push(self.parse_expression()?);
|
||||
if self.match_token(&TokenType::COMMA) { self.advance(); }
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RPAREN)?;
|
||||
Ok(ASTNode::FromCall { parent, method, arguments, span: Span::unknown() })
|
||||
Ok(ASTNode::FromCall {
|
||||
parent,
|
||||
method,
|
||||
arguments,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
} else {
|
||||
Ok(ASTNode::Variable { name: parent, span: Span::unknown() })
|
||||
Ok(ASTNode::Variable {
|
||||
name: parent,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
}
|
||||
TokenType::LPAREN => { self.advance(); let expr = self.parse_expression()?; self.consume(TokenType::RPAREN)?; Ok(expr) }
|
||||
TokenType::LPAREN => {
|
||||
self.advance();
|
||||
let expr = self.parse_expression()?;
|
||||
self.consume(TokenType::RPAREN)?;
|
||||
Ok(expr)
|
||||
}
|
||||
TokenType::FN => {
|
||||
self.advance();
|
||||
let mut params: Vec<String> = Vec::new();
|
||||
if self.match_token(&TokenType::LPAREN) { self.advance();
|
||||
if self.match_token(&TokenType::LPAREN) {
|
||||
self.advance();
|
||||
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
|
||||
if let TokenType::IDENTIFIER(p) = &self.current_token().token_type { params.push(p.clone()); self.advance(); if self.match_token(&TokenType::COMMA) { self.advance(); } }
|
||||
else { let line = self.current_token().line; return Err(ParseError::UnexpectedToken { found: self.current_token().token_type.clone(), expected: "parameter name".to_string(), line }); }
|
||||
if let TokenType::IDENTIFIER(p) = &self.current_token().token_type {
|
||||
params.push(p.clone());
|
||||
self.advance();
|
||||
if self.match_token(&TokenType::COMMA) {
|
||||
self.advance();
|
||||
}
|
||||
} else {
|
||||
let line = self.current_token().line;
|
||||
return Err(ParseError::UnexpectedToken {
|
||||
found: self.current_token().token_type.clone(),
|
||||
expected: "parameter name".to_string(),
|
||||
line,
|
||||
});
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RPAREN)?;
|
||||
}
|
||||
@ -141,12 +290,21 @@ impl NyashParser {
|
||||
let mut body: Vec<ASTNode> = Vec::new();
|
||||
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
|
||||
self.skip_newlines();
|
||||
if !self.match_token(&TokenType::RBRACE) { body.push(self.parse_statement()?); }
|
||||
if !self.match_token(&TokenType::RBRACE) {
|
||||
body.push(self.parse_statement()?);
|
||||
}
|
||||
}
|
||||
self.consume(TokenType::RBRACE)?;
|
||||
Ok(ASTNode::Lambda { params, body, span: Span::unknown() })
|
||||
Ok(ASTNode::Lambda {
|
||||
params,
|
||||
body,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
let line = self.current_token().line;
|
||||
Err(ParseError::InvalidExpression { line })
|
||||
}
|
||||
_ => { let line = self.current_token().line; Err(ParseError::InvalidExpression { line }) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
#[inline]
|
||||
fn is_sugar_enabled() -> bool { crate::parser::sugar_gate::is_enabled() }
|
||||
fn is_sugar_enabled() -> bool {
|
||||
crate::parser::sugar_gate::is_enabled()
|
||||
}
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_range(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -20,9 +22,12 @@ impl NyashParser {
|
||||
}
|
||||
self.advance();
|
||||
let rhs = self.expr_parse_term()?;
|
||||
expr = ASTNode::FunctionCall { name: "Range".to_string(), arguments: vec![expr, rhs], span: Span::unknown() };
|
||||
expr = ASTNode::FunctionCall {
|
||||
name: "Range".to_string(),
|
||||
arguments: vec![expr, rhs],
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, BinaryOperator, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_shift(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -10,13 +10,23 @@ impl NyashParser {
|
||||
if self.match_token(&TokenType::ShiftLeft) {
|
||||
self.advance();
|
||||
let rhs = self.expr_parse_factor()?;
|
||||
expr = ASTNode::BinaryOp { operator: BinaryOperator::Shl, left: Box::new(expr), right: Box::new(rhs), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Shl,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(rhs),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
continue;
|
||||
}
|
||||
if self.match_token(&TokenType::ShiftRight) {
|
||||
self.advance();
|
||||
let rhs = self.expr_parse_factor()?;
|
||||
expr = ASTNode::BinaryOp { operator: BinaryOperator::Shr, left: Box::new(expr), right: Box::new(rhs), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Shr,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(rhs),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -24,4 +34,3 @@ impl NyashParser {
|
||||
Ok(expr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, BinaryOperator, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_term(&mut self) -> Result<ASTNode, ParseError> {
|
||||
@ -15,13 +15,26 @@ impl NyashParser {
|
||||
self.advance();
|
||||
let right = self.expr_parse_shift()?;
|
||||
if std::env::var("NYASH_GRAMMAR_DIFF").ok().as_deref() == Some("1") {
|
||||
let name = match operator { BinaryOperator::Add=>"add", BinaryOperator::Subtract=>"sub", _=>"term" };
|
||||
let name = match operator {
|
||||
BinaryOperator::Add => "add",
|
||||
BinaryOperator::Subtract => "sub",
|
||||
_ => "term",
|
||||
};
|
||||
let ok = crate::grammar::engine::get().syntax_is_allowed_binop(name);
|
||||
if !ok { eprintln!("[GRAMMAR-DIFF][Parser] binop '{}' not allowed by syntax rules", name); }
|
||||
if !ok {
|
||||
eprintln!(
|
||||
"[GRAMMAR-DIFF][Parser] binop '{}' not allowed by syntax rules",
|
||||
name
|
||||
);
|
||||
}
|
||||
}
|
||||
expr = ASTNode::BinaryOp { operator, left: Box::new(expr), right: Box::new(right), span: Span::unknown() };
|
||||
expr = ASTNode::BinaryOp {
|
||||
operator,
|
||||
left: Box::new(expr),
|
||||
right: Box::new(right),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::tokenizer::TokenType;
|
||||
use crate::ast::{ASTNode, Span};
|
||||
use crate::parser::common::ParserUtils;
|
||||
use crate::parser::{NyashParser, ParseError};
|
||||
use crate::tokenizer::TokenType;
|
||||
|
||||
#[inline]
|
||||
fn is_sugar_enabled() -> bool { crate::parser::sugar_gate::is_enabled() }
|
||||
fn is_sugar_enabled() -> bool {
|
||||
crate::parser::sugar_gate::is_enabled()
|
||||
}
|
||||
|
||||
impl NyashParser {
|
||||
pub(crate) fn expr_parse_ternary(&mut self) -> Result<ASTNode, ParseError> {
|
||||
|
||||
Reference in New Issue
Block a user