Adding Custom Operators

Feb 4, 2010 at 3:57 PM

Roman,

I've been searching around in the code for a way to add some new binary operators for the interpreter, but I cannot find a way to get them handled by the DynamicCallDispatcher.

It looks like the LanguageRuntime::InitOperatorImplementations() function is where the OperatorImplementationTable gets initialized.  However, the InitOperatorImplementations function is virtual (implying that it could be overridden by subclasses), but the table itself is private.  The only other function that currently adds to this table is also private (AddImplementation).  Right now, the InitOperatorImplementations function creates a new table and assigns it to the private _baseOperatorImplementations data member.  It seems like it would be better to have the function return a table that the caller can place into the _baseOperatorImplementations data member since it is a virtual function.

I saw in the comments for the LanguageRuntime that the table that is initialized is the "base" that everything gets copied from, and that it "can be extended on the fly to include extra implementations with arg conversions".  What do you mean by this?

Currently, I've been making custom AstNode classes to act as the binary operators that I want / need (since the only use for a custom binary implementation is during execution with an AST).  Is this the intended approach to solving this issue?

Brian

Coordinator
Feb 4, 2010 at 5:13 PM

Hi

yes, this area is not quite done yet, so there are a lot of inconsitencies there; one of the things is "private" attr for the table field. Try to do some workaround for now, do some hacks if you need to. I will revisit this area and make sure I have extensibility scenario. "can be extended..." - I mean that "Init" method creates only implementations for matching argument types, like "int32 + int32". When binOpExpression needs to evaluate "int32 + int16", the implementation is not there - so it is created on the fly at runtime; by taking implementation method from "int32 + int32" and adding a conversion method for the second argument "int16->int32". The newly created record is added to the implementations table.

This dispatch code needs a big revision in general. The problem is that different languages use different symbols for operators and even for the same symbol (like "|") use different implementation. But currently in Irony the implementation is associated with particular symbol - this should change, there must be an extra mapping layer between symbols and implementations. I'm working on this as well. For now do some hacks - make the table field and AddImplementation method protected, override Init method and add your own operators.

Sorry for inconvenience

Roman

Feb 4, 2010 at 5:27 PM

Ah, that's pretty cool.  I have no problems creating the AstNode classes for this use; I just wasn't sure if that was the way I was supposed to or not.  (I didn't even think to look for a different method of doing it until just recently!)

I look forward to what you come up with!  Great work so far!  Irony is amazingly flexible and extremely fast.  I'm using it to write a "calculation engine" or sorts for a much larger project, and it's parsing and executing some fairly complex expressions in about a third of a millisecond (.37 ms).  And most of that time is spent processing the data rather than being consumed by Irony!

Brian