Class: Codgen::Statement

Inherits:
Object
  • Object
show all
Includes:
RegularExpressions
Defined in:
lib/codgen/statement.rb

Constant Summary

Constants included from RegularExpressions

RegularExpressions::IDENTIFIER_REGEX

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(operator = nil) ⇒ Statement

Returns a new instance of Statement.



8
9
10
11
# File 'lib/codgen/statement.rb', line 8

def initialize(operator=nil)
  @words = Array.new
  @operator = operator
end

Instance Attribute Details

#operatorObject (readonly)

Returns the value of attribute operator.



25
26
27
# File 'lib/codgen/statement.rb', line 25

def operator
  @operator
end

#wordsObject (readonly)

Returns the value of attribute words.



26
27
28
# File 'lib/codgen/statement.rb', line 26

def words
  @words
end

Instance Method Details

#accumulate(before, child, operator, get_val) ⇒ Object



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

def accumulate(before, child, operator, get_val)
  if operator == nil && child.is_a?(Statement)
    accumulate(before, child, child.operator, get_val)
  else
    value = child.is_a?(String) ? get_val.call(child) : child.evaluate(get_val)
    case operator
      when :and
        before = before != nil ? before : true
        before && value
      when :or
        before = before != nil ? before : false
        before || value
      when :not
        !value
      else
        value
    end
  end
end

#evaluate(get_val) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/codgen/statement.rb', line 13

def evaluate(get_val)
  if @operator == nil
    expand
  end

  current_val = nil
  @words.each do |child|
    current_val = accumulate(current_val, child, @operator, get_val)
  end
  current_val
end

#expandObject



48
49
50
51
52
# File 'lib/codgen/statement.rb', line 48

def expand
  expand_not
  expand_and
  expand_or
end

#expand_andObject



101
102
103
# File 'lib/codgen/statement.rb', line 101

def expand_and
  expand_two_sided(:and, /and|&/)
end

#expand_notObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/codgen/statement.rb', line 79

def expand_not
  new_words = Array.new
  @words.each do |word|
    if word.is_a?(Statement)
      new_words.push(word)
    elsif word.index(/not|!/)
      if new_words[-1].is_a?(Statement) && new_words[-1].operator == :not
        new_words.delete_at(-1)
      else
        new_words.push(Statement.new(:not))
      end
    else
      if new_words[-1].is_a?(Statement) && new_words[-1].operator == :not && new_words[-1].words.count == 0
        new_words[-1].words.push(word)
      else
        new_words.push(word)
      end
    end
  end
  @words = new_words
end

#expand_orObject



105
106
107
# File 'lib/codgen/statement.rb', line 105

def expand_or
  expand_two_sided(:or, /or|\|/)
end

#expand_two_sided(operator, regex) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/codgen/statement.rb', line 109

def expand_two_sided(operator, regex)
  new_words = Array.new
  index = -1
  skip = false
  @words.each do |word|
    index+=1
    if skip
      skip = false
      next
    end
    if word.is_a?(Statement)
      new_words.push(word)
    elsif word.index(regex)
      if new_words.count > 0 && @words.count > index + 1
        replace_with_statement(new_words, operator)
        skip = true
        next
      else
        throw 'Operator must have a left and a right side'
      end
    else
      new_words.push(word)
    end
  end
  @words = new_words
end

#parse(text) ⇒ Object



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/codgen/statement.rb', line 54

def parse(text)
  count = -1
  text.each_char do |current_char|
    count+=1
    if current_char == ' '
      next 1
    end

    if current_char.index(IDENTIFIER_REGEX)
      if @words.length > 0 && @words[-1].index(IDENTIFIER_REGEX)
        @words[-1] = @words[-1] + current_char
      else
        @words.push(current_char)
      end
    elsif current_char.index(/[&|!]/)
      @words.push(current_char)
    elsif current_char == '('
      @words.push(Statement.new)
      count += @words[-1].parse(text[count...text.length])
    elsif current_char == ')'
      return count
    end
  end
end

#replace_with_statement(new_words, operator) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/codgen/statement.rb', line 136

def replace_with_statement(new_words, operator)
  left = new_words[-1]
  new_words.delete_at(-1)
  new_words.push(Statement.new(operator))
  new_words[-1].words.push(left)
  new_words[-1].words.push(@words[index+1])
end