1use std::fmt::{Debug, Display};
2use std::cell::RefCell;
3use std::ops::{Mul, Div, Add, Sub, Not, Neg};
4use std::rc::Rc;
5
6use crate::class::{Class, Instance};
7use crate::error::RuntimeError;
8use crate::function::{Function, NativeFunction};
9use crate::literal::Literal;
10use crate::interpreter::Interpreter;
11
12#[derive(Debug, Clone)]
15pub enum Object {
16 Literal(Literal),
17 Function(Function),
18 NativeFunction(NativeFunction),
19 Class(Rc<RefCell<Class>>),
20 Instance(Rc<RefCell<Instance>>),
21}
22
23impl Object {
24 pub fn as_bool(&self) -> Option<bool> {
26 match self {
27 Object::Literal(literal) => Some(literal.as_bool()),
28 _ => None,
29 }
30 }
31
32 pub fn type_str(&self) -> &str {
33 match self {
34 Object::Literal(literal) => literal.type_str(),
35 Object::Function(_) => "function",
36 Object::NativeFunction(_) => "native function",
37 Object::Class(_) => "class",
38 Object::Instance(_) => "instance",
39 }
40 }
41}
42
43impl PartialEq for Object {
44 fn eq(&self, other: &Self) -> bool {
45 match (self, other) {
46 (Object::Literal(left), Object::Literal(right)) => left == right,
47 (Object::Function(left), Object::Function(right)) => left == right,
48 (Object::NativeFunction(left), Object::NativeFunction(right)) => left == right,
49 (Object::Class(left), Object::Class(right)) => left == right,
50 (Object::Instance(left), Object::Instance(right)) => left == right,
51 _ => false,
52 }
53 }
54}
55
56impl PartialOrd for Object {
57 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
58 match (self, other) {
59 (Object::Literal(left), Object::Literal(right)) => left.partial_cmp(right),
60 _ => None
61 }
62 }
63}
64
65impl Add for Object {
66 type Output = Option<Self>;
67
68 fn add(self, rhs: Self) -> Self::Output {
69 match (self, rhs) {
70 (Object::Literal(left), Object::Literal(right)) => left + right,
71 _ => None,
72 }.map(|x| x.into())
73 }
74}
75
76impl Sub for Object {
77 type Output = Option<Self>;
78
79 fn sub(self, rhs: Self) -> Self::Output {
80 match (self, rhs) {
81 (Object::Literal(left), Object::Literal(right)) => left - right,
82 _ => None,
83 }.map(|x| x.into())
84 }
85}
86
87impl Mul for Object {
88 type Output = Option<Self>;
89
90 fn mul(self, rhs: Self) -> Self::Output {
91 match (self, rhs) {
92 (Object::Literal(left), Object::Literal(right)) => left * right,
93 _ => None,
94 }.map(|x| x.into())
95 }
96}
97
98impl Div for Object {
99 type Output = Option<Self>;
100
101 fn div(self, rhs: Self) -> Self::Output {
102 match (self, rhs) {
103 (Object::Literal(left), Object::Literal(right)) => left / right,
104 _ => None,
105 }.map(|x| x.into())
106 }
107}
108
109impl Not for Object {
110 type Output = Option<Self>;
111
112 fn not(self) -> Self::Output {
113 match self {
114 Object::Literal(right) => !right,
115 _ => None,
116 }.map(|x| x.into())
117 }
118}
119
120impl Neg for Object {
121 type Output = Option<Self>;
122
123 fn neg(self) -> Self::Output {
124 match self {
125 Object::Literal(right) => -right,
126 _ => None,
127 }.map(|x| x.into())
128 }
129}
130
131impl From<Literal> for Object {
132 fn from(literal: Literal) -> Self {
133 Object::Literal(literal)
134 }
135}
136
137impl From<f64> for Object {
138 fn from(number: f64) -> Self {
139 Object::Literal(Literal::Number(number))
140 }
141}
142
143impl From<bool> for Object {
144 fn from(boolean: bool) -> Self {
145 Object::Literal(Literal::Bool(boolean))
146 }
147}
148
149impl From<String> for Object {
150 fn from(string: String) -> Self {
151 Object::Literal(Literal::String(string))
152 }
153}
154
155impl From<&str> for Object {
156 fn from(string: &str) -> Self {
157 Object::Literal(Literal::String(string.to_owned()))
158 }
159}
160
161impl From<Function> for Object {
162 fn from(value: Function) -> Self {
163 Object::Function(value)
164 }
165}
166
167impl From<NativeFunction> for Object {
168 fn from(value: NativeFunction) -> Self {
169 Object::NativeFunction(value)
170 }
171}
172
173impl From<Rc<RefCell<Class>>> for Object {
174 fn from(value: Rc<RefCell<Class>>) -> Self {
175 Object::Class(value)
176 }
177}
178
179impl From<Instance> for Object {
180 fn from(value: Instance) -> Self {
181 Object::Instance(Rc::new(RefCell::new(value)))
182 }
183}
184
185impl From<Rc<RefCell<Instance>>> for Object {
186 fn from(value: Rc<RefCell<Instance>>) -> Self {
187 Object::Instance(value)
188 }
189}
190
191impl Display for Object {
192 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193 match self {
194 Object::Literal(literal) => write!(f, "{literal}"),
195 Object::Function(function) => write!(f, "{function}"),
196 Object::NativeFunction(function) => write!(f, "{function}"),
197 Object::Class(class) => write!(f, "{}", class.borrow()),
198 Object::Instance(instance) => write!(f, "{}", instance.borrow()),
199 }
200 }
201}
202
203pub trait Callable: Debug {
205 fn call(&self, interpreter: &mut Interpreter, arguments: Vec<Object>) -> Result<Object, RuntimeError>;
210
211 fn arity(&self) -> usize;
213}