Skip to content

Commit

Permalink
Unify operator inheritance
Browse files Browse the repository at this point in the history
With this, there no longer is any ambiguity regarding when/how an operator can be inherited, since type-types can now explicitly declare callbacks that will be used to inherit operators.

Also: Add a dedicated type `Dee_operator_t` to use instead of `uint16_t` in order to represent an operator ID.
  • Loading branch information
GrieferAtWork committed Apr 19, 2024
1 parent bbfb71a commit 78dca07
Show file tree
Hide file tree
Showing 59 changed files with 1,038 additions and 751 deletions.
15 changes: 9 additions & 6 deletions cpp.hint
Original file line number Diff line number Diff line change
Expand Up @@ -1397,16 +1397,16 @@


// Misc. local macros
#define DEFINE_OPERATOR_INVOKE(name,instance_name)struct Dee_operator_invoke name={};DeeObject *invoke_##name(DeeTypeObject*tp_self,DeeObject*self,DeeObject**p_self,size_t argc,DeeObject*const*argv)
#define DEFINE_STRING_TRAIT(n,function,test_ch) DeeObject*string_##n(String*self,size_t argc,DeeObject*const*argv);
#define DEFINE_ANY_STRING_TRAIT(n,function) DeeObject*string_##n(String*self,size_t argc,DeeObject*const*argv,DeeObject*kw);
#define DEFINE_BYTES_TRAIT(n,function,test_ch) DeeObject*bytes_##n(Bytes*self,size_t argc,DeeObject*const*argv);
#define DEFINE_ANY_BYTES_TRAIT(n,function) DeeObject*bytes_##n(Bytes*self,size_t argc,DeeObject*const*argv,DeeObject*kw);
#define DEFINE_OPERATOR_INVOKE(name,...)struct Dee_operator_invoke name={};DeeObject *invoke_##name(DeeTypeObject*tp_self,DeeObject*self,DeeObject**p_self,size_t argc,DeeObject*const*argv)
#define DEFINE_STRING_TRAIT(n,...) DeeObject*string_##n(String*self,size_t argc,DeeObject*const*argv);
#define DEFINE_ANY_STRING_TRAIT(n,...) DeeObject*string_##n(String*self,size_t argc,DeeObject*const*argv,DeeObject*kw);
#define DEFINE_BYTES_TRAIT(n,...) DeeObject*bytes_##n(Bytes*self,size_t argc,DeeObject*const*argv);
#define DEFINE_ANY_BYTES_TRAIT(n,...) DeeObject*bytes_##n(Bytes*self,size_t argc,DeeObject*const*argv,DeeObject*kw);
#define SUPER_PRIVATE_EXPANDARGS(...) (DeeTypeObject *tp_self, __VA_ARGS__)
#define DEFINE_OPERATOR(return,n,args) return DeeObject_T##n SUPER_PRIVATE_EXPANDARGS args{} return DeeObject_##n args
#define DEFINE_INTERNAL_OPERATOR(return,n,args) return DeeObject_T##n SUPER_PRIVATE_EXPANDARGS args{} return DeeObject_##n args
#define DEFINE_FILE_OPERATOR(return,n,args) return DeeFile_T##n SUPER_PRIVATE_EXPANDARGS args{} return DeeFile_##n args
#define DEFINE_MATH_INPLACE_INT_OPERATOR(DeeObject_InplaceXXX,reg,DeeInt_NewXXX,intX_t,operator_name) int DeeObject_InplaceXXX(DeeObject**restrict p_self,intX_t val){}
#define DEFINE_MATH_INPLACE_INT_OPERATOR(n,a,b,c,...) int n(DeeObject**restrict p_self,c val){}
#define DEFINE_JSON_ITERATOR_COMPARE(n,...) DeeObject*n(DeeJsonIteratorObject*self,DeeJsonIteratorObject*other){}
#define DEF_STRING(n,a,b,c) DeeStringObject n={};
#define RESTRICT_IF_NOTYPE
Expand Down Expand Up @@ -1631,6 +1631,9 @@
#define DEFINE_CCALL_OPTIMIZATION(name,...) int name(struct fungen*self,vstackaddr_t argc){}
#define DEFINE_CCALL_OPERATOR(name,...) int name(struct fungen*self,vstackaddr_t argc){}

#define DEFINE_FILETYPE_INHERIT_HOOK(x,...) bool x(DeeFileTypeObject*self,DeeTypeObject*type_type,struct Dee_opinfo const*info){}
#define DEFINE_TYPE_INHERIT_HOOK(x,...) bool x(DeeTypeObject*self,DeeTypeObject*type_type,struct Dee_opinfo const*info){}

#define memstate_foreach(...) for(;;)
#define memstate_foreach_end
#define _memval_foreach_obj(...) for(;;)
Expand Down
44 changes: 22 additions & 22 deletions include/deemon/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,20 +324,20 @@ class_attribute_mayaccess_impl(struct Dee_class_attribute *__restrict self,
struct Dee_class_operator {
/* TODO: It must be possible to define operators by-name (as in: "string"), and have the
* `DeeClass_New()' resolve that name using `DeeTypeType_GetOperatorById(Dee_TYPE(base))' */
uint16_t co_name; /* [const] Operator name (`(uint16_t)-1' for end-of-chain) */
uint16_t co_addr; /* [const] Operator address (within the class member table `cd_members').
* Operators are invoked like attributes with the following flags:
* `Dee_CLASS_ATTRIBUTE_FMETHOD|Dee_CLASS_ATTRIBUTE_FCLASSMEM', meaning
* they are invoked as this-calls, with the callback itself stored
* in class memory.
* WARNING: When overwriting the value of a class operator after the previous
* one has already been used may not actually function, as operators
* get cached upon first use, such-as to allow for operators to be
* inherited from base-classes in order to ensure O(1) execution time.
* HINT: When the pointed-to class member is `NULL' (unbound), operator
* search won't continue, but rather cause a not-implemented error
* to be thrown, thus allowing you to explicitly delete an operator
* by simply declaring it, but not assigning a callback. */
Dee_operator_t co_name; /* [const] Operator name (`(Dee_operator_t)-1' for end-of-chain) */
uint16_t co_addr; /* [const] Operator address (within the class member table `cd_members').
* Operators are invoked like attributes with the following flags:
* `Dee_CLASS_ATTRIBUTE_FMETHOD|Dee_CLASS_ATTRIBUTE_FCLASSMEM', meaning
* they are invoked as this-calls, with the callback itself stored
* in class memory.
* WARNING: When overwriting the value of a class operator after the previous
* one has already been used may not actually function, as operators
* get cached upon first use, such-as to allow for operators to be
* inherited from base-classes in order to ensure O(1) execution time.
* HINT: When the pointed-to class member is `NULL' (unbound), operator
* search won't continue, but rather cause a not-implemented error
* to be thrown, thus allowing you to explicitly delete an operator
* by simply declaring it, but not assigning a callback. */
};


Expand Down Expand Up @@ -432,7 +432,7 @@ struct Dee_class_descriptor_object {
* place when no constructor has actually been defined). */
uint16_t cd_cmemb_size; /* [const] The allocation size of the class member table. */
uint16_t cd_imemb_size; /* [const] The allocation size of the instance member table. */
uint16_t cd_clsop_mask; /* [const] Mask for the `cd_clsop_list' hash-vector. */
Dee_operator_t cd_clsop_mask; /* [const] Mask for the `cd_clsop_list' hash-vector. */
size_t cd_cattr_mask; /* [const] Mask for the `cd_cattr_list' hash-vector. */
size_t cd_iattr_mask; /* [const] Mask for the `cd_cattr_list' hash-vector. */
struct Dee_class_operator *cd_clsop_list; /* [1..cd_clsop_mask+1][owned_if(!= INTERNAL(empty-class-operator-table))]
Expand Down Expand Up @@ -820,36 +820,36 @@ DeeClass_New(DeeObject *bases, DeeObject *descriptor,
* a NotImplemented error, or return NULL and don't throw
* an error when `DeeClass_TryGetOperator()' was used. */
DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL
DeeClass_GetOperator(DeeTypeObject const *__restrict self, uint16_t name);
DeeClass_GetOperator(DeeTypeObject const *__restrict self, Dee_operator_t name);

/* Same as `DeeClass_GetOperator()', but don't simply return `NULL'
* if the operator hasn't been implemented, and `ITER_DONE' when it
* has been, but wasn't assigned anything. */
DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL
DeeClass_TryGetOperator(DeeTypeObject const *__restrict self, uint16_t name);
DeeClass_TryGetOperator(DeeTypeObject const *__restrict self, Dee_operator_t name);

/* Same as `DeeClass_TryGetOperator()', but don't return an operator
* that has been inherited from a base-class, but return `NULL' instead. */
DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL
DeeClass_TryGetPrivateOperator(DeeTypeObject const *__restrict self, uint16_t name);
DeeClass_TryGetPrivateOperator(DeeTypeObject const *__restrict self, Dee_operator_t name);

/* Convenience wrappers for `DeeObject_ThisCall(DeeClass_GetOperator())' */
DFUNDEF WUNUSED ATTR_INS(5, 4) NONNULL((1, 2)) DREF DeeObject *DCALL
DeeClass_CallOperator(DeeTypeObject const *__restrict tp_self, DeeObject *self,
uint16_t name, size_t argc, DeeObject *const *argv);
Dee_operator_t name, size_t argc, DeeObject *const *argv);
DFUNDEF WUNUSED NONNULL((1, 2, 4)) DREF DeeObject *
DeeClass_CallOperatorf(DeeTypeObject const *__restrict tp_self, DeeObject *self,
uint16_t name, char const *format, ...);
Dee_operator_t name, char const *format, ...);
DFUNDEF WUNUSED NONNULL((1, 2, 4)) DREF DeeObject *DCALL
DeeClass_VCallOperatorf(DeeTypeObject const *__restrict tp_self, DeeObject *self,
uint16_t name, char const *format, va_list args);
Dee_operator_t name, char const *format, va_list args);


#ifdef CONFIG_BUILDING_DEEMON

/* Same as `DeeClass_TryGetPrivateOperator()', but don't return a reference */
INTDEF ATTR_PURE WUNUSED NONNULL((1)) DeeObject *DCALL
DeeClass_TryGetPrivateOperatorPtr(DeeTypeObject const *__restrict self, uint16_t name);
DeeClass_TryGetPrivateOperatorPtr(DeeTypeObject const *__restrict self, Dee_operator_t name);

/* The functions bound to the C-level type callbacks when a
* user-defined class provides the associated operator.
Expand Down
4 changes: 2 additions & 2 deletions include/deemon/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -1393,8 +1393,8 @@ struct Dee_function_info {
DREF DeeTypeObject *fi_type; /* [0..1] The type as part of which a function is implemented. */
DREF struct Dee_string_object *fi_name; /* [0..1] The name of the function. */
DREF struct Dee_string_object *fi_doc; /* [0..1] A documentation string for the function. */
uint16_t fi_opname; /* When the function is implementing an operator, the name of that operator.
* Otherwise, this field is set to `(uint16_t)-1'
Dee_operator_t fi_opname; /* When the function is implementing an operator, the name of that operator.
* Otherwise, this field is set to `(Dee_operator_t)-1'
* NOTE: When this field is set, `fi_name' is usually set to `NULL' */
uint16_t fi_getset; /* When the function is a getset callback, one of `CLASS_GETSET_*'.
* Otherwise, this field is set to `(uint16_t)-1' */
Expand Down
10 changes: 5 additions & 5 deletions include/deemon/compiler/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1730,29 +1730,29 @@ ast_gen_setrange(struct ast *__restrict sequence,
INTDEF WUNUSED NONNULL((2)) int DCALL
ast_gen_operator_func(struct ast *binding,
struct ast *ddi_ast,
uint16_t operator_name);
Dee_operator_t operator_name);

INTDEF WUNUSED NONNULL((1, 3)) int DCALL
ast_gen_symbol_inplace(struct symbol *__restrict sym,
struct ast *operand,
struct ast *ddi_ast,
uint16_t inplace_operator_name,
Dee_operator_t inplace_operator_name,
bool is_post_operator,
unsigned int gflags);
INTDEF WUNUSED NONNULL((1, 2, 4)) int DCALL
ast_gen_setattr_inplace(struct ast *__restrict base,
struct ast *__restrict name,
struct ast *operand,
struct ast *ddi_ast,
uint16_t inplace_operator_name,
Dee_operator_t inplace_operator_name,
bool is_post_operator,
unsigned int gflags);
INTDEF WUNUSED NONNULL((1, 2, 4)) int DCALL
ast_gen_setitem_inplace(struct ast *__restrict base,
struct ast *__restrict index,
struct ast *operand,
struct ast *ddi_ast,
uint16_t inplace_operator_name,
Dee_operator_t inplace_operator_name,
bool is_post_operator,
unsigned int gflags);
INTDEF WUNUSED NONNULL((1, 2, 3, 5)) int DCALL
Expand All @@ -1761,7 +1761,7 @@ ast_gen_setrange_inplace(struct ast *__restrict base,
struct ast *__restrict end,
struct ast *operand,
struct ast *ddi_ast,
uint16_t inplace_operator_name,
Dee_operator_t inplace_operator_name,
bool is_post_operator,
unsigned int gflags);

Expand Down
10 changes: 5 additions & 5 deletions include/deemon/compiler/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -743,13 +743,13 @@ DECLARE_AST_GENERATOR(NONNULL((1)), ast_expand, (struct ast *__restrict expr));
/* [AST_FUNCTION] */
DECLARE_AST_GENERATOR(NONNULL((1, 2)), ast_function, (struct ast *__restrict function_code, DeeBaseScopeObject *__restrict scope));
/* [AST_OPERATOR_FUNC] */
DECLARE_AST_GENERATOR(, ast_operator_func, (uint16_t operator_name, struct ast *binding));
DECLARE_AST_GENERATOR(, ast_operator_func, (Dee_operator_t operator_name, struct ast *binding));
/* [AST_OPERATOR] @param: operator_name: One of `OPERATOR_*'.
* @param: flags: Set of `AST_OPERATOR_F*' */
DECLARE_AST_GENERATOR(NONNULL((3)), ast_operator1, (uint16_t operator_name, uint16_t flags, struct ast *__restrict opa));
DECLARE_AST_GENERATOR(NONNULL((3, 4)), ast_operator2, (uint16_t operator_name, uint16_t flags, struct ast *__restrict opa, struct ast *__restrict opb));
DECLARE_AST_GENERATOR(NONNULL((3, 4, 5)), ast_operator3, (uint16_t operator_name, uint16_t flags, struct ast *__restrict opa, struct ast *__restrict opb, struct ast *__restrict opc));
DECLARE_AST_GENERATOR(NONNULL((3, 4, 5, 6)), ast_operator4, (uint16_t operator_name, uint16_t flags, struct ast *__restrict opa, struct ast *__restrict opb, struct ast *__restrict opc, struct ast *__restrict opd));
DECLARE_AST_GENERATOR(NONNULL((3)), ast_operator1, (Dee_operator_t operator_name, uint16_t flags, struct ast *__restrict opa));
DECLARE_AST_GENERATOR(NONNULL((3, 4)), ast_operator2, (Dee_operator_t operator_name, uint16_t flags, struct ast *__restrict opa, struct ast *__restrict opb));
DECLARE_AST_GENERATOR(NONNULL((3, 4, 5)), ast_operator3, (Dee_operator_t operator_name, uint16_t flags, struct ast *__restrict opa, struct ast *__restrict opb, struct ast *__restrict opc));
DECLARE_AST_GENERATOR(NONNULL((3, 4, 5, 6)), ast_operator4, (Dee_operator_t operator_name, uint16_t flags, struct ast *__restrict opa, struct ast *__restrict opb, struct ast *__restrict opc, struct ast *__restrict opd));
/* [AST_ACTION] @param: action_flags: One of `AST_FACTION_*' (see above). */
DECLARE_AST_GENERATOR(, ast_action0, (uint16_t action_flags));
DECLARE_AST_GENERATOR(NONNULL((2)), ast_action1, (uint16_t action_flags, struct ast *__restrict act0));
Expand Down
4 changes: 2 additions & 2 deletions include/deemon/compiler/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,13 @@ ast_parse_operator_name(uint16_t features);
* @param: flags: Set of `AST_OPERATOR_F*'
* WARNING: This flags set may not contain `AST_OPERATOR_FVARARGS'! */
INTDEF WUNUSED NONNULL((3, 4)) DREF struct ast *DCALL
ast_build_bound_operator(uint16_t name, uint16_t flags,
ast_build_bound_operator(Dee_operator_t name, uint16_t flags,
struct ast *__restrict self,
struct ast *__restrict args);

/* Same as `ast_build_bound_operator', but used to build free-standing operators. */
INTDEF WUNUSED NONNULL((3)) DREF struct ast *DCALL
ast_build_operator(uint16_t name, uint16_t flags,
ast_build_operator(Dee_operator_t name, uint16_t flags,
struct ast *__restrict args);

/* Parse a loop statement that appears in an expression:
Expand Down
2 changes: 1 addition & 1 deletion include/deemon/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ DFUNDEF WUNUSED ATTR_INS(4, 3) NONNULL((1)) Dee_ssize_t
* NOTE: This function also accepts "fake" operators (`FAKE_OPERATOR_*') for `name' */
DFUNDEF WUNUSED ATTR_INS(6, 5) NONNULL((1, 3)) Dee_ssize_t DCALL
DeeFormat_PrintOperatorRepr(Dee_formatprinter_t printer, void *arg,
DeeObject *self, uint16_t name,
DeeObject *self, Dee_operator_t name,
size_t argc, DeeObject *const *argv,
char const *self_prefix, size_t self_prefix_len,
char const *self_suffix, size_t self_suffix_len);
Expand Down
Loading

0 comments on commit 78dca07

Please sign in to comment.