diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-01-26 13:49:04 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-01-26 13:49:04 +0100 |
| commit | 16ac3f3ebc49c5a6e3f61d8546f2f187b191c346 (patch) | |
| tree | 7b66f108f23c64614a507e2815f706ceb72df157 /src | |
| parent | ac788f2082711161ec8208eede04d9a2bae02241 (diff) | |
Small improvements ♻
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/mod.rs | 12 | ||||
| -rw-r--r-- | src/parse/mod.rs | 40 | ||||
| -rw-r--r-- | src/parse/tokens.rs | 5 | ||||
| -rw-r--r-- | src/syntax/token.rs | 37 |
4 files changed, 47 insertions, 47 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs index c604f2d0..8563520e 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -270,8 +270,8 @@ impl Spanned<&ExprBinary> { // Short-circuit boolean operations. match (self.v.op.v, &lhs) { - (BinOp::And, Value::Bool(false)) => return Value::Bool(false), - (BinOp::Or, Value::Bool(true)) => return Value::Bool(true), + (BinOp::And, Value::Bool(false)) => return lhs, + (BinOp::Or, Value::Bool(true)) => return lhs, _ => {} } @@ -310,12 +310,10 @@ impl Spanned<&ExprBinary> { let lhs = std::mem::replace(slot, Value::None); *slot = op(lhs, rhs); return Value::None; + } else if ctx.scopes.is_const(id) { + ctx.diag(error!(span, "cannot assign to constant")); } else { - if ctx.scopes.is_const(id) { - ctx.diag(error!(span, "cannot assign to constant")); - } else { - ctx.diag(error!(span, "unknown variable")); - } + ctx.diag(error!(span, "unknown variable")); } } else { ctx.diag(error!(span, "cannot assign to this expression")); diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 00512c3f..9fe8e62e 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -380,42 +380,50 @@ fn stmt_let(p: &mut Parser) -> Option<Expr> { p.start_group(Group::Stmt, TokenMode::Code); p.eat_assert(Token::Let); - let pat = p.span_if(ident); - let mut rhs = None; - - if pat.is_some() { - if p.eat_if(Token::Eq) { - rhs = p.span_if(expr); + let pat = match p.span_if(ident) { + Some(pat) => pat, + None => { + p.expected("identifier"); + p.end_group(); + return None; } + }; - if !p.eof() { - p.expected_at("semicolon or line break", p.last_end()); - } - } else { - p.expected("identifier"); + let rhs = if p.eat_if(Token::Eq) { p.span_if(expr) } else { None }; + + if !p.eof() { + p.expected_at("semicolon or line break", p.last_end()); } p.end_group(); - Some(Expr::Let(ExprLet { pat: pat?, expr: rhs.map(Box::new) })) + Some(Expr::Let(ExprLet { pat, expr: rhs.map(Box::new) })) } /// Parse an if expresion. fn expr_if(p: &mut Parser) -> Option<Expr> { p.start_group(Group::Expr, TokenMode::Code); p.eat_assert(Token::If); - let condition = p.span_if(expr); + + let condition = match p.span_if(expr) { + Some(condition) => Box::new(condition), + None => { + p.end_group(); + return None; + } + }; + p.end_group(); - let condition = Box::new(condition?); let if_body = Box::new(control_body(p)?); - let end = p.last_end(); + + let start = p.last_end(); p.skip_white(); let else_body = if p.eat_if(Token::Else) { control_body(p).map(Box::new) } else { - p.jump(end); + p.jump(start); None }; diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index 312e941b..f5e5baaf 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -127,7 +127,6 @@ impl<'s> Iterator for Tokens<'s> { '=' => Token::Eq, '<' => Token::Lt, '>' => Token::Gt, - '?' => Token::Question, // Identifiers. c if is_id_start(c) => self.ident(start), @@ -206,7 +205,6 @@ impl<'s> Tokens<'s> { "#if" => Token::If, "#else" => Token::Else, "#for" => Token::For, - "#in" => Token::In, "#while" => Token::While, "#break" => Token::Break, "#continue" => Token::Continue, @@ -612,7 +610,6 @@ mod tests { t!(Code: "-=" => HyphEq); t!(Code: "*=" => StarEq); t!(Code: "/=" => SlashEq); - t!(Code: "?" => Question); t!(Code: ".." => Dots); t!(Code: "=>" => Arrow); @@ -636,7 +633,6 @@ mod tests { ("if", If), ("else", Else), ("for", For), - ("in", In), ("while", While), ("break", Break), ("continue", Continue), @@ -654,6 +650,7 @@ mod tests { ("not", Not), ("and", And), ("or", Or), + ("in", In), ("none", Token::None), ("false", Bool(false)), ("true", Bool(true)), diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 43415198..432b4dc5 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -61,8 +61,6 @@ pub enum Token<'s> { StarEq, /// A slash followed by an equals sign: `/=`. SlashEq, - /// A question mark: `?`. - Question, /// Two dots: `..`. Dots, /// An equals sign followed by a greater-than sign: `=>`. @@ -212,30 +210,29 @@ impl<'s> Token<'s> { Self::Eq => "assignment operator", Self::EqEq => "equality operator", Self::BangEq => "inequality operator", - Self::Lt => "less than operator", - Self::LtEq => "less than or equal operator", - Self::Gt => "greater than operator", - Self::GtEq => "greater than or equal operator", + Self::Lt => "less-than operator", + Self::LtEq => "less-than or equal operator", + Self::Gt => "greater-than operator", + Self::GtEq => "greater-than or equal operator", Self::PlusEq => "add-assign operator", Self::HyphEq => "subtract-assign operator", Self::StarEq => "multiply-assign operator", Self::SlashEq => "divide-assign operator", - Self::Question => "question mark", Self::Dots => "dots", Self::Arrow => "arrow", - Self::Not => "not operator", - Self::And => "and operator", - Self::Or => "or operator", - Self::Let => "let keyword", - Self::If => "if keyword", - Self::Else => "else keyword", - Self::For => "for keyword", - Self::In => "in keyword", - Self::While => "while keyword", - Self::Break => "break keyword", - Self::Continue => "continue keyword", - Self::Return => "return keyword", - Self::None => "none", + Self::Not => "operator `not`", + Self::And => "operator `and`", + Self::Or => "operator `or`", + Self::Let => "keyword `let`", + Self::If => "keyword `if`", + Self::Else => "keyword `else`", + Self::For => "keyword `for`", + Self::In => "keyword `in`", + Self::While => "keyword `while`", + Self::Break => "keyword `break`", + Self::Continue => "keyword `continue`", + Self::Return => "keyword `return`", + Self::None => "`none`", Self::Space(_) => "space", Self::Text(_) => "text", Self::Raw(_) => "raw block", |
