Re: Operator overloading

David Hakim <dhakim-Gkm/TONP9n1Wk0Htik3J/[email protected]> Sun, 16 Mar 2003 13:34:05 -0500
Newsgroups gmane.comp.lang.moto.devel
Message-ID <[email protected]>
On Sunday, March 16, 2003, at 07:36  AM, Stefano Corsi wrote:

> Dave,
>
> as I told you I take the task of implementing operator overloading.
> Here are my initial notes.  Let me know if I'm on the right path.
>
> Goal
> --------------
>
> Operator overloading should be provided at the moment for externally 
> defined
> objects. We could use a C like syntax in mxc .i files. Something like:
>
> Object operator SymbolTable::[] (String) =>
> 	void *stab_get(SymbolTable *this, char *key);
>
> where substantially the operator is defined like a method or function 
> with the
> addition of the operator keyword. (Do we need the keyword? I suppose 
> yes.
> Otherwise, could we distinguish methods from operators only by the 
> character
> set used in the name definition?)
>
I don't know that we need the keyword. It seems to me to be a question 
of parse-ability. Does yacc complain when the operator keyword is not 
present?

> For the time being it will be possible to overload ONLY a small set of
> operators. We will define a set of rules in mx.y and mx.l so that the
> programmer will get an error message if he tries to overload operators 
> that
> at the present cannot be overloaded.
>
Good idea

> [ Question: will it be possible in the future to let the programmer 
> overload
> whatever operator and even new ones (those that are not actually 
> handled by
> moto)? What changes would be needed in moto.y and moto.l? ]
>
I don't believe it would be possible to let extension authors overload 
operators that aren't specifically parsed by moto.l and moto.y . There 
is an idea of 'mixins' I've seen in some other languages but I'm not 
sure if those are such a good idea.

> We want to let programmers overload:
>
> 	+ (arg1, arg2)
> 	+= (arg1, arg2)
> 	- (arg1, arg2)
> 	-= (arg1, arg2)
> 	++ (arg)
> 	-- (arg)
> 	[] (arg)		get
> 	[] (arg1, arg2)	set
>
I think initially this set is fine. I might also add 'eq' and 'ne' to 
the list as a way of overloading Object equality

> Changes needed
> -------------------
>
> - Add new syntax for operator in mx.y.
> - Modify mxcg.c and other mxc files to handle new syntax and rules.
> - Modify motov.c, motoi.c, motoc.c to handle overloading in
> 	
> 	motoX_domath();
> 	motoX_lval
> 	motoX_rval	
>
lval and rval will be fun ... I apologize in advance :)

> - Add tests
>
> Mx.y syntax changes
> ------------------------
>
> 1) Add a new terminal "operator"
> 2) Add new non-terminal:
> 	- m_operator_name (the name of the operator could be restricted at 
> the flex
> level to only the operators that we allow to overload??)

yes ... and if there is parser ambiguity we can even go farther to add 
a secondary parse state where an operator is expected to mx.l

> 3) Modify non-terminal
> 	- m_function_declaration
> 	- m_function_declarator
> to include also the case when the operator keyword is used.
>
> Other mxc changes
> ---------------------
>
> Overloaded operators could be implemented as functions or methods that 
> take
> operands as parameters and return a value.
> So we modify the code for M_FUNCTION_DECLARATION and 
> M_FUNCTION_DECLARATOR
> case labels in mxcg.c to set a proper function name in case the 
> function or
> method is an operator. Characters as "+ - += -= []" etc... should not 
> be part
> of a function name, so we have to find a sustitute name for them (plus,
> minus, pluseq, etc...) We should modify also mfn_symbolName mfn.c for
> handling operator functions and methods.
>
Yes ... we should probably generate the same sort of symbols C++ does 
since that's what I model all my other generated symbol names after

> MotoX changes
> ------------------
>
> In motoX.c we have to discover, for any single case, if there's an 
> operator
> for the object that handles the specific operation. How could we do it?
>
You will want to call the function :

int
motox_lookupMethodOrFn(
	MotoFunction **f,
	MotoVal* self,
	char* fbasename,
	int argc,
	char** types,
	int opcode
)

Note that this function is new to moto 0.19.0

f corresponds to a MotoFunction* that will be set if an appropriate 
function or method is discovered

The 'self' motoval  we only need to pass for those operators that 
correspond to methods. Its type is used for building the fully 
qualified method name i.e. "Vector::[]"

fbasename will likely just be "+" or "[]" or "eq" in the case of 
operators. The basename really corresponds to the function name we're 
looking for

argc is the number of types being passed to the function or method we 
are looking for. In the case of operators its going to be either 1 or 
2. types are the string types of the operands.

opcode will either be FN or METHOD. For all binary operators we 
probably want to pass FN. For unary operators we likely want to pass 
METHOD

This function returns FTAB_OK and sets f if a function named 
'self->type :: fbasename' with argc arguments of argt types is found

Otherwise it returns either FTAB_NONE (no such function or method) or 
FTAB_MULTIPLE if more than one possible function is found.

> I have found this piece of code in motoi_new:
>
> /* Fill in the types array for constructor identification */
> motoi_fillArgs(argc,args,argv,types);
>
> /* Generate the Moto name for this Constructor */
> fname = moto_createMotonameForFn(classname,classname);
>
> /* Retrieve the MXFN record */
> code = ftab_cacheGet(env->ftable, &mfn, fname, argc, types);
> free(fname);
>
> We could create a function get_operator or similar that handles all 
> this:
>
> MFN * get_operator(char * oper_name, MotoType * op1, MotoType * op2);
>
> This function should return a pointer to a operator function or NULL 
> if no
> operator is defined for those operands.
>
> ... to be continued ...
>
Great design so far!

-Dave