Skip to main content

quickpython/
value.rs

1use crate::bytecode::ByteCode;
2use regex::Regex;
3use std::cell::RefCell;
4use std::collections::HashMap;
5use std::rc::Rc;
6
7/// Native function type - Rust functions callable from Python
8pub type NativeFunction = fn(Vec<Value>) -> Result<Value, Value>;
9
10/// Module structure
11#[derive(Clone)]
12pub struct Module {
13    pub name: String,
14    pub attributes: HashMap<String, Value>,
15}
16
17impl Module {
18    pub fn new(name: &str) -> Self {
19        Module {
20            name: name.to_string(),
21            attributes: HashMap::new(),
22        }
23    }
24
25    pub fn add_function(&mut self, name: &str, func: NativeFunction) {
26        self.attributes
27            .insert(name.to_string(), Value::NativeFunction(func));
28    }
29
30    pub fn get_attribute(&self, name: &str) -> Option<Value> {
31        self.attributes.get(name).cloned()
32    }
33}
34
35impl std::fmt::Debug for Module {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        f.debug_struct("Module")
38            .field("name", &self.name)
39            .field("attributes", &self.attributes.keys().collect::<Vec<_>>())
40            .finish()
41    }
42}
43
44/// Match object for regex matches
45#[derive(Debug, Clone)]
46pub struct MatchObject {
47    pub text: String,
48    pub start: usize,
49    pub end: usize,
50    pub groups: Vec<Option<String>>,
51}
52
53impl MatchObject {
54    pub fn new(text: String, start: usize, end: usize, groups: Vec<Option<String>>) -> Self {
55        MatchObject {
56            text,
57            start,
58            end,
59            groups,
60        }
61    }
62}
63
64/// List value with version tracking for iterator modification detection
65#[derive(Debug, Clone)]
66pub struct ListValue {
67    pub items: Vec<Value>,
68    pub version: usize,
69}
70
71impl ListValue {
72    pub fn new() -> Self {
73        ListValue {
74            items: Vec::new(),
75            version: 0,
76        }
77    }
78
79    pub fn with_items(items: Vec<Value>) -> Self {
80        ListValue { items, version: 0 }
81    }
82
83    pub fn increment_version(&mut self) {
84        self.version = self.version.wrapping_add(1);
85    }
86}
87
88/// Dictionary key type - only String and Int are supported
89#[derive(Debug, Clone, PartialEq, Eq, Hash)]
90pub enum DictKey {
91    String(String),
92    Int(i32),
93}
94
95/// Iterator state for different types
96#[derive(Debug, Clone)]
97pub enum IteratorState {
98    Range {
99        current: i32,
100        stop: i32,
101        step: i32,
102    },
103    List {
104        list: Rc<RefCell<ListValue>>,
105        index: usize,
106        version: usize, // Version at iterator creation time
107    },
108    DictKeys {
109        keys: Vec<DictKey>,
110        index: usize,
111    },
112    String {
113        chars: Vec<char>,
114        index: usize,
115    },
116}
117
118/// Exception type enumeration
119#[derive(Debug, Clone, PartialEq)]
120pub enum ExceptionType {
121    Exception,         // 基础异常
122    RuntimeError,      // 运行时错误
123    IndexError,        // 索引越界
124    KeyError,          // 键不存在
125    ValueError,        // 值错误
126    TypeError,         // 类型错误
127    ZeroDivisionError, // 除零错误
128    IteratorError,     // 迭代器错误(自定义)
129    OSError,           // 操作系统错误
130    AttributeError,    // 属性错误
131}
132
133impl ExceptionType {
134    pub fn as_i32(&self) -> i32 {
135        match self {
136            ExceptionType::Exception => 0,
137            ExceptionType::RuntimeError => 1,
138            ExceptionType::IndexError => 2,
139            ExceptionType::KeyError => 3,
140            ExceptionType::ValueError => 4,
141            ExceptionType::TypeError => 5,
142            ExceptionType::ZeroDivisionError => 6,
143            ExceptionType::IteratorError => 7,
144            ExceptionType::OSError => 8,
145            ExceptionType::AttributeError => 9,
146        }
147    }
148
149    pub fn from_i32(value: i32) -> Option<Self> {
150        match value {
151            0 => Some(ExceptionType::Exception),
152            1 => Some(ExceptionType::RuntimeError),
153            2 => Some(ExceptionType::IndexError),
154            3 => Some(ExceptionType::KeyError),
155            4 => Some(ExceptionType::ValueError),
156            5 => Some(ExceptionType::TypeError),
157            6 => Some(ExceptionType::ZeroDivisionError),
158            7 => Some(ExceptionType::IteratorError),
159            8 => Some(ExceptionType::OSError),
160            9 => Some(ExceptionType::AttributeError),
161            _ => None,
162        }
163    }
164
165    /// Check if this exception type matches the handler type
166    /// Exception matches all types (it's the base class)
167    pub fn matches(&self, handler: &ExceptionType) -> bool {
168        match handler {
169            ExceptionType::Exception => true, // Exception catches everything
170            _ => self == handler,             // Otherwise exact match
171        }
172    }
173}
174
175/// Traceback frame for exception
176#[derive(Debug, Clone)]
177pub struct TracebackFrame {
178    pub function_name: String,
179    pub line_number: usize,
180}
181
182/// Exception value structure
183#[derive(Debug, Clone)]
184pub struct ExceptionValue {
185    pub exception_type: ExceptionType,
186    pub message: String,
187    pub traceback: Option<Vec<TracebackFrame>>,
188}
189
190/// Value type for QuickPython runtime
191#[derive(Clone)]
192pub enum Value {
193    Int(i32),
194    Float(f64),
195    Bool(bool),
196    None,
197    String(String),
198    List(Rc<RefCell<ListValue>>),
199    Dict(Rc<RefCell<HashMap<DictKey, Value>>>),
200    Tuple(Rc<Vec<Value>>), // Immutable sequence
201    Slice {
202        start: Option<i32>,
203        stop: Option<i32>,
204        step: Option<i32>,
205    },
206    Iterator(Rc<RefCell<IteratorState>>),
207    Function(Function),
208    Coroutine(Function, Vec<Value>), // (async function, captured args)
209    Generator(Rc<RefCell<GeneratorState>>), // Generator object
210    AsyncSleep(f64),                 // Async sleep operation (seconds)
211    Exception(ExceptionValue),
212    Module(Rc<RefCell<Module>>),
213    NativeFunction(NativeFunction),
214    BoundMethod(Box<Value>, String), // (receiver, method_name)
215    Regex(Rc<Regex>),
216    Match(Rc<MatchObject>),
217    Type(TypeObject),
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq)]
221pub enum TypeObject {
222    Int,
223    Float,
224    Bool,
225    Str,
226    List,
227    Dict,
228    Tuple,
229    NoneType,
230}
231
232impl std::fmt::Debug for Value {
233    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234        match self {
235            Value::Int(i) => write!(f, "Int({})", i),
236            Value::Float(fl) => write!(f, "Float({})", fl),
237            Value::Bool(b) => write!(f, "Bool({})", b),
238            Value::None => write!(f, "None"),
239            Value::String(s) => write!(f, "String({:?})", s),
240            Value::List(l) => write!(f, "List({:?})", l),
241            Value::Dict(d) => write!(f, "Dict({:?})", d),
242            Value::Tuple(t) => write!(f, "Tuple({:?})", t),
243            Value::Slice { start, stop, step } => {
244                write!(f, "Slice({:?}:{:?}:{:?})", start, stop, step)
245            }
246            Value::Iterator(i) => write!(f, "Iterator({:?})", i),
247            Value::Function(func) => write!(f, "Function({:?})", func),
248            Value::Coroutine(func, _) => write!(f, "Coroutine({:?})", func.name),
249            Value::Generator(gen_rc) => {
250                let gen_state = gen_rc.borrow();
251                write!(
252                    f,
253                    "Generator({}, finished={})",
254                    gen_state.function.name, gen_state.finished
255                )
256            }
257            Value::AsyncSleep(seconds) => write!(f, "AsyncSleep({})", seconds),
258            Value::Exception(e) => write!(f, "Exception({:?})", e),
259            Value::Module(m) => write!(f, "Module({:?})", m),
260            Value::NativeFunction(_) => write!(f, "NativeFunction(<native>)"),
261            Value::BoundMethod(_, method_name) => write!(f, "BoundMethod(<{}>)", method_name),
262            Value::Regex(_) => write!(f, "Regex(<pattern>)"),
263            Value::Match(m) => write!(f, "Match({:?})", m),
264            Value::Type(t) => write!(f, "Type({:?})", t),
265        }
266    }
267}
268
269#[derive(Debug, Clone, PartialEq)]
270pub struct Function {
271    pub name: String,
272    pub params: Vec<String>,
273    pub code: ByteCode,
274    pub is_async: bool,
275    pub is_generator: bool,
276}
277
278/// Generator state for yield/resume
279#[derive(Debug, Clone)]
280pub struct GeneratorState {
281    pub function: Function,
282    pub locals: Vec<Value>,
283    pub ip: usize,
284    pub stack: Vec<Value>,
285    pub finished: bool,
286}
287
288impl Value {
289    pub fn as_int(&self) -> Option<i32> {
290        match self {
291            Value::Int(i) => Some(*i),
292            _ => None,
293        }
294    }
295
296    pub fn as_float(&self) -> Option<f64> {
297        match self {
298            Value::Float(f) => Some(*f),
299            _ => None,
300        }
301    }
302
303    pub fn as_bool(&self) -> Option<bool> {
304        match self {
305            Value::Bool(b) => Some(*b),
306            _ => None,
307        }
308    }
309
310    pub fn as_string(&self) -> Option<&str> {
311        match self {
312            Value::String(s) => Some(s),
313            _ => None,
314        }
315    }
316
317    pub fn as_list(&self) -> Option<Rc<RefCell<ListValue>>> {
318        match self {
319            Value::List(list) => Some(list.clone()),
320            _ => None,
321        }
322    }
323
324    pub fn as_dict(&self) -> Option<Rc<RefCell<HashMap<DictKey, Value>>>> {
325        match self {
326            Value::Dict(dict) => Some(dict.clone()),
327            _ => None,
328        }
329    }
330
331    /// Create an exception value
332    pub fn error(exception_type: ExceptionType, message: impl Into<String>) -> Value {
333        Value::Exception(ExceptionValue {
334            exception_type,
335            message: message.into(),
336            traceback: None,
337        })
338    }
339
340    /// Check if value is an exception
341    pub fn is_exception(&self) -> bool {
342        matches!(self, Value::Exception(_))
343    }
344
345    /// Get exception value
346    pub fn as_exception(&self) -> Option<&ExceptionValue> {
347        match self {
348            Value::Exception(exc) => Some(exc),
349            _ => None,
350        }
351    }
352
353    pub fn is_truthy(&self) -> bool {
354        match self {
355            Value::Bool(b) => *b,
356            Value::Int(i) => *i != 0,
357            Value::Float(f) => *f != 0.0,
358            Value::None => false,
359            Value::String(s) => !s.is_empty(),
360            Value::List(list) => !list.borrow().items.is_empty(),
361            Value::Dict(dict) => !dict.borrow().is_empty(),
362            Value::Tuple(tuple) => !tuple.is_empty(),
363            Value::Slice { .. } => true,
364            Value::Iterator(_) => true,
365            Value::Function(_) => true,
366            Value::Coroutine(_, _) => true,
367            Value::Generator(_) => true,
368            Value::AsyncSleep(_) => true,
369            Value::Exception(_) => true,
370            Value::Module(_) => true,
371            Value::NativeFunction(_) => true,
372            Value::BoundMethod(_, _) => true,
373            Value::Regex(_) => true,
374            Value::Match(_) => true,
375            Value::Type(_) => true,
376        }
377    }
378}
379
380impl PartialEq for Value {
381    fn eq(&self, other: &Self) -> bool {
382        match (self, other) {
383            (Value::Int(a), Value::Int(b)) => a == b,
384            (Value::Float(a), Value::Float(b)) => a == b,
385            // Mixed int/float comparison
386            (Value::Int(a), Value::Float(b)) => (*a as f64) == *b,
387            (Value::Float(a), Value::Int(b)) => *a == (*b as f64),
388            (Value::Bool(a), Value::Bool(b)) => a == b,
389            (Value::None, Value::None) => true,
390            (Value::String(a), Value::String(b)) => a == b,
391            (Value::List(a), Value::List(b)) => {
392                let a_items = &a.borrow().items;
393                let b_items = &b.borrow().items;
394                a_items == b_items
395            }
396            (Value::Dict(a), Value::Dict(b)) => Rc::ptr_eq(a, b),
397            (Value::Tuple(a), Value::Tuple(b)) => a.as_ref() == b.as_ref(),
398            (
399                Value::Slice {
400                    start: s1,
401                    stop: st1,
402                    step: step1,
403                },
404                Value::Slice {
405                    start: s2,
406                    stop: st2,
407                    step: step2,
408                },
409            ) => s1 == s2 && st1 == st2 && step1 == step2,
410            (Value::Iterator(a), Value::Iterator(b)) => Rc::ptr_eq(a, b),
411            (Value::Function(a), Value::Function(b)) => a == b,
412            (Value::Coroutine(f1, _), Value::Coroutine(f2, _)) => f1 == f2,
413            (Value::Generator(a), Value::Generator(b)) => Rc::ptr_eq(a, b),
414            (Value::AsyncSleep(a), Value::AsyncSleep(b)) => a == b,
415            (Value::Exception(a), Value::Exception(b)) => {
416                a.exception_type == b.exception_type && a.message == b.message
417            }
418            (Value::Module(a), Value::Module(b)) => Rc::ptr_eq(a, b),
419            (Value::NativeFunction(a), Value::NativeFunction(b)) => std::ptr::eq(a, b),
420            (Value::BoundMethod(a1, m1), Value::BoundMethod(a2, m2)) => a1 == a2 && m1 == m2,
421            (Value::Regex(a), Value::Regex(b)) => Rc::ptr_eq(a, b),
422            (Value::Match(a), Value::Match(b)) => Rc::ptr_eq(a, b),
423            (Value::Type(a), Value::Type(b)) => a == b,
424            _ => false,
425        }
426    }
427}