Class: GlooLang::Persist::FileLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/gloo_lang/persist/file_loader.rb

Constant Summary collapse

BEGIN_BLOCK =
'BEGIN'.freeze
END_BLOCK =
'END'.freeze
SPACE_CNT =
2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(engine, pn) ⇒ FileLoader

Set up a file storage for an object.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/gloo_lang/persist/file_loader.rb', line 20

def initialize( engine, pn )
  @engine = engine
  @mech = @engine.platform.getFileMech( @engine )
  @pn = pn
  @tabs = 0
  @obj = nil
  @in_multiline = false
  @exiting_multiline = false
  @in_block = false
  @block_value = ''
  @debug = false
end

Instance Attribute Details

#objObject (readonly)

Returns the value of attribute obj.



15
16
17
# File 'lib/gloo_lang/persist/file_loader.rb', line 15

def obj
  @obj
end

Instance Method Details

#determine_indent(line) ⇒ Object

Determine the relative indent level for the line.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/gloo_lang/persist/file_loader.rb', line 91

def determine_indent( line )
  tabs = tab_count( line )
  @indent = 0 # same level as prior line
  if tabs > @tabs # indent
    # TODO:  What if indent is more than one more level?
    @tabs = tabs
    @indent = 1
  elsif tabs < @tabs # outdent
    diff = @tabs - tabs
    @tabs -= diff
    @indent -= diff
  end
  puts "tabs: #{@tabs}, indent: #{@indent}, line: #{line}" if @debug
end

#handle_one_line(line) ⇒ Object

Process one one of the file we’re loading.



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

def handle_one_line( line )
  if line.strip.end_with? BEGIN_BLOCK
    @in_block = true
    @save_line = line
  elsif @in_block
    if line.strip == END_BLOCK
      @in_block = false
      determine_indent @save_line
      process_line @save_line
    else
      @block_value << line
    end
  else
    determine_indent line
    process_line line
  end
end

#loadObject

Load the objects from the file.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/gloo_lang/persist/file_loader.rb', line 36

def load
  unless @mech.exist?( @pn )
    @engine.log.error "File '#{@pn}' does not exist."
    return
  end

  @engine.log.debug "Loading file '#{@pn}'"
  @tabs = 0
  @parent_stack = []
  @parent = @engine.heap.root
  @parent_stack.push @parent
  f = @mech.read( @pn )
  f.each_line do |line|
    next if skip_line? line

    handle_one_line line
  end
end

#process_line(line) ⇒ Object

Process one line and add objects.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/gloo_lang/persist/file_loader.rb', line 109

def process_line( line )
  # reset multiline unless we're actually indented
  if @in_multiline && @multi_indent > @indent
    puts "Done multiline mi: #{@multi_indent}, i: #{@indent}" if @debug
    @in_multiline = false
    @exiting_multiline = true
  end

  if @in_multiline
    @last.add_line line
  else
    setup_process_obj_line
    process_obj_line line
  end
end

#process_obj_line(line) ⇒ Object

Process one line and add objects.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/gloo_lang/persist/file_loader.rb', line 148

def process_obj_line( line )
  name, type, value = split_line( line )
  unless @block_value == ''
    value = @block_value
    @block_value = ''
  end
  params = { name: name, type: type, value: value, parent: @parent }
  @last = @engine.factory.create( params )

  if value.empty? && @last&.multiline_value?
    @multi_indent = 0
    @in_multiline = true
    puts "*** Start multiline. multi_indent: #{@multi_indent}" if @debug
  end

  @obj = @last if @obj.nil?
end

#setup_process_obj_lineObject

Setup and get ready to process an object line.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/gloo_lang/persist/file_loader.rb', line 128

def setup_process_obj_line
  if @exiting_multiline
    @exiting_multiline = false
    @indent += 1
  end

  if @indent.positive?
    @parent = @last
    @parent_stack.push @parent
  elsif @indent.negative?
    @indent.abs.times do
      @parent_stack.pop
      @parent = @parent_stack.last
    end
  end
end

#skip_line?(line) ⇒ Boolean

Is this line a comment or a blank line? If so we’ll skip it.

Returns:

  • (Boolean)


80
81
82
83
84
85
86
# File 'lib/gloo_lang/persist/file_loader.rb', line 80

def skip_line?( line )
  line = line.strip
  return true if line.empty?
  return true if line[ 0 ] == '#'

  return false
end

#split_line(line) ⇒ Object

Split the line into 3 parts.



186
187
188
189
# File 'lib/gloo_lang/persist/file_loader.rb', line 186

def split_line( line )
  o = LineSplitter.new( line, @tabs )
  return o.split
end

#tab_count(line) ⇒ Object

Get the number of leading tabs.



169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/gloo_lang/persist/file_loader.rb', line 169

def tab_count( line )
  i = 0

  if line[ i ] == ' '
    i += 1 while line[ i ] == ' '
    tab_equiv = ( i / SPACE_CNT ).to_i
    puts "Found #{i} spaces => #{tab_equiv}" if @debug
    return tab_equiv
  end

  i += 1 while line[ i ] == "\t"
  return i
end