1. Need help with PD source (again)
- Posted by Vincent <darkvincentdude at yahoo.com> Apr 03, 2005
- 427 views
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)
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Apr 04, 2005
- 414 views
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)
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Apr 04, 2005
- 410 views
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)
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Apr 04, 2005
- 423 views
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
- 426 views
- 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)
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Apr 05, 2005
- 425 views
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)
- Posted by Vincent <darkvincentdude at yahoo.com> Apr 05, 2005
- 409 views
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)
- Posted by Vincent <darkvincentdude at yahoo.com> Apr 05, 2005
- 453 views
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)
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Apr 05, 2005
- 419 views
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)
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Apr 05, 2005
- 428 views
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)
- Posted by h4x3r <h4x3r at bellsouth.net> Apr 05, 2005
- 416 views
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
- 395 views
- 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
- 422 views
- 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)
- Posted by Vincent <darkvincentdude at yahoo.com> Apr 06, 2005
- 446 views
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.