luaaaaah/src/parser.rs

290 lines
5.6 KiB
Rust

use std::slice::Iter;
use crate::tokenizer::Token;
#[derive(Debug)]
pub struct BlockNode
{
stats: Vec<StatNode>,
retstat: Option<RetstatNode>
}
#[derive(Debug)]
pub enum StatNode
{
Semicolon,
Assignment(AssignmentNode),
FunctionCall(FunctionCallNode),
Label(LabelNode),
Break,
Goto(GotoNode),
Block(BlockNode),
While(WhileNode),
Repeat(RepeatNode),
If(IfNode),
For(ForNode),
ForIn(ForInNode),
Function(FunctionNode),
LocalFunction(LocalFunctionNode),
Local(LocalNode),
}
#[derive(Debug)]
pub struct AssignmentNode
{
}
#[derive(Debug)]
pub struct FunctionCallNode
{
}
#[derive(Debug)]
pub struct RetstatNode
{
}
#[derive(Debug)]
pub struct LabelNode
{
}
#[derive(Debug)]
pub struct GotoNode
{
label: String
}
#[derive(Debug)]
pub struct WhileNode
{
condition: ExpNode,
block: BlockNode,
}
#[derive(Debug)]
pub struct RepeatNode
{
condition: ExpNode,
block: BlockNode,
}
#[derive(Debug)]
pub struct IfNode
{
condition: ExpNode,
then_block: BlockNode,
elseifs: Option<Vec<ElseIfNode>>
}
#[derive(Debug)]
pub struct ElseIfNode
{
condition: ExpNode,
block: BlockNode,
}
#[derive(Debug)]
pub struct ForNode
{
}
#[derive(Debug)]
pub struct ForInNode
{
}
#[derive(Debug)]
pub struct FunctionNode
{
}
#[derive(Debug)]
pub struct LocalFunctionNode
{
}
#[derive(Debug)]
pub struct LocalNode
{
}
#[derive(Debug)]
pub struct ExpNode
{
}
pub fn parse(tokens: Vec<Token>) -> Result<BlockNode, &'static str>
{
let mut iter = tokens.iter();
return parse_block(&mut iter);
}
fn parse_block(tokens: &mut Iter<'_, Token>) -> Result<BlockNode, &'static str>
{
let mut block_node = BlockNode { retstat: None, stats: Vec::new() };
while let Some(stat) = parse_stat(tokens)?
{
block_node.stats.push(stat);
}
block_node.retstat = parse_retstat(tokens)?;
return Ok(block_node);
}
fn parse_stat(tokens: &mut Iter<'_, Token>) -> Result<Option<StatNode>, &'static str>
{
match tokens.next()
{
Some(token) =>
{
match token
{
Token::Semicolon => return Ok(Some(StatNode::Semicolon)),
Token::Break => return Ok(Some(StatNode::Break)),
Token::Goto =>
{
match tokens.next()
{
Some(Token::Name(string)) => return Ok(Some(StatNode::Goto(GotoNode { label: string.clone() }))),
_ => return Err("Failed to parse goto statement")
}
}
Token::Do =>
{
let block = parse_block(tokens)?;
match tokens.next()
{
Some(Token::End) => return Ok(Some(StatNode::Block(block))),
_ => return Err("Failed to parse block statement")
}
}
Token::While =>
{
if let Some(condition) = parse_exp(tokens)?
{
match tokens.next()
{
Some(Token::Do) =>
{
let block = parse_block(tokens)?;
match tokens.next()
{
Some(Token::End) => return Ok(Some(StatNode::While(WhileNode { condition, block }))),
_ => Err("No end after while block")
}
}
_ => Err("No do after while condition"),
}
}
else
{
return Err("Failed to parse while condition");
}
}
Token::Repeat =>
{
let block = parse_block(tokens)?;
match tokens.next()
{
Some(Token::Until) =>
{
match parse_exp(tokens)?
{
Some(exp) => return Ok(Some(StatNode::Repeat(RepeatNode { condition: exp, block }))),
None => Err("Failed to parse repeat condition")
}
}
_ => Err("Missing until after repeat block")
}
}
Token::If =>
{
if let Some(condition) = parse_exp(tokens)?
{
match tokens.next()
{
Some(Token::Then) =>
{
let block = parse_block(tokens)?;
let mut elseifs: Vec<ElseIfNode> = Vec::new();
loop
{
match tokens.next()
{
Some(Token::Elseif) =>
{
if let Some(elseif_condition) = parse_exp(tokens)?
{
match tokens.next()
{
Some(Token::Then) =>
{
elseifs.push(ElseIfNode { block: parse_block(tokens)?, condition: elseif_condition });
}
_ => return Err("Missing Then after elseif statement"),
}
}
else
{
return Err("Failed to parse elseif condition");
}
}
Some(Token::Else) =>
{
match tokens.next()
{
Some(Token::End) => return Ok(Some(StatNode::If(IfNode { condition, then_block: block, elseifs: Some(elseifs) }))),
_ => return Err("Missing end after else")
}
}
Some(Token::End) =>
{
return Ok(Some(StatNode::If(IfNode { condition, then_block: block, elseifs: None })));
}
_ => return Err("Missing end after if block")
}
}
}
_ => return Err("Missing then after if condition")
}
}
else
{
return Err("Failed to parse if condition");
}
}
Token::For =>
{
match tokens.next()
{
Some(Token::Name(name)) =>
{
match tokens.next()
{
Some(Token::Equals) =>
{
todo!();
}
_ => todo!()
}
}
_ => Err("Missing name after for"),
}
}
_ => todo!()
}
}
None => return Ok(None),
}
}
fn parse_exp(tokens: &mut Iter<'_, Token>) -> Result<Option<ExpNode>, &'static str>
{
todo!();
}
fn parse_retstat(tokens: &mut Iter<'_, Token>) -> Result<Option<RetstatNode>, &'static str>
{
match tokens.next()
{
Some(Token::Return) =>
{
todo!()
}
None => return Ok(None),
_ => return Err("Found wrong token at the beginning of retstat")
}
}