Class: Parse

Inherits:
Object
  • Object
show all
Defined in:
lib/parse.rb

Constant Summary collapse

@@timeFields =
[
  [:week, "w", "week"],
  [:second, "s", "second"],
  [:year, "y", "year"],
  [:month, "m", "mon", "month"],
  [:day, "d", "day"],
  [:hour, "h", "hour"],
  [:minute, "min", "minute"],
]

Class Method Summary collapse

Class Method Details

.editFlag(argument, entries) ⇒ Object

Time



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/parse.rb', line 27

def self.editFlag(argument, entries) # Time
  Parse.entrySpecBase(argument, entries) do |*vars|
    location, operands, ops, locator = vars

    expr = operands.take_while(&:integer?).zip(ops).map(&:reverse)
    ops = ops[expr.size..]
    operands = operands[expr.size..]

    arg = (eval expr.join) || 0
    op = ops.shift
    anchor = locator[entries, arg]
    anchor or err("entry #{location}#{arg.to_ss} does not exist")

    operands.map { |x| Parse.timeLiteral x }
            .zip(ops).join
            .then { |time| anchor.to_t + (op == "+" ? 1 : -1) * (eval(time) || 0) }
  end
end

.entrySpec(argument, entries) ⇒ Object

Time



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/parse.rb', line 46

def self.entrySpec(argument, entries) # Time
  Parse.entrySpecBase(argument, entries) do |*vars|
    _, operands, ops, locator = vars

    operands.all?(&:integer?) or err("invalid argument '#{argument}'")
    (operands.size == ops.size) or err("invalid expression")
    arg = (eval ops.zip(operands).join) || 0

    locator[entries, arg].to_t
  end
end

.entrySpecBase(argument, entries) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/parse.rb', line 12

def self.entrySpecBase(argument, entries)
  location, *operands = argument.split(/[+-]/)
  ops = argument.scan(/[+-]/)

  { ["", "t", "tail"] => proc { |a, n| a[a.size - 1 + n] },
   %w[h head] => proc { |a, n| a[n] },
   %w[m mid middle] => proc { |a, n| a[(a.size / 2) + n] } }.find { |k, _v| k.any? location }
    .default { err "undefined location '#{location}'" }
    .then do |_, locator|
    return locator[entries, 0].to_t if operands.empty?

    yield location, operands, ops, locator
  end
end

.lastFirstFlag(argument) ⇒ Object

Symbol, Integer


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/parse.rb', line 58

def self.lastFirstFlag(argument) # [Symbol, Integer]
  return [:entry, argument.to_i] if argument.integer?

  @@timeFields
    .find { |_, *forms| forms.any? argument }
    .when(Array) { argument = "1.#{argument}" }

  operands = argument.split(/[+-]/)
  ops = argument.scan(/[+-]/)

  operands
    .map { |x| Parse.timeLiteral x }
    .zip(ops).join
    .then { |r| [:time, eval(r)] }
end

.timeLiteral(x) ⇒ Object

Integer



74
75
76
77
78
79
80
81
82
# File 'lib/parse.rb', line 74

def self.timeLiteral(x) # Integer
  x =~ /\d+\.[a-z]+/ or err("malformed time spec '#{x}'")
  n, field = x.split(".")

  @@timeFields
    .find { |_m, *forms| forms.any? field }
    .tap { |_| _ or err "undefined time field '#{field}'" }
    .slice(0).then { |m| n.to_i.send(m) }
end

.yornalType(type) ⇒ Object



84
85
86
87
# File 'lib/parse.rb', line 84

def self.yornalType(type)
  (@@timeFields[2..] + [[:box, "x", "box"]])
    .find { |_, *forms| forms.any? type }
end