1use crate::{protocol::*, Result};
9use oxur_lang::{Expander, Parser};
10use std::collections::HashMap;
11
12#[derive(Debug, Clone, Copy)]
14enum ExecutionTier {
15 Interpreter,
16 Cached,
17 Jit,
18}
19
20pub struct ReplServer {
22 #[allow(dead_code)]
23 parser: Parser,
24 #[allow(dead_code)]
25 expander: Expander,
26 cache: HashMap<String, String>,
27 stats: TierStats,
28}
29
30#[derive(Debug, Default)]
31struct TierStats {
32 tier1_count: usize,
33 tier2_count: usize,
34 tier3_count: usize,
35}
36
37impl ReplServer {
38 pub fn new() -> Self {
39 Self {
40 parser: Parser::new(String::new()),
41 expander: Expander::new(),
42 cache: HashMap::new(),
43 stats: TierStats::default(),
44 }
45 }
46
47 pub fn handle(&mut self, request: ReplRequest) -> Result<ReplResponse> {
49 match request {
50 ReplRequest::Eval { source } => self.eval(&source),
51 ReplRequest::Load { path } => self.load(&path),
52 ReplRequest::Reset => {
53 self.reset();
54 Ok(ReplResponse::Ok)
55 }
56 ReplRequest::Status => Ok(ReplResponse::Status {
57 tier1_count: self.stats.tier1_count,
58 tier2_count: self.stats.tier2_count,
59 tier3_count: self.stats.tier3_count,
60 }),
61 ReplRequest::Shutdown => Ok(ReplResponse::Ok),
62 }
63 }
64
65 fn eval(&mut self, source: &str) -> Result<ReplResponse> {
66 let tier = self.choose_tier(source);
68
69 match tier {
70 ExecutionTier::Interpreter => {
71 self.stats.tier1_count += 1;
72 self.eval_interpret(source)
73 }
74 ExecutionTier::Cached => {
75 self.stats.tier2_count += 1;
76 self.eval_cached(source)
77 }
78 ExecutionTier::Jit => {
79 self.stats.tier3_count += 1;
80 self.eval_jit(source)
81 }
82 }
83 }
84
85 fn choose_tier(&self, source: &str) -> ExecutionTier {
86 if source.len() < 50 {
88 ExecutionTier::Interpreter
89 } else if self.cache.contains_key(source) {
90 ExecutionTier::Cached
91 } else {
92 ExecutionTier::Jit
93 }
94 }
95
96 fn eval_interpret(&mut self, source: &str) -> Result<ReplResponse> {
97 Ok(ReplResponse::Value { value: format!("interpreted: {}", source) })
99 }
100
101 fn eval_cached(&self, source: &str) -> Result<ReplResponse> {
102 if let Some(result) = self.cache.get(source) {
104 Ok(ReplResponse::Value { value: result.clone() })
105 } else {
106 Ok(ReplResponse::Error { message: "Cache miss".to_string() })
107 }
108 }
109
110 fn eval_jit(&mut self, source: &str) -> Result<ReplResponse> {
111 let result = format!("jit-compiled: {}", source);
113 self.cache.insert(source.to_string(), result.clone());
114 Ok(ReplResponse::Value { value: result })
115 }
116
117 fn load(&mut self, _path: &str) -> Result<ReplResponse> {
118 Ok(ReplResponse::Ok)
120 }
121
122 fn reset(&mut self) {
123 self.cache.clear();
124 self.stats = TierStats::default();
125 }
126}
127
128impl Default for ReplServer {
129 fn default() -> Self {
130 Self::new()
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137
138 #[test]
139 fn test_server_creation() {
140 let server = ReplServer::new();
141 assert_eq!(server.stats.tier1_count, 0);
142 }
143
144 #[test]
145 fn test_server_default() {
146 let server = ReplServer::default();
147 assert_eq!(server.stats.tier1_count, 0);
148 }
149
150 #[test]
151 fn test_tier_selection() {
152 let server = ReplServer::new();
153
154 let tier = server.choose_tier("(+ 1 2)");
156 assert!(matches!(tier, ExecutionTier::Interpreter));
157
158 let tier = server.choose_tier(&"x".repeat(100));
160 assert!(matches!(tier, ExecutionTier::Jit));
161 }
162
163 #[test]
164 fn test_tier_selection_boundary() {
165 let server = ReplServer::new();
166 let tier = server.choose_tier(&"x".repeat(49));
168 assert!(matches!(tier, ExecutionTier::Interpreter));
169 let tier = server.choose_tier(&"x".repeat(50));
171 assert!(matches!(tier, ExecutionTier::Jit));
172 }
173
174 #[test]
175 fn test_handle_eval() {
176 let mut server = ReplServer::new();
177 let req = ReplRequest::Eval { source: "test".to_string() };
178 let resp = server.handle(req);
179 assert!(resp.is_ok());
180 }
181
182 #[test]
183 fn test_handle_load() {
184 let mut server = ReplServer::new();
185 let req = ReplRequest::Load { path: "test.ox".to_string() };
186 let resp = server.handle(req);
187 assert!(resp.is_ok());
188 }
189
190 #[test]
191 fn test_handle_reset() {
192 let mut server = ReplServer::new();
193 server.stats.tier1_count = 10;
194 let req = ReplRequest::Reset;
195 let resp = server.handle(req);
196 assert!(resp.is_ok());
197 match resp.unwrap() {
198 ReplResponse::Ok => (),
199 _ => panic!("Expected Ok response"),
200 }
201 }
202
203 #[test]
204 fn test_handle_status() {
205 let mut server = ReplServer::new();
206 server.stats.tier1_count = 1;
207 server.stats.tier2_count = 2;
208 server.stats.tier3_count = 3;
209 let req = ReplRequest::Status;
210 let resp = server.handle(req);
211 assert!(resp.is_ok());
212 match resp.unwrap() {
213 ReplResponse::Status { tier1_count, tier2_count, tier3_count } => {
214 assert_eq!(tier1_count, 1);
215 assert_eq!(tier2_count, 2);
216 assert_eq!(tier3_count, 3);
217 }
218 _ => panic!("Expected Status response"),
219 }
220 }
221
222 #[test]
223 fn test_handle_shutdown() {
224 let mut server = ReplServer::new();
225 let req = ReplRequest::Shutdown;
226 let resp = server.handle(req);
227 assert!(resp.is_ok());
228 match resp.unwrap() {
229 ReplResponse::Ok => (),
230 _ => panic!("Expected Ok response"),
231 }
232 }
233
234 #[test]
235 fn test_tier_stats() {
236 let stats = TierStats { tier1_count: 5, tier2_count: 10, tier3_count: 15 };
237 assert_eq!(stats.tier1_count, 5);
238 assert_eq!(stats.tier2_count, 10);
239 assert_eq!(stats.tier3_count, 15);
240 }
241
242 #[test]
243 fn test_tier_stats_default() {
244 let stats = TierStats::default();
245 assert_eq!(stats.tier1_count, 0);
246 assert_eq!(stats.tier2_count, 0);
247 assert_eq!(stats.tier3_count, 0);
248 }
249
250 #[test]
251 fn test_eval_short_source() {
252 let mut server = ReplServer::new();
253 let req = ReplRequest::Eval { source: "short".to_string() };
254 let resp = server.handle(req);
255 assert!(resp.is_ok());
256 assert_eq!(server.stats.tier1_count, 1);
257 }
258
259 #[test]
260 fn test_eval_long_source() {
261 let mut server = ReplServer::new();
262 let req = ReplRequest::Eval { source: "x".repeat(100) };
263 let resp = server.handle(req);
264 assert!(resp.is_ok());
265 assert_eq!(server.stats.tier3_count, 1);
266 }
267
268 #[test]
269 fn test_reset_clears_cache() {
270 let mut server = ReplServer::new();
271 let req = ReplRequest::Eval { source: "x".repeat(100) };
273 server.handle(req).unwrap();
274 assert!(server.cache.len() > 0);
275
276 server.handle(ReplRequest::Reset).unwrap();
278 assert_eq!(server.cache.len(), 0);
279 }
280
281 #[test]
282 fn test_reset_clears_stats() {
283 let mut server = ReplServer::new();
284 server.stats.tier1_count = 10;
285 server.stats.tier2_count = 20;
286 server.stats.tier3_count = 30;
287
288 server.handle(ReplRequest::Reset).unwrap();
289 assert_eq!(server.stats.tier1_count, 0);
290 assert_eq!(server.stats.tier2_count, 0);
291 assert_eq!(server.stats.tier3_count, 0);
292 }
293}