mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
Merge branch 'do-parse'
This commit is contained in:
commit
f847029e16
3 changed files with 48 additions and 1 deletions
|
@ -2269,6 +2269,15 @@ impl LambdaSignature {
|
||||||
bounds,
|
bounds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn do_sig(do_symbol: &Token) -> Self {
|
||||||
|
let parens = Some((do_symbol.clone(), do_symbol.clone()));
|
||||||
|
Self::new(
|
||||||
|
Params::new(vec![], vec![], parens),
|
||||||
|
None,
|
||||||
|
TypeBoundSpecs::empty(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -53,6 +53,7 @@ enum PosOrKwArg {
|
||||||
pub enum Side {
|
pub enum Side {
|
||||||
LhsAssign,
|
LhsAssign,
|
||||||
LhsLambda,
|
LhsLambda,
|
||||||
|
Do,
|
||||||
Rhs,
|
Rhs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +157,15 @@ impl Parser {
|
||||||
/// `(Rhs) , (LhsLambda) ->`
|
/// `(Rhs) , (LhsLambda) ->`
|
||||||
/// `(Rhs) (LhsLambda) -> (Rhs);`
|
/// `(Rhs) (LhsLambda) -> (Rhs);`
|
||||||
fn cur_side(&self) -> Side {
|
fn cur_side(&self) -> Side {
|
||||||
|
match self.peek() {
|
||||||
|
Some(t) => {
|
||||||
|
let name = &t.inspect()[..];
|
||||||
|
if name == "do" || name == "do!" {
|
||||||
|
return Side::Do;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
// 以降に=, ->などがないならすべて右辺値
|
// 以降に=, ->などがないならすべて右辺値
|
||||||
let opt_equal_pos = self.tokens.iter().skip(1).position(|t| t.is(Equal));
|
let opt_equal_pos = self.tokens.iter().skip(1).position(|t| t.is(Equal));
|
||||||
let opt_arrow_pos = self
|
let opt_arrow_pos = self
|
||||||
|
@ -1651,6 +1661,29 @@ impl Parser {
|
||||||
Ok(Lambda::new(sig, op, body, self.counter))
|
Ok(Lambda::new(sig, op, body, self.counter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_reduce_do_block(&mut self) -> ParseResult<Lambda> {
|
||||||
|
debug_call_info!(self);
|
||||||
|
let do_symbol = self.lpop();
|
||||||
|
let sig = LambdaSignature::do_sig(&do_symbol);
|
||||||
|
let op = match &do_symbol.inspect()[..] {
|
||||||
|
"do" => Token::from_str(FuncArrow, "->"),
|
||||||
|
"do!" => Token::from_str(ProcArrow, "=>"),
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
if self.cur_is(Colon) {
|
||||||
|
self.lpop();
|
||||||
|
let body = self.try_reduce_block().map_err(|_| self.stack_dec())?;
|
||||||
|
self.counter.inc();
|
||||||
|
self.level -= 1;
|
||||||
|
Ok(Lambda::new(sig, op, body, self.counter))
|
||||||
|
} else {
|
||||||
|
let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?;
|
||||||
|
let block = Block::new(vec![expr]);
|
||||||
|
self.level -= 1;
|
||||||
|
Ok(Lambda::new(sig, op, block, self.counter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn try_reduce_expr(&mut self) -> ParseResult<Expr> {
|
fn try_reduce_expr(&mut self) -> ParseResult<Expr> {
|
||||||
debug_call_info!(self);
|
debug_call_info!(self);
|
||||||
let mut stack = Vec::<ExprOrOp>::new();
|
let mut stack = Vec::<ExprOrOp>::new();
|
||||||
|
@ -1665,6 +1698,11 @@ impl Parser {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(Expr::Lambda(lambda))
|
Ok(Expr::Lambda(lambda))
|
||||||
}
|
}
|
||||||
|
Side::Do => {
|
||||||
|
let lambda = self.try_reduce_do_block().map_err(|_| self.stack_dec())?;
|
||||||
|
self.level -= 1;
|
||||||
|
Ok(Expr::Lambda(lambda))
|
||||||
|
}
|
||||||
Side::Rhs => {
|
Side::Rhs => {
|
||||||
stack.push(ExprOrOp::Expr(
|
stack.push(ExprOrOp::Expr(
|
||||||
self.try_reduce_bin_lhs().map_err(|_| self.stack_dec())?,
|
self.try_reduce_bin_lhs().map_err(|_| self.stack_dec())?,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
if True, () -> log "hello"
|
if True, () -> log "hello"
|
||||||
if! True, () => print! "hello"
|
if! True, () => print! "hello"
|
||||||
# if True, () => print! "hello" # this should cause a type error
|
# if True, () => print! "hello" # this should cause a type error
|
||||||
if True, () ->
|
if True, do:
|
||||||
_x = "aaa" + input!() # this should cause an effect error
|
_x = "aaa" + input!() # this should cause an effect error
|
||||||
print! "hello" # this should cause an effect error
|
print! "hello" # this should cause an effect error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue