fixup parsing

This commit is contained in:
SimonFJ20 2024-09-01 02:09:24 +02:00
parent 5d563527fd
commit 21857307d7
8 changed files with 422 additions and 237 deletions

View File

@ -1,11 +1,12 @@
fn b() { fn b() {
a(); a()
} }
fn a() { fn a() {
let abc = 123;
abc
} }

101
src/ast.rs Normal file
View File

@ -0,0 +1,101 @@
use crate::pos::Pos;
#[derive(Clone, PartialEq, Debug)]
pub struct Stmt {
pub kind: StmtKind,
pub pos: Pos,
}
impl Stmt {
pub fn new(kind: StmtKind, pos: Pos) -> Self {
Self { kind, pos }
}
}
#[derive(Clone, PartialEq, Debug)]
pub enum StmtKind {
Error,
Let {
subject: Box<Param>,
value: Box<Expr>,
},
Fn {
subject: Box<Expr>,
params: Vec<Param>,
return_typ: Option<Box<Typ>>,
body: Box<Expr>,
},
Return {
expr: Option<Box<Expr>>,
},
Break {
expr: Option<Box<Expr>>,
},
Assign {
subject: Box<Expr>,
value: Box<Expr>,
},
Expr(Box<Expr>),
}
#[derive(Clone, PartialEq, Debug)]
pub struct Expr {
pub kind: ExprKind,
pub pos: Pos,
}
impl Expr {
pub fn new(kind: ExprKind, pos: Pos) -> Self {
Self { kind, pos }
}
}
#[derive(Clone, PartialEq, Debug)]
pub enum ExprKind {
Error,
Ident(u64),
Int(i64),
Str(String),
Group(Box<Expr>),
Block {
stmts: Vec<Stmt>,
expr: Option<Box<Expr>>,
},
Call {
subject: Box<Expr>,
args: Vec<Expr>,
},
If {
cond: Box<Expr>,
truthy: Box<Expr>,
falsy: Option<Box<Expr>>,
},
Loop {
body: Box<Expr>,
},
}
#[derive(Clone, PartialEq, Debug)]
pub struct Typ {
pub kind: TypKind,
pub pos: Pos,
}
impl Typ {
pub fn new(kind: TypKind, pos: Pos) -> Self {
Self { kind, pos }
}
}
#[derive(Clone, PartialEq, Debug)]
pub enum TypKind {
Error,
Ident(u64),
}
#[derive(Clone, PartialEq, Debug)]
pub struct Param {
pub subject: Box<Expr>,
pub typ: Option<Box<Typ>>,
pub pos: Pos,
}

View File

@ -1,7 +1,6 @@
use crate::{ use crate::{
pos::{Error, ErrorAcc, Pos}, pos::{Error, ErrorAcc, Pos},
token::{Token, TokenKind, TokenValue}, token::{Token, TokenKind, TokenValue},
util::hash,
}; };
use std::{collections::HashMap, rc::Rc, str::Chars, sync::Mutex}; use std::{collections::HashMap, rc::Rc, str::Chars, sync::Mutex};
@ -72,9 +71,13 @@ impl<'a> Lexer<'a> {
if let Some(kind) = self.keywords.get(&value) { if let Some(kind) = self.keywords.get(&value) {
return self.token(kind.clone(), pos); return self.token(kind.clone(), pos);
} }
let id = hash(&value); let id = self.symbols.len() as u64;
self.symbols.insert(id, value); self.symbols.insert(id, value);
break self.token_with_value(TokenKind::Id, TokenValue::Id(id), pos); break self.token_with_value(
TokenKind::Ident,
TokenValue::Ident(id),
pos,
);
} }
} }
} }
@ -242,7 +245,7 @@ impl<'a> Lexer<'a> {
}); });
} }
fn pos(&self) -> Pos { pub fn pos(&self) -> Pos {
Pos { Pos {
index: self.index, index: self.index,
line: self.line, line: self.line,

View File

@ -1,13 +1,39 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::{rc::Rc, sync::Mutex};
use parser::Parser;
use pos::{ErrorAcc, Pos};
mod ast;
mod lexer; mod lexer;
mod parsed;
mod parser; mod parser;
mod pos; mod pos;
mod sym;
mod token; mod token;
mod util;
fn main() { fn main() {
println!("Hello, world!"); let args = std::env::args().collect::<Vec<_>>();
let filename = args[1].clone();
let text = std::fs::read_to_string(filename).unwrap();
let error_acc = Rc::new(Mutex::new(ErrorAcc::new()));
let mut parser = Parser::new(&text, error_acc.clone());
let ast = parser.parse();
println!("{ast:#?}");
let error_acc = error_acc.lock().unwrap();
if !error_acc.ok() {
println!("Compilation failed");
for error in error_acc.iter() {
match error.pos {
Some(Pos { line, col, .. }) => {
println!("{:?} at {line}:{col}: {}", error.kind, error.msg)
}
None => println!("{:?}: {}", error.kind, error.msg),
}
}
}
} }

View File

@ -1,57 +0,0 @@
use crate::pos::Pos;
#[derive(Clone, PartialEq, Debug)]
pub struct Node {
pub kind: NodeKind,
pub pos: Pos,
}
impl Node {
pub fn new(kind: NodeKind, pos: Pos) -> Self {
Self { kind, pos }
}
}
#[derive(Clone, PartialEq, Debug)]
pub enum NodeKind {
Error,
Id(u64),
Int(i64),
Str(String),
Group(Box<Node>),
Block(Vec<Node>),
Call {
subject: Box<Node>,
args: Vec<Node>,
},
If {
cond: Box<Node>,
truthy: Box<Node>,
falsy: Option<Box<Node>>,
},
Loop {
body: Box<Node>,
},
Break,
Assign {
subject: Box<Node>,
value: Box<Node>,
},
Let {
subject: Box<Node>,
value: Box<Node>,
},
Fn {
subject: Box<Node>,
params: Vec<Node>,
return_typ: Box<Node>,
body: Box<Node>,
},
Return {
value: Option<Box<Node>>,
},
Param {
subject: Box<Node>,
typ: Option<Box<Node>>,
},
}

View File

@ -1,10 +1,10 @@
use std::{collections::HashMap, rc::Rc, sync::Mutex}; use std::{collections::HashMap, rc::Rc, sync::Mutex};
use crate::{ use crate::{
ast::{Expr, ExprKind as EK, Param, Stmt, StmtKind as SK, Typ, TypKind},
lexer::Lexer, lexer::Lexer,
parsed::{Node, NodeKind},
pos::{Error, ErrorAcc, Pos}, pos::{Error, ErrorAcc, Pos},
token::{Token, TokenKind, TokenValue}, token::{Token, TokenKind as TK, TokenValue},
}; };
pub struct Parser<'a> { pub struct Parser<'a> {
@ -24,7 +24,7 @@ impl<'a> Parser<'a> {
} }
} }
pub fn parse(&mut self) -> Vec<Node> { pub fn parse(&mut self) -> Vec<Stmt> {
self.parse_file() self.parse_file()
} }
@ -32,7 +32,7 @@ impl<'a> Parser<'a> {
self.lexer.symbols() self.lexer.symbols()
} }
fn parse_file(&mut self) -> Vec<Node> { fn parse_file(&mut self) -> Vec<Stmt> {
let mut stmts = Vec::new(); let mut stmts = Vec::new();
loop { loop {
match self.current { match self.current {
@ -42,73 +42,66 @@ impl<'a> Parser<'a> {
} }
} }
fn parse_stmt(&mut self) -> Node { fn parse_stmt(&mut self) -> Stmt {
let pos = self.pos().unwrap(); use TK::*;
let pos = self.pos();
match self.curr_kind() { match self.curr_kind() {
Some(TokenKind::LBrace) => self.parse_block(), Some(Fn) => self.parse_fn(),
Some(TokenKind::If) => self.parse_if(), Some(kind @ (LBrace | If | Loop)) => Stmt::new(
Some(TokenKind::Loop) => self.parse_loop(), SK::Expr(Box::new(match kind {
Some(TokenKind::Fn) => self.parse_fn(), LBrace => self.parse_block(),
_ => { If => self.parse_if(),
let stmt = match self.curr_kind() { Loop => self.parse_loop(),
Some(TokenKind::Let) => self.parse_let(), _ => unreachable!(),
Some(TokenKind::Break) => { })),
self.step(); pos,
self.node(NodeKind::Break, pos.clone()) ),
} Some(kind) => {
Some(TokenKind::Return) => { let stmt = match kind {
self.step(); Let => self.parse_let(),
let value = match self.curr_kind() { Return => self.parse_return(),
Some(TokenKind::Semicolon) => None, Break => self.parse_break(),
_ => Some(Box::new(self.parse_expr())), _ => match self.parse_assign() {
}; ParsedAssign::Assign(stmt) => stmt,
self.node(NodeKind::Return { value }, pos.clone()) ParsedAssign::Expr(expr, pos) => Stmt::new(SK::Expr(Box::new(expr)), pos),
} },
_ => self.parse_assign(),
}; };
match self.curr_kind() { self.eat_semicolon();
Some(TokenKind::Semicolon) => { stmt
self.step();
stmt
}
_ => {
self.error("expected ';'", pos.clone());
self.error_node(pos)
}
}
} }
_ => unreachable!(),
} }
} }
fn parse_fn(&mut self) -> Node { fn parse_fn(&mut self) -> Stmt {
let pos = self.pos().unwrap(); let pos = self.pos();
self.step(); self.step();
if !self.curr_is(TokenKind::Id) { if !self.curr_is(TK::Ident) {
self.error("expected id", pos.clone()); self.error("expected id", pos.clone());
return self.error_node(pos); return self.error_stmt(pos);
} }
let subject = Box::new(self.parse_id()); let subject = Box::new(self.parse_ident_expr());
if !self.curr_is(TokenKind::LParen) { if !self.curr_is(TK::LParen) {
self.error("expected '('", pos.clone()); self.error("expected '('", pos.clone());
return self.error_node(pos); return self.error_stmt(pos);
} }
let params = match self.parse_fn_params() { let params = match self.parse_fn_params() {
Ok(params) => params, Ok(params) => params,
Err(expr) => return expr, Err(pos) => return self.error_stmt(pos),
}; };
if !self.curr_is(TokenKind::MinusLt) { let return_typ = if self.curr_is(TK::MinusLt) {
self.error("expected '->'", pos.clone()); self.step();
return self.error_node(pos); Some(Box::new(self.parse_typ()))
} } else {
self.step(); None
let return_typ = Box::new(self.parse_typ()); };
if !self.curr_is(TokenKind::LBrace) { if !self.curr_is(TK::LBrace) {
self.error("expected '{'", pos.clone()); self.error("expected '{'", pos.clone());
return self.error_node(pos); return self.error_stmt(pos);
} }
let body = Box::new(self.parse_block()); let body = Box::new(self.parse_block());
self.node( Stmt::new(
NodeKind::Fn { SK::Fn {
subject, subject,
params, params,
return_typ, return_typ,
@ -118,49 +111,49 @@ impl<'a> Parser<'a> {
) )
} }
fn parse_fn_params(&mut self) -> Result<Vec<Node>, Node> { fn parse_fn_params(&mut self) -> Result<Vec<Param>, Pos> {
let pos = self.pos().unwrap(); let pos = self.pos();
self.step(); self.step();
let mut params = Vec::new(); let mut params = Vec::new();
if !self.curr_is(TokenKind::RParen) { if !self.curr_is(TK::RParen) {
if !self.curr_is(TokenKind::Id) { if !self.curr_is(TK::Ident) {
self.error("expected id", pos.clone()); self.error("expected id", pos.clone());
return Err(self.error_node(pos)); return Err(pos);
} }
params.push(self.parse_param()); params.push(self.parse_param());
while let Some(TokenKind::Comma) = self.curr_kind() { while let Some(TK::Comma) = self.curr_kind() {
self.step(); self.step();
if self.curr_is(TokenKind::RParen) { if self.curr_is(TK::RParen) {
self.error("expected ')'", pos.clone()); self.error("expected ')'", pos.clone());
break; break;
} }
params.push(self.parse_param()); params.push(self.parse_param());
} }
} }
if !self.curr_is(TokenKind::RParen) { if !self.curr_is(TK::RParen) {
self.error("expected ')'", pos.clone()); self.error("expected ')'", pos.clone());
return Err(self.error_node(pos)); return Err(pos);
} }
self.step(); self.step();
Ok(params) Ok(params)
} }
fn parse_let(&mut self) -> Node { fn parse_let(&mut self) -> Stmt {
let pos = self.pos().unwrap(); let pos = self.pos();
self.step(); self.step();
if !self.curr_is(TokenKind::Id) { if !self.curr_is(TK::Ident) {
self.error("expected id", pos.clone()); self.error("expected id", pos.clone());
return self.error_node(pos); return self.error_stmt(pos);
} }
let subject = self.parse_param(); let subject = self.parse_param();
if !self.curr_is(TokenKind::Equal) { if !self.curr_is(TK::Equal) {
self.error("expected '='", pos.clone()); self.error("expected '='", pos.clone());
return self.error_node(pos); return self.error_stmt(pos);
} }
self.step(); self.step();
let value = self.parse_expr(); let value = self.parse_expr();
self.node( Stmt::new(
NodeKind::Let { SK::Let {
subject: Box::new(subject), subject: Box::new(subject),
value: Box::new(value), value: Box::new(value),
}, },
@ -168,68 +161,64 @@ impl<'a> Parser<'a> {
) )
} }
fn parse_param(&mut self) -> Node { fn parse_return(&mut self) -> Stmt {
let pos = self.pos().unwrap(); let pos = self.pos();
let subject = Box::new(self.parse_id()); self.step();
let typ = if let Some(TokenKind::Colon) = self.curr_kind() { let expr = match self.curr_kind() {
self.step(); Some(TK::Semicolon) => None,
Some(Box::new(self.parse_typ())) _ => Some(Box::new(self.parse_expr())),
} else {
None
}; };
self.node(NodeKind::Param { subject, typ }, pos) Stmt::new(SK::Return { expr }, pos.clone())
} }
fn parse_typ(&mut self) -> Node { fn parse_break(&mut self) -> Stmt {
let pos = self.pos().unwrap(); let pos = self.pos();
match self.curr_kind() { self.step();
Some(TokenKind::Id) => self.parse_id(), let expr = match self.curr_kind() {
_ => { Some(TK::Semicolon) => None,
self.error("expected type", pos.clone()); _ => Some(Box::new(self.parse_expr())),
self.step(); };
self.error_node(pos) Stmt::new(SK::Break { expr }, pos.clone())
}
}
} }
fn parse_assign(&mut self) -> Node { fn parse_assign(&mut self) -> ParsedAssign {
let pos = self.pos().unwrap(); let pos = self.pos();
let subject = self.parse_expr(); let subject = self.parse_expr();
match self.curr_kind() { match self.curr_kind() {
Some(TokenKind::Equal) => { Some(TK::Equal) => {
self.step(); self.step();
let value = self.parse_expr(); let value = self.parse_expr();
self.node( ParsedAssign::Assign(Stmt::new(
NodeKind::Assign { SK::Assign {
subject: Box::new(subject), subject: Box::new(subject),
value: Box::new(value), value: Box::new(value),
}, },
pos, pos,
) ))
} }
_ => subject, _ => ParsedAssign::Expr(subject, pos),
} }
} }
fn parse_expr(&mut self) -> Node { fn parse_expr(&mut self) -> Expr {
self.parse_call() self.parse_call()
} }
fn parse_call(&mut self) -> Node { fn parse_call(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
let mut subject = self.parse_value(); let mut subject = self.parse_value();
loop { loop {
match self.curr_kind() { match self.curr_kind() {
Some(TokenKind::LParen) => { Some(TK::LParen) => {
self.step(); self.step();
let mut args = Vec::new(); let mut args = Vec::new();
match self.curr_kind() { match self.curr_kind() {
None | Some(TokenKind::RParen) => {} None | Some(TK::RParen) => {}
Some(_) => { Some(_) => {
args.push(self.parse_expr()); args.push(self.parse_expr());
while let Some(TokenKind::Comma) = self.curr_kind() { while let Some(TK::Comma) = self.curr_kind() {
self.step(); self.step();
if let Some(TokenKind::RParen) = self.curr_kind() { if let Some(TK::RParen) = self.curr_kind() {
break; break;
} }
args.push(self.parse_expr()); args.push(self.parse_expr());
@ -237,15 +226,15 @@ impl<'a> Parser<'a> {
} }
} }
match self.curr_kind() { match self.curr_kind() {
Some(TokenKind::RParen) => {} Some(TK::RParen) => {}
_ => { _ => {
self.error("expected ')'", pos.clone()); self.error("expected ')'", pos.clone());
return self.error_node(pos); return self.error_expr(pos);
} }
} }
self.step(); self.step();
subject = self.node( subject = Expr::new(
NodeKind::Call { EK::Call {
subject: Box::new(subject), subject: Box::new(subject),
args, args,
}, },
@ -257,42 +246,42 @@ impl<'a> Parser<'a> {
} }
} }
fn parse_value(&mut self) -> Node { fn parse_value(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
match self.curr_kind() { match self.curr_kind() {
Some(TokenKind::Id) => self.parse_id(), Some(TK::Ident) => self.parse_ident_expr(),
Some(TokenKind::Int) => self.parse_int(), Some(TK::Int) => self.parse_int(),
Some(TokenKind::Str) => self.parse_string(), Some(TK::Str) => self.parse_string(),
Some(TokenKind::LParen) => self.parse_group(), Some(TK::LParen) => self.parse_group(),
Some(TokenKind::LBrace) => self.parse_block(), Some(TK::LBrace) => self.parse_block(),
Some(TokenKind::If) => self.parse_if(), Some(TK::If) => self.parse_if(),
Some(TokenKind::Loop) => self.parse_loop(), Some(TK::Loop) => self.parse_loop(),
_ => { _ => {
self.error("expected value", pos.clone()); self.error("expected value", pos.clone());
self.step(); self.step();
self.error_node(pos) self.error_expr(pos)
} }
} }
} }
fn parse_id(&mut self) -> Node { fn parse_ident_expr(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
let Some(Token { let Some(Token {
kind: TokenKind::Id, kind: TK::Ident,
value: TokenValue::Id(value), value: TokenValue::Ident(value),
.. ..
}) = self.current }) = self.current
else { else {
unreachable!() unreachable!()
}; };
self.step(); self.step();
self.node(NodeKind::Id(value), pos) Expr::new(EK::Ident(value), pos)
} }
fn parse_int(&mut self) -> Node { fn parse_int(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
let Some(Token { let Some(Token {
kind: TokenKind::Int, kind: TK::Int,
value: TokenValue::Int(value), value: TokenValue::Int(value),
.. ..
}) = self.current }) = self.current
@ -300,13 +289,13 @@ impl<'a> Parser<'a> {
unreachable!() unreachable!()
}; };
self.step(); self.step();
self.node(NodeKind::Int(value), pos) Expr::new(EK::Int(value), pos)
} }
fn parse_string(&mut self) -> Node { fn parse_string(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
let Some(Token { let Some(Token {
kind: TokenKind::Str, kind: TK::Str,
value: TokenValue::Str(value), value: TokenValue::Str(value),
.. ..
}) = self.current.clone() }) = self.current.clone()
@ -314,62 +303,121 @@ impl<'a> Parser<'a> {
unreachable!() unreachable!()
}; };
self.step(); self.step();
self.node(NodeKind::Str(value.clone()), pos) Expr::new(EK::Str(value.clone()), pos)
} }
fn parse_group(&mut self) -> Node { fn parse_group(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
self.step(); self.step();
let expr = Box::new(self.parse_expr()); let expr = Box::new(self.parse_expr());
if !self.curr_is(TokenKind::RParen) { if !self.curr_is(TK::RParen) {
self.error("expected ')'", pos.clone()); self.error("expected ')'", pos.clone());
return self.error_node(pos); return self.error_expr(pos);
} }
self.step(); self.step();
self.node(NodeKind::Group(expr), pos) Expr::new(EK::Group(expr), pos)
} }
fn parse_block(&mut self) -> Node { fn parse_block(&mut self) -> Expr {
let pos = self.pos().unwrap(); use TK::*;
let pos = self.pos();
self.step(); self.step();
let mut stmts = Vec::new(); let mut stmts = Vec::new();
loop { loop {
match self.curr_kind() { match self.curr_kind() {
None => { None => {
self.error("expected ')'", pos.clone()); self.error("expected '}'", pos.clone());
break self.error_node(pos); break self.error_expr(pos);
} }
Some(TokenKind::RBrace) => { Some(RBrace) => {
self.step(); self.step();
break self.node(NodeKind::Block(stmts), pos); break Expr::new(EK::Block { stmts, expr: None }, pos);
} }
_ => stmts.push(self.parse_stmt()), Some(Fn) => stmts.push(self.parse_fn()),
Some(kind @ (Let | Return | Break)) => {
let stmt = match kind {
Let => self.parse_let(),
Return => self.parse_return(),
Break => self.parse_break(),
_ => unreachable!(),
};
self.eat_semicolon();
stmts.push(stmt);
}
Some(kind @ (LBrace | If | Loop)) => {
let expr = match kind {
LBrace => self.parse_block(),
If => self.parse_if(),
Loop => self.parse_loop(),
_ => unreachable!(),
};
match self.curr_kind() {
Some(TK::Semicolon) => {
self.step();
stmts.push(Stmt::new(SK::Expr(Box::new(expr)), pos.clone()))
}
Some(TK::RBrace) => {
self.step();
break Expr::new(
EK::Block {
stmts,
expr: Some(Box::new(expr)),
},
pos,
);
}
_ => {}
}
}
Some(_) => match self.parse_assign() {
ParsedAssign::Assign(stmt) => {
self.eat_semicolon();
stmts.push(stmt);
}
ParsedAssign::Expr(expr, pos) => match self.curr_kind() {
Some(TK::Semicolon) => {
self.step();
stmts.push(Stmt::new(SK::Expr(Box::new(expr)), pos))
}
Some(TK::RBrace) => {
self.step();
break Expr::new(
EK::Block {
stmts,
expr: Some(Box::new(expr)),
},
pos,
);
}
_ => {}
},
},
} }
} }
} }
fn parse_if(&mut self) -> Node { fn parse_if(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
self.step(); self.step();
let cond = Box::new(self.parse_expr()); let cond = Box::new(self.parse_expr());
if !self.curr_is(TokenKind::LBrace) { if !self.curr_is(TK::LBrace) {
self.error("expected '}'", pos.clone()); self.error("expected '}'", pos.clone());
return self.error_node(pos); return self.error_expr(pos);
} }
let truthy = Box::new(self.parse_block()); let truthy = Box::new(self.parse_block());
let falsy = match self.curr_kind() { let falsy = match self.curr_kind() {
Some(TokenKind::Else) => { Some(TK::Else) => {
self.step(); self.step();
if !self.curr_is(TokenKind::LBrace) { if !self.curr_is(TK::LBrace) {
self.error("expected '}'", pos.clone()); self.error("expected '}'", pos.clone());
return self.error_node(pos); return self.error_expr(pos);
} }
Some(Box::new(self.parse_block())) Some(Box::new(self.parse_block()))
} }
_ => None, _ => None,
}; };
self.node( Expr::new(
NodeKind::If { EK::If {
cond, cond,
truthy, truthy,
falsy, falsy,
@ -378,15 +426,65 @@ impl<'a> Parser<'a> {
) )
} }
fn parse_loop(&mut self) -> Node { fn parse_loop(&mut self) -> Expr {
let pos = self.pos().unwrap(); let pos = self.pos();
self.step(); self.step();
if !self.curr_is(TokenKind::LBrace) { if !self.curr_is(TK::LBrace) {
self.error("expected '}'", pos.clone()); self.error("expected '}'", pos.clone());
return self.error_node(pos); return self.error_expr(pos);
} }
let body = Box::new(self.parse_block()); let body = Box::new(self.parse_block());
self.node(NodeKind::Loop { body }, pos) Expr::new(EK::Loop { body }, pos)
}
fn parse_typ(&mut self) -> Typ {
let pos = self.pos();
match self.curr_kind() {
Some(TK::Ident) => self.parse_ident_typ(),
_ => {
self.error("expected type", pos.clone());
self.step();
self.error_typ(pos)
}
}
}
fn parse_ident_typ(&mut self) -> Typ {
let pos = self.pos();
let Some(Token {
kind: TK::Ident,
value: TokenValue::Ident(value),
..
}) = self.current
else {
unreachable!()
};
self.step();
Typ::new(TypKind::Ident(value), pos)
}
fn parse_param(&mut self) -> Param {
let pos = self.pos();
let subject = Box::new(self.parse_ident_expr());
let typ = if let Some(TK::Colon) = self.curr_kind() {
self.step();
Some(Box::new(self.parse_typ()))
} else {
None
};
Param { subject, typ, pos }
}
fn eat_semicolon(&mut self) {
let pos = self.pos();
match self.curr_kind() {
Some(TK::Semicolon) => {
self.step();
}
_ => {
self.error("expected ';'", pos.clone());
}
}
} }
fn error<S: Into<String>>(&mut self, msg: S, pos: Pos) { fn error<S: Into<String>>(&mut self, msg: S, pos: Pos) {
@ -402,26 +500,35 @@ impl<'a> Parser<'a> {
self.current = self.lexer.next(); self.current = self.lexer.next();
} }
fn node(&self, kind: NodeKind, pos: Pos) -> Node { fn error_stmt(&self, pos: Pos) -> Stmt {
Node { kind, pos } Stmt::new(SK::Error, pos)
} }
fn error_node(&self, pos: Pos) -> Node { fn error_expr(&self, pos: Pos) -> Expr {
Node { Expr::new(EK::Error, pos)
kind: NodeKind::Error,
pos,
}
} }
fn pos(&self) -> Option<Pos> { fn error_typ(&self, pos: Pos) -> Typ {
self.current.as_ref().map(|token| token.pos.clone()) Typ::new(TypKind::Error, pos)
} }
fn curr_is(&self, kind: TokenKind) -> bool { fn pos(&self) -> Pos {
self.current
.as_ref()
.map(|token| token.pos.clone())
.unwrap_or_else(|| self.lexer.pos())
}
fn curr_is(&self, kind: TK) -> bool {
self.curr_kind() == Some(kind) self.curr_kind() == Some(kind)
} }
fn curr_kind(&self) -> Option<TokenKind> { fn curr_kind(&self) -> Option<TK> {
self.current.as_ref().map(|t| t.kind.clone()) self.current.as_ref().map(|t| t.kind.clone())
} }
} }
enum ParsedAssign {
Assign(Stmt),
Expr(Expr, Pos),
}

View File

@ -41,4 +41,8 @@ impl ErrorAcc {
pub fn add(&mut self, error: Error) { pub fn add(&mut self, error: Error) {
self.errors.push(error) self.errors.push(error)
} }
pub fn iter(&self) -> impl Iterator<Item = &Error> {
self.errors.iter()
}
} }

View File

@ -10,7 +10,7 @@ pub struct Token {
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum TokenKind { pub enum TokenKind {
Error, Error,
Id, Ident,
Int, Int,
Str, Str,
If, If,
@ -34,7 +34,7 @@ pub enum TokenKind {
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum TokenValue { pub enum TokenValue {
None, None,
Id(u64), Ident(u64),
Int(i64), Int(i64),
Str(String), Str(String),
} }