@@ -9,6 +9,8 @@ package json
99
1010import (
1111 "fmt"
12+ "math"
13+ "strconv"
1214 "unicode"
1315)
1416
@@ -21,14 +23,14 @@ func Load(s string) interface{} {
2123func load (iter * iterator ) interface {} {
2224 consumeWhiteSpace (iter )
2325 switch {
24- case iter .isEnd ():
25- return nil
2626 case iter .getCurrent () == 'n' :
2727 return loadKeyword (iter , "null" , nil )
2828 case iter .getCurrent () == 't' :
2929 return loadKeyword (iter , "true" , true )
3030 case iter .getCurrent () == 'f' :
3131 return loadKeyword (iter , "false" , false )
32+ case isNumber (iter ):
33+ return loadNumber (iter )
3234 case iter .getCurrent () == '"' :
3335 return loadString (iter )
3436 case iter .getCurrent () == '[' :
@@ -54,7 +56,74 @@ func loadKeyword(iter *iterator, keyword string, value interface{}) interface{}
5456 return value
5557}
5658
57- func loadString (iter * iterator ) interface {} {
59+ func isNumber (iter * iterator ) bool {
60+ switch iter .getCurrent () {
61+ case '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '-' , '0' :
62+ return true
63+ }
64+ return false
65+ }
66+
67+ func loadNumber (iter * iterator ) interface {} {
68+ //negative numbers
69+ sign := 1.0
70+ if iter .getCurrent () == '-' {
71+ sign = - 1.0
72+ iter .advance ()
73+ }
74+ num := 0.0
75+ for ! iter .isEnd () && unicode .IsDigit (rune (iter .getCurrent ())) {
76+ num *= 10
77+ val , _ := strconv .ParseInt (string (iter .getCurrent ()), 10 , 64 )
78+ num += float64 (val )
79+ iter .advance ()
80+ }
81+
82+ // decimal
83+ // some of the code here is a duplicate of what is above, I should consolidate into one function.
84+ consume (iter , '.' )
85+ frac := 0.0
86+ power := 0.1
87+ for ! iter .isEnd () && unicode .IsDigit (rune (iter .getCurrent ())) {
88+ val , _ := strconv .ParseInt (string (iter .getCurrent ()), 10 , 64 )
89+ frac += power * float64 (val )
90+ power *= 0.1
91+ iter .advance ()
92+ }
93+
94+ exponent := 0.0
95+ //exponent
96+ if ! iter .isEnd () && ((iter .getCurrent () == 'e' ) || (iter .getCurrent () == 'E' )) {
97+ if iter .getCurrent () == 'e' {
98+ consume (iter , 'e' )
99+ }
100+ if iter .getCurrent () == 'E' {
101+ consume (iter , 'E' )
102+ }
103+ exponentSign := 1.0
104+ //TODO(ope) this is subtly wrong since it allows +-123234, I will fix later
105+ if ! iter .isEnd () && iter .getCurrent () == '+' {
106+ consume (iter , '+' )
107+ }
108+ if ! iter .isEnd () && iter .getCurrent () == '-' {
109+ consume (iter , '-' )
110+ exponentSign = - 1.0
111+ }
112+ // there needs to be at least one digit after an exponent
113+ exponent = 0.0
114+ for ! iter .isEnd () && unicode .IsDigit (rune (iter .getCurrent ())) {
115+ exponent *= 10
116+ val , _ := strconv .ParseInt (string (iter .getCurrent ()), 10 , 64 )
117+ exponent += float64 (val )
118+ iter .advance ()
119+ }
120+ exponent *= exponentSign
121+ }
122+ fmt .Println (num , frac , exponent )
123+ return (num + frac ) * sign * math .Pow (10 , exponent )
124+ }
125+
126+ func loadString (iter * iterator ) string {
58127 consume (iter , '"' )
59128 s := make ([]rune , 0 )
60129 mapping := map [rune ]rune {
@@ -101,6 +170,7 @@ func loadString(iter *iterator) interface{} {
101170 //need to handle the default case and handle u and hex digits
102171 case 'u' :
103172 var ans rune
173+ // I should make sure these are valid hex digits btw, but will leave it for error reporting
104174 for i := 0 ; i < 4 ; i ++ {
105175 iter .advance () // move past the 'u'
106176 fmt .Println (i , ans , string (iter .getCurrent ()))
@@ -170,7 +240,7 @@ func consumeWhiteSpace(iter *iterator) {
170240
171241func consume (iter * iterator , char byte ) {
172242 // actually should probably raise an error if char isn't consumed
173- if iter .getCurrent () == char {
243+ if ! iter . isEnd () && iter .getCurrent () == char {
174244 iter .advance ()
175245 }
176246}
0 commit comments