parse type annotations to ast
This commit is contained in:
parent
f54f630b38
commit
49c72e8930
6 changed files with 207 additions and 64 deletions
src
|
@ -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
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue