Tail expressions, integer literal exprs
This commit is contained in:
parent
1b36737203
commit
9d074ddd19
|
@ -57,12 +57,15 @@ pub enum Token {
|
||||||
#[regex(r"[a-zA-Z_][a-zA-Z0-9_]*")]
|
#[regex(r"[a-zA-Z_][a-zA-Z0-9_]*")]
|
||||||
Identifier,
|
Identifier,
|
||||||
|
|
||||||
#[regex(r"0b_*[01][_01]*")]
|
#[regex(r"0b_*[01][_'01]*")]
|
||||||
BinaryInteger,
|
BinaryInteger,
|
||||||
|
|
||||||
#[regex(r"0o_*[0-7][_0-7]*")]
|
#[regex(r"0o_*[0-7][_'0-7]*")]
|
||||||
OctalInteger,
|
OctalInteger,
|
||||||
|
|
||||||
|
#[regex(r"0x_*[0-9a-fA-F][_'0-9a-fA-F]*")]
|
||||||
|
HexInteger,
|
||||||
|
|
||||||
#[regex(r"-?[0-9][_'0-9]*")]
|
#[regex(r"-?[0-9][_'0-9]*")]
|
||||||
DecimalInteger,
|
DecimalInteger,
|
||||||
|
|
||||||
|
|
58
src/parse.rs
58
src/parse.rs
|
@ -191,37 +191,45 @@ impl<'a> FnBody<'a> {
|
||||||
pub fn build(lexer: &mut Lexer<'a>) -> Self {
|
pub fn build(lexer: &mut Lexer<'a>) -> Self {
|
||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
|
|
||||||
let mut tail = Some(Token::Semicolon);
|
let mut tail_expr = None;
|
||||||
loop {
|
loop {
|
||||||
match tail {
|
let tok = lexer.next().unwrap();
|
||||||
Some(Token::Semicolon) => match lexer.next().unwrap() {
|
match tok {
|
||||||
Token::Let => {
|
Token::Let => {
|
||||||
let (statement, next) = Statement::build_let(lexer);
|
let (statement, next) = Statement::build_let(lexer);
|
||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
tail = Some(next);
|
match next {
|
||||||
|
Token::Semicolon => {}
|
||||||
|
Token::BraceClose => break,
|
||||||
|
_ => lexer.panic_message("Unexpected token"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Token::Var => {
|
Token::Var => {
|
||||||
let (statement, next) = Statement::build_var(lexer);
|
let (statement, next) = Statement::build_var(lexer);
|
||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
tail = Some(next);
|
match next {
|
||||||
|
Token::Semicolon => {}
|
||||||
|
Token::BraceClose => break,
|
||||||
|
_ => lexer.panic_message("Unexpected token"),
|
||||||
}
|
}
|
||||||
Token::Identifier => {
|
|
||||||
let var = lexer.slice();
|
|
||||||
let (expr, next) = Statement::eat_assign(lexer);
|
|
||||||
statements.push(Statement::Assign { var, expr });
|
|
||||||
tail = Some(next);
|
|
||||||
}
|
}
|
||||||
|
Token::Identifier => match Expr::build_start(tok, lexer) {
|
||||||
|
(None, Token::Semicolon | Token::BraceClose) => {}
|
||||||
|
(Some(expr), Token::Semicolon) => statements.push(Statement::Expr(expr)),
|
||||||
|
(Some(expr), Token::BraceClose) => {
|
||||||
|
tail_expr = Some(expr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => lexer.panic_message("Unexpected token"),
|
||||||
|
},
|
||||||
Token::BraceClose => break,
|
Token::BraceClose => break,
|
||||||
_ => lexer.panic_message("Expected var, let, or assign"),
|
_ => lexer.panic_message("Expected var, let, or assign"),
|
||||||
},
|
|
||||||
Some(Token::BraceClose) => break,
|
|
||||||
_ => lexer.panic_message("Unexpected token"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
statements,
|
statements,
|
||||||
tail_expr: None,
|
tail_expr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,11 +251,14 @@ pub enum Expr<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Expr<'a> {
|
impl<'a> Expr<'a> {
|
||||||
pub fn build(lexer: &mut Lexer<'a>) -> (Option<Self>, Token) {
|
pub fn build_start(tok: Token, lexer: &mut Lexer<'a>) -> (Option<Self>, Token) {
|
||||||
let tok = lexer.next().unwrap();
|
|
||||||
let lhs = match tok {
|
let lhs = match tok {
|
||||||
Token::Identifier => Self::Local(lexer.slice()),
|
Token::Identifier => Self::Local(lexer.slice()),
|
||||||
Token::Dot => Self::Member(lexer.eat_expect_id()),
|
Token::Dot => Self::Member(lexer.eat_expect_id()),
|
||||||
|
Token::BinaryInteger => Self::Literal(Literal::BinaryInteger(lexer.slice())),
|
||||||
|
Token::OctalInteger => Self::Literal(Literal::OctalInteger(lexer.slice())),
|
||||||
|
Token::HexInteger => Self::Literal(Literal::HexInteger(lexer.slice())),
|
||||||
|
Token::DecimalInteger => Self::Literal(Literal::DecimalInteger(lexer.slice())),
|
||||||
Token::Semicolon | Token::BraceClose | Token::ParanClose => return (None, tok),
|
Token::Semicolon | Token::BraceClose | Token::ParanClose => return (None, tok),
|
||||||
_ => lexer.panic_message("Unexpected token"),
|
_ => lexer.panic_message("Unexpected token"),
|
||||||
};
|
};
|
||||||
|
@ -260,6 +271,10 @@ impl<'a> Expr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build(lexer: &mut Lexer<'a>) -> (Option<Self>, Token) {
|
||||||
|
Self::build_start(lexer.next().unwrap(), lexer)
|
||||||
|
}
|
||||||
|
|
||||||
fn eat_op(lexer: &mut Lexer<'a>) -> (Option<(BinaryOp, Self)>, Token) {
|
fn eat_op(lexer: &mut Lexer<'a>) -> (Option<(BinaryOp, Self)>, Token) {
|
||||||
let tok = lexer.next().unwrap();
|
let tok = lexer.next().unwrap();
|
||||||
if let Some(op) = BinaryOp::from_token(tok) {
|
if let Some(op) = BinaryOp::from_token(tok) {
|
||||||
|
@ -311,15 +326,13 @@ impl BinaryOp {
|
||||||
pub enum Literal<'a> {
|
pub enum Literal<'a> {
|
||||||
BinaryInteger(&'a str),
|
BinaryInteger(&'a str),
|
||||||
OctalInteger(&'a str),
|
OctalInteger(&'a str),
|
||||||
|
HexInteger(&'a str),
|
||||||
DecimalInteger(&'a str),
|
DecimalInteger(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Statement<'a> {
|
pub enum Statement<'a> {
|
||||||
Assign {
|
Expr(Expr<'a>),
|
||||||
var: &'a str,
|
|
||||||
expr: Expr<'a>,
|
|
||||||
},
|
|
||||||
Let {
|
Let {
|
||||||
var: &'a str,
|
var: &'a str,
|
||||||
expr: Expr<'a>,
|
expr: Expr<'a>,
|
||||||
|
@ -406,6 +419,11 @@ mod tests {
|
||||||
assert_eq!(expr.1, Token::Semicolon);
|
assert_eq!(expr.1, Token::Semicolon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn int_literals() {
|
||||||
|
parse_expr("0b1 + 0x2 - 0o3 * 0x4;");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn locals() {
|
fn locals() {
|
||||||
parse_expr("local1 + local2 - local3;");
|
parse_expr("local1 + local2 - local3;");
|
||||||
|
|
Loading…
Reference in New Issue