diff --git a/valuescript_compiler/src/asm.rs b/valuescript_compiler/src/asm.rs index c5bddda..bb5bc75 100644 --- a/valuescript_compiler/src/asm.rs +++ b/valuescript_compiler/src/asm.rs @@ -141,7 +141,7 @@ impl std::fmt::Display for Function { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Class { pub constructor: Value, pub prototype: Value, @@ -348,6 +348,7 @@ pub enum Value { String(String), Array(Box), Object(Box), + Class(Box), Register(Register), Pointer(Pointer), Builtin(Builtin), @@ -395,6 +396,11 @@ impl Value { v.visit_values_mut(visit); } } + Value::Class(class) => { + class.constructor.visit_values_mut(visit); + class.prototype.visit_values_mut(visit); + class.static_.visit_values_mut(visit); + } Value::Void => {} Value::Undefined => {} Value::Null => {} @@ -424,6 +430,11 @@ impl Value { k.visit_registers_mut_rev(visit); } } + Value::Class(class) => { + class.constructor.visit_registers_mut_rev(visit); + class.prototype.visit_registers_mut_rev(visit); + class.static_.visit_registers_mut_rev(visit); + } Value::Void => {} Value::Undefined => {} Value::Null => {} @@ -466,6 +477,7 @@ impl std::fmt::Display for Value { ), Value::Array(value) => write!(f, "{}", value), Value::Object(value) => write!(f, "{}", value), + Value::Class(class) => write!(f, "{}", class), Value::Register(value) => write!(f, "{}", value), Value::Pointer(value) => write!(f, "{}", value), Value::Builtin(value) => write!(f, "{}", value), diff --git a/valuescript_compiler/src/assembler.rs b/valuescript_compiler/src/assembler.rs index 53175b5..3f06cca 100644 --- a/valuescript_compiler/src/assembler.rs +++ b/valuescript_compiler/src/assembler.rs @@ -288,6 +288,7 @@ impl Assembler { Value::Undefined => self.output.push(ValueType::Undefined as u8), Value::Array(array) => self.array(array), Value::Object(object) => self.object(object), + Value::Class(class) => self.class(class), Value::Pointer(pointer) => self.pointer(pointer), Value::Builtin(builtin) => self.builtin(builtin), } diff --git a/valuescript_compiler/src/module_compiler.rs b/valuescript_compiler/src/module_compiler.rs index 0de5f8b..d7996e6 100644 --- a/valuescript_compiler/src/module_compiler.rs +++ b/valuescript_compiler/src/module_compiler.rs @@ -949,6 +949,6 @@ impl ModuleCompiler { } pub fn static_ec(&mut self) -> StaticExpressionCompiler { - StaticExpressionCompiler { mc: self } + StaticExpressionCompiler::new(self) } } diff --git a/valuescript_compiler/src/optimization/extract_constants.rs b/valuescript_compiler/src/optimization/extract_constants.rs index b73af1a..54b309e 100644 --- a/valuescript_compiler/src/optimization/extract_constants.rs +++ b/valuescript_compiler/src/optimization/extract_constants.rs @@ -100,6 +100,7 @@ fn should_extract_value_as_constant(value: &Value) -> Option { None } } + Value::Class(_) => Some("class".to_string()), } } @@ -120,6 +121,11 @@ fn is_constant(value: &Value) -> bool { .properties .iter() .all(|(k, v)| is_constant(k) && is_constant(v)), + Value::Class(class) => { + is_constant(&class.constructor) + && is_constant(&class.prototype) + && is_constant(&class.static_) + } } } diff --git a/valuescript_compiler/src/optimization/kal.rs b/valuescript_compiler/src/optimization/kal.rs index 64d4ffb..1ad113c 100644 --- a/valuescript_compiler/src/optimization/kal.rs +++ b/valuescript_compiler/src/optimization/kal.rs @@ -1,6 +1,7 @@ use num_bigint::BigInt; use valuescript_vm::{ operations, unicode_at, + vs_class::VsClass, vs_object::VsObject, vs_value::{number_to_index, ToVal, Val}, }; @@ -46,6 +47,7 @@ pub enum Kal { String(String), Array(Box), Object(Box), + Class(Box), Register(Register), Pointer(Pointer), Builtin(Builtin), @@ -61,6 +63,13 @@ pub struct Object { pub properties: Vec<(Kal, Kal)>, } +#[derive(Clone)] +pub struct Class { + pub constructor: Kal, + pub prototype: Kal, + pub static_: Kal, +} + impl Kal { fn visit_kals_mut(&mut self, visit: &mut F) where @@ -80,6 +89,11 @@ impl Kal { v.visit_kals_mut(visit); } } + Kal::Class(class) => { + class.constructor.visit_kals_mut(visit); + class.prototype.visit_kals_mut(visit); + class.static_.visit_kals_mut(visit); + } Kal::Unknown => {} Kal::Void => {} Kal::Undefined => {} @@ -113,6 +127,11 @@ impl Kal { .map(|(k, v)| (Kal::from_value(k), Kal::from_value(v))) .collect(), })), + Value::Class(class) => Kal::Class(Box::new(Class { + constructor: Kal::from_value(&class.constructor), + prototype: Kal::from_value(&class.prototype), + static_: Kal::from_value(&class.static_), + })), Value::Register(reg) => Kal::Register(reg.clone()), Value::Pointer(p) => Kal::Pointer(p.clone()), Value::Builtin(b) => Kal::Builtin(b.clone()), @@ -164,6 +183,11 @@ impl Kal { properties }, }))), + Kal::Class(class) => Some(Value::Class(Box::new(asm::Class { + constructor: class.constructor.try_to_value()?, + prototype: class.prototype.try_to_value()?, + static_: class.static_.try_to_value()?, + }))), Kal::Register(x) => Some(Value::Register(x.clone())), Kal::Pointer(x) => Some(Value::Pointer(x.clone())), Kal::Builtin(x) => Some(Value::Builtin(x.clone())), @@ -202,6 +226,12 @@ impl Kal { } .to_val() } + Kal::Class(class) => VsClass { + constructor: class.constructor.try_to_val()?, + prototype: class.prototype.try_to_val()?, + static_: class.static_.try_to_val()?, + } + .to_val(), Kal::Void | Kal::Register(..) | Kal::Pointer(..) | Kal::Builtin(..) => { return None; @@ -222,6 +252,7 @@ impl Kal { Kal::String(s) => Some(s.clone()), Kal::Array(_) => None, Kal::Object(_) => None, + Kal::Class(_) => None, Kal::Register(_) => None, Kal::Pointer(_) => None, Kal::Builtin(_) => None, @@ -641,6 +672,11 @@ impl FnState { Kal::Object(Box::new(Object { properties })) } + Value::Class(class) => Kal::Class(Box::new(Class { + constructor: self.eval_arg(&mut class.constructor), + prototype: self.eval_arg(&mut class.prototype), + static_: self.eval_arg(&mut class.static_), + })), Value::Register(reg) => { let kal = self.get(reg.name.clone()).clone(); diff --git a/valuescript_compiler/src/optimization/try_to_val.rs b/valuescript_compiler/src/optimization/try_to_val.rs index 0848efb..5b9134e 100644 --- a/valuescript_compiler/src/optimization/try_to_val.rs +++ b/valuescript_compiler/src/optimization/try_to_val.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use valuescript_vm::{ + vs_class::VsClass, vs_object::VsObject, vs_value::{ToVal, Val}, }; @@ -43,6 +44,12 @@ impl TryToVal for Value { } .to_val() } + Value::Class(class) => VsClass { + constructor: class.constructor.try_to_val()?, + prototype: class.prototype.try_to_val()?, + static_: class.static_.try_to_val()?, + } + .to_val(), Value::Void | Value::Register(..) | Value::Pointer(..) | Value::Builtin(..) => { return Err("Invalid argument".to_val()); diff --git a/valuescript_compiler/src/visit_pointers.rs b/valuescript_compiler/src/visit_pointers.rs index e0fe816..1e9853e 100644 --- a/valuescript_compiler/src/visit_pointers.rs +++ b/valuescript_compiler/src/visit_pointers.rs @@ -87,6 +87,11 @@ where Object(object) => { self.object(owner, object); } + Class(class) => { + self.value(owner, &mut class.constructor); + self.value(owner, &mut class.prototype); + self.value(owner, &mut class.static_); + } Pointer(pointer) => { (self.visitor)(match owner { Some(owner) => PointerVisitation::Reference(owner, pointer), diff --git a/valuescript_vm/src/lib.rs b/valuescript_vm/src/lib.rs index 18c9a90..2682080 100644 --- a/valuescript_vm/src/lib.rs +++ b/valuescript_vm/src/lib.rs @@ -21,7 +21,7 @@ mod string_methods; mod todo_fn; mod virtual_machine; pub mod vs_array; -mod vs_class; +pub mod vs_class; mod vs_function; pub mod vs_object; mod vs_symbol;