hence/hence/src/lib/parser.rs

71 lines
2.3 KiB
Rust
Raw Normal View History

2022-08-28 10:31:56 +00:00
use anyhow::{bail, Result};
2022-07-17 18:24:49 +00:00
use itertools::PeekingNext;
use crate::arg;
use crate::lexer;
pub mod ast;
2022-08-28 10:31:56 +00:00
pub fn parse(tokens: Vec<lexer::Token>) -> Result<ast::AST> {
2022-07-17 18:24:49 +00:00
let mut iter = tokens.iter().peekable();
2022-09-03 13:14:58 +00:00
let mut body: ast::Body = vec![];
2022-07-17 18:24:49 +00:00
2022-07-20 12:24:38 +00:00
while let Some(&token) = iter.peek() {
2022-07-17 18:24:49 +00:00
match token {
lexer::Token::Comment(x) => {
body.push(ast::Node::Comment(x.trim().to_string()));
iter.next();
}
lexer::Token::MacroLiteral(x) => {
iter.next();
body.push(ast::Node::MacroCall {
name: (&x[1..]).to_string(),
args: arg::parse_args(
iter.by_ref()
.take_while(|t| !matches!(t, lexer::Token::Newline(_)))
.filter(|t| !matches!(t, lexer::Token::Whitespace(_)))
.collect(),
2022-09-02 09:33:46 +00:00
)?,
2022-07-17 18:24:49 +00:00
});
}
lexer::Token::Literal(x) => {
iter.next();
if iter
.peeking_next(|t| matches!(t, lexer::Token::Colon))
.is_some()
{
body.push(ast::Node::Label(x.clone()));
} else {
2022-08-23 14:20:38 +00:00
let args = match arg::parse_args(
2022-07-17 18:24:49 +00:00
iter.by_ref()
.take_while(|t| !matches!(t, lexer::Token::Newline(_)))
2022-08-23 14:20:38 +00:00
.filter(|t| {
!matches!(t, lexer::Token::Whitespace(_) | lexer::Token::Comment(_))
})
2022-07-17 18:24:49 +00:00
.collect(),
2022-08-23 14:20:38 +00:00
) {
Ok(x) => x,
2022-08-28 10:31:56 +00:00
Err(x) => bail!("{}", x),
2022-08-23 14:20:38 +00:00
};
2022-07-17 18:24:49 +00:00
if args.len() > 1 {
2022-08-28 10:31:56 +00:00
bail!("Opcode call only accepts one argument");
2022-07-17 18:24:49 +00:00
}
body.push(ast::Node::Call {
name: x.clone(),
2022-08-26 13:02:48 +00:00
arg: args.first().cloned(),
2022-07-17 18:24:49 +00:00
});
}
}
lexer::Token::Whitespace(_) | lexer::Token::Newline(_) => {
iter.next();
}
2022-08-28 10:31:56 +00:00
_ => bail!("Unexpected token"),
2022-07-17 18:24:49 +00:00
}
}
Ok(ast::AST { body })
}