1use crate::ast::*;
4use crate::error::{KoreError, KoreResult};
5use crate::lexer::Lexer;
6use crate::parser::Parser;
7use crate::types::TypedProgram;
8use flume::Sender;
9use pyo3::prelude::*;
10use pyo3::types::{PyDict, PyList};
11use std::collections::HashMap;
12use std::fmt;
13use std::sync::{Arc, RwLock};
14
15fn py_to_value(obj: &PyAny) -> PyResult<Value> {
16 if let Ok(s) = obj.extract::<String>() {
17 return Ok(Value::String(s));
18 }
19 if let Ok(b) = obj.extract::<bool>() {
20 return Ok(Value::Bool(b));
21 }
22 if let Ok(i) = obj.extract::<i64>() {
23 return Ok(Value::Int(i));
24 }
25 if let Ok(f) = obj.extract::<f64>() {
26 return Ok(Value::Float(f));
27 }
28 if let Ok(l) = obj.downcast::<PyList>() {
29 let mut vec = Vec::new();
30 for item in l {
31 vec.push(py_to_value(item)?);
32 }
33 return Ok(Value::Array(Arc::new(RwLock::new(vec))));
34 }
35 Ok(Value::String(format!("{}", obj)))
37}
38
39#[derive(Clone, Debug)]
41pub enum VNode {
42 Element {
43 tag: String,
44 attrs: HashMap<String, Value>,
45 children: Vec<VNode>,
46 },
47 Text(String),
48}
49
50#[derive(Clone)]
52pub enum Value {
53 Unit,
54 Bool(bool),
55 Int(i64),
56 Float(f64),
57 String(String),
58 Array(Arc<RwLock<Vec<Value>>>),
59 Tuple(Vec<Value>),
60 Struct(String, Arc<RwLock<HashMap<String, Value>>>),
61 Function(String),
62 NativeFn(String, fn(&mut Env, Vec<Value>) -> KoreResult<Value>),
63 ActorRef(ActorRef),
64 None,
65 Return(Box<Value>),
67 Break(Option<Box<Value>>),
69 Continue,
71 Result(bool, Box<Value>),
73 Closure(Vec<String>, Box<Expr>, Vec<HashMap<String, Value>>),
75 StructConstructor(String, Vec<String>),
77 JSX(VNode),
79 EnumVariant(String, String, Vec<Value>),
81 Poll(bool, Option<Box<Value>>),
83 Future(String, Arc<RwLock<HashMap<String, Value>>>),
85}
86
87impl fmt::Debug for Value {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match self {
90 Value::Unit => write!(f, "Unit"),
91 Value::Bool(b) => write!(f, "Bool({})", b),
92 Value::Int(i) => write!(f, "Int({})", i),
93 Value::Float(fl) => write!(f, "Float({})", fl),
94 Value::String(s) => write!(f, "String({:?})", s),
95 Value::Array(arr) => write!(f, "Array({:?})", arr),
96 Value::Tuple(t) => write!(f, "Tuple({:?})", t),
97 Value::Struct(name, fields) => write!(f, "Struct({}, {:?})", name, fields),
98 Value::Function(name) => write!(f, "Function({})", name),
99 Value::NativeFn(name, _) => write!(f, "NativeFn({})", name),
100 Value::StructConstructor(name, _) => write!(f, "StructConstructor({})", name),
101 Value::ActorRef(r) => write!(f, "ActorRef({:?})", r),
102 Value::None => write!(f, "None"),
103 Value::Return(v) => write!(f, "Return({:?})", v),
104 Value::Result(ok, v) => {
105 if *ok {
106 write!(f, "Ok({:?})", v)
107 } else {
108 write!(f, "Err({:?})", v)
109 }
110 }
111 Value::Closure(params, _, _) => write!(f, "Closure({:?})", params),
112 Value::JSX(node) => write!(f, "JSX({:?})", node),
113 Value::EnumVariant(e, v, _) => write!(f, "{}::{}", e, v),
114 Value::Poll(ready, val) => {
115 if *ready {
116 write!(f, "Poll::Ready({:?})", val)
117 } else {
118 write!(f, "Poll::Pending")
119 }
120 }
121 Value::Future(name, _) => write!(f, "Future<{}>", name),
122 Value::Break(v) => write!(f, "Break({:?})", v),
123 Value::Continue => write!(f, "Continue"),
124 }
125 }
126}
127
128impl fmt::Display for VNode {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 match self {
131 VNode::Element {
132 tag,
133 attrs,
134 children,
135 } => {
136 write!(f, "<{}", tag)?;
137 for (k, v) in attrs {
138 write!(f, " {}=\"{}\"", k, v)?;
139 }
140 if children.is_empty() {
141 write!(f, " />")
142 } else {
143 write!(f, ">")?;
144 for child in children {
145 write!(f, "{}", child)?;
146 }
147 write!(f, "</{}>", tag)
148 }
149 }
150 VNode::Text(s) => write!(f, "{}", s),
151 }
152 }
153}
154
155impl fmt::Display for Value {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 match self {
158 Value::Unit => write!(f, "()"),
159 Value::Bool(b) => write!(f, "{}", b),
160 Value::Int(i) => write!(f, "{}", i),
161 Value::Float(fl) => write!(f, "{}", fl),
162 Value::String(s) => write!(f, "{}", s),
163 Value::Array(arr) => {
164 write!(f, "[")?;
165 let arr = arr.read().unwrap();
166 for (i, v) in arr.iter().enumerate() {
167 if i > 0 {
168 write!(f, ", ")?;
169 }
170 write!(f, "{}", v)?;
171 }
172 write!(f, "]")
173 }
174 Value::Tuple(t) => {
175 write!(f, "(")?;
176 for (i, v) in t.iter().enumerate() {
177 if i > 0 {
178 write!(f, ", ")?;
179 }
180 write!(f, "{}", v)?;
181 }
182 write!(f, ")")
183 }
184 Value::Struct(name, fields) => {
185 write!(f, "{} {{", name)?;
186 let fields = fields.read().unwrap();
187 for (i, (k, v)) in fields.iter().enumerate() {
188 if i > 0 {
189 write!(f, ", ")?;
190 }
191 write!(f, "{}: {}", k, v)?;
192 }
193 write!(f, "}}")
194 }
195 Value::Function(name) => write!(f, "<fn {}>", name),
196 Value::NativeFn(name, _) => write!(f, "<native fn {}>", name),
197 Value::StructConstructor(name, _) => write!(f, "<constructor {}>", name),
198 Value::ActorRef(r) => write!(f, "<actor {}>", r.id),
199 Value::None => write!(f, "none"),
200 Value::Return(v) => write!(f, "{}", v),
201 Value::Result(ok, v) => {
202 if *ok {
203 write!(f, "Ok({})", v)
204 } else {
205 write!(f, "Err({})", v)
206 }
207 }
208 Value::Closure(_, _, _) => write!(f, "<closure>"),
209 Value::JSX(node) => write!(f, "{}", node),
210 Value::EnumVariant(enum_name, variant, fields) => {
211 if fields.is_empty() {
212 write!(f, "{}::{}", enum_name, variant)
213 } else {
214 write!(f, "{}::{}(", enum_name, variant)?;
215 for (i, v) in fields.iter().enumerate() {
216 if i > 0 {
217 write!(f, ", ")?;
218 }
219 write!(f, "{}", v)?;
220 }
221 write!(f, ")")
222 }
223 }
224 Value::Poll(ready, val) => {
225 if *ready {
226 if let Some(v) = val {
227 write!(f, "Poll::Ready({})", v)
228 } else {
229 write!(f, "Poll::Ready(())")
230 }
231 } else {
232 write!(f, "Poll::Pending")
233 }
234 }
235 Value::Future(name, _) => write!(f, "<future {}>", name),
236 Value::Break(v) => {
237 if let Some(val) = v {
238 write!(f, "<break {}>", val)
239 } else {
240 write!(f, "<break>")
241 }
242 }
243 Value::Continue => write!(f, "<continue>"),
244 }
245 }
246}
247
248#[derive(Debug, Clone)]
250pub struct ActorRef {
251 pub id: u64,
252 pub sender: Sender<Message>,
253}
254
255#[derive(Debug, Clone)]
257pub struct Message {
258 pub name: String,
259 pub args: Vec<Value>,
260}
261
262#[derive(Clone)]
264pub struct Env {
265 scopes: Vec<HashMap<String, Value>>,
266 functions: HashMap<String, Function>,
267 components: HashMap<String, Component>,
268 methods: HashMap<String, HashMap<String, Function>>,
270 #[allow(dead_code)]
271 actors: HashMap<u64, Sender<Message>>,
272 #[allow(dead_code)]
273 next_actor_id: u64,
274 actor_defs: HashMap<String, Actor>,
275 self_actor_id: Option<u64>,
277 python_scope: Option<PyObject>,
279}
280
281impl Env {
282 pub fn new() -> Self {
283 let mut env = Self {
284 scopes: vec![HashMap::new()],
285 functions: HashMap::new(),
286 components: HashMap::new(),
287 methods: HashMap::new(),
288 actors: HashMap::new(),
289 next_actor_id: 1,
290 actor_defs: HashMap::new(),
291 self_actor_id: None,
292 python_scope: None,
293 };
294
295 Python::with_gil(|py| {
297 let locals = PyDict::new(py);
298 env.python_scope = Some(locals.into());
299 });
300
301 env.register_stdlib();
302 env.register_net_stdlib();
303 env.register_stdlib();
304 env.register_net_stdlib();
305 env.register_json_stdlib();
306 env.register_kos_bridge();
307 env
308 }
309
310 pub fn register_kos_bridge(&mut self) {
311 self.define_native("spawn_cube", |_env, args| {
312 if args.len() != 2 {
313 return Err(KoreError::runtime(
314 "spawn_cube: expected 2 arguments (x, y)",
315 ));
316 }
317 let x = match args[0] {
318 Value::Int(n) => n as f64,
319 Value::Float(n) => n,
320 _ => return Err(KoreError::runtime("spawn_cube: x must be number")),
321 };
322 let y = match args[1] {
323 Value::Int(n) => n as f64,
324 Value::Float(n) => n,
325 _ => return Err(KoreError::runtime("spawn_cube: y must be number")),
326 };
327
328 println!(
329 " [KOS Bridge] Spawning Cube at {{ x: {:.2}, y: {:.2} }}",
330 x, y
331 );
332 Ok(Value::Unit)
333 });
334 }
335
336 pub fn register_net_stdlib(&mut self) {
337 self.define_native("http_get", |_env, args| {
339 if args.len() != 1 {
340 return Err(KoreError::runtime("http_get: expected 1 argument (url)"));
341 }
342 let url = match &args[0] {
343 Value::String(s) => s.clone(),
344 _ => return Err(KoreError::runtime("http_get: argument must be string url")),
345 };
346
347 let res = reqwest::blocking::get(&url);
348
349 match res {
350 Ok(resp) => match resp.text() {
351 Ok(text) => Ok(Value::String(text)),
352 Err(e) => Err(KoreError::runtime(format!(
353 "http_get: failed to read body: {}",
354 e
355 ))),
356 },
357 Err(e) => Err(KoreError::runtime(format!(
358 "http_get: request failed: {}",
359 e
360 ))),
361 }
362 });
363
364 self.define_native("http_post_json", |_env, args| {
365 if args.len() != 2 {
366 return Err(KoreError::runtime(
367 "http_post: expected 2 arguments (url, json_string)",
368 ));
369 }
370 let url = match &args[0] {
371 Value::String(s) => s.clone(),
372 _ => return Err(KoreError::runtime("http_post: url must be string")),
373 };
374 let body = match &args[1] {
375 Value::String(s) => s.clone(),
376 _ => return Err(KoreError::runtime("http_post: body must be string")),
377 };
378
379 let client = reqwest::blocking::Client::new();
380
381 let res = client
382 .post(&url)
383 .header("Content-Type", "application/json")
384 .body(body)
385 .send();
386
387 match res {
388 Ok(resp) => match resp.text() {
389 Ok(text) => Ok(Value::String(text)),
390 Err(e) => Err(KoreError::runtime(format!(
391 "http_post: failed to read response: {}",
392 e
393 ))),
394 },
395 Err(e) => Err(KoreError::runtime(format!(
396 "http_post: request failed: {}",
397 e
398 ))),
399 }
400 });
401 }
402
403 pub fn register_json_stdlib(&mut self) {
404 self.define_native("json_parse", |_env, args| {
405 if args.len() != 1 {
406 return Err(KoreError::runtime(
407 "json_parse: expected 1 argument (string)",
408 ));
409 }
410 let s = match &args[0] {
411 Value::String(s) => s,
412 _ => return Err(KoreError::runtime("json_parse: argument must be string")),
413 };
414
415 fn from_json(v: &serde_json::Value) -> Value {
416 match v {
417 serde_json::Value::Null => Value::None,
418 serde_json::Value::Bool(b) => Value::Bool(*b),
419 serde_json::Value::Number(n) => {
420 if let Some(i) = n.as_i64() {
421 Value::Int(i)
422 } else if let Some(f) = n.as_f64() {
423 Value::Float(f)
424 } else {
425 Value::Int(0) }
427 }
428 serde_json::Value::String(s) => Value::String(s.clone()),
429 serde_json::Value::Array(arr) => {
430 let k_arr = arr.iter().map(from_json).collect();
431 Value::Array(Arc::new(RwLock::new(k_arr)))
432 }
433 serde_json::Value::Object(obj) => {
434 let mut map = HashMap::new();
435 for (k, v) in obj {
436 map.insert(k.clone(), from_json(v));
437 }
438 Value::Struct("Json".to_string(), Arc::new(RwLock::new(map)))
439 }
440 }
441 }
442
443 match serde_json::from_str::<serde_json::Value>(s) {
444 Ok(v) => Ok(from_json(&v)),
445 Err(e) => Err(KoreError::runtime(format!(
446 "json_parse: invalid json: {}",
447 e
448 ))),
449 }
450 });
451
452 self.define_native("json_string", |_env, args| {
453 if args.len() != 1 {
454 return Err(KoreError::runtime("json_string: expected 1 argument"));
455 }
456
457 fn to_json(v: &Value) -> serde_json::Value {
458 match v {
459 Value::Unit => serde_json::Value::Null,
460 Value::None => serde_json::Value::Null,
461 Value::Bool(b) => serde_json::Value::Bool(*b),
462 Value::Int(i) => serde_json::json!(i),
463 Value::Float(f) => serde_json::json!(f),
464 Value::String(s) => serde_json::Value::String(s.clone()),
465 Value::Array(arr) => {
466 let arr = arr.read().unwrap();
467 serde_json::Value::Array(arr.iter().map(to_json).collect())
468 }
469 Value::Struct(_, fields) => {
470 let fields = fields.read().unwrap();
471 let mut map = serde_json::Map::new();
472 for (k, v) in fields.iter() {
473 map.insert(k.clone(), to_json(v));
474 }
475 serde_json::Value::Object(map)
476 }
477 Value::Tuple(items) => {
478 serde_json::Value::Array(items.iter().map(to_json).collect())
479 }
480 _ => serde_json::Value::String(format!("{}", v)), }
482 }
483
484 Ok(Value::String(to_json(&args[0]).to_string()))
485 });
486 }
487
488 pub fn register_stdlib(&mut self) {
489 self.define("None".to_string(), Value::None);
491 self.define("none".to_string(), Value::None); self.define_native("Some", |_env, args| {
496 if args.len() != 1 {
497 return Err(KoreError::runtime("Some: expected 1 argument"));
498 }
499 Ok(args[0].clone())
500 });
501
502 self.define_native("print", |_env, args| {
504 for arg in args {
505 print!("{} ", arg);
506 }
507 Ok(Value::Unit)
508 });
509
510 self.define_native("println", |_env, args| {
511 for arg in args {
512 print!("{} ", arg);
513 }
514 println!("");
515 Ok(Value::Unit)
516 });
517
518 self.define_native("min", |_env, args| {
520 if args.len() != 2 {
521 return Err(KoreError::runtime("min: expected 2 arguments"));
522 }
523 match (&args[0], &args[1]) {
524 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(*a.min(b))),
525 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a.min(*b))),
526 _ => Err(KoreError::runtime("min: arguments must be numbers")),
527 }
528 });
529
530 self.define_native("max", |_env, args| {
531 if args.len() != 2 {
532 return Err(KoreError::runtime("max: expected 2 arguments"));
533 }
534 match (&args[0], &args[1]) {
535 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(*a.max(b))),
536 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a.max(*b))),
537 _ => Err(KoreError::runtime("max: arguments must be numbers")),
538 }
539 });
540
541 self.define_native("abs", |_env, args| {
542 if args.len() != 1 {
543 return Err(KoreError::runtime("abs: expected 1 argument"));
544 }
545 match &args[0] {
546 Value::Int(n) => Ok(Value::Int(n.abs())),
547 Value::Float(n) => Ok(Value::Float(n.abs())),
548 _ => Err(KoreError::runtime("abs: argument must be number")),
549 }
550 });
551
552 self.define_native("sqrt", |_env, args| {
553 if args.len() != 1 {
554 return Err(KoreError::runtime("sqrt: expected 1 argument"));
555 }
556 match &args[0] {
557 Value::Int(n) => Ok(Value::Float((*n as f64).sqrt())),
558 Value::Float(n) => Ok(Value::Float(n.sqrt())),
559 _ => Err(KoreError::runtime("sqrt: argument must be number")),
560 }
561 });
562
563 self.define_native("random", |_env, _args| {
565 use std::time::SystemTime;
568 let seed = SystemTime::now()
569 .duration_since(std::time::UNIX_EPOCH)
570 .unwrap()
571 .as_nanos() as u64;
572 let x = (seed % 1000) as f64 / 1000.0;
573 Ok(Value::Float(x))
574 });
575
576 self.define_native("sleep", |_env, args| {
577 if args.len() != 1 {
578 return Err(KoreError::runtime("sleep: expected 1 argument (ms)"));
579 }
580 match args[0] {
581 Value::Int(ms) => {
582 std::thread::sleep(std::time::Duration::from_millis(ms as u64));
583 Ok(Value::Unit)
584 }
585 _ => Err(KoreError::runtime("sleep: argument must be int")),
586 }
587 });
588
589 self.define_native("len", |_env, args| {
591 if args.len() != 1 {
592 return Err(KoreError::runtime("len: expected 1 argument"));
593 }
594 match &args[0] {
595 Value::String(s) => Ok(Value::Int(s.len() as i64)),
596 Value::Array(arr) => Ok(Value::Int(arr.read().unwrap().len() as i64)),
597 _ => Err(KoreError::runtime("len: argument must be string or array")),
598 }
599 });
600
601 self.define_native("ord", |_env, args| {
603 if args.len() != 1 {
604 return Err(KoreError::runtime("ord: expected 1 argument"));
605 }
606 match &args[0] {
607 Value::String(s) => {
608 if let Some(c) = s.chars().next() {
609 Ok(Value::Int(c as i64))
610 } else {
611 Err(KoreError::runtime("ord: empty string"))
612 }
613 }
614 _ => Err(KoreError::runtime("ord: argument must be string")),
615 }
616 });
617
618 self.define_native("chr", |_env, args| {
620 if args.len() != 1 {
621 return Err(KoreError::runtime("chr: expected 1 argument"));
622 }
623 match &args[0] {
624 Value::Int(n) => {
625 if let Some(c) = char::from_u32(*n as u32) {
626 Ok(Value::String(c.to_string()))
627 } else {
628 Err(KoreError::runtime("chr: invalid code point"))
629 }
630 }
631 _ => Err(KoreError::runtime("chr: argument must be int")),
632 }
633 });
634
635 self.define_native("first", |_env, args| {
636 if args.len() != 1 {
637 return Err(KoreError::runtime("first: expected 1 argument"));
638 }
639 match &args[0] {
640 Value::Array(arr) => {
641 let arr = arr.read().unwrap();
642 if arr.is_empty() {
643 return Err(KoreError::runtime("first: empty array"));
644 }
645 Ok(arr[0].clone())
646 }
647 _ => Err(KoreError::runtime("first: argument must be array")),
648 }
649 });
650
651 self.define_native("last", |_env, args| {
652 if args.len() != 1 {
653 return Err(KoreError::runtime("last: expected 1 argument"));
654 }
655 match &args[0] {
656 Value::Array(arr) => {
657 let arr = arr.read().unwrap();
658 if arr.is_empty() {
659 return Err(KoreError::runtime("last: empty array"));
660 }
661 Ok(arr[arr.len() - 1].clone())
662 }
663 _ => Err(KoreError::runtime("last: argument must be array")),
664 }
665 });
666
667 self.define_native("push", |_env, args| {
668 if args.len() != 2 {
669 return Err(KoreError::runtime("push: expected 2 arguments"));
670 }
671 match &args[0] {
672 Value::Array(arr) => {
673 arr.write().unwrap().push(args[1].clone());
674 Ok(Value::Unit)
675 }
676 _ => Err(KoreError::runtime("push: first argument must be array")),
677 }
678 });
679
680 self.define_native("range", |_env, args| {
682 if args.len() != 2 {
683 return Err(KoreError::runtime("range: expected 2 arguments"));
684 }
685 let start = match args[0] {
686 Value::Int(n) => n,
687 _ => return Err(KoreError::runtime("range: expected int")),
688 };
689 let end = match args[1] {
690 Value::Int(n) => n,
691 _ => return Err(KoreError::runtime("range: expected int")),
692 };
693
694 let arr = (start..end).map(Value::Int).collect();
695 Ok(Value::Array(Arc::new(RwLock::new(arr))))
696 });
697
698 self.define_native("first", |_env, args| {
700 if args.len() != 1 {
701 return Err(KoreError::runtime("first: expected 1 argument"));
702 }
703 match &args[0] {
704 Value::Array(arr) => arr
705 .read()
706 .unwrap()
707 .first()
708 .cloned()
709 .ok_or_else(|| KoreError::runtime("Array is empty")),
710 Value::String(s) => s
711 .chars()
712 .next()
713 .map(|c| Value::String(c.to_string()))
714 .ok_or_else(|| KoreError::runtime("String is empty")),
715 _ => Err(KoreError::runtime("first: expected array or string")),
716 }
717 });
718
719 self.define_native("last", |_env, args| {
720 if args.len() != 1 {
721 return Err(KoreError::runtime("last: expected 1 argument"));
722 }
723 match &args[0] {
724 Value::Array(arr) => arr
725 .read()
726 .unwrap()
727 .last()
728 .cloned()
729 .ok_or_else(|| KoreError::runtime("Array is empty")),
730 Value::String(s) => s
731 .chars()
732 .last()
733 .map(|c| Value::String(c.to_string()))
734 .ok_or_else(|| KoreError::runtime("String is empty")),
735 _ => Err(KoreError::runtime("last: expected array or string")),
736 }
737 });
738
739 self.define_native("reverse", |_env, args| {
740 if args.len() != 1 {
741 return Err(KoreError::runtime("reverse: expected 1 argument"));
742 }
743 match &args[0] {
744 Value::Array(arr) => {
745 let mut reversed = arr.read().unwrap().clone();
746 reversed.reverse();
747 Ok(Value::Array(Arc::new(RwLock::new(reversed))))
748 }
749 Value::String(s) => Ok(Value::String(s.chars().rev().collect())),
750 _ => Err(KoreError::runtime("reverse: expected array or string")),
751 }
752 });
753
754 self.define_native("sum", |_env, args| {
755 if args.len() != 1 {
756 return Err(KoreError::runtime("sum: expected 1 argument"));
757 }
758 match &args[0] {
759 Value::Array(arr) => {
760 let mut total = 0i64;
761 for v in arr.read().unwrap().iter() {
762 match v {
763 Value::Int(n) => total += n,
764 _ => {
765 return Err(KoreError::runtime("sum: array must contain integers"))
766 }
767 }
768 }
769 Ok(Value::Int(total))
770 }
771 _ => Err(KoreError::runtime("sum: expected array")),
772 }
773 });
774
775 self.define_native("type_of", |_env, args| {
777 if args.len() != 1 {
778 return Err(KoreError::runtime("type_of: expected 1 argument"));
779 }
780 let type_name = match &args[0] {
781 Value::Unit => "unit",
782 Value::Bool(_) => "bool",
783 Value::Int(_) => "int",
784 Value::Float(_) => "float",
785 Value::String(_) => "string",
786 Value::Array(_) => "array",
787 Value::Tuple(_) => "tuple",
788 Value::Struct(name, _) => name.as_str(),
789 Value::Function(_) => "function",
790 Value::NativeFn(_, _) => "native_function",
791 Value::ActorRef(_) => "actor",
792 Value::None => "none",
793 Value::Return(_) => "return_value",
794 Value::Closure(_, _, _) => "function",
795 Value::Result(_, _) => "result",
796 Value::StructConstructor(_, _) => "struct_constructor",
797 Value::JSX(_) => "jsx",
798 Value::EnumVariant(enum_name, _, _) => return Ok(Value::String(enum_name.clone())),
799 Value::Poll(_, _) => "poll",
800 Value::Future(name, _) => return Ok(Value::String(format!("Future<{}>", name))),
801 Value::Break(_) => "break",
802 Value::Continue => "continue",
803 };
804 Ok(Value::String(type_name.to_string()))
805 });
806
807 self.define_native("variant_of", |_env, args| {
809 if args.len() != 1 {
810 return Err(KoreError::runtime("variant_of: expected 1 argument"));
811 }
812 match &args[0] {
813 Value::EnumVariant(_, variant, _) => Ok(Value::String(variant.clone())),
814 _ => Ok(Value::String("".to_string())), }
816 });
817
818 self.define_native("variant_field", |_env, args| {
821 if args.len() != 2 {
822 return Err(KoreError::runtime(
823 "variant_field: expected 2 arguments (enum, index)",
824 ));
825 }
826 let idx = match &args[1] {
827 Value::Int(n) => *n as usize,
828 _ => return Err(KoreError::runtime("variant_field: index must be int")),
829 };
830 match &args[0] {
831 Value::EnumVariant(_, _, fields) => {
832 if idx < fields.len() {
833 let field = fields[idx].clone();
834 if let Value::Struct(name, inner) = &field {
836 if name == "Box" {
837 let inner = inner.read().unwrap();
838 if let Some(boxed) = inner.get("0") {
839 return Ok(boxed.clone());
840 }
841 }
842 }
843 if let Value::EnumVariant(enum_name, variant_name, inner_fields) = &field {
845 if enum_name == "Box"
846 && variant_name == "new"
847 && inner_fields.len() == 1
848 {
849 return Ok(inner_fields[0].clone());
850 }
851 }
852 Ok(field)
853 } else {
854 Err(KoreError::runtime(format!(
855 "variant_field: index {} out of bounds (has {} fields)",
856 idx,
857 fields.len()
858 )))
859 }
860 }
861 _ => Err(KoreError::runtime(
862 "variant_field: first argument must be enum variant",
863 )),
864 }
865 });
866
867 self.define_native("str", |_env, args| {
868 if args.len() != 1 {
869 return Err(KoreError::runtime("str: expected 1 argument"));
870 }
871 Ok(Value::String(format!("{}", args[0])))
872 });
873
874 self.define_native("int", |_env, args| {
875 if args.len() != 1 {
876 return Err(KoreError::runtime("int: expected 1 argument"));
877 }
878 match &args[0] {
879 Value::Int(n) => Ok(Value::Int(*n)),
880 Value::Float(n) => Ok(Value::Int(*n as i64)),
881 Value::String(s) => s
882 .parse::<i64>()
883 .map(Value::Int)
884 .map_err(|_| KoreError::runtime("Invalid int string")),
885 _ => Err(KoreError::runtime("int: argument must be number or string")),
886 }
887 });
888
889 self.define_native("float", |_env, args| {
890 if args.len() != 1 {
891 return Err(KoreError::runtime("float: expected 1 argument"));
892 }
893 match &args[0] {
894 Value::Int(n) => Ok(Value::Float(*n as f64)),
895 Value::Float(n) => Ok(Value::Float(*n)),
896 Value::String(s) => s
897 .parse::<f64>()
898 .map(Value::Float)
899 .map_err(|_| KoreError::runtime("Invalid float string")),
900 _ => Err(KoreError::runtime(
901 "float: argument must be number or string",
902 )),
903 }
904 });
905
906 self.define_native("ok", |_env, args| {
908 if args.len() != 1 {
909 return Err(KoreError::runtime("ok: expected 1 argument"));
910 }
911 Ok(Value::Result(true, Box::new(args[0].clone())))
912 });
913
914 self.define_native("err", |_env, args| {
915 if args.len() != 1 {
916 return Err(KoreError::runtime("err: expected 1 argument"));
917 }
918 Ok(Value::Result(false, Box::new(args[0].clone())))
919 });
920
921 self.define_native("sleep", |_env, args| {
922 if args.len() != 1 {
923 return Err(KoreError::runtime("sleep: expected 1 argument"));
924 }
925 match &args[0] {
926 Value::Int(n) => {
927 std::thread::sleep(std::time::Duration::from_secs(*n as u64));
928 Ok(Value::Unit)
929 }
930 Value::Float(n) => {
931 std::thread::sleep(std::time::Duration::from_secs_f64(*n));
932 Ok(Value::Unit)
933 }
934 _ => Err(KoreError::runtime("sleep: expected number")),
935 }
936 });
937
938 self.define_native("now", |_env, _args| {
939 let start = std::time::SystemTime::now();
940 let since_the_epoch = start
941 .duration_since(std::time::UNIX_EPOCH)
942 .map_err(|e| KoreError::runtime(&format!("Time error: {}", e)))?;
943 Ok(Value::Float(since_the_epoch.as_secs_f64()))
944 });
945
946 self.define_native("map", |env, args| {
950 if args.len() != 2 {
951 return Err(KoreError::runtime(
952 "map: expected 2 arguments (array, function)",
953 ));
954 }
955 let arr = match &args[0] {
956 Value::Array(a) => a.read().unwrap().clone(),
957 _ => return Err(KoreError::runtime("map: first argument must be an array")),
958 };
959 let func = args[1].clone();
960 let mut results = Vec::new();
961 for item in arr {
962 let result = call_function(env, func.clone(), vec![item])?;
963 results.push(result);
964 }
965 Ok(Value::Array(Arc::new(RwLock::new(results))))
966 });
967
968 self.define_native("filter", |env, args| {
969 if args.len() != 2 {
970 return Err(KoreError::runtime(
971 "filter: expected 2 arguments (array, function)",
972 ));
973 }
974 let arr = match &args[0] {
975 Value::Array(a) => a.read().unwrap().clone(),
976 _ => {
977 return Err(KoreError::runtime(
978 "filter: first argument must be an array",
979 ))
980 }
981 };
982 let func = args[1].clone();
983 let mut results = Vec::new();
984 for item in arr {
985 let result = call_function(env, func.clone(), vec![item.clone()])?;
986 match result {
987 Value::Bool(true) => results.push(item),
988 Value::Bool(false) => {}
989 _ => return Err(KoreError::runtime("filter: function must return bool")),
990 }
991 }
992 Ok(Value::Array(Arc::new(RwLock::new(results))))
993 });
994
995 self.define_native("reduce", |env, args| {
996 if args.len() != 3 {
997 return Err(KoreError::runtime(
998 "reduce: expected 3 arguments (array, initial, function)",
999 ));
1000 }
1001 let arr = match &args[0] {
1002 Value::Array(a) => a.read().unwrap().clone(),
1003 _ => {
1004 return Err(KoreError::runtime(
1005 "reduce: first argument must be an array",
1006 ))
1007 }
1008 };
1009 let mut acc = args[1].clone();
1010 let func = args[2].clone();
1011 for item in arr {
1012 acc = call_function(env, func.clone(), vec![acc, item])?;
1013 }
1014 Ok(acc)
1015 });
1016
1017 self.define_native("foreach", |env, args| {
1018 if args.len() != 2 {
1019 return Err(KoreError::runtime(
1020 "foreach: expected 2 arguments (array, function)",
1021 ));
1022 }
1023 let arr = match &args[0] {
1024 Value::Array(a) => a.read().unwrap().clone(),
1025 _ => {
1026 return Err(KoreError::runtime(
1027 "foreach: first argument must be an array",
1028 ))
1029 }
1030 };
1031 let func = args[1].clone();
1032 for item in arr {
1033 call_function(env, func.clone(), vec![item])?;
1034 }
1035 Ok(Value::Unit)
1036 });
1037
1038 self.define_native("read_file", |_env, args| {
1040 if args.len() != 1 {
1041 return Err(KoreError::runtime("read_file: expected 1 argument"));
1042 }
1043 let path = match &args[0] {
1044 Value::String(s) => s,
1045 _ => return Err(KoreError::runtime("read_file: argument must be string")),
1046 };
1047
1048 match std::fs::read_to_string(path) {
1049 Ok(s) => Ok(Value::String(s)),
1050 Err(e) => Ok(Value::Result(
1051 false,
1052 Box::new(Value::String(format!("Failed to read file: {}", e))),
1053 )),
1054 }
1055 });
1056
1057 self.define_native("write_file", |_env, args| {
1058 if args.len() != 2 {
1059 return Err(KoreError::runtime("write_file: expected 2 arguments"));
1060 }
1061 let path = match &args[0] {
1062 Value::String(s) => s,
1063 _ => {
1064 return Err(KoreError::runtime(
1065 "write_file: first argument must be string",
1066 ))
1067 }
1068 };
1069 let content = match &args[1] {
1070 Value::String(s) => s,
1071 _ => {
1072 return Err(KoreError::runtime(
1073 "write_file: second argument must be string",
1074 ))
1075 }
1076 };
1077
1078 match std::fs::write(path, content) {
1079 Ok(_) => Ok(Value::Unit),
1080 Err(e) => Ok(Value::Result(
1081 false,
1082 Box::new(Value::String(format!("Failed to read file: {}", e))),
1083 )),
1084 }
1085 });
1086
1087 self.define_native("split", |_env, args| {
1089 if args.len() != 2 {
1090 return Err(KoreError::runtime(
1091 "split: expected 2 arguments (string, delimiter)",
1092 ));
1093 }
1094 let s = match &args[0] {
1095 Value::String(s) => s.clone(),
1096 _ => return Err(KoreError::runtime("split: first argument must be a string")),
1097 };
1098 let delim = match &args[1] {
1099 Value::String(s) => s.clone(),
1100 _ => {
1101 return Err(KoreError::runtime(
1102 "split: second argument must be a string",
1103 ))
1104 }
1105 };
1106 let parts: Vec<Value> = if delim.is_empty() {
1108 s.chars().map(|c| Value::String(c.to_string())).collect()
1109 } else {
1110 s.split(&delim)
1111 .map(|p| Value::String(p.to_string()))
1112 .collect()
1113 };
1114 Ok(Value::Array(Arc::new(RwLock::new(parts))))
1115 });
1116
1117 self.define_native("join", |_env, args| {
1118 if args.len() != 2 {
1119 return Err(KoreError::runtime(
1120 "join: expected 2 arguments (array, delimiter)",
1121 ));
1122 }
1123 let arr = match &args[0] {
1124 Value::Array(a) => a.read().unwrap().clone(),
1125 _ => return Err(KoreError::runtime("join: first argument must be an array")),
1126 };
1127 let delim = match &args[1] {
1128 Value::String(s) => s.clone(),
1129 _ => return Err(KoreError::runtime("join: second argument must be a string")),
1130 };
1131 let parts: Vec<String> = arr.iter().map(|v| format!("{}", v)).collect();
1132 Ok(Value::String(parts.join(&delim)))
1133 });
1134
1135 self.define_native("trim", |_env, args| {
1136 if args.len() != 1 {
1137 return Err(KoreError::runtime("trim: expected 1 argument (string)"));
1138 }
1139 match &args[0] {
1140 Value::String(s) => Ok(Value::String(s.trim().to_string())),
1141 _ => Err(KoreError::runtime("trim: argument must be a string")),
1142 }
1143 });
1144
1145 self.define_native("upper", |_env, args| {
1146 if args.len() != 1 {
1147 return Err(KoreError::runtime("upper: expected 1 argument (string)"));
1148 }
1149 match &args[0] {
1150 Value::String(s) => Ok(Value::String(s.to_uppercase())),
1151 _ => Err(KoreError::runtime("upper: argument must be a string")),
1152 }
1153 });
1154
1155 self.define_native("lower", |_env, args| {
1156 if args.len() != 1 {
1157 return Err(KoreError::runtime("lower: expected 1 argument (string)"));
1158 }
1159 match &args[0] {
1160 Value::String(s) => Ok(Value::String(s.to_lowercase())),
1161 _ => Err(KoreError::runtime("lower: argument must be a string")),
1162 }
1163 });
1164
1165 self.define_native("contains", |_env, args| {
1166 if args.len() != 2 {
1167 return Err(KoreError::runtime(
1168 "contains: expected 2 arguments (string, pattern)",
1169 ));
1170 }
1171 let s = match &args[0] {
1172 Value::String(s) => s.clone(),
1173 Value::Array(arr) => {
1174 let needle = &args[1];
1176 return Ok(Value::Bool(arr.read().unwrap().iter().any(|v| {
1177 match (v, needle) {
1178 (Value::Int(n1), Value::Int(n2)) => n1 == n2,
1179 (Value::String(s1), Value::String(s2)) => s1 == s2,
1180 (Value::Bool(b1), Value::Bool(b2)) => b1 == b2,
1181 _ => false,
1182 }
1183 })));
1184 }
1185 _ => {
1186 return Err(KoreError::runtime(
1187 "contains: first argument must be a string or array",
1188 ))
1189 }
1190 };
1191 let sub = match &args[1] {
1192 Value::String(s) => s.clone(),
1193 _ => {
1194 return Err(KoreError::runtime(
1195 "contains: second argument must be a string",
1196 ))
1197 }
1198 };
1199 Ok(Value::Bool(s.contains(&sub)))
1200 });
1201
1202 self.define_native("starts_with", |_env, args| {
1203 if args.len() != 2 {
1204 return Err(KoreError::runtime("starts_with: expected 2 arguments"));
1205 }
1206 let s = match &args[0] {
1207 Value::String(s) => s,
1208 _ => return Err(KoreError::runtime("expected string")),
1209 };
1210 let sub = match &args[1] {
1211 Value::String(s) => s,
1212 _ => return Err(KoreError::runtime("expected string")),
1213 };
1214 Ok(Value::Bool(s.starts_with(sub)))
1215 });
1216
1217 self.define_native("ends_with", |_env, args| {
1218 if args.len() != 2 {
1219 return Err(KoreError::runtime("ends_with: expected 2 arguments"));
1220 }
1221 let s = match &args[0] {
1222 Value::String(s) => s,
1223 _ => return Err(KoreError::runtime("expected string")),
1224 };
1225 let sub = match &args[1] {
1226 Value::String(s) => s,
1227 _ => return Err(KoreError::runtime("expected string")),
1228 };
1229 Ok(Value::Bool(s.ends_with(sub)))
1230 });
1231
1232 self.define_native("replace", |_env, args| {
1233 if args.len() != 3 {
1234 return Err(KoreError::runtime(
1235 "replace: expected 3 arguments (string, from, to)",
1236 ));
1237 }
1238 let s = match &args[0] {
1239 Value::String(s) => s,
1240 _ => return Err(KoreError::runtime("expected string")),
1241 };
1242 let from = match &args[1] {
1243 Value::String(s) => s,
1244 _ => return Err(KoreError::runtime("expected string")),
1245 };
1246 let to = match &args[2] {
1247 Value::String(s) => s,
1248 _ => return Err(KoreError::runtime("expected string")),
1249 };
1250 Ok(Value::String(s.replace(from, to)))
1251 });
1252
1253 self.define_native("char_at", |_env, args| {
1254 if args.len() != 2 {
1255 return Err(KoreError::runtime("char_at: expected 2 arguments"));
1256 }
1257 let s = match &args[0] {
1258 Value::String(s) => s,
1259 _ => return Err(KoreError::runtime("expected string")),
1260 };
1261 let idx = match &args[1] {
1262 Value::Int(n) => *n as usize,
1263 _ => return Err(KoreError::runtime("expected int")),
1264 };
1265 match s.chars().nth(idx) {
1266 Some(c) => Ok(Value::String(c.to_string())),
1267 None => Ok(Value::None),
1268 }
1269 });
1270
1271 self.define_native("substring", |_env, args| {
1272 if args.len() < 2 || args.len() > 3 {
1273 return Err(KoreError::runtime(
1274 "substring: expected 2-3 arguments (string, start, [end])",
1275 ));
1276 }
1277 let s = match &args[0] {
1278 Value::String(s) => s.clone(),
1279 _ => {
1280 return Err(KoreError::runtime(
1281 "substring: first argument must be a string",
1282 ))
1283 }
1284 };
1285 let start = match &args[1] {
1286 Value::Int(n) => *n as usize,
1287 _ => {
1288 return Err(KoreError::runtime(
1289 "substring: second argument must be an integer",
1290 ))
1291 }
1292 };
1293 let end = if args.len() == 3 {
1294 match &args[2] {
1295 Value::Int(n) => *n as usize,
1296 _ => {
1297 return Err(KoreError::runtime(
1298 "substring: third argument must be an integer",
1299 ))
1300 }
1301 }
1302 } else {
1303 s.len()
1304 };
1305 let chars: String = s.chars().skip(start).take(end - start).collect();
1306 Ok(Value::String(chars))
1307 });
1308
1309 self.define_native("send", |_env, args| {
1312 if args.len() < 2 {
1313 return Err(KoreError::runtime(
1314 "send: expected at least 2 arguments (actor, msg_name)",
1315 ));
1316 }
1317 let actor_ref = match &args[0] {
1318 Value::ActorRef(r) => r,
1319 _ => return Err(KoreError::runtime("send: first argument must be actor ref")),
1320 };
1321 let msg_name = match &args[1] {
1322 Value::String(s) => s.clone(),
1323 _ => {
1324 return Err(KoreError::runtime(
1325 "send: second argument must be message name",
1326 ))
1327 }
1328 };
1329
1330 let msg_args = args[2..].to_vec();
1331
1332 let _ = actor_ref.sender.send(Message {
1333 name: msg_name,
1334 args: msg_args,
1335 });
1336
1337 Ok(Value::Unit)
1338 });
1339
1340 self.define_native("sleep", |_env, args| {
1341 if args.len() != 1 {
1342 return Err(KoreError::runtime("sleep: expected 1 argument (ms)"));
1343 }
1344 let ms = match args[0] {
1345 Value::Int(i) => i as u64,
1346 _ => return Err(KoreError::runtime("sleep: expected int")),
1347 };
1348 std::thread::sleep(std::time::Duration::from_millis(ms));
1349 Ok(Value::Unit)
1350 });
1351
1352 self.define_native("time", |_env, _args| {
1354 use std::time::{SystemTime, UNIX_EPOCH};
1355 let now = SystemTime::now()
1356 .duration_since(UNIX_EPOCH)
1357 .unwrap_or_default();
1358 Ok(Value::Float(now.as_secs_f64()))
1359 });
1360
1361 self.define_native("exit", |_env, args| {
1362 let code = if args.len() > 0 {
1363 match args[0] {
1364 Value::Int(n) => n as i32,
1365 _ => 0,
1366 }
1367 } else {
1368 0
1369 };
1370 std::process::exit(code);
1371 });
1372
1373 self.define_native("env", |_env, args| {
1374 if args.len() != 1 {
1375 return Err(KoreError::runtime("env: expected 1 argument"));
1376 }
1377 match &args[0] {
1378 Value::String(key) => match std::env::var(key) {
1379 Ok(v) => Ok(Value::String(v)),
1380 Err(_) => Ok(Value::None),
1381 },
1382 _ => Err(KoreError::runtime("env: expected string key")),
1383 }
1384 });
1385
1386 self.define_native("assert", |_env, args| {
1387 if args.len() < 1 {
1388 return Err(KoreError::runtime("assert: expected condition"));
1389 }
1390 match &args[0] {
1391 Value::Bool(true) => Ok(Value::Unit),
1392 _ => {
1393 let msg = if args.len() > 1 {
1394 format!("{}", args[1])
1395 } else {
1396 "Assertion failed".to_string()
1397 };
1398 Err(KoreError::runtime(msg))
1399 }
1400 }
1401 });
1402
1403 self.define_native("panic", |_env, args| {
1404 let msg = if args.len() > 0 {
1405 format!("{}", args[0])
1406 } else {
1407 "Panic".to_string()
1408 };
1409 Err(KoreError::runtime(msg))
1410 });
1411
1412 self.define_native("dbg", |_env, args| {
1414 for arg in args {
1415 println!("[DEBUG] {:?}", arg);
1416 }
1417 Ok(Value::Unit)
1418 });
1419
1420 self.define_native("int", |_env, args| {
1422 if args.len() != 1 {
1423 return Err(KoreError::runtime("int: expected 1 argument"));
1424 }
1425 match &args[0] {
1426 Value::Int(n) => Ok(Value::Int(*n)),
1427 Value::Float(n) => Ok(Value::Int(*n as i64)),
1428 Value::String(s) => s
1429 .parse::<i64>()
1430 .map(Value::Int)
1431 .map_err(|_| KoreError::runtime(format!("Cannot parse '{}' as int", s))),
1432 Value::Bool(b) => Ok(Value::Int(if *b { 1 } else { 0 })),
1433 _ => Err(KoreError::runtime("int: cannot convert this type")),
1434 }
1435 });
1436
1437 self.define_native("float", |_env, args| {
1438 if args.len() != 1 {
1439 return Err(KoreError::runtime("float: expected 1 argument"));
1440 }
1441 match &args[0] {
1442 Value::Int(n) => Ok(Value::Float(*n as f64)),
1443 Value::Float(n) => Ok(Value::Float(*n)),
1444 Value::String(s) => s
1445 .parse::<f64>()
1446 .map(Value::Float)
1447 .map_err(|_| KoreError::runtime(format!("Cannot parse '{}' as float", s))),
1448 _ => Err(KoreError::runtime("float: cannot convert this type")),
1449 }
1450 });
1451
1452 self.define_native("str", |_env, args| {
1453 if args.len() != 1 {
1454 return Err(KoreError::runtime("str: expected 1 argument"));
1455 }
1456 Ok(Value::String(format!("{}", &args[0])))
1457 });
1458
1459 self.define_native("to_string", |_env, args| {
1461 if args.len() != 1 {
1462 return Err(KoreError::runtime("to_string: expected 1 argument"));
1463 }
1464 Ok(Value::String(format!("{}", &args[0])))
1465 });
1466
1467 self.define_native("bool", |_env, args| {
1468 if args.len() != 1 {
1469 return Err(KoreError::runtime("bool: expected 1 argument"));
1470 }
1471 let result = match &args[0] {
1472 Value::Bool(b) => *b,
1473 Value::Int(n) => *n != 0,
1474 Value::Float(n) => *n != 0.0,
1475 Value::String(s) => !s.is_empty(),
1476 Value::None => false,
1477 Value::Unit => false,
1478 _ => true,
1479 };
1480 Ok(Value::Bool(result))
1481 });
1482
1483 self.define_native("to_int", |_env, args| {
1485 if args.len() != 1 {
1486 return Err(KoreError::runtime("to_int: expected 1 argument"));
1487 }
1488 match &args[0] {
1489 Value::Int(n) => Ok(Value::Int(*n)),
1490 Value::Float(n) => Ok(Value::Int(*n as i64)),
1491 Value::String(s) => s
1492 .parse::<i64>()
1493 .map(Value::Int)
1494 .map_err(|_| KoreError::runtime(format!("Cannot parse '{}' as int", s))),
1495 Value::Bool(b) => Ok(Value::Int(if *b { 1 } else { 0 })),
1496 _ => Err(KoreError::runtime("to_int: cannot convert this type")),
1497 }
1498 });
1499
1500 self.define_native("sqrt", |_env, args| {
1502 if args.len() != 1 {
1503 return Err(KoreError::runtime("sqrt: expected 1 argument"));
1504 }
1505 match args[0] {
1506 Value::Int(n) => Ok(Value::Float((n as f64).sqrt())),
1507 Value::Float(n) => Ok(Value::Float(n.sqrt())),
1508 _ => Err(KoreError::runtime("sqrt: expected number")),
1509 }
1510 });
1511
1512 self.define_native("sin", |_env, args| {
1513 if args.len() != 1 {
1514 return Err(KoreError::runtime("sin: expected 1 argument"));
1515 }
1516 match args[0] {
1517 Value::Int(n) => Ok(Value::Float((n as f64).sin())),
1518 Value::Float(n) => Ok(Value::Float(n.sin())),
1519 _ => Err(KoreError::runtime("sin: expected number")),
1520 }
1521 });
1522
1523 self.define_native("cos", |_env, args| {
1524 if args.len() != 1 {
1525 return Err(KoreError::runtime("cos: expected 1 argument"));
1526 }
1527 match args[0] {
1528 Value::Int(n) => Ok(Value::Float((n as f64).cos())),
1529 Value::Float(n) => Ok(Value::Float(n.cos())),
1530 _ => Err(KoreError::runtime("cos: expected number")),
1531 }
1532 });
1533
1534 self.define_native("tan", |_env, args| {
1535 if args.len() != 1 {
1536 return Err(KoreError::runtime("tan: expected 1 argument"));
1537 }
1538 match args[0] {
1539 Value::Int(n) => Ok(Value::Float((n as f64).tan())),
1540 Value::Float(n) => Ok(Value::Float(n.tan())),
1541 _ => Err(KoreError::runtime("tan: expected number")),
1542 }
1543 });
1544
1545 self.define_native("read_line", |_env, _args| {
1547 use std::io::{self, BufRead};
1548 let stdin = io::stdin();
1549 let mut line = String::new();
1550 stdin.lock().read_line(&mut line).ok();
1551 Ok(Value::String(line.trim_end().to_string()))
1552 });
1553
1554 self.define_native("py_eval", |env, args| {
1556 if args.len() != 1 {
1557 return Err(KoreError::runtime("py_eval: expected 1 argument (code)"));
1558 }
1559 let code = match &args[0] {
1560 Value::String(s) => s,
1561 _ => return Err(KoreError::runtime("py_eval: expected string")),
1562 };
1563
1564 let scope = env.python_scope.as_ref().unwrap();
1565
1566 Python::with_gil(|py| {
1567 let locals = scope.as_ref(py).downcast::<PyDict>().unwrap();
1568 let result = py
1569 .eval(code, None, Some(locals))
1570 .map_err(|e| KoreError::runtime(format!("Python Error: {}", e)))?;
1571 py_to_value(result)
1572 .map_err(|e| KoreError::runtime(format!("Conversion Error: {}", e)))
1573 })
1574 });
1575
1576 self.define_native("py_exec", |env, args| {
1577 if args.len() != 1 {
1578 return Err(KoreError::runtime("py_exec: expected 1 argument"));
1579 }
1580 let code = match &args[0] {
1581 Value::String(s) => s,
1582 _ => return Err(KoreError::runtime("py_exec: expected string")),
1583 };
1584
1585 let scope = env.python_scope.as_ref().unwrap();
1586
1587 Python::with_gil(|py| {
1588 let locals = scope.as_ref(py).downcast::<PyDict>().unwrap();
1589 py.run(code, None, Some(locals))
1590 .map_err(|e| KoreError::runtime(format!("Python Error: {}", e)))?;
1591 Ok(Value::Unit)
1592 })
1593 });
1594
1595 self.define_native("py_import", |env, args| {
1596 if args.len() != 1 {
1597 return Err(KoreError::runtime("py_import: expected 1 argument"));
1598 }
1599 let module_name = match &args[0] {
1600 Value::String(s) => s,
1601 _ => return Err(KoreError::runtime("py_import: argument must be string")),
1602 };
1603
1604 let scope = env.python_scope.as_ref().unwrap();
1605
1606 Python::with_gil(|py| {
1607 let locals = scope.as_ref(py).downcast::<PyDict>().unwrap();
1608 let module = py
1609 .import(module_name.as_str())
1610 .map_err(|e| KoreError::runtime(format!("Python error: {}", e)))?;
1611
1612 locals
1614 .set_item(module_name, module)
1615 .map_err(|e| KoreError::runtime(format!("Failed to set module: {}", e)))?;
1616
1617 py_to_value(module)
1618 .map_err(|e| KoreError::runtime(format!("Conversion Error: {}", e)))
1619 })
1620 });
1621
1622 self.define_native("file_exists", |_env, args| {
1623 if args.len() != 1 {
1624 return Err(KoreError::runtime("file_exists: expected 1 argument"));
1625 }
1626 match &args[0] {
1627 Value::String(path) => Ok(Value::Bool(std::path::Path::new(path).exists())),
1628 _ => Err(KoreError::runtime("file_exists: path must be string")),
1629 }
1630 });
1631
1632 self.define_native("block_on", |env, args| {
1636 if args.len() != 1 {
1637 return Err(KoreError::runtime("block_on: expected 1 argument (future)"));
1638 }
1639
1640 let future_val = args[0].clone();
1641 poll_future_to_completion(env, future_val)
1642 });
1643
1644 self.define_native("spawn_task", |env, args| {
1646 if args.len() != 1 {
1647 return Err(KoreError::runtime(
1648 "spawn_task: expected 1 argument (future)",
1649 ));
1650 }
1651
1652 let future_val = args[0].clone();
1655 poll_future_to_completion(env, future_val)
1656 });
1657
1658 self.define_native("poll_once", |env, args| {
1660 if args.len() != 1 {
1661 return Err(KoreError::runtime(
1662 "poll_once: expected 1 argument (future)",
1663 ));
1664 }
1665
1666 poll_future_once(env, args[0].clone())
1667 });
1668
1669 self.define_native("is_ready", |_env, args| {
1671 if args.len() != 1 {
1672 return Err(KoreError::runtime("is_ready: expected 1 argument"));
1673 }
1674
1675 match &args[0] {
1676 Value::Poll(ready, _) => Ok(Value::Bool(*ready)),
1677 Value::EnumVariant(_, variant, _) => Ok(Value::Bool(variant == "Ready")),
1678 _ => Ok(Value::Bool(false)),
1679 }
1680 });
1681
1682 self.define_native("is_pending", |_env, args| {
1684 if args.len() != 1 {
1685 return Err(KoreError::runtime("is_pending: expected 1 argument"));
1686 }
1687
1688 match &args[0] {
1689 Value::Poll(ready, _) => Ok(Value::Bool(!*ready)),
1690 Value::EnumVariant(_, variant, _) => Ok(Value::Bool(variant == "Pending")),
1691 _ => Ok(Value::Bool(false)),
1692 }
1693 });
1694
1695 self.define_native("unwrap_ready", |_env, args| {
1697 if args.len() != 1 {
1698 return Err(KoreError::runtime("unwrap_ready: expected 1 argument"));
1699 }
1700
1701 match &args[0] {
1702 Value::Poll(true, Some(val)) => Ok(*val.clone()),
1703 Value::Poll(true, None) => Ok(Value::Unit),
1704 Value::Poll(false, _) => {
1705 Err(KoreError::runtime("unwrap_ready: called on Poll::Pending"))
1706 }
1707 Value::EnumVariant(_, variant, fields) if variant == "Ready" => {
1708 if fields.is_empty() {
1709 Ok(Value::Unit)
1710 } else {
1711 Ok(fields[0].clone())
1712 }
1713 }
1714 Value::EnumVariant(_, variant, _) if variant == "Pending" => {
1715 Err(KoreError::runtime("unwrap_ready: called on Poll::Pending"))
1716 }
1717 _ => Err(KoreError::runtime("unwrap_ready: expected Poll value")),
1718 }
1719 });
1720 }
1721
1722 fn define_native(&mut self, name: &str, func: fn(&mut Env, Vec<Value>) -> KoreResult<Value>) {
1723 self.scopes[0].insert(name.to_string(), Value::NativeFn(name.to_string(), func));
1724 }
1725
1726 fn define(&mut self, name: String, value: Value) {
1727 self.scopes.last_mut().unwrap().insert(name, value);
1728 }
1729
1730 fn assign(&mut self, name: &str, value: Value) -> KoreResult<()> {
1731 for scope in self.scopes.iter_mut().rev() {
1732 if scope.contains_key(name) {
1733 scope.insert(name.to_string(), value);
1734 return Ok(());
1735 }
1736 }
1737 Err(KoreError::runtime(format!("Undefined variable '{}'", name)))
1738 }
1739
1740 fn lookup(&self, name: &str) -> Option<&Value> {
1741 for scope in self.scopes.iter().rev() {
1742 if let Some(v) = scope.get(name) {
1743 return Some(v);
1744 }
1745 }
1746 None
1747 }
1748
1749 fn push_scope(&mut self) {
1750 self.scopes.push(HashMap::new());
1751 }
1752
1753 fn pop_scope(&mut self) {
1754 self.scopes.pop();
1755 }
1756}
1757
1758pub fn interpret(program: &TypedProgram) -> KoreResult<Value> {
1762 let mut env = Env::new();
1763
1764 for item in &program.items {
1766 match item {
1767 crate::types::TypedItem::Use(u) => {
1768 load_module(&mut env, &u.ast)?;
1770 }
1771 crate::types::TypedItem::Function(f) => {
1772 env.functions.insert(f.ast.name.clone(), f.ast.clone());
1773 env.define(f.ast.name.clone(), Value::Function(f.ast.name.clone()));
1774 }
1775 crate::types::TypedItem::Actor(a) => {
1776 env.actor_defs.insert(a.ast.name.clone(), a.ast.clone());
1777 }
1778 crate::types::TypedItem::Component(c) => {
1779 env.components.insert(c.ast.name.clone(), c.ast.clone());
1780 }
1781 crate::types::TypedItem::Const(c) => {
1782 let val = eval_expr(&mut env, &c.ast.value)?;
1783 env.define(c.ast.name.clone(), val);
1784 }
1785 crate::types::TypedItem::Impl(i) => {
1786 let type_name = match &i.ast.target_type {
1788 Type::Named { name, .. } => name.clone(),
1789 _ => continue,
1790 };
1791 let type_methods = env.methods.entry(type_name).or_insert_with(HashMap::new);
1793 for method in &i.ast.methods {
1794 type_methods.insert(method.name.clone(), method.clone());
1795 }
1796 }
1797 crate::types::TypedItem::Comptime(_) => {} _ => {}
1799 }
1800 }
1801
1802 if let Some(main_fn) = env.functions.get("main").cloned() {
1804 eval_block(&mut env, &main_fn.body)
1805 } else {
1806 Ok(Value::Unit)
1807 }
1808}
1809
1810fn load_module(env: &mut Env, u: &Use) -> KoreResult<()> {
1811 let path = u.path.join("/");
1812
1813 if path == "stdlib" {
1815 return Ok(());
1816 }
1817
1818 let file_path = if path.starts_with("std/") || path.starts_with("stdlib/") {
1820 let module_name = path
1822 .trim_start_matches("std/")
1823 .trim_start_matches("stdlib/");
1824
1825 let possible_paths = [
1827 format!("stdlib/{}.kr", module_name),
1828 format!("../stdlib/{}.kr", module_name),
1829 format!("examples/../stdlib/{}.kr", module_name),
1830 ];
1831
1832 possible_paths
1833 .into_iter()
1834 .map(|p| std::path::PathBuf::from(p))
1835 .find(|p| p.exists())
1836 .ok_or_else(|| {
1837 KoreError::runtime(format!("Stdlib module not found: {}", module_name))
1838 })?
1839 } else {
1840 let base_path = std::path::Path::new(&path);
1842
1843 let possible_paths = [
1845 base_path.with_extension("kr"), std::path::PathBuf::from(format!("src/{}.kr", path)), std::path::PathBuf::from(format!("{}.kr", path)), base_path.with_extension("god"), ];
1850
1851 possible_paths
1852 .iter()
1853 .find(|p| p.exists())
1854 .cloned()
1855 .ok_or_else(|| {
1856 KoreError::runtime(format!(
1857 "Module not found: {} (tried: {:?})",
1858 path,
1859 possible_paths
1860 .iter()
1861 .map(|p| p.display().to_string())
1862 .collect::<Vec<_>>()
1863 ))
1864 })?
1865 };
1866
1867 let source = std::fs::read_to_string(&file_path)
1868 .map_err(|e| KoreError::runtime(format!("Failed to read module {}: {}", path, e)))?;
1869
1870 let lexer = Lexer::new(&source);
1871 let tokens = lexer.tokenize()?;
1872 let mut parser = Parser::new(&tokens);
1873 let program = parser.parse()?;
1874
1875 for item in program.items {
1877 match item {
1878 Item::Function(f) => {
1879 env.functions.insert(f.name.clone(), f.clone());
1880 env.define(f.name.clone(), Value::Function(f.name.clone()));
1881 }
1882 Item::Component(c) => {
1883 env.components.insert(c.name.clone(), c);
1884 }
1885 Item::Struct(s) => {
1886 let field_names = s.fields.iter().map(|f| f.name.clone()).collect();
1887 env.define(
1888 s.name.clone(),
1889 Value::StructConstructor(s.name.clone(), field_names),
1890 );
1891 }
1892 Item::Enum(e) => {
1893 for variant in &e.variants {
1895 let variant_name = format!("{}::{}", e.name, variant.name);
1896 env.define(
1897 variant_name,
1898 Value::Function(format!("{}::{}", e.name, variant.name)),
1899 );
1900 }
1901 }
1902 Item::Actor(a) => {
1903 env.actor_defs.insert(a.name.clone(), a);
1904 }
1905 Item::Const(c) => {
1906 let val = eval_expr(env, &c.value)?;
1907 env.define(c.name.clone(), val);
1908 }
1909 Item::Impl(i) => {
1910 if let Type::Named { name, .. } = &i.target_type {
1911 let lowered_fns: Vec<(String, Function)> = i
1913 .methods
1914 .iter()
1915 .map(|m| (format!("{}_{}", name, m.name), m.clone()))
1916 .collect();
1917
1918 for (lowered_name, method) in lowered_fns {
1920 env.functions.insert(lowered_name.clone(), method);
1921 env.define(lowered_name.clone(), Value::Function(lowered_name));
1922 }
1923
1924 let type_methods = env.methods.entry(name.clone()).or_insert_with(HashMap::new);
1926 for method in &i.methods {
1927 type_methods.insert(method.name.clone(), method.clone());
1928 }
1929 }
1930 }
1931 Item::Use(u) => {
1932 load_module(env, &u)?;
1933 }
1934 _ => {}
1935 }
1936 }
1937
1938 Ok(())
1939}
1940
1941pub fn eval_block(env: &mut Env, block: &Block) -> KoreResult<Value> {
1942 for stmt in &block.stmts {
1943 let result = eval_stmt(env, stmt)?;
1944 match &result {
1946 Value::Return(_) | Value::Break(_) | Value::Continue => return Ok(result),
1947 _ => {}
1948 }
1949 }
1950 Ok(Value::Unit)
1951}
1952
1953fn eval_stmt(env: &mut Env, stmt: &Stmt) -> KoreResult<Value> {
1954 match stmt {
1955 Stmt::Expr(expr) => {
1956 let val = eval_expr(env, expr)?;
1957 match &val {
1959 Value::Return(_) | Value::Break(_) | Value::Continue => return Ok(val),
1960 _ => {}
1961 }
1962 Ok(Value::Unit)
1963 }
1964 Stmt::Let { pattern, value, .. } => {
1965 let val = if let Some(expr) = value {
1966 eval_expr(env, expr)?
1967 } else {
1968 Value::None
1969 };
1970 if let Value::Return(_) = val {
1971 return Ok(val);
1972 }
1973
1974 if let Pattern::Binding { name, .. } = pattern {
1976 env.define(name.clone(), val);
1977 }
1978 Ok(Value::Unit)
1979 }
1980 Stmt::Return(expr, _) => {
1981 let val = if let Some(e) = expr {
1982 eval_expr(env, e)?
1983 } else {
1984 Value::Unit
1985 };
1986 if let Value::Return(_) = val {
1987 return Ok(val);
1988 }
1989 Ok(Value::Return(Box::new(val)))
1990 }
1991 Stmt::For {
1992 binding,
1993 iter,
1994 body,
1995 ..
1996 } => {
1997 let iter_val = eval_expr(env, iter)?;
1998 if let Value::Return(_) = iter_val {
1999 return Ok(iter_val);
2000 }
2001
2002 if let Value::Array(arr) = iter_val {
2003 let arr = arr.read().unwrap().clone();
2004 for val in arr.iter() {
2005 env.push_scope();
2006 if let Pattern::Binding { name, .. } = binding {
2007 env.define(name.clone(), val.clone());
2008 }
2009 let res = eval_block(env, body)?;
2010 env.pop_scope();
2011
2012 match res {
2013 Value::Return(_) => return Ok(res),
2014 Value::Break(_) => break,
2015 Value::Continue => continue,
2016 _ => {}
2017 }
2018 }
2019 } else if let Value::String(s) = iter_val {
2020 for c in s.chars() {
2021 env.push_scope();
2022 if let Pattern::Binding { name, .. } = binding {
2023 env.define(name.clone(), Value::String(c.to_string()));
2024 }
2025 let res = eval_block(env, body)?;
2026 env.pop_scope();
2027
2028 match res {
2029 Value::Return(_) => return Ok(res),
2030 Value::Break(_) => break,
2031 Value::Continue => continue,
2032 _ => {}
2033 }
2034 }
2035 }
2036 Ok(Value::Unit)
2037 }
2038 Stmt::While {
2039 condition, body, ..
2040 } => {
2041 loop {
2042 let cond = eval_expr(env, condition)?;
2043 if let Value::Return(_) = cond {
2044 return Ok(cond);
2045 }
2046 if let Value::Bool(false) = cond {
2047 break;
2048 }
2049
2050 let res = eval_block(env, body)?;
2051 match res {
2052 Value::Return(_) => return Ok(res),
2053 Value::Break(_) => break,
2054 Value::Continue => continue,
2055 _ => {}
2056 }
2057 }
2058 Ok(Value::Unit)
2059 }
2060 Stmt::Loop { body, .. } => loop {
2061 let res = eval_block(env, body)?;
2062 match res {
2063 Value::Return(_) => return Ok(res),
2064 Value::Break(val) => {
2065 return Ok(val.map(|v| *v).unwrap_or(Value::Unit));
2066 }
2067 Value::Continue => continue,
2068 _ => {}
2069 }
2070 },
2071 Stmt::Break(expr, _) => {
2072 let val = if let Some(e) = expr {
2073 Some(Box::new(eval_expr(env, e)?))
2074 } else {
2075 None
2076 };
2077 Ok(Value::Break(val))
2078 }
2079 Stmt::Continue(_) => Ok(Value::Continue),
2080 _ => Ok(Value::Unit),
2081 }
2082}
2083
2084fn eval_assignment(env: &mut Env, target: &Expr, value: Value) -> KoreResult<()> {
2085 match target {
2086 Expr::Ident(name, _) => env.assign(name, value),
2087 Expr::Field { object, field, .. } => {
2088 let obj_val = eval_expr(env, object)?;
2089 if let Value::Struct(_, fields) = obj_val {
2090 fields.write().unwrap().insert(field.clone(), value);
2091 } else if let Value::ActorRef(r) = obj_val {
2092 if let Some(self_id) = env.self_actor_id {
2093 if self_id == r.id {
2094 return env.assign(field, value);
2095 }
2096 }
2097 return Err(KoreError::runtime("Cannot assign to remote actor fields"));
2098 } else {
2099 return Err(KoreError::runtime(
2100 "Field assignment only supported on structs",
2101 ));
2102 }
2103 Ok(())
2104 }
2105 Expr::Index { object, index, .. } => {
2106 let obj_val = eval_expr(env, object)?;
2107 let idx_val = eval_expr(env, index)?;
2108 match (obj_val, idx_val) {
2109 (Value::Array(arr), Value::Int(i)) => {
2110 let i = i as usize;
2111 let mut arr = arr.write().unwrap();
2112 if i < arr.len() {
2113 arr[i] = value;
2114 } else {
2115 return Err(KoreError::runtime("Index out of bounds"));
2116 }
2117 }
2118 _ => {
2119 return Err(KoreError::runtime(
2120 "Index assignment only supported on arrays with int index",
2121 ))
2122 }
2123 }
2124 Ok(())
2125 }
2126 _ => Err(KoreError::runtime("Invalid assignment target")),
2127 }
2128}
2129
2130pub fn eval_expr(env: &mut Env, expr: &Expr) -> KoreResult<Value> {
2131 match expr {
2132 Expr::MethodCall {
2133 receiver,
2134 method,
2135 args,
2136 span: _,
2137 } => {
2138 let obj_val = eval_expr(env, receiver)?;
2140 if let Value::Return(_) = obj_val {
2141 return Ok(obj_val);
2142 }
2143
2144 let mut arg_vals = Vec::new();
2146 for arg in args {
2147 let v = eval_expr(env, &arg.value)?;
2148 if let Value::Return(_) = v {
2149 return Ok(v);
2150 }
2151 arg_vals.push(v);
2152 }
2153
2154 match obj_val {
2155 Value::Struct(ref name, _) | Value::Future(ref name, _) => {
2157 let func_name = format!("{}_{}", name, method);
2158
2159 if let Some(func) = env.functions.get(&func_name).cloned() {
2160 env.push_scope();
2162 env.define("self".to_string(), obj_val);
2163
2164 let param_iter = if func
2166 .params
2167 .first()
2168 .map(|p| p.name == "self")
2169 .unwrap_or(false)
2170 {
2171 func.params.iter().skip(1)
2172 } else {
2173 func.params.iter().skip(0)
2174 };
2175
2176 if param_iter.len() != arg_vals.len() {
2177 return Err(KoreError::runtime(format!(
2178 "Method {} arg mismatch",
2179 func_name
2180 )));
2181 }
2182
2183 for (param, arg) in param_iter.zip(arg_vals.into_iter()) {
2184 env.define(param.name.clone(), arg);
2185 }
2186
2187 let result = eval_block(env, &func.body)?;
2188 env.pop_scope();
2189
2190 match result {
2191 Value::Return(v) => Ok(*v),
2192 v => Ok(v),
2193 }
2194 } else {
2195 Err(KoreError::runtime(format!(
2196 "Method {} not found for type {}",
2197 method, name
2198 )))
2199 }
2200 }
2201
2202 Value::Array(_) => {
2204 match method.as_str() {
2206 "push" => {
2207 if arg_vals.len() != 1 {
2208 return Err(KoreError::runtime("push expects 1 argument"));
2209 }
2210 if let Value::Array(arr) = obj_val {
2211 arr.write().unwrap().push(arg_vals[0].clone());
2212 Ok(Value::Unit)
2213 } else {
2214 unreachable!()
2215 }
2216 }
2217 "len" => {
2218 if let Value::Array(arr) = obj_val {
2219 Ok(Value::Int(arr.read().unwrap().len() as i64))
2220 } else {
2221 unreachable!()
2222 }
2223 }
2224 _ => Err(KoreError::runtime(format!(
2225 "Method {} not found on Array",
2226 method
2227 ))),
2228 }
2229 }
2230
2231 _ => Err(KoreError::runtime(format!(
2232 "Method calls not supported on this type: {:?}",
2233 obj_val
2234 ))),
2235 }
2236 }
2237
2238 Expr::Call { callee, args, .. } => {
2239 if let Expr::Field { object, field, .. } = callee.as_ref() {
2241 if let Expr::Ident(type_name, _) = object.as_ref() {
2243 let method = env
2245 .methods
2246 .get(type_name)
2247 .and_then(|m| m.get(field))
2248 .cloned();
2249
2250 if let Some(method) = method {
2251 let mut arg_vals = Vec::new();
2253 for arg in args {
2254 let v = eval_expr(env, &arg.value)?;
2255 if let Value::Return(_) = v {
2256 return Ok(v);
2257 }
2258 arg_vals.push(v);
2259 }
2260
2261 env.push_scope();
2263 for (param, arg) in method.params.iter().zip(arg_vals.into_iter()) {
2264 env.define(param.name.clone(), arg);
2265 }
2266 let result = eval_block(env, &method.body);
2267 env.pop_scope();
2268
2269 return match result? {
2270 Value::Return(v) => Ok(*v),
2271 v => Ok(v),
2272 };
2273 }
2274 }
2275
2276 let obj_val = eval_expr(env, object)?;
2278 if let Value::Return(_) = obj_val {
2279 return Ok(obj_val);
2280 }
2281
2282 let type_name = match &obj_val {
2284 Value::Struct(name, _) => Some(name.clone()),
2285 _ => None,
2286 };
2287
2288 if let Some(type_name) = type_name {
2289 let method = env
2291 .methods
2292 .get(&type_name)
2293 .and_then(|m| m.get(field))
2294 .cloned();
2295
2296 if let Some(method) = method {
2297 let mut arg_vals = Vec::new();
2299 for arg in args {
2300 let v = eval_expr(env, &arg.value)?;
2301 if let Value::Return(_) = v {
2302 return Ok(v);
2303 }
2304 arg_vals.push(v);
2305 }
2306
2307 env.push_scope();
2309 env.define("self".to_string(), obj_val);
2310
2311 let params_iter = if let Some(first) = method.params.first() {
2313 if first.name == "self" {
2314 method.params.iter().skip(1)
2315 } else {
2316 method.params.iter().skip(0)
2317 }
2318 } else {
2319 method.params.iter().skip(0)
2320 };
2321
2322 for (param, arg) in params_iter.zip(arg_vals.into_iter()) {
2323 env.define(param.name.clone(), arg);
2324 }
2325 let result = eval_block(env, &method.body);
2326 env.pop_scope();
2327
2328 return match result? {
2329 Value::Return(v) => Ok(*v),
2330 v => Ok(v),
2331 };
2332 }
2333 }
2334 }
2335
2336 let func_val = {
2338 let v = eval_expr(env, callee)?;
2339 if let Value::Return(_) = v {
2340 return Ok(v);
2341 }
2342 v
2343 };
2344
2345 let mut arg_vals = Vec::new();
2347 for arg in args {
2348 let v = eval_expr(env, &arg.value)?;
2349 if let Value::Return(_) = v {
2350 return Ok(v);
2351 }
2352 arg_vals.push(v);
2353 }
2354
2355 call_function(env, func_val, arg_vals)
2356 }
2357
2358 Expr::Try(inner, _) => {
2359 let val = eval_expr(env, inner)?;
2360 if let Value::Return(_) = val {
2361 return Ok(val);
2362 }
2363 match val {
2364 Value::Result(true, v) => Ok(*v),
2365 Value::Result(false, e) => Ok(Value::Return(Box::new(Value::Result(false, e)))),
2366 _ => Err(KoreError::runtime(
2367 "Type error: expected Result for ? operator",
2368 )),
2369 }
2370 }
2371
2372 Expr::If {
2373 condition,
2374 then_branch,
2375 else_branch,
2376 ..
2377 } => {
2378 let cond = eval_expr(env, condition)?;
2379 if let Value::Return(_) = cond {
2380 return Ok(cond);
2381 }
2382 if let Value::Bool(true) = cond {
2383 eval_block(env, then_branch)
2384 } else if let Some(eb) = else_branch {
2385 match eb.as_ref() {
2386 ElseBranch::Else(block) => eval_block(env, block),
2387 _ => Ok(Value::Unit),
2388 }
2389 } else {
2390 Ok(Value::Unit)
2391 }
2392 }
2393
2394 Expr::Match {
2395 scrutinee, arms, ..
2396 } => {
2397 let val = eval_expr(env, scrutinee)?;
2398 if let Value::Return(_) = val {
2399 return Ok(val);
2400 }
2401
2402 for arm in arms {
2403 if pattern_matches(&arm.pattern, &val) {
2404 env.push_scope();
2405 bind_pattern(env, &arm.pattern, &val);
2406 let res = eval_expr(env, &arm.body)?;
2407 env.pop_scope();
2408 return Ok(res);
2409 }
2410 }
2411 Ok(Value::Unit)
2413 }
2414
2415 Expr::MacroCall { name, args, .. } => {
2416 match name.as_str() {
2418 "vec" => {
2419 let mut vals = Vec::new();
2420 for arg in args {
2421 let v = eval_expr(env, arg)?;
2422 if let Value::Return(_) = v {
2423 return Ok(v);
2424 }
2425 vals.push(v);
2426 }
2427 Ok(Value::Array(Arc::new(RwLock::new(vals))))
2428 }
2429 "format" => {
2430 let mut res = String::new();
2432 for arg in args {
2433 let v = eval_expr(env, arg)?;
2434 res.push_str(&format!("{}", v));
2435 }
2436 Ok(Value::String(res))
2437 }
2438 "type_name" => {
2439 if let Some(arg) = args.first() {
2440 let v = eval_expr(env, arg)?;
2441 let type_name = match v {
2442 Value::Unit => "unit",
2443 Value::Bool(_) => "bool",
2444 Value::Int(_) => "int",
2445 Value::Float(_) => "float",
2446 Value::String(_) => "string",
2447 Value::Array(_) => "array",
2448 Value::Tuple(_) => "tuple",
2449 Value::Struct(name, _) => return Ok(Value::String(name.clone())),
2450 Value::Function(_) => "function",
2451 Value::NativeFn(_, _) => "native_fn",
2452 Value::StructConstructor(_, _) => "struct_constructor",
2453 Value::ActorRef(_) => "actor",
2454 Value::None => "none",
2455 Value::Return(_) => "return",
2456 Value::Result(_, _) => "result",
2457 Value::Closure(_, _, _) => "closure",
2458 Value::JSX(_) => "jsx",
2459 Value::EnumVariant(enum_name, _, _) => {
2460 return Ok(Value::String(enum_name.clone()))
2461 }
2462 Value::Poll(_, _) => "poll",
2463 Value::Future(name, _) => {
2464 return Ok(Value::String(format!("Future<{}>", name)))
2465 }
2466 Value::Break(_) => "break",
2467 Value::Continue => "continue",
2468 };
2469 Ok(Value::String(type_name.to_string()))
2470 } else {
2471 Err(KoreError::runtime("type_name! requires an argument"))
2472 }
2473 }
2474 _ => Err(KoreError::runtime(format!("Unknown macro: {}!", name))),
2475 }
2476 }
2477 Expr::Assign { target, value, .. } => {
2478 let v = eval_expr(env, value)?;
2479 if let Value::Return(_) = v {
2480 return Ok(v);
2481 }
2482 eval_assignment(env, target, v)?;
2483 Ok(Value::Unit)
2484 }
2485 Expr::Int(n, _) => Ok(Value::Int(*n)),
2486 Expr::Float(n, _) => Ok(Value::Float(*n)),
2487 Expr::String(s, _) => Ok(Value::String(s.clone())),
2488 Expr::FString(parts, _) => {
2489 let mut result = String::new();
2490 for part in parts {
2491 let val = eval_expr(env, part)?;
2492 if let Value::Return(_) = val {
2493 return Ok(val);
2494 }
2495 result.push_str(&format!("{}", val));
2496 }
2497 Ok(Value::String(result))
2498 }
2499 Expr::Bool(b, _) => Ok(Value::Bool(*b)),
2500 Expr::None(_) => Ok(Value::None),
2501 Expr::Lambda { params, body, .. } => {
2502 let param_names = params.iter().map(|p| p.name.clone()).collect();
2503 Ok(Value::Closure(
2504 param_names,
2505 body.clone(),
2506 env.scopes.clone(),
2507 ))
2508 }
2509 Expr::Ident(name, _span) => env
2510 .lookup(name)
2511 .cloned()
2512 .ok_or_else(|| KoreError::runtime(format!("Undefined: {}", name))),
2513
2514 Expr::Binary {
2515 left, op, right, ..
2516 } => {
2517 let l = eval_expr(env, left)?;
2518 if let Value::Return(_) = l {
2519 return Ok(l);
2520 }
2521 let r = eval_expr(env, right)?;
2522 if let Value::Return(_) = r {
2523 return Ok(r);
2524 }
2525 eval_binop(*op, l, r)
2526 }
2527
2528 Expr::Unary { op, operand, .. } => {
2529 let v = eval_expr(env, operand)?;
2530 if let Value::Return(_) = v {
2531 return Ok(v);
2532 }
2533 match (op, v) {
2534 (UnaryOp::Neg, Value::Int(n)) => Ok(Value::Int(-n)),
2535 (UnaryOp::Neg, Value::Float(n)) => Ok(Value::Float(-n)),
2536 (UnaryOp::Not, Value::Bool(b)) => Ok(Value::Bool(!b)),
2537 _ => Err(KoreError::runtime("Invalid unary operation")),
2538 }
2539 }
2540
2541 Expr::Array(elements, _) => {
2542 let mut vals = Vec::new();
2543 for elem in elements {
2544 let v = eval_expr(env, elem)?;
2545 if let Value::Return(_) = v {
2546 return Ok(v);
2547 }
2548 vals.push(v);
2549 }
2550 Ok(Value::Array(Arc::new(RwLock::new(vals))))
2551 }
2552
2553 Expr::Index { object, index, .. } => {
2554 let obj = eval_expr(env, object)?;
2555 if let Value::Return(_) = obj {
2556 return Ok(obj);
2557 }
2558 let idx = eval_expr(env, index)?;
2559 if let Value::Return(_) = idx {
2560 return Ok(idx);
2561 }
2562
2563 match (obj, idx) {
2564 (Value::Array(arr), Value::Int(i)) => {
2565 let i = i as usize;
2566 let arr = arr.read().unwrap();
2567 if i < arr.len() {
2568 Ok(arr[i].clone())
2569 } else {
2570 Err(KoreError::runtime(format!("Index out of bounds: {}", i)))
2571 }
2572 }
2573 (Value::String(s), Value::Int(i)) => {
2574 let i = i as usize;
2575 if i < s.len() {
2576 Ok(Value::String(s.chars().nth(i).unwrap().to_string()))
2577 } else {
2578 Err(KoreError::runtime(format!("Index out of bounds: {}", i)))
2579 }
2580 }
2581 _ => Err(KoreError::runtime(
2582 "Index operator requires array/string and int",
2583 )),
2584 }
2585 }
2586
2587 Expr::Struct { name, fields, .. } => {
2589 let mut field_vals = HashMap::new();
2590 for (k, expr) in fields {
2591 let v = eval_expr(env, expr)?;
2592 if let Value::Return(_) = v {
2593 return Ok(v);
2594 }
2595 field_vals.insert(k.clone(), v);
2596 }
2597 Ok(Value::Struct(
2598 name.clone(),
2599 Arc::new(RwLock::new(field_vals)),
2600 ))
2601 }
2602
2603 Expr::JSX(node, _) => eval_jsx(env, node),
2605
2606 Expr::Field { object, field, .. } => {
2607 let obj_val = eval_expr(env, object)?;
2608 if let Value::Return(_) = obj_val {
2609 return Ok(obj_val);
2610 }
2611
2612 match obj_val {
2613 Value::Struct(_, fields) => {
2614 let fields = fields.read().unwrap();
2615 fields
2616 .get(field)
2617 .cloned()
2618 .ok_or_else(|| KoreError::runtime(format!("Field not found: {}", field)))
2619 }
2620 Value::ActorRef(r) => {
2621 if let Some(self_id) = env.self_actor_id {
2623 if self_id == r.id {
2624 return env.lookup(field).cloned().ok_or_else(|| {
2625 KoreError::runtime(format!("Actor field not found: {}", field))
2626 });
2627 }
2628 }
2629
2630 if field == "id" {
2632 return Ok(Value::Int(r.id as i64));
2633 }
2634 Err(KoreError::runtime("Actor fields not accessible"))
2635 }
2636 _ => Err(KoreError::runtime(format!(
2637 "Field access on non-struct value: {:?}",
2638 obj_val
2639 ))),
2640 }
2641 }
2642
2643 Expr::Tuple(elements, _) => {
2644 let mut vals = Vec::new();
2645 for elem in elements {
2646 let v = eval_expr(env, elem)?;
2647 if let Value::Return(_) = v {
2648 return Ok(v);
2649 }
2650 vals.push(v);
2651 }
2652 Ok(Value::Tuple(vals))
2653 }
2654
2655 Expr::Spawn { actor, init, .. } => {
2656 let actor_def = env
2658 .actor_defs
2659 .get(actor)
2660 .cloned()
2661 .ok_or_else(|| KoreError::runtime(format!("Unknown actor: {}", actor)))?;
2662
2663 let mut init_vals = HashMap::new();
2665 for (field, expr) in init {
2666 let v = eval_expr(env, expr)?;
2667 if let Value::Return(_) = v {
2668 return Ok(v);
2669 }
2670 init_vals.insert(field.clone(), v);
2671 }
2672
2673 let (tx, rx) = flume::unbounded();
2675 let id = env.next_actor_id;
2676 env.next_actor_id += 1;
2677 let sender = tx.clone();
2678 env.actors.insert(id, sender.clone());
2679
2680 let functions = env.functions.clone();
2682 let components = env.components.clone();
2683 let actor_defs = env.actor_defs.clone();
2684 let methods = env.methods.clone();
2685 let global_scope = env.scopes.first().cloned().unwrap_or_default();
2686 let actor_name = actor.clone();
2687 let self_sender = tx.clone();
2688
2689 std::thread::spawn(move || {
2690 let mut actor_env = Env {
2691 scopes: vec![global_scope],
2692 functions,
2693 components,
2694 methods,
2695 actors: HashMap::new(),
2696 next_actor_id: 0,
2697 actor_defs,
2698 self_actor_id: Some(id),
2699 python_scope: None,
2700 };
2701
2702 Python::with_gil(|py| {
2704 let locals = PyDict::new(py);
2705 actor_env.python_scope = Some(locals.into());
2706 });
2707
2708 actor_env.register_stdlib();
2709
2710 actor_env.push_scope(); let actor_val = Value::ActorRef(ActorRef {
2714 id,
2715 sender: self_sender,
2716 });
2717 actor_env.define("self".to_string(), actor_val);
2718
2719 for state_decl in &actor_def.state {
2721 if let Some(val) = init_vals.get(&state_decl.name) {
2722 actor_env.define(state_decl.name.clone(), val.clone());
2723 } else {
2724 match eval_expr(&mut actor_env, &state_decl.initial) {
2726 Ok(val) => actor_env.define(state_decl.name.clone(), val),
2727 Err(e) => {
2728 eprintln!("Actor initialization error: {}", e);
2729 return;
2730 }
2731 }
2732 }
2733 }
2734
2735 while let Ok(msg) = rx.recv() {
2737 let mut handled = false;
2739 for handler in &actor_def.handlers {
2740 if handler.message_type == msg.name {
2741 actor_env.push_scope();
2743 for (i, param) in handler.params.iter().enumerate() {
2745 if let Some(val) = msg.args.get(i) {
2746 actor_env.define(param.name.clone(), val.clone());
2747 }
2748 }
2749
2750 if let Err(e) = eval_block(&mut actor_env, &handler.body) {
2751 println!("Error in actor handler {}: {}", handler.message_type, e);
2752 }
2753 actor_env.pop_scope();
2754 handled = true;
2755 break;
2756 }
2757 }
2758 if !handled {
2759 println!(
2760 "Actor {} received unknown message: {}",
2761 actor_name, msg.name
2762 );
2763 }
2764 }
2765 });
2766
2767 Ok(Value::ActorRef(ActorRef { id, sender }))
2768 }
2769
2770 Expr::SendMsg {
2771 target,
2772 message,
2773 data,
2774 ..
2775 } => {
2776 let actor_val = eval_expr(env, target)?;
2777 if let Value::Return(_) = actor_val {
2778 return Ok(actor_val);
2779 }
2780
2781 if let Value::ActorRef(r) = actor_val {
2782 let mut msg_args = Vec::new();
2783 for (_name, expr) in data {
2784 let v = eval_expr(env, expr)?;
2785 msg_args.push(v);
2786 }
2787
2788 let msg = Message {
2789 name: message.clone(),
2790 args: msg_args,
2791 };
2792
2793 let _ = r.sender.send(msg);
2794 Ok(Value::Unit)
2795 } else {
2796 Err(KoreError::runtime("send target must be an actor"))
2797 }
2798 }
2799
2800 Expr::Block(block, _) => eval_block(env, block),
2802
2803 Expr::Return(expr, _) => {
2805 let val = if let Some(e) = expr {
2806 eval_expr(env, e)?
2807 } else {
2808 Value::Unit
2809 };
2810 Ok(Value::Return(Box::new(val)))
2811 }
2812
2813 Expr::Paren(inner, _) => eval_expr(env, inner),
2814
2815 Expr::Await(future_expr, _span) => {
2818 let future_val = eval_expr(env, future_expr)?;
2819 if let Value::Return(_) = future_val {
2820 return Ok(future_val);
2821 }
2822
2823 poll_future_to_completion(env, future_val)
2825 }
2826
2827 Expr::EnumVariant {
2829 enum_name,
2830 variant,
2831 fields,
2832 ..
2833 } => {
2834 if let Some(type_methods) = env.methods.get(enum_name).cloned() {
2837 if let Some(method) = type_methods.get(variant).cloned() {
2838 let arg_vals: Vec<Value> = match fields {
2840 EnumVariantFields::Unit => Vec::new(),
2841 EnumVariantFields::Tuple(exprs) => {
2842 let mut vals = Vec::new();
2843 for e in exprs {
2844 let v = eval_expr(env, e)?;
2845 if let Value::Return(_) = v {
2846 return Ok(v);
2847 }
2848 vals.push(v);
2849 }
2850 vals
2851 }
2852 EnumVariantFields::Struct(named_fields) => {
2853 let mut vals = Vec::new();
2854 for (_, e) in named_fields {
2855 let v = eval_expr(env, e)?;
2856 if let Value::Return(_) = v {
2857 return Ok(v);
2858 }
2859 vals.push(v);
2860 }
2861 vals
2862 }
2863 };
2864
2865 env.push_scope();
2867 for (param, arg) in method.params.iter().zip(arg_vals.into_iter()) {
2868 env.define(param.name.clone(), arg);
2869 }
2870 let result = eval_block(env, &method.body)?;
2871 env.pop_scope();
2872
2873 return match result {
2874 Value::Return(v) => Ok(*v),
2875 v => Ok(v),
2876 };
2877 }
2878 }
2879
2880 let lowered_name = format!("{}_{}", enum_name, variant);
2882 if let Some(func) = env.functions.get(&lowered_name).cloned() {
2883 let arg_vals: Vec<Value> = match fields {
2885 EnumVariantFields::Unit => Vec::new(),
2886 EnumVariantFields::Tuple(exprs) => {
2887 let mut vals = Vec::new();
2888 for e in exprs {
2889 let v = eval_expr(env, e)?;
2890 if let Value::Return(_) = v {
2891 return Ok(v);
2892 }
2893 vals.push(v);
2894 }
2895 vals
2896 }
2897 EnumVariantFields::Struct(named_fields) => {
2898 let mut vals = Vec::new();
2899 for (_, e) in named_fields {
2900 let v = eval_expr(env, e)?;
2901 if let Value::Return(_) = v {
2902 return Ok(v);
2903 }
2904 vals.push(v);
2905 }
2906 vals
2907 }
2908 };
2909
2910 env.push_scope();
2912 for (param, arg) in func.params.iter().zip(arg_vals.into_iter()) {
2913 env.define(param.name.clone(), arg);
2914 }
2915 let result = eval_block(env, &func.body)?;
2916 env.pop_scope();
2917
2918 return match result {
2919 Value::Return(v) => Ok(*v),
2920 v => Ok(v),
2921 };
2922 }
2923
2924 let field_vals = match fields {
2926 EnumVariantFields::Unit => Vec::new(),
2927 EnumVariantFields::Tuple(exprs) => {
2928 let mut vals = Vec::new();
2929 for e in exprs {
2930 let v = eval_expr(env, e)?;
2931 if let Value::Return(_) = v {
2932 return Ok(v);
2933 }
2934 vals.push(v);
2935 }
2936 vals
2937 }
2938 EnumVariantFields::Struct(named_fields) => {
2939 let mut vals = Vec::new();
2940 for (_, e) in named_fields {
2941 let v = eval_expr(env, e)?;
2942 if let Value::Return(_) = v {
2943 return Ok(v);
2944 }
2945 vals.push(v);
2946 }
2947 vals
2948 }
2949 };
2950
2951 if enum_name == "Poll" {
2953 match variant.as_str() {
2954 "Ready" => {
2955 let inner = if field_vals.is_empty() {
2956 None
2957 } else {
2958 Some(Box::new(
2959 field_vals.into_iter().next().unwrap_or(Value::Unit),
2960 ))
2961 };
2962 Ok(Value::Poll(true, inner))
2963 }
2964 "Pending" => Ok(Value::Poll(false, None)),
2965 _ => Ok(Value::EnumVariant(
2966 enum_name.clone(),
2967 variant.clone(),
2968 field_vals,
2969 )),
2970 }
2971 } else {
2972 Ok(Value::EnumVariant(
2973 enum_name.clone(),
2974 variant.clone(),
2975 field_vals,
2976 ))
2977 }
2978 }
2979
2980 Expr::Break(expr, _) => {
2981 let val = if let Some(e) = expr {
2982 Some(Box::new(eval_expr(env, e)?))
2983 } else {
2984 None
2985 };
2986 Ok(Value::Break(val))
2987 }
2988
2989 Expr::Continue(_) => Ok(Value::Continue),
2990
2991 _ => Err(KoreError::runtime(format!(
2992 "Expression not supported in runtime: {:?}",
2993 expr
2994 ))),
2995 }
2996}
2997
2998fn call_function(env: &mut Env, func: Value, args: Vec<Value>) -> KoreResult<Value> {
2999 match func {
3000 Value::Function(name) => {
3001 let f = env
3002 .functions
3003 .get(&name)
3004 .cloned()
3005 .ok_or_else(|| KoreError::runtime(format!("Function not found: {}", name)))?;
3006 if f.params.len() != args.len() {
3007 return Err(KoreError::runtime(format!(
3008 "Argument mismatch: expected {}, got {}",
3009 f.params.len(),
3010 args.len()
3011 )));
3012 }
3013
3014 env.push_scope();
3015 for (param, arg) in f.params.iter().zip(args.into_iter()) {
3016 env.define(param.name.clone(), arg);
3017 }
3018
3019 let result = eval_block(env, &f.body)?;
3020 env.pop_scope();
3021
3022 match result {
3023 Value::Return(v) => Ok(*v),
3024 v => Ok(v),
3025 }
3026 }
3027 Value::NativeFn(_, f) => f(env, args),
3028 Value::Closure(params, body, captured) => {
3029 if params.len() != args.len() {
3030 return Err(KoreError::runtime(format!("Closure arg mismatch")));
3031 }
3032
3033 let old_scopes = env.scopes.clone();
3035 env.scopes = captured;
3036 env.push_scope();
3037
3038 for (name, arg) in params.iter().zip(args.into_iter()) {
3039 env.define(name.clone(), arg);
3040 }
3041
3042 let result = eval_expr(env, &body)?;
3043
3044 env.pop_scope();
3045 env.scopes = old_scopes;
3046
3047 match result {
3048 Value::Return(v) => Ok(*v),
3049 v => Ok(v),
3050 }
3051 }
3052 Value::StructConstructor(name, fields) => {
3053 if fields.len() != args.len() {
3054 return Err(KoreError::runtime(format!(
3055 "Struct constructor for {} expected {} arguments, got {}",
3056 name,
3057 fields.len(),
3058 args.len()
3059 )));
3060 }
3061
3062 let mut field_vals = HashMap::new();
3063 for (i, val) in args.into_iter().enumerate() {
3064 field_vals.insert(fields[i].clone(), val);
3065 }
3066
3067 Ok(Value::Struct(name, Arc::new(RwLock::new(field_vals))))
3068 }
3069 _ => Err(KoreError::runtime("Not a function")),
3070 }
3071}
3072
3073fn eval_binop(op: BinaryOp, left: Value, right: Value) -> KoreResult<Value> {
3074 match (op, &left, &right) {
3075 (BinaryOp::Add, Value::Int(a), Value::Int(b)) => Ok(Value::Int(a + b)),
3076 (BinaryOp::Sub, Value::Int(a), Value::Int(b)) => Ok(Value::Int(a - b)),
3077 (BinaryOp::Mul, Value::Int(a), Value::Int(b)) => Ok(Value::Int(a * b)),
3078 (BinaryOp::Div, Value::Int(a), Value::Int(b)) => Ok(Value::Int(a / b)),
3079 (BinaryOp::Mod, Value::Int(a), Value::Int(b)) => Ok(Value::Int(a % b)),
3080 (BinaryOp::Add, Value::Float(a), Value::Float(b)) => Ok(Value::Float(a + b)),
3081 (BinaryOp::Sub, Value::Float(a), Value::Float(b)) => Ok(Value::Float(a - b)),
3082 (BinaryOp::Mul, Value::Float(a), Value::Float(b)) => Ok(Value::Float(a * b)),
3083 (BinaryOp::Div, Value::Float(a), Value::Float(b)) => Ok(Value::Float(a / b)),
3084 (BinaryOp::Add, Value::String(a), Value::String(b)) => Ok(Value::String(a.to_owned() + b)),
3085 (BinaryOp::Eq, Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a == b)),
3086 (BinaryOp::Ne, Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a != b)),
3087 (BinaryOp::Eq, Value::String(a), Value::String(b)) => Ok(Value::Bool(a == b)),
3088 (BinaryOp::Ne, Value::String(a), Value::String(b)) => Ok(Value::Bool(a != b)),
3089 (BinaryOp::Eq, Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(a == b)),
3090 (BinaryOp::Ne, Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(a != b)),
3091
3092 (BinaryOp::Lt, Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a < b)),
3094 (BinaryOp::Gt, Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a > b)),
3095 (BinaryOp::Le, Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a <= b)),
3096 (BinaryOp::Ge, Value::Float(a), Value::Float(b)) => Ok(Value::Bool(a >= b)),
3097 (BinaryOp::Eq, Value::Float(a), Value::Float(b)) => {
3098 Ok(Value::Bool((a - b).abs() < f64::EPSILON))
3099 }
3100 (BinaryOp::Ne, Value::Float(a), Value::Float(b)) => {
3101 Ok(Value::Bool((a - b).abs() >= f64::EPSILON))
3102 }
3103
3104 (BinaryOp::Lt, Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a < b)),
3105 (BinaryOp::Gt, Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a > b)),
3106 (BinaryOp::Le, Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a <= b)),
3107 (BinaryOp::Ge, Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a >= b)),
3108 (BinaryOp::And, Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(*a && *b)),
3109 (BinaryOp::Or, Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(*a || *b)),
3110 (BinaryOp::Eq, Value::None, Value::None) => Ok(Value::Bool(true)),
3111 (BinaryOp::Ne, Value::None, Value::None) => Ok(Value::Bool(false)),
3112 (BinaryOp::Eq, Value::Unit, Value::Unit) => Ok(Value::Bool(true)),
3113 (BinaryOp::Ne, Value::Unit, Value::Unit) => Ok(Value::Bool(false)),
3114 (BinaryOp::Eq, _, _) => Ok(Value::Bool(false)),
3115 (BinaryOp::Ne, _, _) => Ok(Value::Bool(true)),
3116
3117 _ => Err(KoreError::runtime(format!(
3119 "Type mismatch in binary operation: {:?} {:?} {:?}",
3120 left, op, right
3121 ))),
3122 }
3123}
3124
3125fn pattern_matches(pattern: &Pattern, value: &Value) -> bool {
3126 match pattern {
3127 Pattern::Wildcard(_) => true,
3128 Pattern::Binding { .. } => true,
3129 Pattern::Literal(Expr::Int(n, _)) => matches!(value, Value::Int(v) if *v == *n),
3130 Pattern::Literal(Expr::String(s, _)) => matches!(value, Value::String(v) if v == s),
3131 Pattern::Literal(Expr::Bool(b, _)) => matches!(value, Value::Bool(v) if *v == *b),
3132 Pattern::Variant {
3133 variant, fields, ..
3134 } => {
3135 if let Value::Poll(ready, val) = value {
3136 if *variant == "Ready" {
3137 if !ready {
3138 return false;
3139 }
3140 if let VariantPatternFields::Tuple(pats) = fields {
3141 if pats.len() == 1 {
3142 return if let Some(v) = val {
3143 pattern_matches(&pats[0], v)
3144 } else {
3145 false
3146 };
3147 }
3148 }
3149 return false;
3150 } else if *variant == "Pending" {
3151 return !ready;
3152 }
3153 return false;
3154 }
3155 if let Value::EnumVariant(_, v_name, v_fields) = value {
3156 if variant != v_name {
3157 return false;
3158 }
3159 match fields {
3160 VariantPatternFields::Unit => v_fields.is_empty(),
3161 VariantPatternFields::Tuple(pats) => {
3162 if pats.len() != v_fields.len() {
3163 return false;
3164 }
3165 pats.iter()
3166 .zip(v_fields.iter())
3167 .all(|(p, v)| pattern_matches(p, v))
3168 }
3169 _ => false,
3170 }
3171 } else {
3172 false
3173 }
3174 }
3175 _ => false,
3176 }
3177}
3178
3179fn bind_pattern(env: &mut Env, pattern: &Pattern, value: &Value) {
3180 match pattern {
3181 Pattern::Binding { name, .. } => {
3182 env.define(name.clone(), value.clone());
3183 }
3184 Pattern::Variant {
3185 variant, fields, ..
3186 } => {
3187 if let Value::Poll(ready, val) = value {
3188 if *variant == "Ready" && *ready {
3189 if let VariantPatternFields::Tuple(pats) = fields {
3190 if pats.len() == 1 {
3191 if let Some(v) = val {
3192 bind_pattern(env, &pats[0], v);
3193 }
3194 }
3195 }
3196 }
3197 } else if let Value::EnumVariant(_, _, v_fields) = value {
3198 match fields {
3199 VariantPatternFields::Tuple(pats) => {
3200 for (p, v) in pats.iter().zip(v_fields.iter()) {
3201 bind_pattern(env, p, v);
3202 }
3203 }
3204 _ => {}
3205 }
3206 }
3207 }
3208 _ => {}
3209 }
3210}
3211
3212fn eval_jsx(env: &mut Env, node: &JSXNode) -> KoreResult<Value> {
3213 match node {
3214 JSXNode::Element {
3215 tag,
3216 attributes,
3217 children,
3218 ..
3219 } => {
3220 let mut attr_vals = HashMap::new();
3221 for attr in attributes {
3222 let v = match &attr.value {
3223 JSXAttrValue::String(s) => Value::String(s.clone()),
3224 JSXAttrValue::Bool(b) => Value::Bool(*b),
3225 JSXAttrValue::Expr(e) => eval_expr(env, e)?,
3226 };
3227 if let Value::Return(_) = v {
3228 return Ok(v);
3229 }
3230 attr_vals.insert(attr.name.clone(), v);
3231 }
3232
3233 let mut child_vals = Vec::new();
3234 for child in children {
3235 let v = eval_jsx(env, child)?;
3236 if let Value::Return(_) = v {
3237 return Ok(v);
3238 }
3239 match v {
3240 Value::JSX(node) => child_vals.push(node),
3241 Value::String(s) => child_vals.push(VNode::Text(s)),
3242 Value::Int(n) => child_vals.push(VNode::Text(n.to_string())),
3243 Value::Float(n) => child_vals.push(VNode::Text(n.to_string())),
3244 _ => {}
3245 }
3246 }
3247
3248 Ok(Value::JSX(VNode::Element {
3249 tag: tag.clone(),
3250 attrs: attr_vals,
3251 children: child_vals,
3252 }))
3253 }
3254 JSXNode::Text(s, _) => Ok(Value::String(s.clone())),
3255 JSXNode::Expression(expr) => eval_expr(env, expr),
3256 _ => Ok(Value::Unit),
3257 }
3258}
3259
3260pub fn run_tests(program: &TypedProgram) -> KoreResult<()> {
3262 println!("\n Running Tests...\n");
3263 let mut passed = 0;
3264 let mut failed = 0;
3265
3266 let mut env = Env::new();
3268
3269 for item in &program.items {
3271 match item {
3272 crate::types::TypedItem::Function(f) => {
3273 env.functions.insert(f.ast.name.clone(), f.ast.clone());
3274 env.define(f.ast.name.clone(), Value::Function(f.ast.name.clone()));
3276 }
3277 crate::types::TypedItem::Actor(a) => {
3278 env.actor_defs.insert(a.ast.name.clone(), a.ast.clone());
3279 }
3280 crate::types::TypedItem::Component(c) => {
3281 env.components.insert(c.ast.name.clone(), c.ast.clone());
3282 }
3283 crate::types::TypedItem::Const(c) => {
3284 let val = eval_expr(&mut env, &c.ast.value)?;
3285 env.define(c.ast.name.clone(), val);
3286 }
3287 crate::types::TypedItem::Impl(i) => {
3288 let type_name = match &i.ast.target_type {
3289 Type::Named { name, .. } => name.clone(),
3290 _ => continue,
3291 };
3292 let type_methods = env.methods.entry(type_name).or_insert_with(HashMap::new);
3293 for method in &i.ast.methods {
3294 type_methods.insert(method.name.clone(), method.clone());
3295 }
3296 }
3297 crate::types::TypedItem::Use(u) => {
3298 load_module(&mut env, &u.ast)?;
3299 }
3300 _ => {}
3301 }
3302 }
3303
3304 for item in &program.items {
3306 if let crate::types::TypedItem::Test(test) = item {
3307 print!("test {} ... ", test.ast.name);
3308
3309 env.push_scope();
3311
3312 match eval_block(&mut env, &test.ast.body) {
3313 Ok(_) => {
3314 println!("ok");
3315 passed += 1;
3316 }
3317 Err(e) => {
3318 println!("FAILED");
3319 println!(" Error: {}", e);
3320 failed += 1;
3321 }
3322 }
3323
3324 env.pop_scope();
3325 }
3326 }
3327
3328 println!(
3329 "\nTest result: {}. {} passed; {} failed",
3330 if failed == 0 { "ok" } else { "FAILED" },
3331 passed,
3332 failed
3333 );
3334
3335 if failed > 0 {
3336 Err(KoreError::runtime("Some tests failed"))
3337 } else {
3338 Ok(())
3339 }
3340}
3341
3342fn poll_future_to_completion(env: &mut Env, future_val: Value) -> KoreResult<Value> {
3346 let max_iterations = 100000; let mut iterations = 0;
3348 let current_future = future_val;
3349
3350 loop {
3351 iterations += 1;
3352 if iterations > max_iterations {
3353 return Err(KoreError::runtime("Async timeout: future did not complete"));
3354 }
3355
3356 let poll_result = poll_future_once(env, current_future.clone())?;
3357
3358 match extract_poll_result(&poll_result) {
3359 PollState::Ready(val) => return Ok(val),
3360 PollState::Pending => {
3361 std::thread::sleep(std::time::Duration::from_micros(10));
3364 continue;
3365 }
3366 PollState::NotAPoll => {
3367 return Ok(poll_result);
3369 }
3370 }
3371 }
3372}
3373
3374fn poll_future_once(env: &mut Env, future_val: Value) -> KoreResult<Value> {
3376 match &future_val {
3377 Value::Future(struct_name, state) => {
3379 let poll_fn_name = format!("{}_poll", struct_name);
3380
3381 if let Some(poll_fn) = env.functions.get(&poll_fn_name).cloned() {
3382 let struct_val = Value::Struct(struct_name.clone(), state.clone());
3384
3385 env.push_scope();
3387 env.define("self".to_string(), struct_val.clone());
3388
3389 if let Some(first_param) = poll_fn.params.first() {
3390 env.define(first_param.name.clone(), struct_val);
3391 }
3392
3393 let result = eval_block(env, &poll_fn.body)?;
3394 env.pop_scope();
3395
3396 let actual_result = match result {
3398 Value::Return(v) => *v,
3399 v => v,
3400 };
3401
3402 Ok(normalize_poll_result(actual_result))
3404 } else {
3405 Ok(Value::Poll(true, Some(Box::new(Value::Unit))))
3407 }
3408 }
3409
3410 Value::Struct(struct_name, _) => {
3412 let poll_fn_name = format!("{}_poll", struct_name);
3413
3414 if let Some(poll_fn) = env.functions.get(&poll_fn_name).cloned() {
3415 env.push_scope();
3417 env.define("self".to_string(), future_val.clone());
3418
3419 if let Some(first_param) = poll_fn.params.first() {
3420 env.define(first_param.name.clone(), future_val.clone());
3421 }
3422
3423 let result = eval_block(env, &poll_fn.body)?;
3424 env.pop_scope();
3425
3426 let actual_result = match result {
3428 Value::Return(v) => *v,
3429 v => v,
3430 };
3431
3432 Ok(normalize_poll_result(actual_result))
3433 } else {
3434 Ok(Value::Poll(true, Some(Box::new(future_val))))
3436 }
3437 }
3438
3439 Value::Poll(_, _) => Ok(future_val),
3441
3442 Value::EnumVariant(enum_name, _, _) if enum_name == "Poll" => {
3444 Ok(normalize_poll_result(future_val))
3445 }
3446
3447 _ => Ok(Value::Poll(true, Some(Box::new(future_val)))),
3449 }
3450}
3451
3452enum PollState {
3454 Ready(Value),
3455 Pending,
3456 NotAPoll,
3457}
3458
3459fn extract_poll_result(val: &Value) -> PollState {
3461 match val {
3462 Value::Poll(true, Some(inner)) => PollState::Ready(*inner.clone()),
3464 Value::Poll(true, None) => PollState::Ready(Value::Unit),
3465 Value::Poll(false, _) => PollState::Pending,
3466
3467 Value::EnumVariant(enum_name, variant, fields) if enum_name == "Poll" => {
3469 match variant.as_str() {
3470 "Ready" => {
3471 if fields.is_empty() {
3472 PollState::Ready(Value::Unit)
3473 } else {
3474 PollState::Ready(fields[0].clone())
3475 }
3476 }
3477 "Pending" => PollState::Pending,
3478 _ => PollState::NotAPoll,
3479 }
3480 }
3481
3482 Value::Struct(name, fields) => {
3484 if name.contains("Ready") {
3485 let fields_guard = fields.read().unwrap();
3486 if let Some(val) = fields_guard
3487 .get("0")
3488 .or(fields_guard.get("value"))
3489 .or(fields_guard.values().next())
3490 {
3491 PollState::Ready(val.clone())
3492 } else {
3493 PollState::Ready(Value::Unit)
3494 }
3495 } else if name.contains("Pending") {
3496 PollState::Pending
3497 } else {
3498 PollState::NotAPoll
3499 }
3500 }
3501
3502 Value::Tuple(elems) if elems.len() >= 1 => {
3504 if let Value::String(tag) = &elems[0] {
3505 match tag.as_str() {
3506 "Ready" if elems.len() >= 2 => PollState::Ready(elems[1].clone()),
3507 "Ready" => PollState::Ready(Value::Unit),
3508 "Pending" => PollState::Pending,
3509 _ => PollState::NotAPoll,
3510 }
3511 } else {
3512 PollState::NotAPoll
3513 }
3514 }
3515
3516 _ => PollState::NotAPoll,
3517 }
3518}
3519
3520fn normalize_poll_result(val: Value) -> Value {
3522 match extract_poll_result(&val) {
3523 PollState::Ready(inner) => Value::Poll(true, Some(Box::new(inner))),
3524 PollState::Pending => Value::Poll(false, None),
3525 PollState::NotAPoll => val, }
3527}