@@ -2,248 +2,14 @@ package vibes
22
33import (
44 "fmt"
5- "regexp"
65 "strings"
76 "unicode"
87)
98
109func stringMember (str Value , property string ) (Value , error ) {
1110 switch property {
12- case "size" :
13- return NewAutoBuiltin ("string.size" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
14- if len (args ) > 0 {
15- return NewNil (), fmt .Errorf ("string.size does not take arguments" )
16- }
17- return NewInt (int64 (len ([]rune (receiver .String ())))), nil
18- }), nil
19- case "length" :
20- return NewAutoBuiltin ("string.length" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
21- if len (args ) > 0 {
22- return NewNil (), fmt .Errorf ("string.length does not take arguments" )
23- }
24- return NewInt (int64 (len ([]rune (receiver .String ())))), nil
25- }), nil
26- case "bytesize" :
27- return NewAutoBuiltin ("string.bytesize" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
28- if len (args ) > 0 {
29- return NewNil (), fmt .Errorf ("string.bytesize does not take arguments" )
30- }
31- return NewInt (int64 (len (receiver .String ()))), nil
32- }), nil
33- case "ord" :
34- return NewAutoBuiltin ("string.ord" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
35- if len (args ) > 0 {
36- return NewNil (), fmt .Errorf ("string.ord does not take arguments" )
37- }
38- runes := []rune (receiver .String ())
39- if len (runes ) == 0 {
40- return NewNil (), fmt .Errorf ("string.ord requires non-empty string" )
41- }
42- return NewInt (int64 (runes [0 ])), nil
43- }), nil
44- case "chr" :
45- return NewAutoBuiltin ("string.chr" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
46- if len (args ) > 0 {
47- return NewNil (), fmt .Errorf ("string.chr does not take arguments" )
48- }
49- runes := []rune (receiver .String ())
50- if len (runes ) == 0 {
51- return NewNil (), nil
52- }
53- return NewString (string (runes [0 ])), nil
54- }), nil
55- case "empty?" :
56- return NewAutoBuiltin ("string.empty?" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
57- if len (args ) > 0 {
58- return NewNil (), fmt .Errorf ("string.empty? does not take arguments" )
59- }
60- return NewBool (len (receiver .String ()) == 0 ), nil
61- }), nil
62- case "clear" :
63- return NewAutoBuiltin ("string.clear" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
64- if len (args ) > 0 {
65- return NewNil (), fmt .Errorf ("string.clear does not take arguments" )
66- }
67- return NewString ("" ), nil
68- }), nil
69- case "concat" :
70- return NewAutoBuiltin ("string.concat" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
71- var b strings.Builder
72- b .WriteString (receiver .String ())
73- for _ , arg := range args {
74- if arg .Kind () != KindString {
75- return NewNil (), fmt .Errorf ("string.concat expects string arguments" )
76- }
77- b .WriteString (arg .String ())
78- }
79- return NewString (b .String ()), nil
80- }), nil
81- case "replace" :
82- return NewAutoBuiltin ("string.replace" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
83- if len (args ) != 1 {
84- return NewNil (), fmt .Errorf ("string.replace expects exactly one replacement" )
85- }
86- if args [0 ].Kind () != KindString {
87- return NewNil (), fmt .Errorf ("string.replace replacement must be string" )
88- }
89- return NewString (args [0 ].String ()), nil
90- }), nil
91- case "start_with?" :
92- return NewAutoBuiltin ("string.start_with?" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
93- if len (args ) != 1 {
94- return NewNil (), fmt .Errorf ("string.start_with? expects exactly one prefix" )
95- }
96- if args [0 ].Kind () != KindString {
97- return NewNil (), fmt .Errorf ("string.start_with? prefix must be string" )
98- }
99- return NewBool (strings .HasPrefix (receiver .String (), args [0 ].String ())), nil
100- }), nil
101- case "end_with?" :
102- return NewAutoBuiltin ("string.end_with?" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
103- if len (args ) != 1 {
104- return NewNil (), fmt .Errorf ("string.end_with? expects exactly one suffix" )
105- }
106- if args [0 ].Kind () != KindString {
107- return NewNil (), fmt .Errorf ("string.end_with? suffix must be string" )
108- }
109- return NewBool (strings .HasSuffix (receiver .String (), args [0 ].String ())), nil
110- }), nil
111- case "include?" :
112- return NewAutoBuiltin ("string.include?" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
113- if len (args ) != 1 {
114- return NewNil (), fmt .Errorf ("string.include? expects exactly one substring" )
115- }
116- if args [0 ].Kind () != KindString {
117- return NewNil (), fmt .Errorf ("string.include? substring must be string" )
118- }
119- return NewBool (strings .Contains (receiver .String (), args [0 ].String ())), nil
120- }), nil
121- case "match" :
122- return NewAutoBuiltin ("string.match" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
123- if len (kwargs ) > 0 {
124- return NewNil (), fmt .Errorf ("string.match does not take keyword arguments" )
125- }
126- if len (args ) != 1 {
127- return NewNil (), fmt .Errorf ("string.match expects exactly one pattern" )
128- }
129- if args [0 ].Kind () != KindString {
130- return NewNil (), fmt .Errorf ("string.match pattern must be string" )
131- }
132- pattern := args [0 ].String ()
133- re , err := regexp .Compile (pattern )
134- if err != nil {
135- return NewNil (), fmt .Errorf ("string.match invalid regex: %v" , err )
136- }
137- text := receiver .String ()
138- indices := re .FindStringSubmatchIndex (text )
139- if indices == nil {
140- return NewNil (), nil
141- }
142- values := make ([]Value , len (indices )/ 2 )
143- for i := range values {
144- start := indices [i * 2 ]
145- end := indices [i * 2 + 1 ]
146- if start < 0 || end < 0 {
147- values [i ] = NewNil ()
148- continue
149- }
150- values [i ] = NewString (text [start :end ])
151- }
152- return NewArray (values ), nil
153- }), nil
154- case "scan" :
155- return NewAutoBuiltin ("string.scan" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
156- if len (kwargs ) > 0 {
157- return NewNil (), fmt .Errorf ("string.scan does not take keyword arguments" )
158- }
159- if len (args ) != 1 {
160- return NewNil (), fmt .Errorf ("string.scan expects exactly one pattern" )
161- }
162- if args [0 ].Kind () != KindString {
163- return NewNil (), fmt .Errorf ("string.scan pattern must be string" )
164- }
165- pattern := args [0 ].String ()
166- re , err := regexp .Compile (pattern )
167- if err != nil {
168- return NewNil (), fmt .Errorf ("string.scan invalid regex: %v" , err )
169- }
170- matches := re .FindAllString (receiver .String (), - 1 )
171- values := make ([]Value , len (matches ))
172- for i , m := range matches {
173- values [i ] = NewString (m )
174- }
175- return NewArray (values ), nil
176- }), nil
177- case "index" :
178- return NewAutoBuiltin ("string.index" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
179- if len (args ) < 1 || len (args ) > 2 {
180- return NewNil (), fmt .Errorf ("string.index expects substring and optional offset" )
181- }
182- if args [0 ].Kind () != KindString {
183- return NewNil (), fmt .Errorf ("string.index substring must be string" )
184- }
185- offset := 0
186- if len (args ) == 2 {
187- i , err := valueToInt (args [1 ])
188- if err != nil || i < 0 {
189- return NewNil (), fmt .Errorf ("string.index offset must be non-negative integer" )
190- }
191- offset = i
192- }
193- index := stringRuneIndex (receiver .String (), args [0 ].String (), offset )
194- if index < 0 {
195- return NewNil (), nil
196- }
197- return NewInt (int64 (index )), nil
198- }), nil
199- case "rindex" :
200- return NewAutoBuiltin ("string.rindex" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
201- if len (args ) < 1 || len (args ) > 2 {
202- return NewNil (), fmt .Errorf ("string.rindex expects substring and optional offset" )
203- }
204- if args [0 ].Kind () != KindString {
205- return NewNil (), fmt .Errorf ("string.rindex substring must be string" )
206- }
207- offset := len ([]rune (receiver .String ()))
208- if len (args ) == 2 {
209- i , err := valueToInt (args [1 ])
210- if err != nil || i < 0 {
211- return NewNil (), fmt .Errorf ("string.rindex offset must be non-negative integer" )
212- }
213- offset = i
214- }
215- index := stringRuneRIndex (receiver .String (), args [0 ].String (), offset )
216- if index < 0 {
217- return NewNil (), nil
218- }
219- return NewInt (int64 (index )), nil
220- }), nil
221- case "slice" :
222- return NewAutoBuiltin ("string.slice" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
223- if len (args ) < 1 || len (args ) > 2 {
224- return NewNil (), fmt .Errorf ("string.slice expects index and optional length" )
225- }
226- start , err := valueToInt (args [0 ])
227- if err != nil {
228- return NewNil (), fmt .Errorf ("string.slice index must be integer" )
229- }
230- runes := []rune (receiver .String ())
231- if len (args ) == 1 {
232- if start < 0 || start >= len (runes ) {
233- return NewNil (), nil
234- }
235- return NewString (string (runes [start ])), nil
236- }
237- length , err := valueToInt (args [1 ])
238- if err != nil {
239- return NewNil (), fmt .Errorf ("string.slice length must be integer" )
240- }
241- substr , ok := stringRuneSlice (receiver .String (), start , length )
242- if ! ok {
243- return NewNil (), nil
244- }
245- return NewString (substr ), nil
246- }), nil
11+ case "size" , "length" , "bytesize" , "ord" , "chr" , "empty?" , "clear" , "concat" , "replace" , "start_with?" , "end_with?" , "include?" , "match" , "scan" , "index" , "rindex" , "slice" :
12+ return stringMemberQuery (property )
24713 case "strip" :
24814 return NewAutoBuiltin ("string.strip" , func (exec * Execution , receiver Value , args []Value , kwargs map [string ]Value , block Value ) (Value , error ) {
24915 if len (args ) > 0 {
0 commit comments