dynamic methods
Posted: Fri Aug 07, 2009 2:58 pm
by John Munro >> Tue, 24 Jun 2008 21:41:06 GMT
I'm working on a feature that is (to some extent) similar to features of dynamic languages - I need to be able to add properties and methods to a class dynamically at runtime.
Between JadeDynamicObject and process.executeTransientMethod I can fake dynamic properties - the JadeDynamicObject can store dynamic property values, and to get the compiler to cooperate I insert code into the method just before it's executed.
For example if you had an Integer dynamic property called "count" with a value of 10 and the developer typed in the method
count := count + 1;
the compiler would complain because there isn't a static property called "count". So this code is inserted before the method:
vars
count : Integer;begin
count := jdo.getPropertyValue("count").Integer;
and this code is appended to the method:
epilog
jdo.setPropertyValue("count", count);
end;
and everything compiles and the dynamic property can be read and updated. Obviously it gets more complicated if the developer types in a method with a vars or epilog section, but it still works. An alternate strategy would be to pass the dynamic properties as io parameters to the developer's method:
temp(count : Integer io);
The problem I have is in faking dynamic methods. The reason the above strategies work is that properties, variables and io parameters act in an interchangeable manner, but methods don't really work interchangeably with anything else.
The only thing I can think of is introducing a non-Jade language element and replacing it with a sendMsg call just before execution. For example if you had a dynamic method called "myMeth" which returned an Integer, and the developer wrote this
write !myMeth + 1;
the method would be modified to this before execution
write process.executeTransientMethod(myDynamicMethods["myMeth"], self).Integer + 1;
and it would compile and run the dynamic method. It introduces some compiler-style work to make sure that the dynamic method exists, sorting out its parameters and return type etc, but it should work.
The thing I don't like about this solution is that it messes up the
code offsets in compiler errors and exceptions because what Jade is executing is no longer exactly what the developer wrote. Fixing that involves tracking all of the places where substitutions were made in order to translate the code offset back to a position in the original code...
Any thoughts? Other than "don't bother"?
John
I'm working on a feature that is (to some extent) similar to features of dynamic languages - I need to be able to add properties and methods to a class dynamically at runtime.
Between JadeDynamicObject and process.executeTransientMethod I can fake dynamic properties - the JadeDynamicObject can store dynamic property values, and to get the compiler to cooperate I insert code into the method just before it's executed.
For example if you had an Integer dynamic property called "count" with a value of 10 and the developer typed in the method
count := count + 1;
the compiler would complain because there isn't a static property called "count". So this code is inserted before the method:
vars
count : Integer;begin
count := jdo.getPropertyValue("count").Integer;
and this code is appended to the method:
epilog
jdo.setPropertyValue("count", count);
end;
and everything compiles and the dynamic property can be read and updated. Obviously it gets more complicated if the developer types in a method with a vars or epilog section, but it still works. An alternate strategy would be to pass the dynamic properties as io parameters to the developer's method:
temp(count : Integer io);
The problem I have is in faking dynamic methods. The reason the above strategies work is that properties, variables and io parameters act in an interchangeable manner, but methods don't really work interchangeably with anything else.
The only thing I can think of is introducing a non-Jade language element and replacing it with a sendMsg call just before execution. For example if you had a dynamic method called "myMeth" which returned an Integer, and the developer wrote this
write !myMeth + 1;
the method would be modified to this before execution
write process.executeTransientMethod(myDynamicMethods["myMeth"], self).Integer + 1;
and it would compile and run the dynamic method. It introduces some compiler-style work to make sure that the dynamic method exists, sorting out its parameters and return type etc, but it should work.
The thing I don't like about this solution is that it messes up the
code offsets in compiler errors and exceptions because what Jade is executing is no longer exactly what the developer wrote. Fixing that involves tracking all of the places where substitutions were made in order to translate the code offset back to a position in the original code...
Any thoughts? Other than "don't bother"?
John