Skip to main content

riddle/
scope.rs

1use crate::{
2    core::Core,
3    env::{Atom, BoolExpr, CommonEnv, Env, Object, Var},
4    language::{ClassDef, ConstructorDef, Expr, MethodDef, PredicateDef, ProblemDef, RiddleError, Statement, execute},
5};
6use std::{
7    any::Any,
8    cell::RefCell,
9    collections::{HashMap, VecDeque},
10    fmt,
11    rc::{Rc, Weak},
12};
13
14/// Runtime type abstraction used by the interpreter.
15///
16/// Implementors expose type identity, optional downcasts to richer kinds
17/// (class or predicate), and a way to create a default runtime instance.
18pub trait Type: fmt::Debug {
19    fn name(&self) -> &str;
20    fn full_name(&self) -> String {
21        self.name().to_string()
22    }
23    fn as_any(self: Rc<Self>) -> Rc<dyn Any>;
24    fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
25        None
26    }
27    fn as_predicate(self: Rc<Self>) -> Option<Rc<Predicate>> {
28        None
29    }
30    fn new_instance(self: Rc<Self>) -> Rc<dyn Var>;
31}
32
33#[derive(Debug)]
34pub struct BoolType {
35    core: Weak<dyn Core>,
36}
37
38impl BoolType {
39    /// Creates the built-in boolean type.
40    pub fn new(core: Weak<dyn Core>) -> Self {
41        Self { core }
42    }
43}
44
45impl Type for BoolType {
46    fn name(&self) -> &str {
47        "bool"
48    }
49
50    fn as_any(self: Rc<Self>) -> Rc<dyn Any> {
51        self
52    }
53
54    fn new_instance(self: Rc<Self>) -> Rc<dyn Var> {
55        let var = self.core.upgrade().unwrap().new_bool_var();
56        Rc::new(BoolExpr::Term { var_type: Rc::downgrade(&self), term: var })
57    }
58}
59
60#[derive(Debug)]
61pub struct IntType {
62    core: Weak<dyn Core>,
63}
64
65impl IntType {
66    /// Creates the built-in integer type.
67    pub fn new(core: Weak<dyn Core>) -> Self {
68        Self { core }
69    }
70}
71
72impl Type for IntType {
73    fn name(&self) -> &str {
74        "int"
75    }
76
77    fn as_any(self: Rc<Self>) -> Rc<dyn Any> {
78        self
79    }
80
81    fn new_instance(self: Rc<Self>) -> Rc<dyn Var> {
82        self.core.upgrade().unwrap().new_int_var()
83    }
84}
85
86#[derive(Debug)]
87pub struct RealType {
88    core: Weak<dyn Core>,
89}
90
91impl RealType {
92    /// Creates the built-in real (floating-point) type.
93    pub fn new(core: Weak<dyn Core>) -> Self {
94        Self { core }
95    }
96}
97
98impl Type for RealType {
99    fn name(&self) -> &str {
100        "real"
101    }
102
103    fn as_any(self: Rc<Self>) -> Rc<dyn Any> {
104        self
105    }
106
107    fn new_instance(self: Rc<Self>) -> Rc<dyn Var> {
108        self.core.upgrade().unwrap().new_real_var()
109    }
110}
111
112#[derive(Debug)]
113pub struct StringType {
114    core: Weak<dyn Core>,
115}
116
117impl StringType {
118    /// Creates the built-in string type.
119    pub fn new(core: Weak<dyn Core>) -> Self {
120        Self { core }
121    }
122}
123
124impl Type for StringType {
125    fn name(&self) -> &str {
126        "string"
127    }
128
129    fn as_any(self: Rc<Self>) -> Rc<dyn Any> {
130        self
131    }
132
133    fn new_instance(self: Rc<Self>) -> Rc<dyn Var> {
134        self.core.upgrade().unwrap().new_string_var()
135    }
136}
137
138/// Describes a named binding declared in a scope.
139///
140/// A field stores its declared type path and optional default expression.
141#[derive(Debug)]
142pub struct Field {
143    name: String,
144    field_type: Vec<String>,
145    default: Option<Expr>,
146}
147
148impl Field {
149    /// Creates a new field descriptor.
150    pub fn new(name: String, field_type: Vec<String>, default: Option<Expr>) -> Self {
151        Self { name, field_type, default }
152    }
153
154    pub fn name(&self) -> &str {
155        &self.name
156    }
157
158    pub fn field_type(&self) -> &[String] {
159        &self.field_type
160    }
161
162    pub fn default(&self) -> Option<&Expr> {
163        self.default.as_ref()
164    }
165}
166
167/// Name-resolution contract shared by classes, methods, predicates, and global scopes.
168pub trait Scope {
169    fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
170        None
171    }
172    fn core(self: Rc<Self>) -> Rc<dyn Core>;
173    fn scope(&self) -> Option<Rc<dyn Scope>>;
174
175    fn get_field(&self, name: &str) -> Option<Rc<Field>>;
176    fn get_method(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Method>>;
177    fn get_type(&self, name: &str) -> Option<Rc<dyn Type>>;
178    fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>>;
179}
180
181/// Generic hierarchical scope used to resolve fields, methods, nested types, and predicates.
182#[derive(Debug)]
183pub struct CommonScope {
184    core: Weak<dyn Core>,
185    scope: Option<Weak<dyn Scope>>,
186    fields: RefCell<HashMap<String, Rc<Field>>>,
187    methods: RefCell<HashMap<String, Vec<Rc<Method>>>>,
188    pub(crate) classes: RefCell<HashMap<String, Rc<dyn Type>>>,
189    predicates: RefCell<HashMap<String, Rc<Predicate>>>,
190}
191
192impl CommonScope {
193    /// Creates an empty scope with an optional parent scope.
194    pub fn new(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>) -> Self {
195        Self {
196            core,
197            scope,
198            fields: RefCell::new(HashMap::new()),
199            methods: RefCell::new(HashMap::new()),
200            classes: RefCell::new(HashMap::new()),
201            predicates: RefCell::new(HashMap::new()),
202        }
203    }
204
205    /// Builds a scope populated from a class definition.
206    pub fn from_class(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, class_scope: Weak<dyn Scope>, class: ClassDef) -> Rc<Self> {
207        let scope = Rc::new(Self::new(core.clone(), scope));
208        for (field_type, fields) in class.fields {
209            for (name, default) in fields {
210                scope.fields.borrow_mut().insert(name.clone(), Rc::new(Field { name, field_type: field_type.clone(), default }));
211            }
212        }
213        for method_def in class.methods {
214            scope.methods.borrow_mut().entry(method_def.name.clone()).or_default().push(Method::new(core.clone(), Some(class_scope.clone()), method_def));
215        }
216        for class_def in class.classes {
217            let class_name = class_def.name.clone();
218            scope.classes.borrow_mut().insert(class_name, CommonClass::new(core.clone(), Some(class_scope.clone()), class_def));
219        }
220        for predicate_def in class.predicates {
221            scope.predicates.borrow_mut().insert(predicate_def.name.clone(), Predicate::new(core.clone(), Some(class_scope.clone()), predicate_def));
222        }
223        scope
224    }
225
226    /// Builds a local scope for constructor arguments.
227    pub fn from_costructor(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, constructor: ConstructorDef) -> Self {
228        let scope = Self::new(core, scope);
229        for (arg_type, arg_name) in constructor.args {
230            scope.fields.borrow_mut().insert(arg_name.clone(), Rc::new(Field { name: arg_name, field_type: arg_type, default: None }));
231        }
232        scope
233    }
234
235    /// Builds a local scope for method arguments.
236    pub fn from_method(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, method: MethodDef) -> Self {
237        let scope = Self::new(core, scope);
238        for (arg_type, arg_name) in method.args {
239            scope.fields.borrow_mut().insert(arg_name.clone(), Rc::new(Field { name: arg_name, field_type: arg_type, default: None }));
240        }
241        scope
242    }
243
244    /// Builds a local scope for predicate arguments.
245    pub fn from_predicate(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, predicate: PredicateDef) -> Self {
246        let scope = Self::new(core, scope);
247        for (arg_type, arg_name) in predicate.args {
248            scope.fields.borrow_mut().insert(arg_name.clone(), Rc::new(Field { name: arg_name, field_type: arg_type, default: None }));
249        }
250        scope
251    }
252
253    /// Merges problem-level declarations into this scope.
254    pub fn add_problem(&self, problem: ProblemDef) {
255        for method_def in problem.methods {
256            self.methods.borrow_mut().entry(method_def.name.clone()).or_default().push(Method::new(self.core.clone(), Some(self.core.clone()), method_def));
257        }
258        for class_def in problem.classes {
259            self.classes.borrow_mut().insert(class_def.name.clone(), CommonClass::new(self.core.clone(), Some(self.core.clone()), class_def));
260        }
261        for predicate_def in problem.predicates {
262            self.predicates.borrow_mut().insert(predicate_def.name.clone(), Predicate::new(self.core.clone(), Some(self.core.clone()), predicate_def));
263        }
264    }
265}
266
267impl Scope for CommonScope {
268    fn core(self: Rc<Self>) -> Rc<dyn Core> {
269        self.core.upgrade().unwrap()
270    }
271
272    fn scope(&self) -> Option<Rc<dyn Scope>> {
273        self.scope.as_ref()?.upgrade()
274    }
275
276    fn get_field(&self, name: &str) -> Option<Rc<Field>> {
277        self.fields.borrow().get(name).cloned().or_else(|| self.scope.as_ref()?.upgrade()?.get_field(name))
278    }
279
280    fn get_method(&self, name: &str, types: &[Rc<dyn Type>]) -> Option<Rc<Method>> {
281        self.methods
282            .borrow()
283            .get(name)
284            .and_then(|methods| {
285                methods
286                    .iter()
287                    .find(|m| {
288                        if m.args().len() != types.len() {
289                            return false;
290                        }
291                        for (class, arg_type) in types.iter().zip(m.args().iter().map(|(t, _)| t)) {
292                            if !class.full_name().split('.').eq(arg_type.iter().map(|s| s.as_str())) {
293                                return false;
294                            }
295                        }
296                        true
297                    })
298                    .cloned()
299            })
300            .or_else(|| self.scope.as_ref()?.upgrade()?.get_method(name, types))
301    }
302
303    fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
304        self.classes.borrow().get(name).cloned().or_else(|| self.scope.as_ref()?.upgrade()?.get_type(name))
305    }
306
307    fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
308        self.predicates.borrow().get(name).cloned().or_else(|| self.scope.as_ref()?.upgrade()?.get_predicate(name))
309    }
310}
311
312/// Executable method declaration with argument and return-type checking.
313#[derive(Debug)]
314pub struct Method {
315    core: Weak<dyn Core>,
316    scope: Rc<CommonScope>,
317    name: String,
318    return_type: Option<Vec<String>>,
319    args: Vec<(Vec<String>, String)>,
320    statements: Vec<Statement>,
321}
322
323impl Method {
324    /// Creates a method from its parsed definition.
325    pub fn new(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, mut method: MethodDef) -> Rc<Self> {
326        Rc::new(Self {
327            core: core.clone(),
328            name: std::mem::take(&mut method.name),
329            return_type: std::mem::take(&mut method.return_type),
330            args: std::mem::take(&mut method.args),
331            statements: std::mem::take(&mut method.statements),
332            scope: Rc::new(CommonScope::from_method(core, scope, method)),
333        })
334    }
335
336    pub fn name(&self) -> &str {
337        &self.name
338    }
339
340    pub fn return_type(&self) -> Option<&[String]> {
341        self.return_type.as_deref()
342    }
343
344    pub fn args(&self) -> &[(Vec<String>, String)] {
345        &self.args
346    }
347
348    pub fn statements(&self) -> &[Statement] {
349        &self.statements
350    }
351
352    /// Invokes the method in a fresh local environment.
353    ///
354    /// The call validates argument count and type compatibility, executes all
355    /// method statements, and checks the declared return type (if any).
356    pub fn call(&self, env: Rc<dyn Env>, args: Vec<Rc<dyn Var>>) -> Result<Option<Rc<dyn Var>>, RiddleError> {
357        if args.len() != self.args.len() {
358            return Err(RiddleError::RuntimeError(format!("Expected {} arguments, got {}", self.args.len(), args.len())));
359        }
360        let method_env = Rc::new(CommonEnv::new(Some(env)));
361        for ((arg_type, arg_name), arg_value) in self.args.iter().zip(args) {
362            if !arg_value.var_type().full_name().split('.').eq(arg_type.iter().map(|s| s.as_str())) {
363                return Err(RiddleError::TypeError(format!("Argument '{}' expected to be of type '{}', got '{}'", arg_name, arg_type.join("."), arg_value.var_type().name())));
364            }
365            method_env.set(arg_name.clone(), arg_value);
366        }
367        for stmt in &self.statements {
368            execute(self.scope.clone(), method_env.clone(), stmt)?;
369        }
370        if let Some(return_type) = &self.return_type {
371            method_env
372                .get("__return")
373                .ok_or_else(|| RiddleError::RuntimeError("Method did not set return value".into()))
374                .and_then(|ret| if ret.var_type().full_name().split('.').eq(return_type.iter().map(|s| s.as_str())) { Ok(Some(ret)) } else { Err(RiddleError::TypeError(format!("Return value expected to be of type '{}', got '{}'", return_type.join("."), ret.var_type().name()))) })
375        } else {
376            Ok(None)
377        }
378    }
379}
380
381impl Scope for Method {
382    fn core(self: Rc<Self>) -> Rc<dyn Core> {
383        self.core.upgrade().expect("Method core should be valid")
384    }
385
386    fn scope(&self) -> Option<Rc<dyn Scope>> {
387        self.scope.scope.as_ref()?.upgrade()
388    }
389
390    fn get_field(&self, name: &str) -> Option<Rc<Field>> {
391        self.scope.get_field(name)
392    }
393
394    fn get_method(&self, name: &str, classes: &[Rc<dyn Type>]) -> Option<Rc<Method>> {
395        self.scope.get_method(name, classes)
396    }
397
398    fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
399        self.scope.get_type(name)
400    }
401
402    fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
403        self.scope.get_predicate(name)
404    }
405}
406
407/// Executable constructor declaration.
408#[derive(Debug)]
409pub struct Constructor {
410    core: Weak<dyn Core>,
411    scope: Rc<CommonScope>,
412    args: Vec<(Vec<String>, String)>,
413    statements: Vec<Statement>,
414}
415
416impl Constructor {
417    /// Creates a constructor from its parsed definition.
418    pub fn new(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, mut constructor: ConstructorDef) -> Self {
419        Self {
420            core: core.clone(),
421            args: std::mem::take(&mut constructor.args),
422            statements: std::mem::take(&mut constructor.statements),
423            scope: Rc::new(CommonScope::from_costructor(core, scope, constructor)),
424        }
425    }
426
427    pub fn args(&self) -> &[(Vec<String>, String)] {
428        &self.args
429    }
430
431    pub fn statements(&self) -> &[Statement] {
432        &self.statements
433    }
434
435    /// Creates a new object instance and runs constructor statements.
436    pub fn call(&self, env: Rc<dyn Env>, args: Vec<Rc<dyn Var>>) -> Result<Option<Rc<dyn Var>>, RiddleError> {
437        if args.len() != self.args.len() {
438            return Err(RiddleError::RuntimeError(format!("Expected {} arguments, got {}", self.args.len(), args.len())));
439        }
440        let class = self.scope.scope.as_ref().and_then(|s| s.upgrade()).and_then(|s| s.as_class()).ok_or_else(|| RiddleError::RuntimeError("Constructor is not defined within a class".into()))?;
441        let object = class.new_instance();
442        let constructor_env = Rc::new(CommonEnv::new(Some(env)));
443        constructor_env.set("this".to_string(), object.clone());
444        for ((arg_type, arg_name), arg_value) in self.args.iter().zip(args) {
445            if !arg_value.var_type().full_name().split('.').eq(arg_type.iter().map(|s| s.as_str())) {
446                return Err(RiddleError::TypeError(format!("Argument '{}' expected to be of type '{}', got '{}'", arg_name, arg_type.join("."), arg_value.var_type().name())));
447            }
448            constructor_env.set(arg_name.clone(), arg_value);
449        }
450        for stmt in &self.statements {
451            execute(self.scope.clone(), constructor_env.clone(), stmt)?;
452        }
453        Ok(Some(object))
454    }
455}
456
457impl Scope for Constructor {
458    fn core(self: Rc<Self>) -> Rc<dyn Core> {
459        self.core.upgrade().unwrap()
460    }
461
462    fn scope(&self) -> Option<Rc<dyn Scope>> {
463        self.scope.scope.as_ref()?.upgrade()
464    }
465
466    fn get_field(&self, name: &str) -> Option<Rc<Field>> {
467        self.scope.get_field(name)
468    }
469
470    fn get_method(&self, name: &str, classes: &[Rc<dyn Type>]) -> Option<Rc<Method>> {
471        self.scope.get_method(name, classes)
472    }
473
474    fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
475        self.scope.get_type(name)
476    }
477
478    fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
479        self.scope.get_predicate(name)
480    }
481}
482
483/// Predicate type and runtime behavior.
484///
485/// Predicates can be instantiated as atoms, can inherit from parent predicates,
486/// and execute associated statements for each atom invocation.
487#[derive(Debug)]
488pub struct Predicate {
489    core: Weak<dyn Core>,
490    scope: CommonScope,
491    name: String,
492    parents: Vec<Vec<String>>,
493    args: Vec<(Vec<String>, String)>,
494    statements: Vec<Statement>,
495    atoms: RefCell<Vec<Rc<Atom>>>,
496}
497
498impl Predicate {
499    /// Creates a predicate from its parsed definition.
500    pub fn new(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, mut predicate: PredicateDef) -> Rc<Self> {
501        Rc::new(Self {
502            core: core.clone(),
503            name: std::mem::take(&mut predicate.name),
504            parents: std::mem::take(&mut predicate.parents),
505            args: std::mem::take(&mut predicate.args),
506            statements: std::mem::take(&mut predicate.statements),
507            scope: CommonScope::from_predicate(core, scope, predicate),
508            atoms: RefCell::new(Vec::new()),
509        })
510    }
511
512    pub fn parents(&self) -> &[Vec<String>] {
513        &self.parents
514    }
515
516    pub fn args(&self) -> &[(Vec<String>, String)] {
517        &self.args
518    }
519
520    pub fn statements(&self) -> &[Statement] {
521        &self.statements
522    }
523
524    /// Registers a new atom for this predicate and all declared parent predicates.
525    pub fn new_atom(self: Rc<Self>, fact: bool, args: HashMap<String, Rc<dyn Var>>) -> Rc<Atom> {
526        let atom = Rc::new(Atom::new(self.clone(), fact, args));
527        let mut pred_hierarchy = VecDeque::new();
528        pred_hierarchy.push_back(self.clone());
529        while !pred_hierarchy.is_empty() {
530            let pred = pred_hierarchy.pop_front().unwrap();
531            pred.atoms.borrow_mut().push(atom.clone());
532            for parent_path in pred.parents() {
533                let (predicate_name, class_path) = parent_path.split_last().expect("Parent predicate name should not be empty");
534                let parent_predicate = if class_path.is_empty() {
535                    self.get_predicate(predicate_name).expect("Parent predicate should exist")
536                } else {
537                    let (first_class, nested_classes) = class_path.split_first().expect("Parent predicate class path should not be empty");
538                    let class_type = self.get_type(first_class).expect("Parent predicate class should exist");
539                    let class_type = nested_classes.iter().fold(class_type, |acc, class_name| {
540                        let acc_name = acc.full_name();
541                        acc.clone().as_class().unwrap_or_else(|| panic!("Type '{}' in parent path is not a class", acc_name)).get_type(class_name).unwrap_or_else(|| panic!("Nested class '{}' in parent path not found in '{}'", class_name, acc_name))
542                    });
543                    let class_type_name = class_type.full_name();
544                    class_type.clone().as_class().unwrap_or_else(|| panic!("Type '{}' in parent path is not a class", class_type_name)).get_predicate(predicate_name).unwrap_or_else(|| panic!("Parent predicate '{}' not found in class '{}'", predicate_name, class_type_name))
545                };
546                pred_hierarchy.push_back(parent_predicate);
547            }
548        }
549        self.core().new_atom(atom.clone());
550        atom
551    }
552
553    /// Executes predicate statements against a concrete atom.
554    pub fn call(self: Rc<Self>, atom: Rc<Atom>) -> Result<(), RiddleError> {
555        for stmt in &self.statements {
556            execute(self.clone(), atom.clone(), stmt)?;
557        }
558        Ok(())
559    }
560
561    pub fn atoms(&self) -> Vec<Rc<Atom>> {
562        self.atoms.borrow().clone()
563    }
564}
565
566impl Type for Predicate {
567    fn name(&self) -> &str {
568        &self.name
569    }
570
571    fn full_name(&self) -> String {
572        if let Some(scope) = self.scope.scope.as_ref().and_then(|scope| scope.upgrade())
573            && let Some(class) = scope.as_class()
574        {
575            format!("{}.{}", class.full_name(), self.name)
576        } else {
577            self.name.clone()
578        }
579    }
580
581    fn as_any(self: Rc<Self>) -> Rc<dyn Any> {
582        self
583    }
584
585    fn as_predicate(self: Rc<Self>) -> Option<Rc<Predicate>> {
586        Some(self)
587    }
588
589    fn new_instance(self: Rc<Self>) -> Rc<dyn Var> {
590        panic!("Cannot create instance of a predicate")
591    }
592}
593
594impl Scope for Predicate {
595    fn core(self: Rc<Self>) -> Rc<dyn Core> {
596        self.core.upgrade().unwrap()
597    }
598
599    fn scope(&self) -> Option<Rc<dyn Scope>> {
600        self.scope.scope.as_ref()?.upgrade()
601    }
602
603    fn get_field(&self, name: &str) -> Option<Rc<Field>> {
604        self.scope.get_field(name)
605    }
606
607    fn get_method(&self, name: &str, classes: &[Rc<dyn Type>]) -> Option<Rc<Method>> {
608        self.scope.get_method(name, classes)
609    }
610
611    fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
612        self.scope.get_type(name)
613    }
614
615    fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
616        self.scope.get_predicate(name)
617    }
618}
619
620/// Class-specific API surface layered on top of type and scope behavior.
621pub trait Class: Type + Scope {
622    fn parents(&self) -> &[Vec<String>];
623    fn constructors(&self) -> &[Constructor];
624    fn constructor(&self, args: &[Rc<dyn Type>]) -> Option<&Constructor>;
625    fn predicates(&self) -> Vec<Rc<Predicate>>;
626    fn classes(&self) -> Vec<Rc<dyn Class>>;
627    fn instances(&self) -> Vec<Rc<Object>>;
628}
629
630/// Returns whether a value of source type can be assigned to target.
631///
632/// The check accepts exact type matches and direct parent/child relationships
633/// between class types.
634pub fn is_assignable_from(target: &Rc<dyn Type>, source: &Rc<dyn Type>) -> bool {
635    if Rc::ptr_eq(target, source) {
636        return true;
637    }
638    if let Some(target_class) = target.clone().as_class()
639        && let Some(source_class) = source.clone().as_class()
640    {
641        for parent in source_class.parents() {
642            if parent.iter().map(|s| s.as_str()).eq(target_class.full_name().split('.')) {
643                return true;
644            }
645        }
646        for parent in target_class.parents() {
647            if parent.iter().map(|s| s.as_str()).eq(source_class.full_name().split('.')) {
648                return true;
649            }
650        }
651    }
652    false
653}
654
655/// Default runtime class implementation.
656#[derive(Debug)]
657pub struct CommonClass {
658    core: Weak<dyn Core>,
659    scope: Rc<CommonScope>,
660    name: String,
661    parents: Vec<Vec<String>>,
662    constructors: Vec<Constructor>,
663    instances: RefCell<Vec<Rc<Object>>>,
664}
665
666impl CommonClass {
667    /// Creates a class type from its parsed definition, including nested members.
668    pub fn new(core: Weak<dyn Core>, scope: Option<Weak<dyn Scope>>, mut class: ClassDef) -> Rc<Self> {
669        let name = std::mem::take(&mut class.name);
670        let parents = std::mem::take(&mut class.parents);
671        let constructors_def = if class.constructors.is_empty() { vec![ConstructorDef { args: Vec::new(), init: Vec::new(), statements: Vec::new() }] } else { std::mem::take(&mut class.constructors) };
672        Rc::new_cyclic(move |weak_self: &Weak<CommonClass>| Self {
673            core: core.clone(),
674            name,
675            parents,
676            constructors: constructors_def.into_iter().map(|c| Constructor::new(core.clone(), Some(weak_self.clone()), c)).collect(),
677            scope: CommonScope::from_class(core.clone(), scope, weak_self.clone(), class),
678            instances: RefCell::new(Vec::new()),
679        })
680    }
681}
682
683impl Type for CommonClass {
684    fn name(&self) -> &str {
685        &self.name
686    }
687
688    fn full_name(&self) -> String {
689        if let Some(scope) = self.scope.scope.as_ref().and_then(|scope| scope.upgrade())
690            && let Some(class) = scope.as_class()
691        {
692            format!("{}.{}", class.full_name(), self.name)
693        } else {
694            self.name.clone()
695        }
696    }
697
698    fn as_any(self: Rc<Self>) -> Rc<dyn Any> {
699        self
700    }
701
702    fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
703        Some(self)
704    }
705
706    fn new_instance(self: Rc<Self>) -> Rc<dyn Var> {
707        let instance = Rc::new(Object::new(self.clone(), None));
708        self.instances.borrow_mut().push(instance.clone());
709        for parent in &self.parents {
710            let (first, rest) = parent.split_first().expect("Parent class name should not be empty");
711            let root = self.get_type(first).expect("Parent class should exist").as_class().expect("Parent class should be a class");
712            let parent_class = rest.iter().fold(root, |current, part| current.get_type(part).expect("Parent class should exist").as_class().expect("Parent class should be a class"));
713            parent_class.as_any().downcast_ref::<CommonClass>().expect("Parent class should be a CommonClass").instances.borrow_mut().push(instance.clone());
714        }
715        instance
716    }
717}
718
719impl Scope for CommonClass {
720    fn as_class(self: Rc<Self>) -> Option<Rc<dyn Class>> {
721        Some(self)
722    }
723
724    fn core(self: Rc<Self>) -> Rc<dyn Core> {
725        self.core.upgrade().expect("Class core should be valid")
726    }
727
728    fn scope(&self) -> Option<Rc<dyn Scope>> {
729        self.scope.scope.as_ref()?.upgrade()
730    }
731
732    fn get_field(&self, name: &str) -> Option<Rc<Field>> {
733        self.scope.get_field(name)
734    }
735
736    fn get_method(&self, name: &str, classes: &[Rc<dyn Type>]) -> Option<Rc<Method>> {
737        self.scope.get_method(name, classes)
738    }
739
740    fn get_type(&self, name: &str) -> Option<Rc<dyn Type>> {
741        self.scope.get_type(name)
742    }
743
744    fn get_predicate(&self, name: &str) -> Option<Rc<Predicate>> {
745        self.scope.get_predicate(name)
746    }
747}
748
749impl Class for CommonClass {
750    fn parents(&self) -> &[Vec<String>] {
751        &self.parents
752    }
753
754    fn constructors(&self) -> &[Constructor] {
755        &self.constructors
756    }
757
758    fn constructor(&self, args: &[Rc<dyn Type>]) -> Option<&Constructor> {
759        self.constructors.iter().find(|c| {
760            if c.args().len() != args.len() {
761                return false;
762            }
763            for ((arg_type, _), class) in c.args().iter().zip(args.iter()) {
764                if !class.full_name().split('.').eq(arg_type.iter().map(|s| s.as_str())) {
765                    return false;
766                }
767            }
768            true
769        })
770    }
771
772    fn predicates(&self) -> Vec<Rc<Predicate>> {
773        self.scope.predicates.borrow().values().cloned().collect()
774    }
775
776    fn classes(&self) -> Vec<Rc<dyn Class>> {
777        self.scope.classes.borrow().values().filter_map(|t| t.clone().as_class()).collect()
778    }
779
780    fn instances(&self) -> Vec<Rc<Object>> {
781        let mut instances = self.instances.borrow().clone();
782        for parent in &self.parents {
783            if let Some(parent_class) = self.core.upgrade().unwrap().get_type(&parent.join("."))
784                && let Some(parent_class) = parent_class.as_class()
785            {
786                instances.extend(parent_class.instances());
787            }
788        }
789        instances
790    }
791}
792
793/// Returns the resulting numeric type for arithmetic terms.
794///
795/// If all terms are int the result is int, otherwise mixed int/real terms yield
796/// real. Any other type combination results in a type error.
797pub fn arith_class(cr: &dyn Core, terms: &[Rc<dyn Var>]) -> Result<Rc<dyn Type>, RiddleError> {
798    if terms.iter().all(|t| t.var_type().name() == "int") {
799        Ok(cr.get_type("int").expect("int class not found"))
800    } else if terms.iter().all(|t| t.var_type().name() == "int" || t.var_type().name() == "real") {
801        Ok(cr.get_type("real").expect("real class not found"))
802    } else {
803        Err(RiddleError::TypeError("Invalid types for arithmetic operation".into()))
804    }
805}