How to experiment with changes to compiler?

13 views
Skip to first unread message

Jimmy Johnson

unread,
Feb 12, 2015, 10:13:44 PM2/12/15
to eiffelst...@googlegroups.com
Manu, I have been trying to figure out how the compiler is organized.  It is very slow going, so I was hoping to get some help with this project.  I want to modify the compiler to either 1) add functionality to the byte code (seems hard), or 2) preprocess a system to output a new system with my code injected into the classes.

1)  I need a new construct a "my_word statement" consisting of a new keyword "my_word" followed by a reference to a non-void, non-basic object.
I assume I would modify eiffel.l to add the keyword and eiffel.y to recognize a my_word statement.  

2)  I need to inject code after an assignment (or creation) on an attribute

3)  I need new code to be added that is called only at the time a class invariant *would* be called (assertions on or off). 

My intuition tells me it would be easier to pre-process and then output new a new system which is then compiled.  (The injected code could be wrapped in a procedure call.)  Of course I don't want to do this until the original code (plus the one added statement) compiles.

I've looked at UNIVERSE_I and the BYTE_NODE classes, but I am very overwhelmed.  Any direction anyone could give to help me understand the compiler would be greatly appreciated.

thanks,
jjj

Emmanuel Stapf

unread,
Feb 16, 2015, 9:26:52 AM2/16/15
to eiffelst...@googlegroups.com
> 1) I need a new construct a "my_word statement" consisting of a new keyword
> "my_word" followed by a reference to a non-void, non-basic object.
> I assume I would modify eiffel.l to add the keyword and eiffel.y to recognize a
> my_word statement.

This is correct.

> 2) I need to inject code after an assignment (or creation) on an attribute

This can be done indeed by preprocessing the Eiffel code or by generating new code during code generation.

> 3) I need new code to be added that is called only at the time a class
> invariant *would* be called (assertions on or off).

Currently an invariant is only verified when you perform a qualified call. Our implementation checks this before and after the call.

For #2 and #3, it seems easier to simply modify the ASSIGN_B classes. For simplicity I'll just focus on finalized code. In this case modify ASSIGN_BL.generate_assignment to change the code generated for an assignment so that it adds what you need there.

For #1, I'm not sure what the new construct does, so I cannot really tell which way is better.

Regards,
Manu

Jimmy Johnson

unread,
Feb 17, 2015, 5:16:49 PM2/17/15
to eiffelst...@googlegroups.com, ma...@eiffel.com
On Monday, February 16, 2015 at 9:26:52 AM UTC-5, Emmanuel Stapf wrote:
> 1)  I need a new construct a "my_word statement" consisting of a new keyword
> "my_word" followed by a reference to a non-void, non-basic object.
> I assume I would modify eiffel.l to add the keyword and eiffel.y to recognize a
> my_word statement.

This is correct.

> 2)  I need to inject code after an assignment (or creation) on an attribute

This can be done indeed by preprocessing the Eiffel code or by generating new code during code generation.
 
> 3)  I need new code to be added that is called only at the time a class
> invariant *would* be called (assertions on or off).

Currently an invariant is only verified when you perform a qualified call. Our implementation checks this before and after the call.

For #2 and #3, it seems easier to simply modify the ASSIGN_B classes. For simplicity I'll just focus on finalized code. In this case modify ASSIGN_BL.generate_assignment to change the code generated for an assignment so that it adds what you need there.
I looked at ASSIGN_BL.generate_assignment and followed through to ASSIGN_BL.generate_normal_assignment where I see calls such as buf.put_string ("RTAR(").  I assume these are calls to C methods?
So, can my generated byte code be in the form of a call to an Eiffel routine?  What do I put to the buf for a procedure of function call?

 

Emmanuel Stapf

unread,
Feb 18, 2015, 2:48:52 AM2/18/15
to Jimmy Johnson, eiffelst...@googlegroups.com
> I looked at ASSIGN_BL.generate_assignment and followed through to
> ASSIGN_BL.generate_normal_assignment where I see calls such as buf.put_string
> ("RTAR("). I assume these are calls to C methods?
> So, can my generated byte code be in the form of a call to an Eiffel
> routine? What do I put to the buf for a procedure of function call?

I was referring to the assignment and changing the code after the assignment to do what you want. If now you want to call an Eiffel routine, then it might be best to change the generated byte nodes further up in the chain to add the call to the Eiffel routine and then let the code generation as is.

I would go in {AST_FEATURE_CHECKER_GENERATOR}.process_assign_as and there change the place where the ASSIGN_B instance is generated to actually generate an instance of an INSTR_LIST_B with the ASSIGN_B previously generated as well as your feature call, usually an instance of FEATURE_B.

Regards,
Manu

Reply all
Reply to author
Forward
0 new messages