fetish_lib/
interpreter_state.rs1extern crate ndarray;
2extern crate ndarray_linalg;
3
4use ndarray::*;
5use std::collections::HashMap;
6use crate::nonprimitive_term_pointer::*;
7use crate::newly_evaluated_terms::*;
8use crate::type_id::*;
9use crate::application_table::*;
10use crate::type_space::*;
11use crate::term_index::*;
12use crate::term::*;
13use crate::context::*;
14use crate::params::*;
15use crate::term_pointer::*;
16use crate::term_reference::*;
17use crate::term_application::*;
18use crate::term_application_result::*;
19use crate::primitive_term_pointer::*;
20use crate::func_impl::*;
21use topological_sort::TopologicalSort;
22
23pub struct InterpreterState<'a> {
28 pub application_tables : HashMap::<TypeId, ApplicationTable<'a>>,
29 pub type_spaces : HashMap::<TypeId, TypeSpace>,
30 pub ctxt : &'a Context
31}
32
33impl <'a> InterpreterState<'a> {
34 pub fn get_context(&self) -> &Context {
36 self.ctxt
37 }
38
39 pub fn store_term(&mut self, type_id : TypeId, term : PartiallyAppliedTerm) -> NonPrimitiveTermPointer {
44 let type_space : &mut TypeSpace = self.type_spaces.get_mut(&type_id).unwrap();
45 let result = type_space.add(term);
46 result
47 }
48
49 pub fn get(&self, term_ptr : TermPointer) -> PartiallyAppliedTerm {
53 match (term_ptr.index) {
54 TermIndex::Primitive(index) => {
55 let primitive_ptr = PrimitiveTermPointer {
56 type_id : term_ptr.type_id,
57 index : index
58 };
59 let result = PartiallyAppliedTerm::new(primitive_ptr);
60 result
61 },
62 TermIndex::NonPrimitive(index) => {
63 self.type_spaces.get(&term_ptr.type_id).unwrap().get(index).clone()
64 }
65 }
66 }
67
68 pub fn get_nonprimitive(&self, term_ptr : NonPrimitiveTermPointer) -> &PartiallyAppliedTerm {
71 self.type_spaces.get(&term_ptr.type_id).unwrap().get(term_ptr.index)
72 }
73
74 pub fn get_app_results_with_arg(&self, arg : &TermReference) -> Vec<TermApplicationResult> {
76 let mut result : Vec<TermApplicationResult> = Vec::new();
77 for table in self.application_tables.values() {
78 let mut temp = table.get_app_results_with_arg(arg);
79 result.append(&mut temp);
80 }
81 result
82 }
83
84 pub fn get_app_results_with_func(&self, func : TermPointer) -> Vec<TermApplicationResult> {
87 let mut result : Vec<TermApplicationResult> = Vec::new();
88 for table in self.application_tables.values() {
89 let mut temp = table.get_app_results_with_func(func);
90 result.append(&mut temp);
91 }
92 result
93 }
94
95 pub fn get_app_results_with_result(&self, result_term : &TermReference) -> Vec<TermApplicationResult> {
98 let mut result : Vec<TermApplicationResult> = Vec::new();
99 for table in self.application_tables.values() {
100 let mut temp = table.get_app_results_with_result(result_term);
101 result.append(&mut temp);
102 }
103 result
104 }
105
106 pub fn evaluate(&mut self, term_app : &TermApplication) -> (TermReference, NewlyEvaluatedTerms) {
111 let func_type_id : TypeId = term_app.get_func_type();
112
113 let func_term : PartiallyAppliedTerm = self.get(term_app.func_ptr);
114 let arg_ref : TermReference = term_app.arg_ref.clone();
115
116 let func_impl = self.ctxt.get_primitive(func_term.func_ptr);
117 let mut args_copy = func_term.args.clone();
118
119 args_copy.push(arg_ref);
120
121 let mut newly_evaluated_terms = NewlyEvaluatedTerms::new();
122
123 let result_ref : TermReference = if (func_impl.ready_to_evaluate(&args_copy)) {
124 let (ret_ref, more_evaluated_terms) = func_impl.evaluate(self, args_copy);
125 newly_evaluated_terms.merge(more_evaluated_terms);
126 ret_ref
127 } else {
128 let result = PartiallyAppliedTerm {
129 func_ptr : func_term.func_ptr.clone(),
130 args : args_copy
131 };
132 let ret_type_id : TypeId = term_app.get_ret_type(self.ctxt);
133 let ret_ptr = self.store_term(ret_type_id, result);
134
135 newly_evaluated_terms.add_term(ret_ptr);
136
137 let ret_ref = TermReference::FuncRef(TermPointer::from(ret_ptr));
138 ret_ref
139 };
140 let application_table : &mut ApplicationTable = self.application_tables.get_mut(&func_type_id).unwrap();
141
142 let term_app_result = TermApplicationResult {
143 term_app : term_app.clone(),
144 result_ref : result_ref.clone()
145 };
146
147 newly_evaluated_terms.add_term_app_result(term_app_result);
148
149 application_table.link(term_app.clone(), result_ref.clone());
150 (result_ref, newly_evaluated_terms)
151 }
152
153 pub fn ensure_every_type_has_a_term_on_init(&mut self) -> NewlyEvaluatedTerms {
157 let mut type_to_term = HashMap::<TypeId, TermReference>::new();
158 for i in 0..self.ctxt.get_total_num_types() {
160 let type_id = i as TypeId;
161 let kind = self.ctxt.get_type(type_id);
162 match (kind) {
163 Type::VecType(n) => {
164 type_to_term.insert(type_id, TermReference::VecRef(type_id, Array::zeros((n,))));
165 },
166 Type::FuncType(_, _) => {
167 let primitive_space = self.ctxt.primitive_directory.primitive_type_spaces.get(&type_id).unwrap();
168
169 if (primitive_space.terms.len() > 0) {
170 let func_ptr = TermPointer {
171 type_id : type_id,
172 index : TermIndex::Primitive(0)
173 };
174 type_to_term.insert(type_id, TermReference::FuncRef(func_ptr));
175 }
176 }
177 }
178 }
179 let mut newly_evaluated_terms = NewlyEvaluatedTerms::new();
180 loop {
181 let mut found_something = false;
182 for i in 0..self.ctxt.get_total_num_types() {
183 let func_type_id = i as TypeId;
184
185 if let Option::Some(func_term) = type_to_term.get(&func_type_id) {
186 if let Type::FuncType(arg_type_id, ret_type_id) = self.ctxt.get_type(func_type_id) {
187 if let Option::Some(arg_ref) = type_to_term.get(&arg_type_id) {
188 if (!type_to_term.contains_key(&ret_type_id)) {
189 if let TermReference::FuncRef(func_ptr) = func_term {
190 let application = TermApplication {
191 func_ptr : func_ptr.clone(),
192 arg_ref : arg_ref.clone()
193 };
194 let (result_ref, more_evaluated_terms) = self.evaluate(&application);
195 newly_evaluated_terms.merge(more_evaluated_terms);
196 type_to_term.insert(ret_type_id, result_ref);
197
198 found_something = true;
199 }
200 }
201 }
202 }
203 }
204 }
205 if (!found_something) {
206 break;
207 }
208 }
209 newly_evaluated_terms
210 }
211
212 pub fn new(ctxt : &'a Context) -> InterpreterState<'a> {
214 let mut application_tables = HashMap::<TypeId, ApplicationTable>::new();
216 let mut type_spaces = HashMap::<TypeId, TypeSpace>::new();
217
218 for type_id in 0..ctxt.get_total_num_types() {
219 if (!ctxt.is_vector_type(type_id)) {
220 application_tables.insert(type_id, ApplicationTable::new(type_id, ctxt));
221 type_spaces.insert(type_id, TypeSpace::new(type_id));
222 }
223 }
224
225 let result = InterpreterState {
226 application_tables,
227 type_spaces,
228 ctxt
229 };
230
231 result
232 }
233}