Tail expressions, integer literal exprs

This commit is contained in:
mars 2022-03-01 10:06:47 -07:00
parent 1b36737203
commit 9d074ddd19
2 changed files with 50 additions and 29 deletions

View File

@ -57,12 +57,15 @@ pub enum Token {
#[regex(r"[a-zA-Z_][a-zA-Z0-9_]*")]
Identifier,
#[regex(r"0b_*[01][_01]*")]
#[regex(r"0b_*[01][_'01]*")]
BinaryInteger,
#[regex(r"0o_*[0-7][_0-7]*")]
#[regex(r"0o_*[0-7][_'0-7]*")]
OctalInteger,
#[regex(r"0x_*[0-9a-fA-F][_'0-9a-fA-F]*")]
HexInteger,
#[regex(r"-?[0-9][_'0-9]*")]
DecimalInteger,

View File

@ -191,37 +191,45 @@ impl<'a> FnBody<'a> {
pub fn build(lexer: &mut Lexer<'a>) -> Self {
let mut statements = Vec::new();
let mut tail = Some(Token::Semicolon);
let mut tail_expr = None;
loop {
match tail {
Some(Token::Semicolon) => match lexer.next().unwrap() {
Token::Let => {
let (statement, next) = Statement::build_let(lexer);
statements.push(statement);
tail = Some(next);
let tok = lexer.next().unwrap();
match tok {
Token::Let => {
let (statement, next) = Statement::build_let(lexer);
statements.push(statement);
match next {
Token::Semicolon => {}
Token::BraceClose => break,
_ => lexer.panic_message("Unexpected token"),
}
Token::Var => {
let (statement, next) = Statement::build_var(lexer);
statements.push(statement);
tail = Some(next);
}
Token::Var => {
let (statement, next) = Statement::build_var(lexer);
statements.push(statement);
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;
}
Token::BraceClose => break,
_ => lexer.panic_message("Expected var, let, or assign"),
_ => lexer.panic_message("Unexpected token"),
},
Some(Token::BraceClose) => break,
_ => lexer.panic_message("Unexpected token"),
Token::BraceClose => break,
_ => lexer.panic_message("Expected var, let, or assign"),
}
}
Self {
statements,
tail_expr: None,
tail_expr,
}
}
}
@ -243,11 +251,14 @@ pub enum Expr<'a> {
}
impl<'a> Expr<'a> {
pub fn build(lexer: &mut Lexer<'a>) -> (Option<Self>, Token) {
let tok = lexer.next().unwrap();
pub fn build_start(tok: Token, lexer: &mut Lexer<'a>) -> (Option<Self>, Token) {
let lhs = match tok {
Token::Identifier => Self::Local(lexer.slice()),
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),
_ => 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) {
let tok = lexer.next().unwrap();
if let Some(op) = BinaryOp::from_token(tok) {
@ -311,15 +326,13 @@ impl BinaryOp {
pub enum Literal<'a> {
BinaryInteger(&'a str),
OctalInteger(&'a str),
HexInteger(&'a str),
DecimalInteger(&'a str),
}
#[derive(Debug)]
pub enum Statement<'a> {
Assign {
var: &'a str,
expr: Expr<'a>,
},
Expr(Expr<'a>),
Let {
var: &'a str,
expr: Expr<'a>,
@ -406,6 +419,11 @@ mod tests {
assert_eq!(expr.1, Token::Semicolon);
}
#[test]
fn int_literals() {
parse_expr("0b1 + 0x2 - 0o3 * 0x4;");
}
#[test]
fn locals() {
parse_expr("local1 + local2 - local3;");