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::{ Word, lexer::Token };
use super::{ Program, Address, Instruction };
impl Program {
pub(crate) fn new(tokens: Vec<Token>, absolute_start: usize) -> Program {
let mut prog = Program {absolute_start, ..Default::default() };
let mut op_name = String::new();
let mut op_args = Vec::new();
let mut value = Address::None;
let mut symbol_def = String::new();
for token in tokens {
match token {
/* Names (lvalue) */
Token::Operator(name) => {
if ! op_name.is_empty() {
prog.instructions.push(Instruction {
name: op_name,
args: op_args.clone(),
});
}
op_name = name;
op_args.clear();
},
Token::Label(name) => {
// Predicting the index
let index = prog.instructions.len() + !op_name.is_empty() as usize;
prog.definitions.insert(name, Address::Instruction(index));
},
Token::SymbolDef(name) => symbol_def = name,
/* Values (rvalue) */
Token::Address(num) => {
value = Address::Memory(num as usize);
},
Token::Number(num) => {
prog.constants.push(num);
value = Address::Constants(prog.constants.len() - 1);
},
Token::String(str) => {
let index = prog.constants.len();
for c in str.chars() {
prog.constants.push(c as Word);
}
prog.constants.push(0); // terminating null
value = Address::Constants(index);
},
Token::Symbol(name) => {
value = Address::Definitions(name);
},
}
if value != Address::None {
if ! symbol_def.is_empty() {
prog.definitions.insert(symbol_def.clone(), value.take());
symbol_def.clear();
}
else {
op_args.push(value.take());
}
}
}
if ! op_name.is_empty() {
prog.instructions.push(Instruction {
name: op_name,
args: op_args.clone(),
});
}
prog
}
}
|