rpg_compiler/type_checker/
mod.rs1use std::collections::HashMap;
2use crate::node::{Node, NodeType, parse_dyn_node};
3use crate::node;
4use crate::compile_error;
5
6pub struct TypeChecker<'a> {
8 nodes: &'a Vec<Box<dyn Node + Send + Sync>>,
9 var_map: HashMap<usize, NodeType>
10}
11impl<'a> TypeChecker<'a> {
12 pub fn new(nodes: &'a Vec<Box<dyn Node + Send + Sync>>) -> Self {
13 Self {
14 nodes,
15 var_map: HashMap::new()
16 }
17 }
18 pub fn check_types(&mut self) {
19 self.check_node_types(self.nodes)
20 }
21 fn check_node_types(&mut self, nodes: &'a Vec<Box<dyn Node + Send + Sync>>) {
22 nodes.iter().for_each(|node| {
23 let node = &**node;
24 match node.get_type() {
25 NodeType::Char => {
26 let node: &node::Char = parse_dyn_node(node);
27 self.var_map.insert(node.id, NodeType::Char);
28 }
29 NodeType::Zombie => {
30 let node: &node::Zombie = parse_dyn_node(node);
31 self.var_map.insert(node.id, NodeType::Zombie);
32 }
33 NodeType::Merchant => {
34 let node: &node::Merchant = parse_dyn_node(node);
35 self.var_map.insert(node.id, NodeType::Merchant);
36 }
37 NodeType::Potion => {
38 let node: &node::Potion = parse_dyn_node(node);
39 self.var_map.insert(node.id, NodeType::Potion);
40 }
41 NodeType::SpellBook => {
42 let node: &node::SpellBook = parse_dyn_node(node);
43 self.var_map.insert(node.id, NodeType::SpellBook);
44 }
45 NodeType::FnBuys => {
46 let node: &node::FnBuys = parse_dyn_node(node);
47 if let Some(user) = self.var_map.get(&node.user) {
48 if let Some(item) = self.var_map.get(&node.item) {
49 if let Some(merchant) = self.var_map.get(&node.merchant) {
50 if user == &NodeType::Char || user == &NodeType::Zombie {
51 if item == &NodeType::Potion || item == &NodeType::SpellBook {
52 if !(merchant == &NodeType::Merchant) {
53 compile_error!("Only merchants can sell items.")
54 }
55 } else {
56 compile_error!("Only potions and spellbooks can be bought from a merchant.")
57 }
58 } else {
59 compile_error!("The one buying must be an actor.")
60 }
61 } else {
62 compile_error!("No merchant found while buying.")
63 }
64 } else {
65 compile_error!("Item you are trying to buy was not found.")
66 }
67 } else {
68 compile_error!("Actor that is trying to buy not found.")
69 }
70
71 }
72 NodeType::FnAttacks => {
73 let node: &node::FnAttacks = parse_dyn_node(node);
74 if let Some(attacked) = self.var_map.get(&node.attacked) {
75 if let Some(attacker) = self.var_map.get(&node.attacker) {
76 if attacked == &NodeType::Char || attacked == &NodeType::Zombie {
77 if !(attacker == &NodeType::Char || attacker == &NodeType::Zombie) {
78 compile_error!("The one attacking is not an actor.")
79 }
80 } else {
81 compile_error!("The one being attacked is not an actor.")
82 }
83 } else {
84 compile_error!("Attacking actor could not be found.")
85 }
86 } else {
87 compile_error!("Actor being attacked could not be found.")
88 }
89 }
90 NodeType::FnUses => {
91 let node: &node::FnUses = parse_dyn_node(node);
92 if let Some(user) = self.var_map.get(&node.user) {
93 if let Some(potion) = self.var_map.get(&node.item) {
94 if user == &NodeType::Char || user == &NodeType::Zombie {
95 if !(potion == &NodeType::Potion) {
96 compile_error!("The item being used is not a potion.")
97 }
98 } else {
99 compile_error!("The user of the potion is not an actor.")
100 }
101 } else {
102 compile_error!("The potion being used was not defined.")
103 }
104 } else {
105 compile_error!("The actor using the potion was not defined.");
106 }
107 }
108 NodeType::FnShouts => {
109 let node: &node::FnShouts = parse_dyn_node(node);
110 if let Some(shouter) = self.var_map.get(&node.user) {
111 if !(shouter == &NodeType::Char || shouter == &NodeType::Zombie) {
112 compile_error!("The one shouting is not an actor.")
113 }
114 } else {
115 compile_error!("The actor shouting was not defined.")
116 }
117 }
118 NodeType::FnShoutsSpeak => {
119 let node: &node::FnShoutsSpeak = parse_dyn_node(node);
120 if let Some(shouter) = self.var_map.get(&node.user) {
121 if let Some(spellbook) = self.var_map.get(&node.spell_book) {
122 if shouter == &NodeType::Char || shouter == &NodeType::Zombie {
123 if !(spellbook == &NodeType::SpellBook) {
124 compile_error!("The actor is not using a spellbook to shout.")
125 }
126 } else {
127 compile_error!("The one shouting is not an actor.")
128 }
129 } else {
130 compile_error!("The spellbook used for speaking was not defined.")
131 }
132 } else {
133 compile_error!("The actor shouting was not defined.")
134 }
135 }
136 NodeType::FnWhispers => {
137 let node: &node::FnWhispers = parse_dyn_node(node);
138 if let Some(whisperer) = self.var_map.get(&node.user) {
139 if !(whisperer == &NodeType::Char || whisperer == &NodeType::Zombie) {
140 compile_error!("The one shouting is not an actor.")
141 }
142 } else {
143 compile_error!("The actor shouting was not defined.")
144 }
145 }
146 NodeType::FnWhispersSpeak => {
147 let node: &node::FnWhispersSpeak = parse_dyn_node(node);
148 if let Some(whisperer) = self.var_map.get(&node.user) {
149 if let Some(spellbook) = self.var_map.get(&node.spell_book) {
150 if whisperer == &NodeType::Char || whisperer == &NodeType::Zombie {
151 if !(spellbook == &NodeType::SpellBook) {
152 compile_error!("The actor is not using a spellbook to shout.")
153 }
154 } else {
155 compile_error!("The one shouting is not an actor.")
156 }
157 } else {
158 compile_error!("The spellbook used for speaking was not defined.")
159 }
160 } else {
161 compile_error!("The actor shouting was not defined.")
162 }
163 }
164 NodeType::FnUsesCasting => {
165 }
167 NodeType::FnBody => {
168 let node: &node::FnBody = parse_dyn_node(node);
169 self.check_node_types(&node.body);
170 }
171 }
172 });
173 }
174}