1. Need help with PD source (again)
Can anyone help me get a "continue" statement implemented in the
PD source code for my modded interpreter? I thought this would of
been an easy task, but it doesnt seem to be after all. The idea came
when people starting mentioning the "next" statement on this message
board, so that is what got me interested.
For those who dont know what this keyword is:
A "continue" statement would be for "for" & "while" loops that causes
the next iteration of the loop to begin instantly. A "for" loop will
continue by incrementing and testing its loop index. A "while" loop
will continue with a test of its conditional.
Any help would be appriciated and ofcourse acknowledged.
Btw Pete Lomax, I decided on using Daryl Border's conflict resolution
system (though I had to fix a major bug with it first) instead of
"import", but I just wanted to thank you for your help anyway
.
Thanks,
Vincent
Euphoria/VEEU v2.5 Rocks!!!
2. Re: Need help with PD source (again)
Vincent wrote:
>
> Can anyone help me get a "continue" statement implemented in the
> PD source code for my modded interpreter? I thought this would of
> been an easy task, but it doesnt seem to be after all. The idea came
> when people starting mentioning the "next" statement on this message
> board, so that is what got me interested.
>
> For those who dont know what this keyword is:
>
> A "continue" statement would be for "for" & "while" loops that causes
> the next iteration of the loop to begin instantly. A "for" loop will
> continue by incrementing and testing its loop index. A "while" loop
> will continue with a test of its conditional.
>
> Any help would be appriciated and ofcourse acknowledged.
>
>
> Btw Pete Lomax, I decided on using Daryl Border's conflict resolution
> system (though I had to fix a major bug with it first) instead of
> "import", but I just wanted to thank you for your help anyway
.
Hopefully, this will put you on the right track. I recommend taking a
look at the output of the front end, to see what you need to do. I use
dis.ex (comes with OOEU), which is where I got the output below. Basically,
you'll need to output the appropriate END loop op, then repair the
cg_stack so that it can be done again (I haven't investigated what, exactly,
you need to do for each type of loop). For example, consider the following
Euphoria code:
with trace
for i = 1 to 3 do
if i = 2 then
puts(1,"continue")
end if
? i
end for
for i = 1 to 3 by 0.5 do
if i = 2 then
puts(1,"continue")
end if
? i
end for
This gets turned into:
SubProgram [_toplevel_:00101]
1: 058 2 # STARTLINE: 2 <<for i = 1 to 3 do>>
3: 125 104 105 104 101 103 35 # FOR_I: inc [LIT 1:104], lim [LIT
3:105],
# initial [LIT 1:104], lv [i:103],
jmp 0035
10: 087 103 # DISPLAY_VAR: [i:103]
12: 058 3 # STARTLINE: 3 <<if i = 2 then>>
14: 121 103 106 23 # IFW [i:103] = [LIT 2:106] goto 0018
else
# goto 0023
18: 058 4 # STARTLINE: 4 <<puts(1,"continue")>>
20: 044 104 108 # PUTS: [LIT 1:104], [LIT
"continue":108]
23: 058 6 # STARTLINE: 6 <<? i>>
25: 036 104 103 # QPRINT: [i:103]
28: 058 7 # STARTLINE: 7 <<end for>>
30: 054 10 105 103 104 # ENDFOR_INT_UP1: top 0010, lim: [LIT
3:105],
# lv [i:103]
35: 090 103 # ERASE_SYMBOL: [i:103]
37: 058 9 # STARTLINE: 9 <<for i = 1 to 3 by 0.5
do>>
39: 021 110 105 104 101 109 71 # FOR: inc [LIT 0.5:110], lim [LIT
3:105],
# initial [LIT 1:104], lv [i:109],
jmp 0071
46: 087 109 # DISPLAY_VAR: [i:109]
48: 058 10 # STARTLINE: 10 <<if i = 2 then>>
50: 104 109 106 59 # IFW [i:109] = [LIT 2:106] goto 0054
else
# goto 0059
54: 058 11 # STARTLINE: 11 <<puts(1,"continue")>>
56: 044 104 108 # PUTS: [LIT 1:104], [LIT
"continue":108]
59: 058 13 # STARTLINE: 13 <<? i >>
61: 036 104 109 # QPRINT: [i:109]
64: 058 14 # STARTLINE: 14 <<end for>>
66: 039 46 105 109 110 # ENDFOR_GENERAL: top 0046 lim [LIT
3:105],
# inc [i:109], lv [LIT 0.5:110]
71: 090 109 # ERASE_SYMBOL: [i:109]
73: 034 # RETURNT:
End SubProgram [_toplevel_:00101]
So it's those ENDFOR_INT_UP1's and ENDFOR_GENERAL's that you need to
reproduce.
Matt Lewis
3. Re: Need help with PD source (again)
On Mon, 04 Apr 2005 03:41:10 -0700, Matt Lewis
<guest at RapidEuphoria.com> wrote:
>Vincent wrote:
>>
>> Can anyone help me get a "continue" statement implemented in the
<snip>
>> Btw Pete Lomax, I decided on using Daryl Border's conflict resolution
>> system (though I had to fix a major bug with it first) instead of
>> "import", but I just wanted to thank you for your help anyway
.
Good, I was never a fan of import.
>
Matt Lewis wrote:
>So it's those ENDFOR_INT_UP1's and ENDFOR_GENERAL's that you need to
>reproduce.
You would need additional goto's after them, to properly exit the
loop, should you be on the last iteration. I think you would be better
off jumping to the existing endfor/endwhile statement instead.
Branch straightening might tidy things up automatically, with luck.
How about duplicating AppendXList/PatchXList in parser.e?
Regards,
Pete
4. Re: Need help with PD source (again)
Pete Lomax wrote:
>
> >
> Matt Lewis wrote:
> > So it's those ENDFOR_INT_UP1's and ENDFOR_GENERAL's that you need to
> > reproduce.
>
> You would need additional goto's after them, to properly exit the
> loop, should you be on the last iteration. I think you would be better
> off jumping to the existing endfor/endwhile statement instead.
> Branch straightening might tidy things up automatically, with luck.
That seems wasteful (execution-wise) and requires changing the back end,
anyway. It was actually pretty simple to do. I basically had to create
a couple of stacks to remember the loop type, variable and the backpatch
addresses, and added a continue statement. In the for-loop case, I just
added an exit right after the ENDFOR statement (ENDWHILE just jumps back
to the while statement for evaluation). Here's what the new routine looks
like:
procedure Continue_statement()
token tok
integer bp1, bp2
sequence s
if preprocess then
CompileErr("continue not allowed in preprocessing")
end if
if not loop_stack[$] then
CompileErr( "continue must be inside of loop" )
elsif loop_stack[$] = FOR then
StartSourceLine(TRUE)
op_info1 = loop_sym_stack[$]
op_info2 = loop_bp_stack[$] + 1
s = Pop() & Pop()
Push( s[2] )
Push( s[1] )
emit_op(ENDFOR_GENERAL) -- will be set at runtime by FOR op
Push( s[2] )
Push( s[1] )
emit_op(EXIT)
AppendXList(length(Code)+1)
emit_forward_addr() -- to be back-patched
tok = next_token()
putback(tok)
elsif loop_stack[$] = WHILE then
bp1 = loop_bp_stack[$][1]
bp2 = loop_bp_stack[$][1]
StartSourceLine(TRUE)
emit_op(ENDWHILE)
emit_addr(bp1)
end if
end procedure
> How about duplicating AppendXList/PatchXList in parser.e?
I don't know what you mean by this...
Matt Lewis
5. Re: Need help with PD source (again)
- Posted by Daryl Border <darylb5 at aol.com>
Apr 04, 2005
-
Last edited Apr 05, 2005
Vincent wrote:
> Btw Pete Lomax, I decided on using Daryl Border's conflict resolution
> system (though I had to fix a major bug with it first) instead of
> "import", but I just wanted to thank you for your help anyway
.
>
>
> Thanks,
> Vincent
>
> Euphoria/VEEU v2.5 Rocks!!!
>
Vincent,
I'm glad you found it useful.
And I guess I should thank you for the micro economy money.
I would like to know what the major bug you fixed was?
Thanks, Daryl Border
6. Re: Need help with PD source (again)
On Mon, 04 Apr 2005 10:25:10 -0700, Matt Lewis
<guest at RapidEuphoria.com> wrote:
>Pete Lomax wrote:
>>
>> >
>> Matt Lewis wrote:
>> > So it's those ENDFOR_INT_UP1's and ENDFOR_GENERAL's that you need to
>> > reproduce.
>>
>> You would need additional goto's after them, to properly exit the
>> loop, should you be on the last iteration. I think you would be better
>> off jumping to the existing endfor/endwhile statement instead.
>> Branch straightening might tidy things up automatically, with luck.
>
>That seems wasteful (execution-wise)
Yes, an extra jump,... but, otoh, slightly less code
).
>and requires changing the back end,
Not sure why you think that. Please elaborate.
>anyway. It was actually pretty simple to do. I basically had to create
>a couple of stacks to remember the loop type, variable and the backpatch
>addresses, and added a continue statement. In the for-loop case, I just
>added an exit right after the ENDFOR statement (ENDWHILE just jumps back
Yes, that is the "additional goto's after them" I was referring to.
>to the while statement for evaluation). Here's what the new routine looks
>like:
>procedure Continue_statement()
<snip>
I have not yet tested that.
>> How about duplicating AppendXList/PatchXList in parser.e?
>
>I don't know what you mean by this...
OK, if your approach has worked, this is all rather moot, but I was
thinking (warning: untested code, all in parser.e):
sequence next_list -- init to {} in InitParser()
procedure AppendNList(integer addr)
-- add next location to list requiring back-patch at end of loop
next_list = append(next_list, addr)
end procedure
procedure PatchNList(integer base)
-- back-patch jump offsets for jumps to next loop
integer next_top
next_top = length(next_list)
while next_top > base do
backpatch(next_list[next_top], length(Code)+1)
next_top -= 1
end while
next_list = next_list[1..base]
end procedure
procedure Next_statement()
-- Parse a next statement
token tok
if loop_nest = 0 then
CompileErr("next statement must be inside a loop")
end if
emit_op(EXIT) -- same for "next"
AppendNList(length(Code)+1)
emit_forward_addr() -- to be back-patched
tok = next_token()
putback(tok)
NotReached(tok[T_ID], "next") --??
end procedure
--in While_statement(), insert
integer exit_base
integer next_base --<==
...
exit_base = length(exit_list)
next_base = length(next_list) --<==
...
tok_match(END)
tok_match(WHILE)
PatchNList(next_base) --<==
StartSourceLine(TRUE)
emit_op(ENDWHILE)
--and similar in For_statement().
Like I said, I have not tested it, it was just a simple suggestion I
thought would do the trick. Maybe the comparison will be useful
anyway.
BTW: feel free to replace "next" with "continue"
)
Regards,
Pete
7. Re: Need help with PD source (again)
Matt Lewis wrote:
>
> Pete Lomax wrote:
> >
> > >
> > Matt Lewis wrote:
> > > So it's those ENDFOR_INT_UP1's and ENDFOR_GENERAL's that you need to
> > > reproduce.
> >
> > You would need additional goto's after them, to properly exit the
> > loop, should you be on the last iteration. I think you would be better
> > off jumping to the existing endfor/endwhile statement instead.
> > Branch straightening might tidy things up automatically, with luck.
>
> That seems wasteful (execution-wise) and requires changing the back end,
> anyway. It was actually pretty simple to do. I basically had to create
> a couple of stacks to remember the loop type, variable and the backpatch
> addresses, and added a continue statement. In the for-loop case, I just
> added an exit right after the ENDFOR statement (ENDWHILE just jumps back
> to the while statement for evaluation). Here's what the new routine looks
> like:
> }}}
<eucode>
> procedure Continue_statement()
> token tok
> integer bp1, bp2
> sequence s
> if preprocess then
> CompileErr("continue not allowed in preprocessing")
> end if
>
> if not loop_stack[$] then
> CompileErr( "continue must be inside of loop" )
>
> elsif loop_stack[$] = FOR then
> StartSourceLine(TRUE)
> op_info1 = loop_sym_stack[$]
> op_info2 = loop_bp_stack[$] + 1
> s = Pop() & Pop()
> Push( s[2] )
> Push( s[1] )
> emit_op(ENDFOR_GENERAL) -- will be set at runtime by FOR op
> Push( s[2] )
> Push( s[1] )
> emit_op(EXIT)
> AppendXList(length(Code)+1)
> emit_forward_addr() -- to be back-patched
> tok = next_token()
> putback(tok)
>
> elsif loop_stack[$] = WHILE then
> bp1 = loop_bp_stack[$][1]
> bp2 = loop_bp_stack[$][1]
> StartSourceLine(TRUE)
> emit_op(ENDWHILE)
> emit_addr(bp1)
>
> end if
>
> end procedure
> </eucode>
{{{
>
> > How about duplicating AppendXList/PatchXList in parser.e?
>
> I don't know what you mean by this...
>
> Matt Lewis
>
Awasome Matt & Pete, thanks so much for responding ...
I've implemented the "continue" keyword in emit.e, keylist.e,
opnames.e, and reswords.e. Matt, I implemented your
Continue_statement() in parser.e.
In parser.e I made stacks variables to hold the values in
For_statement() and While_statement().. like this
(tell me if Im wrong)..
... While_statement() *parser.e*
loop stack
----------
loop_nest += 1
loop_stack &= WHILE <<--- (should this be T_ID instead?)
loop backpatch stack
--------------------
(bp1)
bp1 = length(Code)+1
loop_bp_stack &= bp1 <<--- here
(bp2)
if not optimized_while then
-- WHILE was emitted or combined into IFW op
bp2 = length(Code)+1
loop_bp_stack &= bp2 <<--- here
emit_forward_addr() -- will be patched
else -- WHILE TRUE was optimized to nothing
bp2 = 0
loop_bp_stack &= bp2 <<--- here
end if
... For_statement() *parser.e*
loop stack
----------
loop_nest += 1
loop_stack &= FOR <<--- here
loop variable symbol stack
--------------------------
loop_var_sym = loop_var[T_SYM]
loop_sym_stack &= loop_var_sym <<--- here
loop backpatch stack
--------------------
bp1 = length(Code)+1
loop_bp_stack &= bp1 <<--- here
Matt... I noticed in Continue_statement(), you put
s = Pop() & Pop()
and I'm not sure whats in it.. could you post the Pop() code
and tell where I could place the routine?
I got this error...
------------------------------------
C:\DOCUME~1\Vincent\Desktop\OFFICI~1\parser.e:923
Pop has not been declared
s = Pop() & Pop()
^
------------------------------------
I'm not sure what I should add in execute.e (backend) to
opFOR(), opFOR_GENERAL(), opENDFOR_INT_UP1(), opWHILE(),
etc..
Also I tracked "exit" (perhaps associated feature) here in
InitBackEnd() in execute.e...
elsif find(name, {"EXIT", "ENDWHILE"}) then
name = "ELSE"
I think opELSE is associated with that..
===============================================
Please Reply Matt and/or Pete :)
Thanks,
Vincent
Euphoria/VEEU v2.5 Rocks!!!
8. Re: Need help with PD source (again)
Daryl Border wrote:
> Vincent,
> I'm glad you found it useful.
Daryl Border,
Yea its very cool.. It works like Matt Lewis's system in his
Modified v2.4 interpreter, no? If Im not mistaken this was
the little namespace improvement Rob was planning for Euphoria v2.5,
if so this is even cooler than it sounded.
> I would like to know what the major bug you fixed was?
Ok.. maybe not a "major" bug.. but when Ryan Johnson tried VEEU
(my modded interpreter) with his FluidAE platform on Windows..
he got an error. H.W Overman (Euman) tried VEEU with various
EuGTK examples on his linux box, they both got this error...
.\symtab.e:397 in function keyfind()
second argument of find() must be a sequence
I was able to track this problem to this these lines..
if length(dup_globals) > 1 then
-- duplicate global symbols found
for i = length(dup_globals) to 1 by -1 do
dup = dup_globals[i]
if find(SymTab[dup][S_FILE_NO], include_paths[current_file_no]) then
temp_dups &= dup -- symbol found in the include path
end if
end for
if length(temp_dups) = 1 then -- the include path resolves the conflict
dup_globals = temp_dups
dup = temp_dups[1]
gtok = {SymTab[dup][S_TOKEN], dup} -- set the correct token
end if
end if
I tried changing the first line of the "if" block, with this...
if length(dup_globals) > 1 and sequence(include_paths[current_file_no]) then
When Ryan and Euman tried again, there was no more find() error, thus the
line wont be scanned until a sequence is found in current_file_no index
"include_paths[current_file_no]" (this is odd, it should be a sequence
always?), so to tell you the truth, I'm not even entirly sure I fixed the
issue (if it's even an issue with your code and not Euphoria), I just know
that I eliminated the error message problem, and my "global conflict"
example programs work.
> And I guess I should thank you for the micro economy money.
No, that wasnt me that voted for it, but now that you mention it
I would be delighted to vote a couple bucks for it.. It was
quite useful... plus your name is mentioned in my feature documents
as reciginition for using your code in my interpreter. You may have
to wait a couple weeks though for me to vote, because I spent all
three microeconomy bucks late last month on Mark Honnor's
(Liquid-Nitrogen) "Squid Blaster" game. :P
> Thanks, Daryl Border
>
Regards,
Vincent
Euphoria/VEEU v2.5 Rocks!!!
9. Re: Need help with PD source (again)
Pete Lomax wrote:
>
> On Mon, 04 Apr 2005 10:25:10 -0700, Matt Lewis
> <guest at RapidEuphoria.com> wrote:
>
> >Pete Lomax wrote:
> >>
> >> >
> >> Matt Lewis wrote:
> >> > So it's those ENDFOR_INT_UP1's and ENDFOR_GENERAL's that you need to
> >> > reproduce.
> >>
> >> You would need additional goto's after them, to properly exit the
> >> loop, should you be on the last iteration. I think you would be better
> >> off jumping to the existing endfor/endwhile statement instead.
> >> Branch straightening might tidy things up automatically, with luck.
> >
> >That seems wasteful (execution-wise)
> Yes, an extra jump,... but, otoh, slightly less code
).
> >and requires changing the back end,
> Not sure why you think that. Please elaborate.
Aha. Now that I see your code, I understand what you're saying. I was
thinking that there's no simple GOTO opcode in the interpreter, but of
course, there is, and it's called EXIT. You just have to backpatch the
address. Very slick.
>
> Like I said, I have not tested it, it was just a simple suggestion I
> thought would do the trick. Maybe the comparison will be useful
> anyway.
Definitely useful. Have to consider whether slightly larger code
(about 5 opcodes per use of next/continue) vs the extra jump.
Matt Lewis
10. Re: Need help with PD source (again)
Vincent wrote:
>
> Matt Lewis wrote:
> >
> > Pete Lomax wrote:
>
> Awasome Matt & Pete, thanks so much for responding ...
>
> I've implemented the "continue" keyword in emit.e, keylist.e,
> opnames.e, and reswords.e. Matt, I implemented your
> Continue_statement() in parser.e.
>
> In parser.e I made stacks variables to hold the values in
> For_statement() and While_statement().. like this
> (tell me if Im wrong)..
Here's how I did it. The loop_bp_stack is different based on whether
it's a WHILE or FOR loop:
procedure For_statement()
-- ...
emit_addr(0) -- will be patched - don't straighten
-- begin mwl
loop_stack &= FOR
loop_sym_stack &= loop_var_sym
loop_bp_stack &= bp1
-- end mwl
-- ...
-- begin mwl
loop_stack = loop_stack[1..$-1]
loop_sym_stack = loop_sym_stack[1..$-1]
loop_bp_stack = loop_bp_stack[1..$-1]
-- ene mwl
end procedure
procedure While_statement()
-- ...
-- begin mwl
loop_stack &= WHILE
loop_sym_stack &= 0
loop_bp_stack &= {{bp1, bp2}}
-- end mwl
call_proc(forward_Statement_list, {})
-- ...
-- begin mwl
loop_stack = loop_stack[1..$-1]
loop_sym_stack = loop_sym_stack[1..$-1]
loop_bp_stack = loop_bp_stack[1..$-1]
-- ene mwl
end procedure
> Matt... I noticed in Continue_statement(), you put
>
> s = Pop() & Pop()
>
> and I'm not sure whats in it.. could you post the Pop() code
> and tell where I could place the routine?
Pop() is defined in emit.e. I just made it and Push() global. They
manipulate the cg_stack (code generation stack). Basically, an ENDFOR
opcode pops two values off the stack. Since I'm adding an 'artificial'
ENDFOR, I need to duplicate the top two items on the stack.
> I'm not sure what I should add in execute.e (backend) to
> opFOR(), opFOR_GENERAL(), opENDFOR_INT_UP1(), opWHILE(),
> etc..
Don't need to change anything in execute.e, since you're using already
defined opcodes, just in a more creative way.
You also need to add a call to Continue_statement() into the giant
if-elsif statements in Statement_list() and parser() in parser.e.
Matt Lewis
11. Re: Need help with PD source (again)
On Mon, 2005-04-04 at 19:35 -0700, Vincent wrote:
> .\symtab.e:397 in function keyfind()
> second argument of find() must be a sequence
> if find(SymTab[dup][S_FILE_NO], include_paths[current_file_no])
changed to:
if find(SymTab[dup][S_FILE_NO], {include_paths[current_file_no]})
fixed Linux from issuing an error and all eugtk demo's function
properly.
Euman
12. Re: Need help with PD source (again)
- Posted by Vincent <darkvincentdude at yahoo.com>
Apr 05, 2005
-
Last edited Apr 06, 2005
h4x3r wrote:
>
> On Mon, 2005-04-04 at 19:35 -0700, Vincent wrote:
>
> > .\symtab.e:397 in function keyfind()
> > second argument of find() must be a sequence
>
> > if find(SymTab[dup][S_FILE_NO], include_paths[current_file_no])
>
> changed to:
> if find(SymTab[dup][S_FILE_NO], {include_paths[current_file_no]})
>
> fixed Linux from issuing an error and all eugtk demo's function
> properly.
>
> Euman
>
Euman,
That method prevents the error message from occuring.. but then the
conflict resolution system doesnt work at all, that defeats the whole
purpose to have it implemented, and would only add unnessasary internal
overhead. I think you might of forgotten that I mentioned that happened,
in the chatroom.
Regards,
Vincent
Euphoria v2.5 Rocks!!!
13. Re: Need help with PD source (again)
- Posted by Pete Lomax <petelomax at blueyonder.co.uk>
Apr 05, 2005
-
Last edited Apr 06, 2005
On Tue, 05 Apr 2005 13:43:41 -0400, h4x3r <h4x3r at bellsouth.net> wrote:
>> if find(SymTab[dup][S_FILE_NO], include_paths[current_file_no])
>
>changed to:
>if find(SymTab[dup][S_FILE_NO], {include_paths[current_file_no]})
>
If you think about that carefully, you may as well as not have
replaced it with the equivalent:
>if equal(SymTab[dup][S_FILE_NO],include_paths[current_file_no])
but as Vincent notes it just breaks everything anyway.
Does Vincent's solution of replacing the previous
if length(dup_globals) > 1 then
with
if length(dup_globals) > 1 and
sequence(include_paths[current_file_no]) then
fix it properly, or cause a different problem?
Regards,
Pete
14. Re: Need help with PD source (again)
Pete Lomax wrote:
>
> On Tue, 05 Apr 2005 13:43:41 -0400, h4x3r <h4x3r at bellsouth.net> wrote:
>
> >> if find(SymTab[dup][S_FILE_NO], include_paths[current_file_no])
> >
> >changed to:
> >if find(SymTab[dup][S_FILE_NO], {include_paths[current_file_no]})
> >
> If you think about that carefully, you may as well as not have
> replaced it with the equivalent:
> >if equal(SymTab[dup][S_FILE_NO],include_paths[current_file_no])
> but as Vincent notes it just breaks everything anyway.
>
> Does Vincent's solution of replacing the previous
>
> if length(dup_globals) > 1 then
>
> with
>
> if length(dup_globals) > 1 and
> sequence(include_paths[current_file_no]) then
>
> fix it properly, or cause a different problem?
>
>
> Regards,
> Pete
>
>
It seems to fix the problem, while still being fully functional.
Ive tested Matt's conflict demos that came with his modified eu v2.4
interpreter.. and the ones that came with Daryl Border's updated pd
source files... they all worked. plus i did alot of testing with
different programs and there doesnt seem to be any new problems.
(thank goodness, I've had enough problems as it is, and just fixed
them PPPlleease no more :P, heh..)
And "continue" is almost done, i will post back when Im finished,
maybe in a hour or so (after testing) :D.
Regards,
Vincent
Without walls and fences, there is no need for Windows and Gates.