Class: Lisp::String

Inherits:
Atom show all
Defined in:
lib/rubylisp/string.rb

Instance Attribute Summary

Attributes inherited from Atom

#value

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Atom

#alist?, #all?, #apply_to, #car, #cdr, #character?, #class?, #copy, #doc, #eq?, #evaluate, #false?, #frame?, #function?, #length, #lisp_object?, #list?, #macro?, #negative?, #number?, #object?, #pair?, #positive?, #primitive?, #quoted, #special?, #symbol?, #true?, #vector?, #zero?

Constructor Details

#initialize(n = '') ⇒ String

Returns a new instance of String.



812
813
814
# File 'lib/rubylisp/string.rb', line 812

def initialize(n = '')
  @value = n.to_s
end

Class Method Details

.capitalize_string(str) ⇒ Object



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/rubylisp/string.rb', line 466

def self.capitalize_string(str)
  saw_first = false
  str.chars.map do |c|
    if c =~ /[[:alpha:]]/
      if saw_first
        c.downcase
      else
        saw_first = true
        c.upcase
      end
    else
      c
    end
  end
end

.capitalized?(str) ⇒ Boolean

Returns:



411
412
413
414
415
416
# File 'lib/rubylisp/string.rb', line 411

def self.capitalized?(str)
  first = str[0]
  rest = str[1..-1]
  return false unless first =~ /[[:upper:]]/
  lowercase?(rest)
end

.extract_strings(func, args, env) ⇒ Object



221
222
223
224
225
226
# File 'lib/rubylisp/string.rb', line 221

def self.extract_strings(func, args, env)
  raise "#{func} requires 2 arguments, but received #{args.length}" unless args.length == 2
  str1 = get_string(func, args.nth(1).evaluate(env))
  str2 = get_string(func, args.nth(2).evaluate(env))
  return [str1, str2]
end

.extract_substrings(func, args, env) ⇒ Object



207
208
209
210
211
212
# File 'lib/rubylisp/string.rb', line 207

def self.extract_substrings(func, args, env)
  raise "#{func} requires 6 arguments, but received #{args.length}" unless args.length == 6      
  substr1 = get_substring(func, args.nth(1).evaluate(env), args.nth(2).evaluate(env), args.nth(3).evaluate(env))
  substr2 = get_substring(func, args.nth(4).evaluate(env), args.nth(5).evaluate(env), args.nth(6).evaluate(env))
  return [substr1, substr2]
end

.get_string(func, str) ⇒ Object



215
216
217
218
# File 'lib/rubylisp/string.rb', line 215

def self.get_string(func, str)
  raise "#{func} requires a string, but received #{str}" unless str.string?
  str.value
end

.get_substring(func, str, start_index, end_index) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
# File 'lib/rubylisp/string.rb', line 194

def self.get_substring(func, str, start_index, end_index)
  raise "#{func} requires a string, but received #{str}" unless str.string?
  s = str.value
  raise "#{func} requires an integer start index, but received #{start_index}" unless start_index.integer?
  si = start_index.value
  raise "#{func} received an invalid substring start index: #{si}" if si < 0 || si > s.length
  raise "#{func} requires an integer end index, but received #{end_index}" unless end_index.integer?
  ei = end_index.value
  raise "#{func} received an invalid substring end index: #{ei}" if ei < 0 || ei > s.length
  s[si...ei]
end

.list_string_impl(args, env) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/rubylisp/string.rb', line 118

def self.list_string_impl(args, env)
  raise "list->string requires 1 argument, but received #{args.length}" unless args.length == 1      
  list_of_chars = args.car.evaluate(env)
  raise "list->string requires a list argument, but received #{str_arg}" unless list_of_chars.list?      
  chars = list_of_chars.to_a.map do |a|
    ea = a.evaluate(env)
    raise "string requires a list of characters, but it contained #{ea}." unless ea.character?
    ea.value
  end
  self.with_value(chars.join)
end

.lowercase?(str) ⇒ Boolean

Returns:



406
407
408
# File 'lib/rubylisp/string.rb', line 406

def self.lowercase?(str)
  (str =~ /^[[:lower:]]*$/) == 0
end

.make_string_impl(args, env) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rubylisp/string.rb', line 91

def self.make_string_impl(args, env)
  raise "make-string need requires at least 1 argument" unless args.length > 0
  raise "make-string accepts at most 2 arguments, but was passed #{args.length}" if args.length > 2
  k_arg = args.car.evaluate(env)
  raise "make-string requires an integer as it's first argument." unless k_arg.integer?
  k = k_arg.value
  c = if args.length == 2
        c_arg = args.cadr.evaluate(env)
        raise "make-string requires a character as it's second argument, but received #{c_arg}." unless c_arg.character?
        c_arg.value
      else
        " "
      end
  self.with_value(c * k)
end

.registerObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rubylisp/string.rb', line 5

def self.register
      Primitive.register("str")   {|args, env| Lisp::String::str_impl(args, env) }
      Primitive.register("string?")   {|args, env| Lisp::String::stringp_impl(args, env) }
      Primitive.register("make-string") {|args, env| Lisp::String::make_string_impl(args, env) }      
      Primitive.register("string") {|args, env| Lisp::String::string_impl(args, env) }      
      Primitive.register("list->string") {|args, env| Lisp::String::list_string_impl(args, env) }      
      Primitive.register("string->list") {|args, env| Lisp::String::string_list_impl(args, env) }      
      Primitive.register("string-copy") {|args, env| Lisp::String::string_copy_impl(args, env) }      
      Primitive.register("string-length") {|args, env| Lisp::String::string_length_impl(args, env) }      
      Primitive.register("string-null?") {|args, env| Lisp::String::string_nullp_impl(args, env) }      
      Primitive.register("string-ref") {|args, env| Lisp::String::string_ref_impl(args, env) }      
      Primitive.register("string-set!") {|args, env| Lisp::String::string_set_impl(args, env) }      

      Primitive.register("string=?") {|args, env| Lisp::String::string_eq_impl(args, env) }      
      Primitive.register("substring=?") {|args, env| Lisp::String::substring_eq_impl(args, env) }      
      Primitive.register("string-ci=?") {|args, env| Lisp::String::string_ci_eq_impl(args, env) }      
      Primitive.register("substring-ci=?") {|args, env| Lisp::String::substring_ci_eq_impl(args, env) }      

      Primitive.register("string<?") {|args, env| Lisp::String::string_lt_impl(args, env) }      
      Primitive.register("substring<?") {|args, env| Lisp::String::substring_lt_impl(args, env) }      
      Primitive.register("string-ci<?") {|args, env| Lisp::String::string_ci_lt_impl(args, env) }      
      Primitive.register("substring-ci<?") {|args, env| Lisp::String::substring_ci_lt_impl(args, env) }      

      Primitive.register("string>?") {|args, env| Lisp::String::string_gt_impl(args, env) }      
      Primitive.register("substring>?") {|args, env| Lisp::String::substring_gt_impl(args, env) }      
      Primitive.register("string-ci>?") {|args, env| Lisp::String::string_ci_gt_impl(args, env) }      
      Primitive.register("substring-ci>?") {|args, env| Lisp::String::substring_ci_gt_impl(args, env) }      

      Primitive.register("string<=?") {|args, env| Lisp::String::string_lte_impl(args, env) }      
      Primitive.register("substring<=?") {|args, env| Lisp::String::substring_lte_impl(args, env) }      
      Primitive.register("string-ci<=?") {|args, env| Lisp::String::string_ci_lte_impl(args, env) }      
      Primitive.register("substring-ci<=?") {|args, env| Lisp::String::substring_ci_lte_impl(args, env) }      

      Primitive.register("string>=?") {|args, env| Lisp::String::string_gte_impl(args, env) }      
      Primitive.register("substring>=?") {|args, env| Lisp::String::substring_gte_impl(args, env) }      
      Primitive.register("string-ci>=?") {|args, env| Lisp::String::string_ci_gte_impl(args, env) }      
      Primitive.register("substring-ci>=?") {|args, env| Lisp::String::substring_ci_gte_impl(args, env) }      

      Primitive.register("string-compare") {|args, env| Lisp::String::string_compare_impl(args, env) }      
      Primitive.register("string-compare-ci") {|args, env| Lisp::String::string_compare_ci_impl(args, env) }      

      Primitive.register("string-hash") {|args, env| Lisp::String::string_hash_impl(args, env) }      
      Primitive.register("string-hash-mod") {|args, env| Lisp::String::string_hash_mod_impl(args, env) }      

      Primitive.register("string-capitalized?") {|args, env| Lisp::String::string_capitalizedp_impl(args, env) }      
      Primitive.register("substring-capitalized?") {|args, env| Lisp::String::substring_capitalizedp_impl(args, env) }      
      Primitive.register("string-upper-case?") {|args, env| Lisp::String::string_upperp_impl(args, env) }      
      Primitive.register("substring-upper-case?") {|args, env| Lisp::String::substring_upperp_impl(args, env) }      
      Primitive.register("string-lower-case?") {|args, env| Lisp::String::string_lowerp_impl(args, env) }      
      Primitive.register("substring-lower-case?") {|args, env| Lisp::String::substring_lowerp_impl(args, env) }      

      Primitive.register("string-capitalize") {|args, env| Lisp::String::string_capitalize_impl(args, env) }      
      Primitive.register("string-capitalize!") {|args, env| Lisp::String::string_capitalize_bang_impl(args, env) }      
      Primitive.register("substring-capitalize!") {|args, env| Lisp::String::substring_capitalize_bang_impl(args, env) }      
      Primitive.register("string-downcase") {|args, env| Lisp::String::string_downcase_impl(args, env) }      
      Primitive.register("string-downcase!") {|args, env| Lisp::String::string_downcase_bang_impl(args, env) }      
      Primitive.register("substring-downcase!") {|args, env| Lisp::String::substring_downcase_bang_impl(args, env) }      
      Primitive.register("string-upcase") {|args, env| Lisp::String::string_upcase_impl(args, env) }      
      Primitive.register("string-upcase!") {|args, env| Lisp::String::string_upcase_bang_impl(args, env) }      
      Primitive.register("substring-upcase!") {|args, env| Lisp::String::substring_upcase_bang_impl(args, env) }

      Primitive.register("string-append") {|args, env| Lisp::String::string_append_impl(args, env) }      
      Primitive.register("substring") {|args, env| Lisp::String::substring_impl(args, env) }      
      Primitive.register("string-head") {|args, env| Lisp::String::string_head_impl(args, env) }      
      Primitive.register("string-tail") {|args, env| Lisp::String::string_tail_impl(args, env) }      

      Primitive.register("string-pad-left") {|args, env| Lisp::String::string_pad_left_impl(args, env) }      
      Primitive.register("string-pad-right") {|args, env| Lisp::String::string_pad_right_impl(args, env) }      

      Primitive.register("string-trim") {|args, env| Lisp::String::string_trim_impl(args, env) }      
      Primitive.register("string-trim-right") {|args, env| Lisp::String::string_trim_right_impl(args, env) }      
      Primitive.register("string-trim-left") {|args, env| Lisp::String::string_trim_left_impl(args, env) }      
end

.split_into_words(str) ⇒ Object



419
420
421
# File 'lib/rubylisp/string.rb', line 419

def self.split_into_words(str)
  str.split(/[^[[:alpha:]]]+/)
end

.str_impl(args, env) ⇒ Object



79
80
81
82
# File 'lib/rubylisp/string.rb', line 79

def self.str_impl(args, env)
  strings = args.to_a.map {|e| e.evaluate(env).to_s}
  String.with_value(strings.join)
end

.string_append_impl(args, env) ⇒ Object



617
618
619
620
621
622
623
624
625
# File 'lib/rubylisp/string.rb', line 617

def self.string_append_impl(args, env)
  strings = args.to_a.map do |a|
    s = a.evaluate(env)
    raise "string-append requires strings, but received #{s}" unless s.string?
    s.value
  end

  self.with_value(strings.join)
end

.string_capitalize_bang_impl(args, env) ⇒ Object



491
492
493
494
495
496
497
498
499
500
# File 'lib/rubylisp/string.rb', line 491

def self.string_capitalize_bang_impl(args, env)
  raise "string-capitalize! requires 1 argument, but received #{args.length}" unless args.length == 1
  str = args.nth(1).evaluate(env)
  raise "string-capitalize! requires a string, but received #{str}" unless str.string?
  new_chars = capitalize_string(str.value)
  new_str = ""
  new_chars.each {|c| new_str << c}
  str.set!(new_str)
  str
end

.string_capitalize_impl(args, env) ⇒ Object



482
483
484
485
486
487
488
# File 'lib/rubylisp/string.rb', line 482

def self.string_capitalize_impl(args, env)
  str = get_string("string-capitalize", args.nth(1).evaluate(env))
  new_chars = capitalize_string(str)
  new_str = ""
  new_chars.each {|c| new_str << c}
  self.with_value(new_str)
end

.string_capitalizedp_impl(args, env) ⇒ Object



424
425
426
427
428
# File 'lib/rubylisp/string.rb', line 424

def self.string_capitalizedp_impl(args, env)
  str = get_string("string-capitalized?", args.nth(1).evaluate(env))
  words = split_into_words(str)
  Lisp::Boolean.with_value(capitalized?(words[0])&& words[1..-1].all? {|w| capitalized?(w) || lowercase?(w)})
end

.string_ci_eq_impl(args, env) ⇒ Object



241
242
243
244
# File 'lib/rubylisp/string.rb', line 241

def self.string_ci_eq_impl(args, env)
  str1, str2 = extract_strings("string-ci=?", args, env)
  Lisp::Boolean.with_value(str1.downcase == str2.downcase)
end

.string_ci_gt_impl(args, env) ⇒ Object



289
290
291
292
# File 'lib/rubylisp/string.rb', line 289

def self.string_ci_gt_impl(args, env)
  str1, str2 = extract_strings("string-ci>?", args, env)
  Lisp::Boolean.with_value(str1.downcase > str2.downcase)
end

.string_ci_gte_impl(args, env) ⇒ Object



337
338
339
340
# File 'lib/rubylisp/string.rb', line 337

def self.string_ci_gte_impl(args, env)
  str1, str2 = extract_strings("string-ci>=?", args, env)
  Lisp::Boolean.with_value(str1.downcase >= str2.downcase)
end

.string_ci_lt_impl(args, env) ⇒ Object



265
266
267
268
# File 'lib/rubylisp/string.rb', line 265

def self.string_ci_lt_impl(args, env)
  str1, str2 = extract_strings("string-ci<?", args, env)
  Lisp::Boolean.with_value(str1.downcase < str2.downcase)
end

.string_ci_lte_impl(args, env) ⇒ Object



313
314
315
316
# File 'lib/rubylisp/string.rb', line 313

def self.string_ci_lte_impl(args, env)
  str1, str2 = extract_strings("string-ci<=?", args, env)
  Lisp::Boolean.with_value(str1.downcase <= str2.downcase)
end

.string_compare_ci_impl(args, env) ⇒ Object



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/rubylisp/string.rb', line 367

def self.string_compare_ci_impl(args, env)
  raise "string-compare-ci requires 5 arguments, but received #{args.length}" unless args.length == 5
  str1 = get_string("string-compare-ci", args.nth(1).evaluate(env))
  str2 = get_string("string-compare-ci", args.nth(2).evaluate(env))
  f_number = case str1.downcase <=> str2.downcase
             when -1
               4
             when 0
               3
             when 1
               5
             end
  f = args.nth(f_number).evaluate(env)
  raise "string-compare-ci requires functions for argument #{f_number}, but received #{f}" unless f.function?
  f.apply_to(Lisp::ConsCell.cons, env)
end

.string_compare_impl(args, env) ⇒ Object



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/rubylisp/string.rb', line 349

def self.string_compare_impl(args, env)
  raise "string-compare requires 5 arguments, but received #{args.length}" unless args.length == 5
  str1 = get_string("string-compare", args.nth(1).evaluate(env))
  str2 = get_string("string-compare", args.nth(2).evaluate(env))
  f_number = case str1 <=> str2
             when -1
               4
             when 0
               3
             when 1
               5
             end
  f = args.nth(f_number).evaluate(env)
  raise "string-compare requires functions for argument #{f_number}, but received #{f}" unless f.function?
  f.apply_to(Lisp::ConsCell.cons, env)
end

.string_copy_impl(args, env) ⇒ Object



140
141
142
143
144
145
# File 'lib/rubylisp/string.rb', line 140

def self.string_copy_impl(args, env)
  raise "string-copy requires 1 argument, but received #{args.length}" unless args.length == 1      
  str_arg = args.car.evaluate(env)
  raise "string-copy requires a string argument, but received #{str_arg}" unless str_arg.string?
  self.with_value(str_arg.value)
end

.string_downcase_bang_impl(args, env) ⇒ Object



537
538
539
540
541
542
543
# File 'lib/rubylisp/string.rb', line 537

def self.string_downcase_bang_impl(args, env)
  raise "string-downcase! requires 1 argument, but received #{args.length}" unless args.length == 1
  str = args.nth(1).evaluate(env)
  raise "string-downcase! requires a string, but received #{str}" unless str.string?
  str.set!(str.value.downcase)
  str
end

.string_downcase_impl(args, env) ⇒ Object



531
532
533
534
# File 'lib/rubylisp/string.rb', line 531

def self.string_downcase_impl(args, env)
  str = get_string("string-downcase?", args.nth(1).evaluate(env))
  self.with_value(str.downcase)
end

.string_eq_impl(args, env) ⇒ Object



229
230
231
232
# File 'lib/rubylisp/string.rb', line 229

def self.string_eq_impl(args, env)
  str1, str2 = extract_strings("string=?", args, env)
  Lisp::Boolean.with_value(str1 == str2)
end

.string_gt_impl(args, env) ⇒ Object



277
278
279
280
# File 'lib/rubylisp/string.rb', line 277

def self.string_gt_impl(args, env)
  str1, str2 = extract_strings("string>?", args, env)
  Lisp::Boolean.with_value(str1 > str2)
end

.string_gte_impl(args, env) ⇒ Object



325
326
327
328
# File 'lib/rubylisp/string.rb', line 325

def self.string_gte_impl(args, env)
  str1, str2 = extract_strings("string>=?", args, env)
  Lisp::Boolean.with_value(str1 >= str2)
end

.string_hash_impl(args, env) ⇒ Object



385
386
387
388
# File 'lib/rubylisp/string.rb', line 385

def self.string_hash_impl(args, env)
  str = get_string("string-hash", args.nth(1).evaluate(env))
  Lisp::Number.with_value(str.hash)
end

.string_hash_mod_impl(args, env) ⇒ Object



391
392
393
394
395
396
397
# File 'lib/rubylisp/string.rb', line 391

def self.string_hash_mod_impl(args, env)
  str = get_string("string-hash-mod", args.nth(1).evaluate(env))
  k_arg = args.cadr.evaluate(env)
  raise "string-hash-mod requires it's second argument to be an integer, but received #{k_arg}" unless k_arg.integer?
  k = k_arg.value
  Lisp::Number.with_value(str.hash % k)
end

.string_head_impl(args, env) ⇒ Object



634
635
636
637
638
639
640
641
642
643
644
645
646
# File 'lib/rubylisp/string.rb', line 634

def self.string_head_impl(args, env)
  raise "string-head requires 2 arguments, but received #{args.length}" unless args.length == 2
  s = args.nth(1).evaluate(env)
  raise "string-head requires a string as it's first argument, but received #{s}" unless s.string?
  str = s.value
  
  end_index = args.nth(2).evaluate(env)
  raise "string-head requires an integer end index, but received #{end_index}" unless end_index.integer?
  ei = end_index.value
  raise "string-head received an invalid end index: #{ei}" if ei < 0 || ei > str.length

  self.with_value(str[0...ei])
end

.string_impl(args, env) ⇒ Object



108
109
110
111
112
113
114
115
# File 'lib/rubylisp/string.rb', line 108

def self.string_impl(args, env)
  chars = args.to_a.map do |a|
    ea = a.evaluate(env)
    raise "string requires character args, but was passed #{ea}." unless ea.character?
    ea.value
  end
  self.with_value(chars.join)
end

.string_length_impl(args, env) ⇒ Object



148
149
150
151
152
153
# File 'lib/rubylisp/string.rb', line 148

def self.string_length_impl(args, env)
  raise "string-length requires 1 argument, but received #{args.length}" unless args.length == 1      
  str_arg = args.car.evaluate(env)
  raise "string-length requires a string argument, but received #{str_arg}" unless str_arg.string?
  Lisp::Number.with_value(str_arg.value.length)
end

.string_list_impl(args, env) ⇒ Object



131
132
133
134
135
136
137
# File 'lib/rubylisp/string.rb', line 131

def self.string_list_impl(args, env)
  raise "string->list requires 1 argument, but received #{args.length}" unless args.length == 1      
  str_arg = args.car.evaluate(env)
  raise "string->list requires a string argument, but received #{str_arg}" unless str_arg.string?
  chars = str_arg.value.each_char.map {|c| Lisp::Character.find_character_for_chr(c) }
  Lisp::ConsCell.array_to_list(chars)
end

.string_lowerp_impl(args, env) ⇒ Object



452
453
454
455
456
# File 'lib/rubylisp/string.rb', line 452

def self.string_lowerp_impl(args, env)
  str = get_string("string-lower-case?", args.nth(1).evaluate(env))
  words = split_into_words(str)
  Lisp::Boolean.with_value(words.all? {|w| lowercase?(w)})
end

.string_lt_impl(args, env) ⇒ Object



253
254
255
256
# File 'lib/rubylisp/string.rb', line 253

def self.string_lt_impl(args, env)
  str1, str2 = extract_strings("string<?", args, env)
  Lisp::Boolean.with_value(str1 < str2)
end

.string_lte_impl(args, env) ⇒ Object



301
302
303
304
# File 'lib/rubylisp/string.rb', line 301

def self.string_lte_impl(args, env)
  str1, str2 = extract_strings("string<=?", args, env)
  Lisp::Boolean.with_value(str1 <= str2)
end

.string_nullp_impl(args, env) ⇒ Object



156
157
158
159
160
161
# File 'lib/rubylisp/string.rb', line 156

def self.string_nullp_impl(args, env)
  raise "string-length requires 1 argument, but received #{args.length}" unless args.length == 1      
  str_arg = args.car.evaluate(env)
  raise "string-length requires a string argument, but received #{str_arg}" unless str_arg.string?
  Lisp::Boolean.with_value(str_arg.value.length == 0)
end

.string_pad_left_impl(args, env) ⇒ Object



664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
# File 'lib/rubylisp/string.rb', line 664

def self.string_pad_left_impl(args, env)
  raise "string-pad-left requires 2 or 3 arguments, but received #{args.length}" unless args.length == 2 || args.length == 3
  s = args.nth(1).evaluate(env)
  raise "string-pad-left requires a string as it's first argument, but received #{s}" unless s.string?
  str = s.value
  
  size_arg = args.nth(2).evaluate(env)
  raise "string-pad-left requires an integer size, but received #{size_arg}" unless size_arg.integer?
  size = size_arg.value
  raise "string-pad-left received an invalid size: #{size}" if size < 0

  padding_char = if args.length == 3
                   ch_arg = args.nth(3).evaluate(env)
                   raise "string-pad-left requires a character pad, but received #{ch_arg}" unless ch_arg.character?
                   ch_arg.value
                 else
                   " "
                 end
    
  
  new_str = if size > str.length
              padding = size - str.length
              pad = ""
              padding.times {|i| pad << padding_char}
              pad + str
            else
              start = str.length - size
              str[start..-1]
            end
  self.with_value(new_str)
end

.string_pad_right_impl(args, env) ⇒ Object



697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
# File 'lib/rubylisp/string.rb', line 697

def self.string_pad_right_impl(args, env)
  raise "string-pad-right requires 2 or 3 arguments, but received #{args.length}" unless args.length == 2 || args.length == 3
  s = args.nth(1).evaluate(env)
  raise "string-pad-right requires a string as it's first argument, but received #{s}" unless s.string?
  str = s.value
  
  size_arg = args.nth(2).evaluate(env)
  raise "string-pad-right requires an integer size, but received #{size_arg}" unless size_arg.integer?
  size = size_arg.value
  raise "string-pad-right received an invalid size: #{size}" if size < 0

  padding_char = if args.length == 3
                   ch_arg = args.nth(3).evaluate(env)
                   raise "string-pad-right requires a character pad, but received #{ch_arg}" unless ch_arg.character?
                   ch_arg.value
                 else
                   " "
                 end
    
  
  new_str = if size > str.length
              padding = size - str.length
              pad = ""
              padding.times {|i| pad << padding_char}
              str + pad
            else
              last = str.length - size
              str[0...4]
            end
  self.with_value(new_str)
end

.string_ref_impl(args, env) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
# File 'lib/rubylisp/string.rb', line 164

def self.string_ref_impl(args, env)
  raise "string-ref requires 2 arguments, but received #{args.length}" unless args.length == 2      
  str_arg = args.car.evaluate(env)
  raise "string-ref requires a string as it's first argument, but received #{arg.car}" unless str_arg.string?
  str = str_arg.value
  k_arg = args.cadr.evaluate(env)
  raise "string-ref requires it's second argument to be an integer, but received #{k_arg}" unless k_arg.integer?
  k = k_arg.value
  return Lisp::FALSE if k < 0 || k >= str.length
  Lisp::Character.find_character_for_chr(str[k])
end

.string_set_impl(args, env) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/rubylisp/string.rb', line 177

def self.string_set_impl(args, env)
  raise "string-set! needs 3 arguments, but received #{args.length}" unless args.length == 3
  str_arg = args.car.evaluate(env)
  raise "string-set! needs a string as it's first argument, but received #{str_arg}" unless str_arg.string?
  str = str_arg.value
  k_arg = args.cadr.evaluate(env)
  raise "string-set! requires an integer as it's second argument, but received #{k_arg}" unless k_arg.integer?
  k = k_arg.value
  return Lisp::FALSE if k < 0 || k >= str.length
  replacement_arg = args.caddr.evaluate(env)
  raise "string-set! requires a character as it's third argument, but received #{replacement_arg}" unless replacement_arg.character?
  replacement = replacement_arg.value
  str[k] = replacement
  self.with_value(str)
end

.string_tail_impl(args, env) ⇒ Object



649
650
651
652
653
654
655
656
657
658
659
660
661
# File 'lib/rubylisp/string.rb', line 649

def self.string_tail_impl(args, env)
  raise "string-tail requires 2 arguments, but received #{args.length}" unless args.length == 2
  s = args.nth(1).evaluate(env)
  raise "string-tail requires a string as it's first argument, but received #{s}" unless s.string?
  str = s.value
  
  start_index = args.nth(2).evaluate(env)
  raise "string-tail requires an integer start index, but received #{start_index}" unless start_index.integer?
  si = start_index.value
  raise "string-tail received an invalid end index: #{si}" if si < 0 || si > str.length

  self.with_value(str[si..-1])
end

.string_trim_impl(args, env) ⇒ Object



730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
# File 'lib/rubylisp/string.rb', line 730

def self.string_trim_impl(args, env)
  raise "string-trim requires 1 or 2 arguments, but received #{args.length}" unless args.length == 1 || args.length == 2
  s1 = args.nth(1).evaluate(env)
  raise "string-trim requires a string as it's first argument, but received #{s1}" unless s1.string?
  str = s1.value

  pattern = Regexp.new(if args.length == 2
                         s2 = args.nth(2).evaluate(env)
                         raise "string-trim requires a string as it's second argument, but received #{s2}" unless s2.string?
                         s2.value
                       else
                         "[[:graph:]]"
                       end)

  
  left_i = 0
  while pattern.match(str[left_i]).nil? && left_i < str.length
    left_i += 1
  end
  
  right_i = str.length - 1
  while pattern.match(str[right_i]).nil? && right_i >= 0
    right_i -= 1
  end
  
  self.with_value(str[left_i..right_i])
end

.string_trim_left_impl(args, env) ⇒ Object



759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/rubylisp/string.rb', line 759

def self.string_trim_left_impl(args, env)
  raise "string-trim-left requires 1 or 2 arguments, but received #{args.length}" unless args.length == 1 || args.length == 2
  s1 = args.nth(1).evaluate(env)
  raise "string-trim-left requires a string as it's first argument, but received #{s1}" unless s1.string?
  str = s1.value

  pattern = Regexp.new(if args.length == 2
                         s2 = args.nth(2).evaluate(env)
                         raise "string-trim-left requires a string as it's second argument, but received #{s2}" unless s2.string?
                         s2.value
                       else
                         "[[:graph:]]"
                       end)

  
  left_i = 0
  while pattern.match(str[left_i]).nil? && left_i < str.length
    left_i += 1
  end
  
  self.with_value(str[left_i..-1])
end

.string_trim_right_impl(args, env) ⇒ Object



783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
# File 'lib/rubylisp/string.rb', line 783

def self.string_trim_right_impl(args, env)
  raise "string-trim-right requires 1 or 2 arguments, but received #{args.length}" unless args.length == 1 || args.length == 2
  s1 = args.nth(1).evaluate(env)
  raise "string-trim-right requires a string as it's first argument, but received #{s1}" unless s1.string?
  str = s1.value

  pattern = Regexp.new(if args.length == 2
                         s2 = args.nth(2).evaluate(env)
                         raise "string-trim-right requires a string as it's second argument, but received #{s2}" unless s2.string?
                         s2.value
                       else
                         "[[:graph:]]"
                       end)

  right_i = str.length - 1
  while pattern.match(str[right_i]).nil? && right_i >= 0
    right_i -= 1
  end
  
  self.with_value(str[0..right_i])
end

.string_upcase_bang_impl(args, env) ⇒ Object



580
581
582
583
584
585
586
# File 'lib/rubylisp/string.rb', line 580

def self.string_upcase_bang_impl(args, env)
  raise "string-upcase! requires 1 argument, but received #{args.length}" unless args.length == 1
  str = args.nth(1).evaluate(env)
  raise "string-upcase! requires a string, but received #{str}" unless str.string?
  str.set!(str.value.upcase)
  str
end

.string_upcase_impl(args, env) ⇒ Object



574
575
576
577
# File 'lib/rubylisp/string.rb', line 574

def self.string_upcase_impl(args, env)
  str = get_string("string-upcase?", args.nth(1).evaluate(env))
  self.with_value(str.upcase)
end

.string_upperp_impl(args, env) ⇒ Object



438
439
440
441
442
# File 'lib/rubylisp/string.rb', line 438

def self.string_upperp_impl(args, env)
  str = get_string("string-upper-case?", args.nth(1).evaluate(env))
  words = split_into_words(str)
  Lisp::Boolean.with_value(words.all? {|w| uppercase?(w)})
end

.stringp_impl(args, env) ⇒ Object



85
86
87
88
# File 'lib/rubylisp/string.rb', line 85

def self.stringp_impl(args, env)
  raise "string? requires 1 argument" unless args.length == 1
  return Lisp::Boolean.with_value(args.car.evaluate(env).string?)
end

.substring_capitalize_bang_impl(args, env) ⇒ Object



503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
# File 'lib/rubylisp/string.rb', line 503

def self.substring_capitalize_bang_impl(args, env)
  raise "substring-capitalize! requires 3 arguments, but received #{args.length}" unless args.length == 3
  s = args.nth(1).evaluate(env)
  raise "substring-capitalize! requires a string as it's first argument, but received #{s}" unless s.string?
  str = s.value
  
  start_index = args.nth(2).evaluate(env)
  raise "substring-capitalize! requires an integer start index, but received #{start_index}" unless start_index.integer?
  si = start_index.value
  raise "substring-capitalize! received an invalid substring start index: #{si}" if si < 0 || si > str.length

  end_index = args.nth(3).evaluate(env)
  raise "substring-capitalize! requires an integer end index, but received #{end_index}" unless end_index.integer?
  ei = end_index.value
  raise "substring-capitalize! received an invalid substring end index: #{ei}" if ei < 0 || ei > str.length

  prefix = str[0...si]
  substr = str[si...ei]
  suffix = str[ei..-1]
  
  new_chars = capitalize_string(substr)
  new_substr = ""   
  new_chars.each {|c| new_substr << c}
  s.set!(prefix + new_substr + suffix)
  s
end

.substring_capitalizedp_impl(args, env) ⇒ Object



431
432
433
434
435
# File 'lib/rubylisp/string.rb', line 431

def self.substring_capitalizedp_impl(args, env)
  str = get_substring("substring-capitalized?", args.nth(1).evaluate(env), args.nth(2).evaluate(env), args.nth(3).evaluate(env))
  words = split_into_words(str)
  Lisp::Boolean.with_value(capitalized?(words[0]) && words[1..-1].all? {|w| capitalized?(w) || lowercase?(w)})
end

.substring_ci_eq_impl(args, env) ⇒ Object



247
248
249
250
# File 'lib/rubylisp/string.rb', line 247

def self.substring_ci_eq_impl(args, env)
  substr1, substr2 = extract_substrings("substring-ci=?", args, env)
  Lisp::Boolean.with_value(substr1.downcase == substr2.downcase)
end

.substring_ci_gt_impl(args, env) ⇒ Object



295
296
297
298
# File 'lib/rubylisp/string.rb', line 295

def self.substring_ci_gt_impl(args, env)
  substr1, substr2 = extract_substrings("substring-ci>?", args, env)
  Lisp::Boolean.with_value(substr1.downcase > substr2.downcase)
end

.substring_ci_gte_impl(args, env) ⇒ Object



343
344
345
346
# File 'lib/rubylisp/string.rb', line 343

def self.substring_ci_gte_impl(args, env)
  substr1, substr2 = extract_substrings("substring-ci>=?", args, env)
  Lisp::Boolean.with_value(substr1.downcase >= substr2.downcase)
end

.substring_ci_lt_impl(args, env) ⇒ Object



271
272
273
274
# File 'lib/rubylisp/string.rb', line 271

def self.substring_ci_lt_impl(args, env)
  substr1, substr2 = extract_substrings("substring-ci<?", args, env)
  Lisp::Boolean.with_value(substr1.downcase < substr2.downcase)
end

.substring_ci_lte_impl(args, env) ⇒ Object



319
320
321
322
# File 'lib/rubylisp/string.rb', line 319

def self.substring_ci_lte_impl(args, env)
  substr1, substr2 = extract_substrings("substring-ci<=?", args, env)
  Lisp::Boolean.with_value(substr1.downcase <= substr2.downcase)
end

.substring_downcase_bang_impl(args, env) ⇒ Object



546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
# File 'lib/rubylisp/string.rb', line 546

def self.substring_downcase_bang_impl(args, env)
  raise "substring-downcase! requires 3 arguments, but received #{args.length}" unless args.length == 3
  s = args.nth(1).evaluate(env)
  raise "substring-downcase! requires a string as it's first argument, but received #{s}" unless s.string?
  str = s.value
  
  start_index = args.nth(2).evaluate(env)
  raise "substring-downcase! requires an integer start index, but received #{start_index}" unless start_index.integer?
  si = start_index.value
  raise "substring-downcase! received an invalid substring start index: #{si}" if si < 0 || si > str.length

  end_index = args.nth(3).evaluate(env)
  raise "substring-downcase! requires an integer end index, but received #{end_index}" unless end_index.integer?
  ei = end_index.value
  raise "substring-downcase! received an invalid substring end index: #{ei}" if ei < 0 || ei > str.length

  prefix = str[0...si]
  substr = str[si...ei]
  suffix = str[ei..-1]
  
  new_chars = capitalize_string(substr)
  new_substr = ""   
  new_chars.each {|c| new_substr << c}
  s.set!(prefix + substr.downcase + suffix)
  s
end

.substring_eq_impl(args, env) ⇒ Object



235
236
237
238
# File 'lib/rubylisp/string.rb', line 235

def self.substring_eq_impl(args, env)
  substr1, substr2 = extract_substrings("substring=?", args, env)
  Lisp::Boolean.with_value(substr1 == substr2)
end

.substring_gt_impl(args, env) ⇒ Object



283
284
285
286
# File 'lib/rubylisp/string.rb', line 283

def self.substring_gt_impl(args, env)
  substr1, substr2 = extract_substrings("substring>?", args, env)
  Lisp::Boolean.with_value(substr1 > substr2)
end

.substring_gte_impl(args, env) ⇒ Object



331
332
333
334
# File 'lib/rubylisp/string.rb', line 331

def self.substring_gte_impl(args, env)
  substr1, substr2 = extract_substrings("substring>=?", args, env)
  Lisp::Boolean.with_value(substr1 >= substr2)
end

.substring_impl(args, env) ⇒ Object



628
629
630
631
# File 'lib/rubylisp/string.rb', line 628

def self.substring_impl(args, env)
  str = get_substring("substring", args.nth(1).evaluate(env), args.nth(2).evaluate(env), args.nth(3).evaluate(env))
  self.with_value(str)
end

.substring_lowerp_impl(args, env) ⇒ Object



459
460
461
462
463
# File 'lib/rubylisp/string.rb', line 459

def self.substring_lowerp_impl(args, env)
  str = get_substring("substring-lower-case?", args.nth(1).evaluate(env), args.nth(2).evaluate(env), args.nth(3).evaluate(env))
  words = split_into_words(str)
  Lisp::Boolean.with_value(words.all? {|w| lowercase?(w)})
end

.substring_lt_impl(args, env) ⇒ Object



259
260
261
262
# File 'lib/rubylisp/string.rb', line 259

def self.substring_lt_impl(args, env)
  substr1, substr2 = extract_substrings("substring<?", args, env)
  Lisp::Boolean.with_value(substr1 < substr2)
end

.substring_lte_impl(args, env) ⇒ Object



307
308
309
310
# File 'lib/rubylisp/string.rb', line 307

def self.substring_lte_impl(args, env)
  substr1, substr2 = extract_substrings("substring<=?", args, env)
  Lisp::Boolean.with_value(substr1 <= substr2)
end

.substring_upcase_bang_impl(args, env) ⇒ Object



589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
# File 'lib/rubylisp/string.rb', line 589

def self.substring_upcase_bang_impl(args, env)
  raise "substring-upcase! requires 3 arguments, but received #{args.length}" unless args.length == 3
  s = args.nth(1).evaluate(env)
  raise "substring-upcase! requires a string as it's first argument, but received #{s}" unless s.string?
  str = s.value
  
  start_index = args.nth(2).evaluate(env)
  raise "substring-upcase! requires an integer start index, but received #{start_index}" unless start_index.integer?
  si = start_index.value
  raise "substring-upcase! received an invalid substring start index: #{si}" if si < 0 || si > str.length

  end_index = args.nth(3).evaluate(env)
  raise "substring-upcase! requires an integer end index, but received #{end_index}" unless end_index.integer?
  ei = end_index.value
  raise "substring-upcase! received an invalid substring end index: #{ei}" if ei < 0 || ei > str.length

  prefix = str[0...si]
  substr = str[si...ei]
  suffix = str[ei..-1]
  
  new_chars = capitalize_string(substr)
  new_substr = ""   
  new_chars.each {|c| new_substr << c}
  s.set!(prefix + substr.upcase + suffix)
  s
end

.substring_upperp_impl(args, env) ⇒ Object



445
446
447
448
449
# File 'lib/rubylisp/string.rb', line 445

def self.substring_upperp_impl(args, env)
  str = get_substring("substring-upper-case?", args.nth(1).evaluate(env), args.nth(2).evaluate(env), args.nth(3).evaluate(env))
  words = split_into_words(str)
  Lisp::Boolean.with_value(words.all? {|w| uppercase?(w)})
end

.uppercase?(str) ⇒ Boolean

str is assumed to be a single word

Returns:



401
402
403
# File 'lib/rubylisp/string.rb', line 401

def self.uppercase?(str)
  (str =~ /^[[:upper:]]*$/) == 0
end

.with_value(n) ⇒ Object




808
809
810
# File 'lib/rubylisp/string.rb', line 808

def self.with_value(n)
  self.new(n)
end

Instance Method Details



836
837
838
# File 'lib/rubylisp/string.rb', line 836

def print_string
  "\"#{@value}\""
end

#set!(n) ⇒ Object



816
817
818
# File 'lib/rubylisp/string.rb', line 816

def set!(n)
  @value = n.to_s
end

#string?Boolean

Returns:



820
821
822
# File 'lib/rubylisp/string.rb', line 820

def string?
  true
end

#to_sObject



828
829
830
# File 'lib/rubylisp/string.rb', line 828

def to_s
  @value
end

#to_symObject



832
833
834
# File 'lib/rubylisp/string.rb', line 832

def to_sym
  @value.to_sym
end

#typeObject



824
825
826
# File 'lib/rubylisp/string.rb', line 824

def type
  :string
end