@@ -5,8 +5,10 @@ import (
55 "encoding/json"
66 "fmt"
77 "io"
8+ "math"
89 "reflect"
910 "regexp"
11+ "strconv"
1012 "strings"
1113 "time"
1214)
@@ -132,6 +134,76 @@ func builtinRandomID(exec *Execution, receiver Value, args []Value, kwargs map[s
132134 return NewString (string (chars )), nil
133135}
134136
137+ func builtinToInt (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
138+ if len (args ) != 1 {
139+ return NewNil (), fmt .Errorf ("to_int expects a single value argument" )
140+ }
141+ if len (kwargs ) > 0 {
142+ return NewNil (), fmt .Errorf ("to_int does not accept keyword arguments" )
143+ }
144+ if ! block .IsNil () {
145+ return NewNil (), fmt .Errorf ("to_int does not accept blocks" )
146+ }
147+
148+ switch args [0 ].Kind () {
149+ case KindInt :
150+ return args [0 ], nil
151+ case KindFloat :
152+ f := args [0 ].Float ()
153+ if math .Trunc (f ) != f {
154+ return NewNil (), fmt .Errorf ("to_int cannot convert non-integer float" )
155+ }
156+ n , err := floatToInt64Checked (f , "to_int" )
157+ if err != nil {
158+ return NewNil (), err
159+ }
160+ return NewInt (n ), nil
161+ case KindString :
162+ s := strings .TrimSpace (args [0 ].String ())
163+ if s == "" {
164+ return NewNil (), fmt .Errorf ("to_int expects a numeric string" )
165+ }
166+ n , err := strconv .ParseInt (s , 10 , 64 )
167+ if err != nil {
168+ return NewNil (), fmt .Errorf ("to_int expects a base-10 integer string" )
169+ }
170+ return NewInt (n ), nil
171+ default :
172+ return NewNil (), fmt .Errorf ("to_int expects int, float, or string" )
173+ }
174+ }
175+
176+ func builtinToFloat (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
177+ if len (args ) != 1 {
178+ return NewNil (), fmt .Errorf ("to_float expects a single value argument" )
179+ }
180+ if len (kwargs ) > 0 {
181+ return NewNil (), fmt .Errorf ("to_float does not accept keyword arguments" )
182+ }
183+ if ! block .IsNil () {
184+ return NewNil (), fmt .Errorf ("to_float does not accept blocks" )
185+ }
186+
187+ switch args [0 ].Kind () {
188+ case KindInt :
189+ return NewFloat (float64 (args [0 ].Int ())), nil
190+ case KindFloat :
191+ return args [0 ], nil
192+ case KindString :
193+ s := strings .TrimSpace (args [0 ].String ())
194+ if s == "" {
195+ return NewNil (), fmt .Errorf ("to_float expects a numeric string" )
196+ }
197+ f , err := strconv .ParseFloat (s , 64 )
198+ if err != nil {
199+ return NewNil (), fmt .Errorf ("to_float expects a numeric string" )
200+ }
201+ return NewFloat (f ), nil
202+ default :
203+ return NewNil (), fmt .Errorf ("to_float expects int, float, or string" )
204+ }
205+ }
206+
135207func formatUUIDv4 (raw []byte ) string {
136208 hexValue := hex .EncodeToString (raw )
137209 return hexValue [0 :8 ] + "-" + hexValue [8 :12 ] + "-" + hexValue [12 :16 ] + "-" + hexValue [16 :20 ] + "-" + hexValue [20 :32 ]
0 commit comments