|
|
| version 1.17, 2001/02/25 13:23:01 | version 1.27, 2001/03/10 11:18:14 |
|---|---|
| Line 5 | Line 5 |
| #ifndef PA_VCLASS_H | #ifndef PA_VCLASS_H |
| #define PA_VCLASS_H | #define PA_VCLASS_H |
| #include "pa_value.h" | #include "pa_valiased.h" |
| #include "pa_vhash.h" | #include "pa_vhash.h" |
| #include "pa_vstring.h" | |
| #include "pa_vjunction.h" | #include "pa_vjunction.h" |
| #define CLASS_NAME "CLASS" | #define CLASS_NAME "CLASS" |
| #define BASE_NAME "BASE" | #define BASE_NAME "BASE" |
| class VClass : public Value { | class VClass : public VAliased { |
| public: // Value | public: // Value |
| // all: for error reporting after fail(), etc | // all: for error reporting after fail(), etc |
| const char *type() const { return "Class"; } | const char *type() const { return "class"; } |
| // object_class: (field)=STATIC.value;(STATIC)=hash;(method)=method_ref with self=object_class | // object_class: (field)=STATIC.value;(STATIC)=hash;(method)=method_ref with self=object_class |
| Value *get_element(const String& aname) { | Value *get_element(const String& aname); |
| // $NAME=my name | |
| if(aname==NAME_NAME) | |
| return NEW VString(name()); | |
| // $CLASS=my class=myself | |
| if(aname==CLASS_NAME) | |
| return this; | |
| // $BASE=my parent | |
| if(aname==BASE_NAME) | |
| return base(); | |
| // $method=junction(this+method) | |
| if(Method *method=static_cast<Method *>(methods().get(aname))) { | |
| Junction& j=*NEW Junction(pool(), | |
| *this, | |
| method,0,0,0,0); | |
| return NEW VJunction(j); | |
| } | |
| // $field=static field | |
| return get_field(aname); | |
| } | |
| // object_class, operator_class: (field)=value - static values only | // object_class, operator_class: (field)=value - static values only |
| void put_element(const String& name, Value *value) { | void put_element(const String& name, Value *value); |
| set_field(name, value); | |
| } | |
| // object_class, object_instance: object_class | // object_class, object_instance: object_class |
| VClass *get_class() { return this; } | VClass *get_class() { return this; } |
| public: // usage | public: // usage |
| VClass(Pool& apool) : | VClass(Pool& apool) : VAliased(apool, *this), |
| Value(apool), | fbase(0), |
| fields(apool), | ffields(apool), |
| fmethods(apool), | fmethods(apool) { |
| fbase(0) { | |
| } | } |
| void add_method(const String& name, Method& method) { | void add_method(const String& name, Method& method) { |
| fmethods.put(name, &method); | fmethods.put(name, &method); |
| } | } |
| Hash& methods() { return fmethods; } | // Hash& methods() { return fmethods; } |
| void set_base(VClass& abase) { | void set_base(VClass& abase) { |
| // remember the guy | // remember the guy |
| fbase=&abase; | fbase=&abase; |
| // append base_method to my methods unless already there is one | |
| // 'virtual' here | |
| fmethods.merge_dont_replace(abase.methods()); | |
| } | } |
| VClass *base() { return fbase; } | VClass *base() { return fbase; } |
| bool is_or_derived_from(VClass& vclass) { | |
| return | |
| this==&vclass || | |
| fbase && fbase->is_or_derived_from(vclass); | |
| } | |
| Junction *get_junction(VAliased& self, const String& name) { | |
| if(Method *method=static_cast<Method *>(fmethods.get(name))) | |
| return NEW Junction(pool(), self, this, method, 0,0,0,0); | |
| if(fbase) | |
| return fbase->get_junction(self, name); | |
| return 0; | |
| } | |
| void set_field(const String& name, Value *value) { | |
| if(fbase && fbase->replace_field(name, value)) | |
| return; | |
| ffields.put(name, value); | |
| } | |
| private: | private: |
| Value *get_field(const String& name) { | Value *get_field(const String& name) { |
| Value *result=static_cast<Value *>(fields.get(name)); | Value *result=static_cast<Value *>(ffields.get(name)); |
| if(!result && fbase) | if(!result && fbase) |
| result=fbase->get_field(name); | result=fbase->get_field(name); |
| return result; | return result; |
| } | } |
| void set_field(const String& name, Value *value) { | |
| if(fbase && fbase->replace_field(name, value)) | |
| return; | |
| fields.put(name, value); | |
| } | |
| bool replace_field(const String& name, Value *value) { | bool replace_field(const String& name, Value *value) { |
| return | return |
| (fbase && fbase->replace_field(name, value)) || | (fbase && fbase->replace_field(name, value)) || |
| fields.put_replace(name, value); | ffields.put_replace(name, value); |
| } | } |
| private: | private: |
| VClass *fbase; | VClass *fbase; |
| Hash fields; | Hash ffields; |
| Hash fmethods; | Hash fmethods; |
| }; | }; |