flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
bitRAKE 26 Feb 2025, 23:10
In the past I've created some small tables I thought were missing from the manual - just a dense refresher of organized concepts. Whether you’re working with forward references, blank symbols, or numeric constants, the following cheat sheet explains fasmg's behavior in one place - with code.
Code: ; Some things to note: ; + variable symbols are different based on where they are defined ; - similar to forward symbols if already defined ; - similar to undefined symbols if not defined, yet ; + blank symbols are special case(s) (that depth will catch you!) ; + defined symbols resolve to their values ; (regardless if they are forward/variable symbols) ; + floats can be compared to integers ; ; absent ; symbol not present, by design ; This can NOT be forward referenced: ; (It doesn't matter because there is no code above.) restore vary define vary blank iterate TYPE,\ absent,\ ; ~defined, ~definite vfwd,\ ; ~defined, ~definite, forward variable same as absent blank,\ ; defined, special case here,\ ; defined, forward resolves to blank value vary,\ ; defined, variable resolves to blank value 1,-1,0,\ ; definite reg+2,\ ; defined, ~definite '',\ ; definite 0.0,0.1,-3.2 ; definite display 10,`TYPE,9 if defined TYPE display ' defined,' ; blank special cases match ,TYPE display ' blank' else match temp,TYPE ; special case, deref blanks match ,temp display ' blank+' else ; note: blanks can be nested deep ; (we stop early, assuming all symbols resolve to non-blank) if definite TYPE display ' definite, ' if TYPE eqtype '' display 'string' else if TYPE eqtype 0 ; algebraic display 'algebraic, ' if TYPE relativeto 0 display 'integer, ' if TYPE > 0 display 'positive' else if TYPE < 0 display 'negative' else if TYPE = 0 display 'zero' else display 'ERROR' end if else display 'unknown',10 end if else if TYPE eqtype 0.0 ; float display 'float, ' if TYPE > 0 display 'positive' else if TYPE < 0 display 'negative' else if TYPE = 0 display 'zero' else display 'ERROR' end if else display 'unknown',10 end if else display '~definite, algebraic, linear polynomial' end if end match end match end match else display '~defined' end if end iterate ; These can all be forward referenced, above: define blank ; blank define here blank ; present and defined, but resulting in blank element reg ; algebraic term ; This can NOT be forward referenced, code above doesn't "see" it: restore vfwd define vfwd blank Code: absent ~defined vfwd ~defined blank defined, blank here defined, blank+ vary defined, blank+ 1 defined, definite, algebraic, integer, positive -1 defined, definite, algebraic, integer, negative 0 defined, definite, algebraic, integer, zero reg+2 defined,~definite, algebraic, linear polynomial '' defined, definite, string 0.0 defined, definite, float, zero 0.1 defined, definite, float, positive -3.2 defined, definite, float, negative ![]() |
|||
![]() |
|
dosmancer 27 Feb 2025, 17:45
Nice tables! They might be handy as a reference.
I tried to add some more tests out of curiosity: Code: ; Some things to note: ; + variable symbols are different based on where they are defined ; - similar to forward symbols if already defined ; - similar to undefined symbols if not defined, yet ; + blank symbols are special case(s) (that depth will catch you!) ; + defined symbols resolve to their values ; (regardless if they are forward/variable symbols) ; + floats can be compared to integers ; ; absent ; symbol not present, by design ; This can NOT be forward referenced: ; (It doesn't matter because there is no code above.) restore vary define vary blank iterate TYPE,\ absent,\ ; ~defined, ~definite vfwd,\ ; ~defined, ~definite, forward variable same as absent blank,\ ; defined, special case here,\ ; defined, forward resolves to blank value vary,\ ; defined, variable resolves to blank value 1,-1,0,\ ; definite reg+2,\ ; defined, ~definite '',\ ; definite 0.0,0.1,-3.2,\ ; definite x,\ y,\ z display 10,`TYPE,9 if defined TYPE display ' defined,' ; blank special cases match ,TYPE display ' blank' else match temp,TYPE ; special case, deref blanks match ,temp display ' blank+' else ; note: blanks can be nested deep ; (we stop early, assuming all symbols resolve to non-blank) if definite TYPE display ' definite, ' if TYPE eqtype '' display 'string' else if TYPE eqtype 0 ; algebraic display 'algebraic, ' if TYPE relativeto 0 display 'integer, ' if TYPE > 0 display 'positive' else if TYPE < 0 display 'negative' else if TYPE = 0 display 'zero' else display 'ERROR' end if else display 'unknown',10 end if else if TYPE eqtype 0.0 ; float display 'float, ' if TYPE > 0 display 'positive' else if TYPE < 0 display 'negative' else if TYPE = 0 display 'zero' else display 'ERROR' end if else display 'unknown',10 end if else display '~definite, algebraic, linear polynomial' end if end match end match end match else display '~defined' end if end iterate ; These can all be forward referenced, above: define blank ; blank define here blank ; present and defined, but resulting in blank element reg ; algebraic term ; This can NOT be forward referenced, code above doesn't "see" it: restore vfwd define vfwd blank ; some more tests define x 1 y = 2 define z y Output: Code: absent ~defined vfwd ~defined blank defined, blank here defined, blank+ vary defined, blank+ 1 defined, definite, algebraic, integer, positive -1 defined, definite, algebraic, integer, negative 0 defined, definite, algebraic, integer, zero reg+2 defined,~definite, algebraic, linear polynomial '' defined, definite, string 0.0 defined, definite, float, zero 0.1 defined, definite, float, positive -3.2 defined, definite, float, negative x defined, definite, algebraic, integer, positive y defined,~definite, algebraic, linear polynomial z defined,~definite, algebraic, linear polynomial I guessed what the output would be but was wrong about z which I thought would be definite, but think about it I think it makes sense... The "linear polynomial" for y and z are wrong too (I suppose) but that's because the code assumes it's a linear polynomial if the thing is not definite (I think). |
|||
![]() |
|
bitRAKE 27 Feb 2025, 20:59
`z` will resolve to whatever `y` is, imho.
I'm surprised `y = 2` is ~definite - even `y := 2` is ~definite which is a constant. Yet, if we move the statement before then both `y=2` and `y:=2` are definite - as expected. Honestly, not sure why this is the case. |
|||
![]() |
|
bitRAKE 27 Feb 2025, 21:07
Abstracting out the type resolution:
Code: macro typetype ITEM* if ITEM eqtype '' display 'string' else if ITEM eqtype 0 ; algebraic display 'algebraic, ' if ITEM relativeto 0 display 'integer, ' if ITEM > 0 display 'positive' else if ITEM < 0 display 'negative' else if ITEM = 0 display 'zero' else display 'ERROR' end if else display 'linear polynomial' end if else if ITEM eqtype 0.0 ; float display 'float, ' if ITEM > 0 display 'positive' else if ITEM < 0 display 'negative' else if ITEM = 0 display 'zero' else display 'ERROR' end if else display 'unknown',10 end if end macro |
|||
![]() |
|
dosmancer 27 Feb 2025, 21:14
bitRAKE wrote: `z` will resolve to whatever `y` is, imho. Yes, I was dumb. bitRAKE wrote: `I'm surprised `y = 2` is ~definite - even `y := 2` is ~definite which is a constant. `defined` is true if the thing is defined anywhere in the code. `definite` becomes true if thing thing is defined anywhere in the code before the definite-check. I think that's the purpose of definite. The reason why x is definite is what is weird imo but that has something to do with the stuff being defined with `equ` and `define` are replaced with their values in the code in the whole file even before any definite-check has been made. The preprocessor and assembler stage of fasm1 are still present to some extent in fasm2. I might get this wrong since I am new to fasm, but I've been re-reading the manual many times. |
|||
![]() |
|
bitRAKE 27 Feb 2025, 21:24
This effect is seen on element as well. Such that we could change the code to:
Code: if definite TYPE display 'earlier, ' typetype TYPE else display 'later, ' typetype TYPE end if Quote: the "definite" operator should be used instead, as it checks whether all symbols within a basic expression that follows have been defined earlier. |
|||
![]() |
|
bitRAKE 27 Feb 2025, 21:31
dosmancer wrote: The reason why x is definite is what is weird imo but that has something to do with the stuff being defined with `equ` and `define` are replaced with their values in the code in the whole file even before any definite-check has been made. The preprocessor and assembler stage of fasm1 are still present to some extent in fasm2. |
|||
![]() |
|
bitRAKE 27 Feb 2025, 21:33
I think we need to use CALM to discriminate between direct values and symbols with a value (i.e. 1 verses x; with define x 1).
|
|||
![]() |
|
dosmancer 27 Feb 2025, 23:03
bitRAKE wrote: I think we need to use CALM to discriminate between direct values and symbols with a value (i.e. 1 verses x; with define x 1). I guess that would be pretty tricky. An experiment: Code: define x 1 calminstruction symbolic_or_direct_value local tmp arrange tmp,=x ; outputs "symbolic" for =x. Replace with 1 and it outputs "direct value" transform tmp jyes sym asm display "direct value" exit sym: asm display "symbolic" end calminstruction symbolic_or_direct_value |
|||
![]() |
|
bitRAKE 28 Feb 2025, 01:02
I think it does offer insight into parsing values:
Code: calminstruction sign item* local show arrange show,=display 'negative' check item < 0 jyes done arrange show,=display 'positive' check item > 0 jyes done arrange show,=display 'zero' check item = 0 jyes done arrange show,=display 'error: integer or float expected' done: assemble show end calminstruction calminstruction type item local any,j check defined item jyes mt display '~defined' exit mt: compute j,0 match ,item jyes b0 arrange any,item transform any b1: compute j,j+1 transform any jyes b1 match ,any jno def b0: display 'blank ' display j+48 exit def: check definite item jno late display 'early, ' transform item jyes sym display 'literal, ' jump more late: display 'late, ' sym: display 'symbol, ' more: check '' eqtype item jyes str check 0.0 eqtype item jyes flt check 0 eqtype item jyes alg display 'error: defined value expected' exit str: display 'string' exit poly: display 'linear polynomial' exit flt: display 'float, ' call sign,item exit alg: check item relativeto 0 jno poly display 'integer, ' call sign,item end calminstruction Results in ... Code: blank 0 blank 0 absent ~defined vfwd ~defined blank blank 1 here blank 2 vary blank 2 1 early, literal, integer, positive -1 early, literal, integer, negative 0 early, literal, integer, zero reg+2 early, literal, linear polynomial '' early, literal, string 0.0 early, literal, float, zero 0.1 early, literal, float, positive -3.2 early, literal, float, negative x early, symbol, integer, positive y late, symbol, integer, positive |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.