use std::result;
use std::collections::HashMap;
use crate::lexer::Lexer;
use crate::lexer::Token;
use crate::lexer::TokenType;
use crate::ast::*;
type Env = HashMap<String, Name>;
#[derive(Debug)]
pub struct Error {
pub start: usize,
pub end: usize,
pub message: &'static str
}
pub type Result<T> = result::Result<T, Error>;
impl Error {
pub fn new<'a>(tok: Token<'a>, message: &'static str) -> Error {
let start = tok.start;
let end = tok.end();
Error{start,end,message}
}
}
pub struct Parser<'a, F>
where F : FnMut(usize,&'a str) {
lexer: Lexer<'a>,
ast: &'a mut AbstractSyntaxTree,
env: Env,
mapper : F
}
impl<'a,'b,F> Parser<'a,F>
where 'a :'b, F : FnMut(usize,&'a str) {
pub fn new(input: &'a str, ast: &'a mut AbstractSyntaxTree, mapper : F) -> Self {
let env : Env = HashMap::new();
Self { lexer: Lexer::new(input), ast, env, mapper }
}
pub fn parse_decl(&'b mut self) -> Result<Decl> {
let lookahead = self.lexer.peek();
match lookahead.kind {
TokenType::Type => {
self.parse_decl_type()
}
TokenType::Function => {
self.parse_decl_function()
}
_ => {
todo!("Unknown declaration")
}
}
}
pub fn parse_decl_function(&'b mut self) -> Result<Decl> {
self.snap(TokenType::Function)?;
let name = self.parse_identifier()?;
let params = self.parse_decl_parameters()?;
let returns = if self.lookahead(TokenType::MinusGreater) {
self.gap_snap(TokenType::MinusGreater)?;
self.parse_decl_parameters()?
} else {
vec![]
};
self.gap_snap(TokenType::Colon)?;
self.match_line_end()?;
let body = self.parse_stmt_block(&"")?;
let n = Node::from(FunctionDecl::new(name,params,returns,body));
Ok(Decl::new(self.ast,n))
}
pub fn parse_decl_property(&'b mut self) -> Result<Decl> {
todo![];
}
pub fn parse_decl_type(&'b mut self) -> Result<Decl> {
let start = self.snap(TokenType::Type)?;
let name = self.parse_identifier()?;
self.gap_snap(TokenType::Is)?;
let typ_e = self.parse_type()?;
let end = self.lexer.offset();
self.match_line_end()?;
let slice = &self.lexer.input[start.start .. end];
Ok(Decl::new(self.ast,Node::from(TypeDecl::new(name,typ_e))))
}
pub fn parse_decl_parameters(&mut self) -> Result<Vec<Parameter>> {
let mut params : Vec<Parameter> = vec![];
self.skip_gap();
self.snap(TokenType::LeftBrace)?;
while self.snap(TokenType::RightBrace).is_err() {
if !params.is_empty() {
self.snap(TokenType::Comma)?;
}
let f_type = self.parse_type()?;
let f_name = self.parse_identifier()?;
params.push(Parameter{declared:f_type,name:f_name});
}
Ok(params)
}
pub fn parse_stmt_block(&mut self, indent : &'a str) -> Result<Stmt> {
let mut stmts : Vec<Stmt> = Vec::new();
let nindent = self.snap(TokenType::Gap)?;
if !nindent.content.starts_with(indent) || indent.len() == nindent.len() {
return Err(Error::new(nindent,"invalid block"));
}
stmts.push(self.parse_stmt()?);
while self.lexer.peek().content == nindent.content {
self.snap(TokenType::Gap)?;
stmts.push(self.parse_stmt()?);
}
Ok(Stmt::new(self.ast,Node::from(BlockStmt(stmts))))
}
pub fn parse_stmt(&mut self) -> Result<Stmt> {
let lookahead = self.lexer.peek();
match lookahead.kind {
_ => self.parse_unit_stmt()
}
}
pub fn parse_unit_stmt(&mut self) -> Result<Stmt> {
let lookahead = self.lexer.peek();
let stmt = match lookahead.kind {
TokenType::Assert => {
self.parse_stmt_assert()
}
TokenType::Skip => {
self.parse_stmt_skip()
}
_ => {
return Err(Error::new(lookahead,"unknown token encountered"));
}
};
self.match_line_end()?;
stmt
}
pub fn parse_stmt_assert(&mut self) -> Result<Stmt> {
self.snap(TokenType::Assert)?;
let expr = self.parse_expr()?;
Ok(Stmt::new(self.ast,Node::from(AssertStmt(expr))))
}
pub fn parse_stmt_skip(&mut self) -> Result<Stmt> {
self.snap(TokenType::Skip)?;
Ok(Stmt::new(self.ast,Node::from(SkipStmt())))
}
pub fn parse_expr(&mut self) -> Result<Expr> {
let lhs = self.parse_expr_term()?;
self.skip_gap();
let lookahead = self.lexer.peek();
match lookahead.kind {
TokenType::LeftAngle => {
self.lexer.next();
let rhs = self.parse_expr_term()?;
Ok(Expr::new(self.ast,Node::from(LessThanExpr(lhs,rhs))))
}
_ => {
Ok(lhs)
}
}
}
pub fn parse_expr_term(&mut self) -> Result<Expr> {
self.skip_gap();
let lookahead = self.lexer.peek();
let expr = match lookahead.kind {
TokenType::False => {
self.lexer.next();
Expr::new(self.ast,Node::from(BoolExpr(false)))
}
TokenType::Identifier => {
let n = self.parse_identifier();
Expr::new(self.ast,Node::from(VarExpr(n.unwrap())))
}
TokenType::Integer => {
self.lexer.next();
Expr::new(self.ast,Node::from(IntExpr(lookahead.as_int())))
}
TokenType::LeftBrace => {
return self.parse_expr_bracketed()
}
TokenType::True => {
self.lexer.next();
Expr::new(self.ast,Node::from(BoolExpr(true)))
}
_ => {
return Err(Error::new(lookahead,"unknown token encountered"))
}
};
Ok(expr)
}
pub fn parse_expr_bracketed(&mut self) -> Result<Expr> {
self.snap(TokenType::LeftBrace)?;
let expr = self.parse_expr();
self.snap(TokenType::RightBrace)?;
expr
}
pub fn parse_type(&mut self) -> Result<Type> {
self.skip_gap();
self.parse_type_compound()
}
pub fn parse_type_compound(&mut self) -> Result<Type> {
let lookahead = self.lexer.peek();
match lookahead.kind {
TokenType::EOF => {
Err(Error::new(lookahead,"unexpected end-of-file"))
}
TokenType::Ampersand => {
self.parse_type_ref()
}
TokenType::LeftCurly => {
self.parse_type_record()
}
_ => {
self.parse_type_array()
}
}
}
pub fn parse_type_ref(&mut self) -> Result<Type> {
let mut n = 1;
self.snap(TokenType::Ampersand)?;
while self.snap(TokenType::Ampersand).is_ok() {
n = n + 1;
}
let mut t = self.parse_type_bracketed()?;
for _i in 0..n {
t = Type::new(self.ast,Node::from(ReferenceType(t)));
}
Ok(t)
}
pub fn parse_type_record(&mut self) -> Result<Type> {
let mut fields : Vec<(Type,Name)> = vec![];
self.snap(TokenType::LeftCurly)?;
while self.snap(TokenType::RightCurly).is_err() {
if !fields.is_empty() {
self.snap(TokenType::Comma)?;
}
let f_type = self.parse_type()?;
let f_name = self.parse_identifier()?;
fields.push((f_type,f_name));
}
Ok(Type::new(self.ast,Node::from(RecordType(fields))))
}
pub fn parse_type_array(&'b mut self) -> Result<Type> {
let mut t = self.parse_type_bracketed()?;
while self.snap(TokenType::LeftSquare).is_ok() {
self.snap(TokenType::RightSquare)?;
t = Type::new(self.ast,Node::from(ArrayType(t)));
}
Ok(t)
}
pub fn parse_type_bracketed(&'b mut self) -> Result<Type> {
if self.snap(TokenType::LeftBrace).is_ok() {
let typ_e = self.parse_type()?;
self.snap(TokenType::RightBrace)?;
Ok(typ_e)
} else {
self.parse_type_base()
}
}
pub fn parse_type_base(&'b mut self) -> Result<Type> {
let lookahead = self.lexer.peek();
let typ_e : Type = match lookahead.kind {
TokenType::Null => {
Type::new(self.ast,Node::from(NullType()))
}
TokenType::Bool => {
Type::new(self.ast,Node::from(BoolType()))
}
TokenType::I8 => {
Type::new(self.ast,Node::from(IntType(true,8)))
}
TokenType::I16 => {
Type::new(self.ast,Node::from(IntType(true,16)))
}
TokenType::I32 => {
Type::new(self.ast,Node::from(IntType(true,32)))
}
TokenType::I64 => {
Type::new(self.ast,Node::from(IntType(true,64)))
}
TokenType::U8 => {
Type::new(self.ast,Node::from(IntType(false,8)))
}
TokenType::U16 => {
Type::new(self.ast,Node::from(IntType(false,16)))
}
TokenType::U32 => {
Type::new(self.ast,Node::from(IntType(false,32)))
}
TokenType::U64 => {
Type::new(self.ast,Node::from(IntType(false,64)))
}
TokenType::Void => {
Type::new(self.ast,Node::from(VoidType()))
}
_ => {
return Err(Error::new(lookahead,"unknown token encountered"));
}
};
self.lexer.next();
Ok(typ_e)
}
pub fn parse_identifier(&mut self) -> Result<Name> {
self.skip_gap();
let tok = self.snap(TokenType::Identifier)?;
Ok(Name::new(self.ast,&tok.content))
}
fn skip_gap(&mut self) {
let lookahead = self.lexer.peek();
match lookahead.kind {
TokenType::Gap => {
self.snap(TokenType::Gap).unwrap();
}
_ => {
}
}
}
fn match_line_end(&mut self) -> Result<()> {
let lookahead = self.lexer.peek();
match lookahead.kind {
TokenType::EOF => {
Ok(())
}
TokenType::NewLine => {
self.snap(lookahead.kind)?;
Ok(())
}
_ => {
Err(Error::new(lookahead,"expecting end-of-line"))
}
}
}
fn lookahead(&mut self, kind : TokenType) -> bool {
self.skip_gap();
let lookahead = self.lexer.peek();
return lookahead.kind == kind;
}
fn gap_snap(&mut self, kind : TokenType) -> Result<Token<'a>> {
self.skip_gap();
self.snap(kind)
}
fn matches(&mut self, kind : TokenType) -> Result<Token<'a>> {
let lookahead = self.lexer.peek();
if lookahead.kind == kind {
Ok(lookahead)
} else {
Err(Error::new(lookahead,"expected one thing, found another"))
}
}
fn snap(&mut self, kind : TokenType) -> Result<Token<'a>> {
let lookahead = self.lexer.peek();
if lookahead.kind == kind {
self.lexer.next();
Ok(lookahead)
} else {
Err(Error::new(lookahead,"expected one thing, found another"))
}
}
}