1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::{LabelManager, ParseError, Token, TokenType};
use super::{functions::Function, instructions::Operand, ParseResult};
pub struct Parser {}
impl Parser {
pub fn parse(
tokens: Vec<Token>,
label_manager: &mut LabelManager,
) -> ParseResult<Vec<Function>> {
let mut functions = Vec::new();
let mut location_counter = 0;
let mut token_iter = tokens.iter().peekable();
while token_iter.peek().is_some() {
while token_iter.peek().is_some()
&& token_iter.peek().unwrap().tt() == TokenType::NEWLINE
{
token_iter.next();
}
if token_iter.peek().is_some() {
if token_iter.peek().unwrap().tt() == TokenType::FUNCTION {
token_iter.next();
let func =
Function::parse(&mut token_iter, &mut location_counter, label_manager)?;
functions.push(func);
} else {
return Err(ParseError::TokenOutsideFunctionError(
token_iter.peek().unwrap().line(),
));
}
}
}
Parser::check_labels(&functions, label_manager)?;
Ok(functions)
}
fn check_labels(functions: &Vec<Function>, label_manager: &LabelManager) -> ParseResult<()> {
for function in functions {
for instr in function.instructions() {
for op in instr.operands() {
match op {
Operand::LABELREF(r) => {
if !label_manager.ifdef(r) {
return Err(ParseError::UndefinedLabelError(r.to_owned()));
}
}
_ => {}
}
}
}
}
Ok(())
}
}