Class: Gloo::Persist::FileLoader
- Inherits:
-
Object
- Object
- Gloo::Persist::FileLoader
- Defined in:
- lib/gloo/persist/file_loader.rb
Constant Summary collapse
- BEGIN_BLOCK =
'BEGIN'.freeze
- END_BLOCK =
'END'.freeze
- SPACE_CNT =
2- LIB_DIRECTIVE =
A 'load lib name' (or 'load ext name') statement at the top of a file, before the first object declaration. It makes a core library's object types available to the declarations that follow. Same syntax as the load verb, but the loader runs it before building the object tree instead of a script running it afterward.
/\A(?:load|ld)\s+(?:lib|ext)\s+\S+\s*\z/i.freeze
Instance Attribute Summary collapse
-
#obj ⇒ Object
readonly
Returns the value of attribute obj.
Instance Method Summary collapse
-
#determine_indent(line) ⇒ Object
Determine the relative indent level for the line.
-
#handle_one_line(line) ⇒ Object
Process one one of the file we're loading.
-
#initialize(engine, pn) ⇒ FileLoader
constructor
Set up a file storage for an object.
-
#join_continuations(data) ⇒ Object
Join continuation lines.
-
#load ⇒ Object
Load the objects from the file.
-
#process_line(line) ⇒ Object
Process one line and add objects.
-
#process_obj_line(line) ⇒ Object
Process one line and add objects.
-
#run_lib_directive(line) ⇒ Object
Run a top-of-file 'load lib name' directive.
-
#setup_process_obj_line ⇒ Object
Setup and get ready to process an object line.
-
#skip_line?(line) ⇒ Boolean
Is this line a comment or a blank line? If so we'll skip it.
-
#split_line(line) ⇒ Object
Split the line into 3 parts.
-
#tab_count(line) ⇒ Object
Get the number of leading tabs.
Constructor Details
#initialize(engine, pn) ⇒ FileLoader
Set up a file storage for an object.
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/gloo/persist/file_loader.rb', line 28 def initialize( engine, pn ) @engine = engine @mech = @engine.platform.get_file_mech( @engine ) @pn = pn @tabs = 0 @obj = nil @in_multiline = false @exiting_multiline = false @in_block = false @block_value = '' @body_started = false @debug = false end |
Instance Attribute Details
#obj ⇒ Object (readonly)
Returns the value of attribute obj.
23 24 25 |
# File 'lib/gloo/persist/file_loader.rb', line 23 def obj @obj end |
Instance Method Details
#determine_indent(line) ⇒ Object
Determine the relative indent level for the line.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/gloo/persist/file_loader.rb', line 127 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.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/gloo/persist/file_loader.rb', line 94 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 |
#join_continuations(data) ⇒ Object
Join continuation lines.
87 88 89 |
# File 'lib/gloo/persist/file_loader.rb', line 87 def join_continuations( data ) return data.gsub( "\\\n", '' ) end |
#load ⇒ Object
Load the objects from the file.
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 |
# File 'lib/gloo/persist/file_loader.rb', line 45 def load unless @mech.exist?( @pn ) @engine.err "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 = join_continuations( f ) f.each_line do |line| next if skip_line? line if !@body_started && line =~ LIB_DIRECTIVE run_lib_directive line next end @body_started = true handle_one_line line end end |
#process_line(line) ⇒ Object
Process one line and add objects.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/gloo/persist/file_loader.rb', line 145 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.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/gloo/persist/file_loader.rb', line 184 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 |
#run_lib_directive(line) ⇒ Object
Run a top-of-file 'load lib name' directive. It goes through the same load verb a script would use, so libraries are loaded and their object types registered before the declarations that depend on them are parsed.
79 80 81 82 |
# File 'lib/gloo/persist/file_loader.rb', line 79 def run_lib_directive( line ) @engine.log.debug "Loading file directive: #{line.strip}" @engine.parser.run line.strip end |
#setup_process_obj_line ⇒ Object
Setup and get ready to process an object line.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/gloo/persist/file_loader.rb', line 164 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.
116 117 118 119 120 121 122 |
# File 'lib/gloo/persist/file_loader.rb', line 116 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.
222 223 224 225 |
# File 'lib/gloo/persist/file_loader.rb', line 222 def split_line( line ) o = LineSplitter.new( line, @tabs ) return o.split end |
#tab_count(line) ⇒ Object
Get the number of leading tabs.
205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/gloo/persist/file_loader.rb', line 205 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 |