290 lines
5.6 KiB
Rust
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")
|
|
}
|
|
} |