flat assembler
Message board for the users of flat assembler.
Index
> Main > [fasmg] Troubles with defined/definite Goto page 1, 2 Next |
Author |
|
Tomasz Grysztar 13 Jan 2021, 17:05
You cannot use DEFINED/DEFINITE operators to check the status of symbolic variables, because they are preprocessed before the text of the condition is evaluated. So if you "define var PE GUI", then "if definite var" becomes "if definite PE GUI" before the condition is evaluated, and you end up actually checking whether symbol named "PE" has been defined, with "GUI" appended at the end of condition and causing a syntax error. This actually ends up working quite similarly as it was in fasm 1 with regard to symbolic variables and expression evaluation.
However if you are using CALM, there is a simple trick that allows to check whether a symbol has a value assigned, even a symbolic one. See what the manual says about the TAKE command: fasmg manual, section 15 wrote: If the destination symbol is the same as source, the result flag can be used to check whether there is an available value without affecting it. |
|||
13 Jan 2021, 17:05 |
|
Tomasz Grysztar 13 Jan 2021, 17:13
A simple demonstration:
Code: define var ; this is to make CALM code see "var" as global symbol calminstruction Format take var,var jyes use_var ; here handle a case when var is not defined exit use_var: local cmd arrange cmd, =format var assemble cmd end calminstruction restore var ; remove temporary definition ; now test it: define var PE GUI Format |
|||
13 Jan 2021, 17:13 |
|
Calanor 13 Jan 2021, 17:22
I resorted to using "match =var, var", followed by the "default" format if no specific one was defined. If the match is false, some CALM-code kicks in order to properly send the argument to format. However, your solution is definitely prettier than mine Thanks!
|
|||
13 Jan 2021, 17:22 |
|
Tomasz Grysztar 13 Jan 2021, 17:23
There is also another method, which you would use if the identifier of the symbol to check for was provided at run-time to the instruction, for example as an argument to macro. Then you can use TRANSFORM and see whether any replacement has been made:
Code: calminstruction Format symbol transform symbol jyes use_var ; here handle a case when symbol is not defined exit use_var: local cmd arrange cmd, =format symbol assemble cmd end calminstruction ; now test it: define var PE GUI Format var |
|||
13 Jan 2021, 17:23 |
|
Calanor 13 Jan 2021, 17:27
I did use transform, but it never occurred to me to actually check the flag. Interesting approach!
|
|||
13 Jan 2021, 17:27 |
|
fabbel 30 Mar 2023, 14:06
i do this
Code: calminstruction initsymndef? name*, def& take name, name jyes _err publish name, def exit _err: err "!! symbol already defined" end calminstruction initsymndef foo, FOOBAR and get : Custom error: !! symbol already defined. ... not what I expected ! intent : check if some symbol already has some value (foo in sample above), and only if not, then define it ... I also tried replacing 'take name, name' with 'transform name' but result is the same... tx 4 help Tomasz, wud u pls clarify why ? I thought above discussion was pointing to this... ... but getting confused.... |
|||
30 Mar 2023, 14:06 |
|
fabbel 30 Mar 2023, 14:17
... also, to show msg in calm using display command, how wud i go about adding CRLF at the end ??
Code: display "!! symbol already defined",13,10 does not work... |
|||
30 Mar 2023, 14:17 |
|
Tomasz Grysztar 30 Mar 2023, 14:25
Your TAKE command applies to symbol "name". The name "foo" is the text of the value that has been assigned to "name" symbol - the TAKE does not check the existence of value of "foo", it looks for the presence of value of "name".
As for TRANSFORM, it is only going to do something when the name has been assigned a symbolic value - but this is what you're doing, so it's not an issue in your case. I think what has thrown you off is that the symbols can be forward-referenced - it is the classic case of "if symbol is not defined, then it's defined" paradox - note that you likely get an error message about exceeding the allowed number of passes. If you do anything to prevent forward-references (for example execute your PUBLISH line twice), the "oscillation problem" should go away. See my articles about multi-pass assembly for other methods of dealing with this kind of issues. Going even further back, the manual for fasm 1 has a section that discusses the "if ~ defined" issue in its most basic form. |
|||
30 Mar 2023, 14:25 |
|
Tomasz Grysztar 30 Mar 2023, 14:27
fabbel wrote: ... also, to show msg in calm using display command, how wud i go about adding CRLF at the end ?? Code: display "!! symbol already defined" display 13 display 10 Code: display "!! symbol already defined" bappend 13 bappend 10 Code: calminstruction calminstruction?.display? list& loop: match item=,list, list jno final arrange item, =display item assemble item jump loop final: arrange item, =display list assemble item end calminstruction |
|||
30 Mar 2023, 14:27 |
|
fabbel 30 Mar 2023, 14:44
tx vm
..i resorted to using 2x publish command then ... Code: calminstruction initsymndef? name*, def& transform name jyes _err publish name, def publish name, def exit _err: display "symbol already defined" bappend 13 bappend 10 end calminstruction initsymndef foo, FOOBAR ... which now works as expected .... i get the fwd ref issue, but must admit that the above syntax (having 2xpublish) looks kinda weird to me though... |
|||
30 Mar 2023, 14:44 |
|
Tomasz Grysztar 30 Mar 2023, 14:52
fabbel wrote: ... which now works as expected .... i get the fwd ref issue, but must admit that the above syntax (having 2xpublish) looks kinda weird to me though... For numeric symbols the issue is solved through use of DEFINITE operator instead of DEFINED, but there is no analogous facilities for symbolic values - which is exactly the problem mentioned by the OP. I've been in fact working on some additional operators for inspection of symbolic definitions, but it's an experimental branch that I'm still unsure about. |
|||
30 Mar 2023, 14:52 |
|
fabbel 31 Mar 2023, 07:14
To generalize definite operator (which is for numeric variable only),
and check if some symbol - either symbolic or numeric - already has some value, the below seems to be working (trying to circumvent fwd-referencing) : Code: struc (name) isdef? var* name = 0 irpv v, var indx %% name = 1 break end irpv end struc ; un-comment below symbolic / numeric to test ;foo equ FOOBAR ;foo = 1 chk_foo isdef foo ; un-comment below symbolic / numeric to test with/without fwd-ref ;foo equ FOOBAR ;foo = 1 repeat 1, d:chk_foo display 'chk_foo : ',`d,13,10 end repeat Tomasz : can u pls comment ? Do u see any issue with the above ? tx |
|||
31 Mar 2023, 07:14 |
|
Tomasz Grysztar 31 Mar 2023, 07:31
Looks great! Yes, IRPV is a very good solution, even if a bit tricky. It detects all kinds of values and never forward-references.
|
|||
31 Mar 2023, 07:31 |
|
fabbel 31 Mar 2023, 08:12
tx ! appreciated ( gratifying to see that am starting to understand a bit... but still... am about to post another question in another thread....)
|
|||
31 Mar 2023, 08:12 |
|
fabbel 25 Jan 2024, 11:07
Hi Tomasz,
Any news regarding those 'experimental' operators that you previously referred to ? I kinda feel those could be useful to address some topics/isues that have (re)surfaced in the forum on multiple occasions : * check if variable hold symbolic value ? * check if some text can be valid identifier ? -> you already demontrated some macro / struc workaround in the form of 'struc isname' and 'struc isidentifier' .. but wouldn't that be perfect case for such dedicted operator ? * check if variable hold 'legal' computable text / value -> not the same as defined / definite that will actually err (Error: invalid expression) if fed with non computable text e.g. define var 1 2 -> aim here would be to check var contents and allow for some alternate handling if non computable -> typ. in CALM, do 'compute var, var' if legally computable or alternate handling otherwise... |
|||
25 Jan 2024, 11:07 |
|
Tomasz Grysztar 25 Jan 2024, 12:05
Have you tried the experimental branch I linked previously? It needs to get all the latest fixed merged from the trunk, but otherwise it was already functional.
|
|||
25 Jan 2024, 12:05 |
|
fabbel 25 Jan 2024, 12:11
not yet tbh, was kinda waiting for the merge to signal that they were 'officialized' and here to stay ...
but will give it a try .. to proceed could u pls give some more details * list of new experimental operators introduced here * quick use / syntax guide for each of those tx rgds |
|||
25 Jan 2024, 12:11 |
|
fabbel 25 Jan 2024, 12:14
.... am especially interested in seeing how those can address the 3 points I mentionned above
|
|||
25 Jan 2024, 12:14 |
|
Tomasz Grysztar 25 Jan 2024, 17:37
The operators implemented in the "calm3" branch are for testing values of symbolic variables, and for this reason they can only be used in CALM, because normally values of symbolic variables are replaced with corresponding text before the expression is evaluated. Only in CALM you have a chance to actually "catch" such variable, because there expressions are pre-parsed with hardcoded references to symbols.
__text checks whether the value of given variable is actually symbolic, that is: whether it's a tokenized text. Code: ;fossil open https://flatassembler.net/fossil/repo/fasmg ;fossil checkout calm3 calminstruction show arg check __text arg jno error stringify arg display arg jump done exit error: display 'non-symbolic value cannot be shown' done: display 10 exit end calminstruction calminstruction demo arrange tmp, 3*7 call show, tmp compute tmp, tmp call show, tmp end calminstruction demo __name additionally checks whether the text within a variable is a valid identifier of a symbol and without any additional tokens. __nameofequ checks whether the text within a variable is an identifier of a defined symbol with symbolic value. __nameofpriorequ checks whether the text within a variable is an identifier of a symbol with symbolic value defined earlier in the source. Note that each of these consecutive operators performs the same check as the previous ones, with even more restrictions added. "__name x" cannot be true unless "__text x" is true, and so on. Code: ;fossil open https://flatassembler.net/fossil/repo/fasmg ;fossil checkout calm3 __if_true equ if 1 __if_false equ if 0 calminstruction ifdef? name* check __name name & (__nameofequ name | defined name) jyes true assemble __if_false exit true: assemble __if_true end calminstruction calminstruction ifdefprior? name* check __name name & (__nameofpriorequ name | (~__nameofequ name & definite name)) jyes true assemble __if_false exit true: assemble __if_true end calminstruction ifdef a display 'Yes' else display 'No' end if ifdefprior a display 'Yes' else display 'No' end if a equ 8 __nameofmacro and __nameofpriormacro are analogous to __nameofequ and __nameofpriorequ, but they check for existence of an instruction symbol instead. Similarly __nameofstruc and __nameofpriorstruc check existence of labeled instructions. |
|||
25 Jan 2024, 17:37 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.