[REBOL] Help needed with a GHOST variable ...
From: gerardcote:sympatico:ca at: 10-Oct-2005 15:42
Hi List,
I have the following exec listing where the "eval-content" function simply returns the
value and type of number or identifier it
found amongst integer (int), decimal (dec), decimal in sci notation (sci), hexadecimal
(hex), octal (oct), binary (bin). In the case
of an identifier (ident) the function extracts the identifier value from the dictionary,
creates a new parse command from the
appended elements and the rule set (issue-rules/expr) is automatically parsed again with
the new value extracted.
The problem is : the first time it seems to work but the subsequent the system memorizes
old value from the first call (in the
new-value
word defined inside the "issue-rules/print-info" function). I really don't know where
to look at and how to debug things
that come from objects other than inspecting and printing them visually.
Can some one give and explanation ?
Thanks in advance
Gerard
My Code follows:
Eval for an integer value -- Result OK
=====================
>> eval-content [999]
999
Type: int
Eval for an identifier value <-- Result seems OK the first time ONLY
============================================
>> nom: 444
== 444
>> eval-content [nom]
variable: nom -> 444
ident
444 <-- The second call is started here
Type: int
== true
New try with a second identifier <-- Result is false as the value retrieved comes
===================== from the previous call.
>> r
== 777
>> eval-content [r]
variable: r -> 777
ident
444
Type: int
== [copy my-num1 bin-number (print-info my-num1 "bin") to end |
copy my-num2 oct-number (print-info my-num2 "oct") to end |
...
Notice the above ending instead of the TRUE value found in other cases
================================================
Here is the listing of the "Eval-content" function:
================================
Eval-content: func [value][
new-value: 0 ; try to define global words instead of using "issue-rules"
values
new-type: "UNDEF"
either parse to-string value issue-rules/expr [
; Double parse is necessary if a var name was provided - because of indirection level
; The parse rules return the GLOBALLY DEFINED VARs new-value and new-type
; In the specific case of a varname a new-type of value "ident" is returned
; A second parse is then necessary to get the type and content of the variable
;
if issue-rules/new-type = "ident" [ ; This is returned by issue-rules/print-info
str-to-parse: [parse to-string] ; Incrementally creates the second parse cmd
append/only str-to-parse to block! get in issue-rules 'new-value
append/only str-to-parse issue-rules/expr
do str-to-parse
;unset [issue-rules/new-value issue-rules/new-type]
]
][
print "No number type was detected with current rules (issue-rules/expr)"
]
]
Finally, here is the "issue-rules" object :
==========================
issue-rules: make object! [
expr: [copy my-num1 bin-number (print-info my-num1 "bin") to end |
copy my-num2 oct-number (print-info my-num2 "oct") to end |
copy my-num3 hex-number (print-info my-num3 "hex") to end |
copy my-num4 dec-number (print-info my-num4 type) to end |
copy my-ident identifier (print-info my-ident "ident") to end
]
if debug [print "------- Start of issue-rules ---"
print ["new-value: " new-value newline
"new-type: " new-type]]
letter-b: charset "bB"
letter-o: charset "oO"
letter-x: charset "xX"
bin-digit: charset "01"
bin-digits: [some bin-digit]
bin-number: [bin-digits letter-b]
oct-digit: charset "01234567"
oct-digits: [some oct-digit]
oct-number: [oct-digits letter-o]
dec-digit: charset "0123456789"
hex-digit: union charset "abcdefABCDEF" dec-digit
hex-digits: [some hex-digit]
hex-number: [hex-digits letter-x]
dec-number: [0 1 "-" [sci-decimal-number (type: "sci")| decimal-number (type: "dec")
| unsigned-integer (type: "int") ]]
unsigned-integer: [some digit]
decimal-number: [0 1 unsigned-integer decimal-fraction]
decimal-fraction: ["." unsigned-integer]
sci-decimal-number: [mantissa "E" ["+" | "-" | none] exponent]
mantissa: [decimal-number | unsigned-integer]
exponent: [unsigned-integer]
identifier: [letter any [digit | letter | letter-sep]]
letter: charset [#"A" - #"Z" #"a" - #"z"]
letter-sep: charset "_-"
digit: charset "0123456789"
print-info: func [my-info info-type][
new-value: 0 ; try to neutralize ghost effect
new-type: "UNDEF"
; Binary, Octal and Hexadecimal cases
either any [info-type = "bin" info-type = "oct" info-type = "hex"][
info-num: remove back tail my-info
info-num: head info-num
print info-num
print info-type
new-value: info-num
new-type: copy info-type
][
; Identifier case
either info-type = "ident" [
either unset? my-info [ ; When identifier not defined
print ["variable: " "non définie"]
print ["type: " info-type]
new-value: 0 ; Value given when word not defined
new-type: copy "UNDEF"
][
info-num: get to word! my-info ; When identifier defined
print ["variable: " my-info "-> " info-num]
print info-type
new-value: info-num ; Normally this is where the value
new-type: copy info-type ; of the IDENT is kept into new-value
]
][
; Integer and decimal cases (including SCI notation)
print my-info
print ["Type: " info-type]
info-num: my-info
new-value: info-num
new-type: copy info-type
]
]
]
]