Re: Phix : variable types

new topic     » goto parent     » topic index » view thread      » older message » newer message
katsmeow said...

Was looking for "goto" or the other flow control keywords. I didn't see any mention of it in the section about differences between OE and Phix. Ergo, on that one word, i was confused about if it existed in Phix, or not, or if you had improved on it's performance from OE, or maybe i simply could not find it in the docs.

The following (draft) text is copied from pops.e, and yes it should be tidied up and added to the docs somewhere (there should really be an Internals/#ilASM section, or something, but there's only one of me):

-- A brief note from the author about goto. 
-- ======================================== 
--  The subject of many a holy war, perhaps the most compelling argument against 
--  goto is that were it not pure evil we would all still be coding in assembly. 
--  High level constructs, such as if, for, while, procedure, and so on, along 
--  with sensible indentation, clearly make code far easier to read/understand. 
-- 
--  There is no shame in using a sensibly-named flag to control processing, and  
--  in many cases that additional sensible name also improves code legibility. 
-- 
--  There is no hll goto statement in Phix. However goto/jmp is unavoidable in 
--  assembly programming, and of course Phix supports inline assembly, hence in  
--  the very rare cases a goto is genuinely needed in hll code (I have seen just 
--  /three/ in the last two decades), the following construct(s) may be used: 
-- 
--          #ilASM{ jump :meaningful_label } 
--          ... 
--          #ilASM{ ::meaningful_label } 
-- 
--  In top level code, label scope is restricted to a single ilASM construct,  
--  but within a routine, the scope is across all the ilASM in that routine.  
-- 
--  There is quite deliberately no support for jumping from the middle of one  
--  routine into another: without a frame, then quite simply parameters and  
--  local variables have not been allocated and cannot be used/referenced. 
--  (See also global labels discussed below.) 
-- 
--  Making "goto" somewhat more difficult to type in this manner ensures that 
--  it is far less likely to be abused, and discourages newbie programmers  
--  from adopting it as a weapon of choice, as usually(/always) happens with  
--  a hll goto. 
-- 
--  Ultimately, and paradoxically, the real problem with goto is that as soon 
--  as they get daisy-chained together, something will inevitably end up in  
--  the wrong place, usually with no clue as to how or why they got there. 
--  Minor savings when writing code should of course always be balanced against 
--  potential wasted time trying to understand or debug it at some later date. 
--  Meaningless label names (eg "label4") make code substantially harder to  
--  understand. Error handling is much better and easier with normal hll code  
--  such as "return error(..)" or "error(..); return" - not only will any  
--  diagnostics have a clear "called from", but you can pass any required  
--  arguments, have just one error handler which serves several different  
--  routines, and very easily write unit tests for it - which you simply  
--  cannot do should it be embedded as a label inside something else. 
--  It is plain wrong to use more than one "goto" a year in hll code, the 
--  only real justification is when you find an algorithm which works and 
--  there is no simple way to replace jumps with proper hll constructs, or 
--  (extremely rarely) when doing so significantly impacts performance. 
 
-- Global Labels: (design notes) 
-- ============================= 
--  These were added to enable the replacement of (closed source) asm back end  
--  code with (open source) hll/#ilASM. In particular, tests showed that getc()  
--  would suffer badly with an opFrame/opCall overhead, besides it might prove  
--  rather difficult to ever implement opFrame/opCall via themselves! 
-- 
--  The "brief note about goto" above explained the use of local labels, which 
--  are deliberately rather limited due to the opFrame requirement. It is also 
--  possible to declare global labels, which are superficially similar however  
--  quite different internally, and have a different set of restrictions: 
-- 
--          #ilASM{ call :%unique_label } 
--          ... 
--          #ilASM{ jmp :skip 
--                 :%unique_label 
--                  ret 
--                 ::skip } 
-- 
--  Global labels cannot be declared inside a routine, since without an opFrame  
--  there are no parameters or local variables, and as shown (almost always)  
--  require a skip construct. It is up to the programmer to ensure global labels  
--  are unique across the entire application, including any and all third party 
--  sources, and as mentioned above anything already set in pttree.e/iload().  
--  Note that global labels are both declared and referenced with ":%".  
--  
--  Whereas local labels are resolved using various offsets and are automatically 
--  converted into short form when the offset fits in a byte, global labels are 
--  resolved as absolute addresses. Since they are intended to be used with call,  
--  which has no short form, no such similar packing is attempted. 
-- 
--  To implement global labels I added several new tables to pglobals.e (glblused etc) 
--  and opLogPos to pops.e. The latter records the x86 offset in pilx86.e, which is 
--  adjusted at the end of scanforShortJmp() in pemit.e (and used in blurph()). 
-- 
--  Since global labels were implemented for the specific purpose of migrating back 
--  end code, use with caution, particularly so for any shared code. There is no 
--  attempt to permit the use of namespaces or anything similar. You may want to 
--  minimise the risk of clashes by using eg "printPL20130508" instead of "print". 

HTH, Pete

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu