Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial rules for decimal support #700

Closed
wants to merge 8 commits into from
4 changes: 2 additions & 2 deletions boot.red
Expand Up @@ -46,7 +46,7 @@ routine!: make datatype! #get-definition TYPE_ROUTINE
object!: make datatype! #get-definition TYPE_OBJECT object!: make datatype! #get-definition TYPE_OBJECT
;port!: make datatype! #get-definition TYPE_PORT ;port!: make datatype! #get-definition TYPE_PORT
bitset!: make datatype! #get-definition TYPE_BITSET bitset!: make datatype! #get-definition TYPE_BITSET
;float!: make datatype! #get-definition TYPE_FLOAT float!: make datatype! #get-definition TYPE_FLOAT
point!: make datatype! #get-definition TYPE_POINT point!: make datatype! #get-definition TYPE_POINT


none: make none! 0 none: make none! 0
Expand Down Expand Up @@ -1090,4 +1090,4 @@ load: function [
transcode source out transcode source out
unless :all [if 1 = length? out [out: out/1]] unless :all [if 1 = length? out [out: out/1]]
out out
] ]
34 changes: 33 additions & 1 deletion lexer.r
Expand Up @@ -211,7 +211,33 @@ lexer: context [
] :pos ] :pos
fail? fail?
] ]


decimal-number-rule: [
(type: decimal!)
opt [#"-" | #"+"] [
;for numbers like: 1.0 -1.e2 1.0e-2
[
any digit #"." some digit
| some digit #"." any digit
]
opt [[#"e" | #"E"] opt [#"-" | #"+"] some digit]
|
;for numbers like: 1e2
some digit
[#"e" | #"E"] opt [#"-" | #"+"] some digit
]
e:
]

decimal-rule: [
decimal-number-rule
pos: [ ;-- protection rule from typo with sticky words
[integer-end | ws-no-count | end] (fail?: none)
| skip (fail?: [end skip])
] :pos
fail?
]

block-rule: [#"[" (stack/push block!) any-value #"]" (value: stack/pop block!)] block-rule: [#"[" (stack/push block!) any-value #"]" (value: stack/pop block!)]


paren-rule: [#"(" (stack/push paren!) any-value #")" (value: stack/pop paren!)] paren-rule: [#"(" (stack/push paren!) any-value #")" (value: stack/pop paren!)]
Expand Down Expand Up @@ -326,6 +352,7 @@ lexer: context [
| multiline-comment-rule | multiline-comment-rule
| escaped-rule (stack/push value) | escaped-rule (stack/push value)
| integer-rule (stack/push load-integer copy/part s e) | integer-rule (stack/push load-integer copy/part s e)
| decimal-rule (stack/push load-decimal copy/part s e)
| hexa-rule (stack/push decode-hexa copy/part s e) | hexa-rule (stack/push decode-hexa copy/part s e)
| word-rule (stack/push to type value) | word-rule (stack/push to type value)
| lit-word-rule (stack/push to type value) | lit-word-rule (stack/push to type value)
Expand Down Expand Up @@ -485,6 +512,11 @@ lexer: context [
s s
] ]


load-decimal: func [s [string!]][
unless attempt [s: to decimal! s][throw-error]
s
]

load-string: func [s [string!] e [string!] /local new filter][ load-string: func [s [string!] e [string!] /local new filter][
new: make string! offset? s e ;-- allocated size close to final size new: make string! offset? s e ;-- allocated size close to final size
filter: get pick [UTF8-char UTF8-filtered-char] s/-1 = #"{" filter: get pick [UTF8-char UTF8-filtered-char] s/-1 = #"{"
Expand Down
150 changes: 150 additions & 0 deletions lexer.red
Expand Up @@ -97,6 +97,134 @@ trans-hexa: routine [
n n
] ]


trans-decimal: routine [
start [string!]
end [string!]
/local
c [integer!]
value [integer!]
m [integer!]
len [integer!]
p [byte-ptr!]
neg? [logic!]
expon [integer!] ;should be decimal!
frac [logic!]
scale [integer!] ;should be decimal!
;pow10 [deecimal!]
][
str: GET_BUFFER(start)
unit: GET_UNIT(str)
p: string/rs-head start
len: end/head - start/head
neg?: no

c: string/get-char p unit
if any [
c = as-integer #"+"
c = as-integer #"-"
][
neg?: c = as-integer #"-"
p: p + unit
len: len - 1
]
value: 0
while [
c: string/get-char p unit
all [
c >= as-integer #"0"
c <= as-integer #"9"
]
][
m: value * 10
if m < value [SET_RETURN(none-value) exit] ;-- return NONE on overflow
value: m

m: value + c - #"0"
if m < value [SET_RETURN(none-value) exit] ;-- return NONE on overflow
value: m

p: p + unit
len: len - 1
]

;Handle numbers after decimal point if there are any
if c = as-integer #"." [
p: p + unit
len: len - 1
while [
c: string/get-char p unit
all [
c >= as-integer #"0"
c <= as-integer #"9"
]
][
;DO NOTHING SO FAR AS I CANNOT DIVIDE PROPERLY YET
;pow10: 10.0
;value: value + (c - #"0") / pow10
;pow10: pow10 * 10.0
p: p + unit
len: len - 1
]
]

frac: no
scale: 1 ;should be 1.0!

if all [
len > 0
any [
c = as-integer #"e"
c = as-integer #"E"
]
][
expon: 0
p: p + unit
len: len - 1

c: string/get-char p unit
if any [
c = as-integer #"+"
c = as-integer #"-"
][
frac: c = as-integer #"-"
p: p + unit
len: len - 1
]
until [
c: string/get-char p unit

m: expon * 10 ;should be 10.0
if m < expon [SET_RETURN(none-value) exit] ;-- return NONE on overflow
expon: m

m: expon + c - #"0"
if m < expon [SET_RETURN(none-value) exit] ;-- return NONE on overflow
expon: m

p: p + unit
len: len - 1
zero? len
]
;while [expon >= 50] [
; scale: scale * 1E50
; expon: expon - 50
;]
while [expon >= 8] [
scale: scale * 100000000 ;1E8
expon: expon - 8
]
while [expon > 0] [
scale: scale * 10 ;10.0
expon: expon - 1
]
value: either frac [
value / scale
][ value * scale ]
]

integer/box either neg? [0 - value][value]
]

trans-push-path: routine [ trans-push-path: routine [
stack [block!] stack [block!]
type [datatype!] type [datatype!]
Expand Down Expand Up @@ -387,6 +515,27 @@ transcode: func [
ahead [integer-end | ws-no-count | end] ahead [integer-end | ws-no-count | end]
] ]


decimal-number-rule: [
opt [#"-" | #"+"] [
;for numbers like: 1.0 -1.e2 1.0e-2
[
any digit #"." some digit
| some digit #"." any digit
]
opt [[#"e" | #"E"] opt [#"-" | #"+"] some digit]
|
;for numbers like: 1e2
some digit
[#"e" | #"E"] opt [#"-" | #"+"] some digit
]
e:
]

decimal-rule: [
decimal-number-rule
ahead [integer-end | ws-no-count | end]
]

block-rule: [ block-rule: [
#"[" (append/only stack make block! 4) #"[" (append/only stack make block! 4)
any-value any-value
Expand Down Expand Up @@ -456,6 +605,7 @@ transcode: func [
| multiline-comment-rule | multiline-comment-rule
| escaped-rule (append last stack value) | escaped-rule (append last stack value)
| integer-rule (append last stack trans-integer s e) | integer-rule (append last stack trans-integer s e)
| decimal-rule (append last stack trans-decimal s e)
| hexa-rule (append last stack trans-hexa s e) | hexa-rule (append last stack trans-hexa s e)
| word-rule | word-rule
| lit-word-rule | lit-word-rule
Expand Down