parse type annotations to ast

This commit is contained in:
Michael Sippel 2024-05-12 18:56:10 +02:00
parent f54f630b38
commit 49c72e8930
Signed by: senvas
GPG key ID: F96CF119C34B64A6
6 changed files with 207 additions and 64 deletions

View file

@ -1,8 +1,11 @@
use {
std::iter::Peekable,
std::{
iter::Peekable,
sync::{Arc, RwLock}
},
crate::{
lexer::{LTIRLexer, LTIRToken, LexError},
expr::{LTExpr, Statement}
expr::{LTExpr, Statement, TypeTag, TypeError}
}
};
@ -46,7 +49,34 @@ where It: Iterator<Item = char>
}
}
pub fn parse_type_tag<It>(
typectx: &Arc<RwLock<laddertypes::dict::TypeDict>>,
tokens: &mut Peekable<LTIRLexer<It>>
) -> Option<TypeTag>
where It: Iterator<Item = char>
{
if let Some(peektok) = tokens.peek().clone() {
match peektok.clone() {
Ok(LTIRToken::AssignType(typeterm_str)) => {
tokens.next();
match typectx.write().unwrap().parse(typeterm_str.as_str()) {
Ok(typeterm) => {
Some(Ok(typeterm))
}
Err(parse_error) => {
Some(Err(TypeError::ParseError(parse_error)))
}
}
}
_ => None
}
} else {
None
}
}
pub fn parse_statement<It>(
typectx: &Arc<RwLock<laddertypes::dict::TypeDict>>,
tokens: &mut Peekable<LTIRLexer<It>>
) -> Result< crate::expr::Statement, ParseError >
where It: Iterator<Item = char>
@ -59,7 +89,7 @@ where It: Iterator<Item = char>
tokens.next();
// todo accept address-expression instead of symbol
let name = parse_symbol(tokens)?;
let val_expr = parse_expr(tokens)?;
let val_expr = parse_expr(typectx, tokens)?;
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
Ok(Statement::Assignment {
@ -70,11 +100,13 @@ where It: Iterator<Item = char>
"let" => {
tokens.next();
let name = parse_symbol(tokens)?;
let typ = parse_type_tag(typectx, tokens);
let _ = parse_expect(tokens, LTIRToken::AssignValue);
let val_expr = parse_expr(tokens)?;
let val_expr = parse_expr(typectx, tokens)?;
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
Ok(Statement::LetAssign {
typ,
var_id: name,
val_expr
})
@ -82,28 +114,28 @@ where It: Iterator<Item = char>
"while" => {
tokens.next();
let _ = parse_expect(tokens, LTIRToken::ExprOpen)?;
let cond = parse_expr(tokens)?;
let cond = parse_expr(typectx, tokens)?;
let _ = parse_expect(tokens, LTIRToken::ExprClose)?;
Ok(Statement::WhileLoop {
condition: cond,
body: parse_block(tokens)?
body: parse_block(typectx, tokens)?
})
}
"return" => {
tokens.next();
let expr = parse_expr(tokens)?;
let expr = parse_expr(typectx, tokens)?;
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
Ok(Statement::Return(parse_expr(tokens)?))
Ok(Statement::Return(parse_expr(typectx, tokens)?))
}
_ => {
let expr = parse_expr(tokens)?;
let expr = parse_expr(typectx, tokens)?;
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
Ok(Statement::Expr(expr))
}
}
}
Ok(_) => {
let expr = parse_expr(tokens)?;
let expr = parse_expr(typectx, tokens)?;
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
Ok(Statement::Expr(expr))
},
@ -115,6 +147,7 @@ where It: Iterator<Item = char>
}
pub fn parse_block<It>(
typectx: &Arc<RwLock<laddertypes::dict::TypeDict>>,
tokens: &mut Peekable<LTIRLexer<It>>
) -> Result< Vec<Statement>, ParseError >
where It: Iterator<Item = char>
@ -128,7 +161,7 @@ where It: Iterator<Item = char>
tokens.next();
return Ok(statements)
}
Ok(_) => { statements.push( parse_statement(tokens)? ); }
Ok(_) => { statements.push( parse_statement(typectx, tokens)? ); }
Err(err) => { return Err(ParseError::LexError(err.clone())); }
}
}
@ -164,6 +197,7 @@ where It: Iterator<Item = char>
}
pub fn parse_expr<It>(
typectx: &Arc<RwLock<laddertypes::dict::TypeDict>>,
tokens: &mut Peekable<LTIRLexer<It>>
) -> Result< crate::expr::LTExpr, ParseError >
where It: Iterator<Item = char>
@ -178,9 +212,14 @@ where It: Iterator<Item = char>
let mut args = Vec::new();
while let Some(Ok(LTIRToken::Symbol(_))) = tokens.peek() {
args.push((parse_symbol(tokens)?, None));
args.push((
parse_symbol(tokens)?,
parse_type_tag(typectx, tokens)
));
}
let body = parse_expr(tokens)?;
let _ = parse_expect(tokens, LTIRToken::LambdaBody);
let body = parse_expr(typectx, tokens)?;
return Ok(LTExpr::Abstraction{
args,
@ -200,11 +239,13 @@ where It: Iterator<Item = char>
}
_ => {}
}
children.push(parse_expr(tokens)?);
children.push(parse_expr(typectx, tokens)?);
}
},
Ok(LTIRToken::ExprClose) => { break; }
Ok(LTIRToken::BlockOpen) => { children.push( LTExpr::block(parse_block(tokens)?)); }
Ok(LTIRToken::BlockOpen) => {
children.push( LTExpr::block(parse_block(typectx, tokens)?));
}
Ok(LTIRToken::BlockClose) => { break; }
Ok(LTIRToken::StatementSep) => { break; }
Ok(LTIRToken::Symbol(name)) => {
@ -212,16 +253,16 @@ where It: Iterator<Item = char>
"if" => {
tokens.next();
let _ = parse_expect(tokens, LTIRToken::ExprOpen)?;
let cond = parse_expr(tokens)?;
let cond = parse_expr(typectx, tokens)?;
let _ = parse_expect(tokens, LTIRToken::ExprClose)?;
let if_expr = LTExpr::block(parse_block(tokens)?);
let if_expr = LTExpr::block(parse_block(typectx, tokens)?);
let mut else_expr = LTExpr::block(vec![]);
if let Some(peektok) = tokens.peek() {
if let Ok(LTIRToken::Symbol(name)) = peektok {
if name == "else" {
tokens.next();
else_expr = parse_expr(tokens)?;
else_expr = parse_expr(typectx, tokens)?;
}
}
}
@ -245,6 +286,7 @@ where It: Iterator<Item = char>
if children.len() > 0 {
let head = children.remove(0);
Ok(LTExpr::Application {
typ: None,
head: Box::new(head),
body: children
})