lib/tcl/ruby/commands/list.rb in tcl-ruby-0.1.0 vs lib/tcl/ruby/commands/list.rb in tcl-ruby-0.1.1
- old
+ new
@@ -1,72 +1,116 @@
module Tcl
module Ruby
class Interpreter
private
- def ___llength(arg)
- raise(CommandError, 'llength list') if arg.size != 1
- parse(arg[0], true).size
+ def ___concat(*arg)
+ arg.map(&:strip).join(' ')
end
- def ___list(arg)
- arg.join(' ').to_s
+ def ___llength(list)
+ parse(list, true).size.to_s
end
- def ___lindex(arg)
- if arg[1].nil?
- arg[0]
- elsif arg[1] == ''
- arg[0]
- else
- l = arg[0]
- arg[1..-1].each do |as|
- parse(as, true).each do |a|
- l = parse(l, true)
- a.gsub!(/end/, (l.size - 1).to_s)
- pos = eval(a)
- if (0...l.size).cover?(pos)
- l = l[pos]
- else
- return ''
- end
- end
+ def ___list(*arg)
+ ListArray.new(arg).to_list
+ end
+
+ def ___lindex(list, *indexes)
+ return list if indexes.nil? || indexes.empty?
+ l = list
+ indexes.each do |as|
+ parse(as, true).each do |a|
+ l = parse(l, true)
+ pos = parse_index_format(a)
+ l = l[pos]
end
- l
end
+ l || ''
end
- def ___join(arg)
- raise(CommandError, 'join list joinString?') unless (1..2).cover? arg.size
- separator = arg[1] || ' '
- parse(arg[0], true).join(separator)
+ def ___join(list, separator = ' ')
+ parse(list, true).join(separator)
end
- def ___linsert(arg)
- raise(CommandError, 'linsert list insertposition elements') unless arg.size >= 3
- l = parse(arg[0], true)
- l.insert(arg[1].to_i, *arg[2..-1])
- # "{#{l.join(' ')}}"
+ def ___linsert(list, index, element, *elements)
+ l = parse(list, true)
+ l.insert(parse_index_format(index), element, *elements)
l.to_list
end
- def ___lrange(arg)
- raise(CommandError, 'lrange list first last') unless arg.size == 3
- first = arg[1].to_i
- first = 0 if first < 0
- last = arg[2].to_i
- l = parse(arg[0], true)
- if first <= last
- l[first..last].to_list
+ def ___lrange(list, first, last)
+ first = parse_index_format first
+ last = parse_index_format last
+ l = parse(list, true)
+ l[first..last].to_list
+ end
+
+ def ___lappend(var_name, *values)
+ l = parse(variables(var_name), true)
+ l.push(*values)
+ @variables[var_name] = l.to_list
+ end
+
+ def ___lsort(*args)
+ opts = {}
+ if args.size > 1
+ opts = OptionParser.parse(
+ ['ascii', 'dictionary', 'integer', 'real', 'command?', 'increasing',
+ 'decreasing', 'index?', 'unique'], args)
+ end
+ __lsort_body(*args, opts)
+ end
+
+ def __lsort_body(list, opts)
+ l = parse(list, true)
+ func = if opts['directionary'] then :upcase
+ elsif opts['integer'] then :to_i
+ elsif opts['real'] then :to_f
+ else :to_s
+ end
+ if opts['index']
+ index = parse_index_format(opts['index'])
+ sort_func = -> (x) { parse(x, true)[index].send(func) }
else
- ''
+ sort_func = func
end
+ l.uniq!(&sort_func) if opts['unique']
+ l.sort_by!(&sort_func)
+ l.reverse! if opts['decreasing']
+ ListArray.new(l).to_list
end
- def ___lappend(arg)
- l = parse(variables(arg[0]), true)
- l.push(*arg[1..-1])
- @variables[arg[0]] = l.to_list
+ def ___lsearch(*args)
+ opts = {}
+ if args.size > 2
+ opts = OptionParser.parse(
+ ['all', 'ascii', 'decreasing', 'dictionary', 'exact', 'glob',
+ 'increasing', 'inline', 'integer', 'not', 'real', 'regexp',
+ 'sorted', 'start?'], args)
+ end
+ __lsearch_body(*args, opts)
+ end
+
+ def __lsearch_body(list, pattern, opts)
+ l = parse(list, true)
+ func = case [opts['all'], opts['inline']]
+ when [true, true] then :select
+ when [true, nil] then :find_index_all
+ when [nil, true] then :find
+ else :index
+ end
+ block = if opts['regexp'] then -> (b, x) { !!(x =~ /#{pattern}/) == b }
+ elsif opts['exact'] then -> (b, x) { (x == pattern) == b }
+ else
+ pattern.gsub!(/\*/, '.*')
+ pattern.tr!('?', '.')
+ pattern.gsub!(/\\(.)/) { Regexp.last_match(1) }
+ -> (b, x) { !!(x =~ /\A#{pattern}\z/) == b }
+ end.curry
+
+ v = l.send(func, &block.call(!opts['not']))
+ ListArray.new(v).to_list
end
end
end
end