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!!!