flor 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +8 -0
- data/lib/flor.rb +1 -1
- data/lib/flor/core.rb +7 -0
- data/lib/flor/core/executor.rb +43 -8
- data/lib/flor/core/node.rb +84 -54
- data/lib/flor/core/procedure.rb +36 -19
- data/lib/flor/core/texecutor.rb +4 -1
- data/lib/flor/deep.rb +43 -51
- data/lib/flor/dollar.rb +2 -3
- data/lib/flor/flor.rb +38 -9
- data/lib/flor/parser.rb +123 -72
- data/lib/flor/pcore/_arr.rb +15 -0
- data/lib/flor/pcore/_atom.rb +6 -5
- data/lib/flor/pcore/_att.rb +9 -4
- data/lib/flor/pcore/_obj.rb +28 -34
- data/lib/flor/pcore/_pat_.rb +77 -0
- data/lib/flor/pcore/_pat_arr.rb +131 -0
- data/lib/flor/pcore/_pat_guard.rb +70 -0
- data/lib/flor/pcore/_pat_obj.rb +143 -0
- data/lib/flor/pcore/_pat_or.rb +46 -0
- data/lib/flor/pcore/_val.rb +20 -0
- data/lib/flor/pcore/arith.rb +7 -1
- data/lib/flor/pcore/case.rb +46 -69
- data/lib/flor/pcore/cursor.rb +24 -24
- data/lib/flor/pcore/define.rb +5 -1
- data/lib/flor/pcore/do_return.rb +32 -0
- data/lib/flor/pcore/length.rb +18 -0
- data/lib/flor/pcore/logo.rb +47 -0
- data/lib/flor/pcore/map.rb +12 -10
- data/lib/flor/pcore/match.rb +276 -0
- data/lib/flor/pcore/not.rb +13 -0
- data/lib/flor/pcore/push.rb +52 -13
- data/lib/flor/pcore/range.rb +69 -0
- data/lib/flor/pcore/set.rb +82 -24
- data/lib/flor/unit/hook.rb +28 -0
- data/lib/flor/unit/hooker.rb +5 -0
- data/lib/flor/unit/loader.rb +4 -1
- data/lib/flor/unit/storage.rb +5 -3
- data/lib/flor/unit/waiter.rb +12 -2
- data/lib/flor/unit/wlist.rb +4 -3
- data/match.md +22 -0
- metadata +15 -5
- data/lib/flor/pcore/_happly.rb +0 -49
- data/lib/flor/pcore/val.rb +0 -16
- data/t.txt +0 -4
    
        data/lib/flor/core/texecutor.rb
    CHANGED
    
    | @@ -182,7 +182,10 @@ module Flor | |
| 182 182 |  | 
| 183 183 | 
             
                  vs = Hash.new { |h, k| k }
         | 
| 184 184 | 
             
                  class << vs
         | 
| 185 | 
            -
                    def has_key?(k) | 
| 185 | 
            +
                    def has_key?(k)
         | 
| 186 | 
            +
                      prc = Flor::Procedure[k]
         | 
| 187 | 
            +
                      ( ! prc) || ( ! prc.core?) # ignore non-core procedures
         | 
| 188 | 
            +
                    end
         | 
| 186 189 | 
             
                  end
         | 
| 187 190 |  | 
| 188 191 | 
             
                  vs['root'] = determine_root(path)
         | 
    
        data/lib/flor/deep.rb
    CHANGED
    
    | @@ -32,97 +32,89 @@ module Flor | |
| 32 32 | 
             
                    end }
         | 
| 33 33 | 
             
              end
         | 
| 34 34 |  | 
| 35 | 
            -
               | 
| 35 | 
            +
              # Returns a symbol in case of failure.
         | 
| 36 | 
            +
              #
         | 
| 37 | 
            +
              def self.deep_get(o, k)
         | 
| 36 38 |  | 
| 37 | 
            -
                return  | 
| 39 | 
            +
                return o unless k
         | 
| 38 40 |  | 
| 39 | 
            -
                val  | 
| 41 | 
            +
                split_deep_path(k).inject([ o, [] ]) do |(val, seen), kk|
         | 
| 40 42 |  | 
| 41 | 
            -
             | 
| 43 | 
            +
                  seen << kk
         | 
| 42 44 |  | 
| 43 45 | 
             
                  case val
         | 
| 44 46 | 
             
                  when Array
         | 
| 45 47 | 
             
                    i = to_array_index(kk)
         | 
| 46 | 
            -
                    return  | 
| 47 | 
            -
                     | 
| 48 | 
            +
                    return seen.join('.').to_sym unless i
         | 
| 49 | 
            +
                    [ val[i], seen ]
         | 
| 48 50 | 
             
                  when Hash
         | 
| 49 | 
            -
                     | 
| 51 | 
            +
                    [ val[kk], seen ]
         | 
| 50 52 | 
             
                  else
         | 
| 51 | 
            -
                    return [ | 
| 53 | 
            +
                    return seen[0..-2].join('.').to_sym
         | 
| 52 54 | 
             
                  end
         | 
| 53 | 
            -
                end
         | 
| 54 55 |  | 
| 55 | 
            -
                 | 
| 56 | 
            +
                end.first
         | 
| 56 57 | 
             
              end
         | 
| 57 58 |  | 
| 58 | 
            -
              def self.deep_set(o, k, v) | 
| 59 | 
            +
              def self.deep_set(o, k, v)
         | 
| 59 60 |  | 
| 60 61 | 
             
                ks = split_deep_path(k)
         | 
| 61 62 | 
             
                key = ks.pop
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                b, col = deep_get(o, ks)
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                return [ false, v ] unless b
         | 
| 63 | 
            +
                col = deep_get(o, ks)
         | 
| 66 64 |  | 
| 67 65 | 
             
                case col
         | 
| 66 | 
            +
                when Symbol
         | 
| 67 | 
            +
                  col
         | 
| 68 68 | 
             
                when Array
         | 
| 69 69 | 
             
                  i = to_array_index(key)
         | 
| 70 | 
            -
                  return  | 
| 70 | 
            +
                  return ks.join('.').to_sym unless i
         | 
| 71 71 | 
             
                  col[i] = v
         | 
| 72 72 | 
             
                when Hash
         | 
| 73 73 | 
             
                  col[key] = v
         | 
| 74 74 | 
             
                else
         | 
| 75 | 
            -
                   | 
| 75 | 
            +
                  ks.join('.').to_sym
         | 
| 76 76 | 
             
                end
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                [ true, v ]
         | 
| 79 77 | 
             
              end
         | 
| 80 78 |  | 
| 81 | 
            -
              def self.deep_insert(o, k, v) | 
| 79 | 
            +
              def self.deep_insert(o, k, v)
         | 
| 82 80 |  | 
| 83 81 | 
             
                ks = split_deep_path(k)
         | 
| 84 82 | 
             
                key = ks.pop
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                b, col = deep_get(o, ks)
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                return [ false, nil ] unless b
         | 
| 83 | 
            +
                col = deep_get(o, ks)
         | 
| 89 84 |  | 
| 90 85 | 
             
                case col
         | 
| 86 | 
            +
                when Symbol
         | 
| 87 | 
            +
                  col
         | 
| 91 88 | 
             
                when Array
         | 
| 92 89 | 
             
                  i = to_array_index(key)
         | 
| 93 | 
            -
                  return  | 
| 90 | 
            +
                  return ks.join('.').to_sym unless i
         | 
| 94 91 | 
             
                  col.insert(i, v)
         | 
| 92 | 
            +
                  v
         | 
| 95 93 | 
             
                when Hash
         | 
| 96 94 | 
             
                  col[key] = v
         | 
| 97 95 | 
             
                else
         | 
| 98 | 
            -
                   | 
| 96 | 
            +
                  ks.join('.').to_sym
         | 
| 99 97 | 
             
                end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                [ true, v ]
         | 
| 102 98 | 
             
              end
         | 
| 103 99 |  | 
| 104 | 
            -
              def self.deep_unset(o, k) | 
| 100 | 
            +
              def self.deep_unset(o, k)
         | 
| 105 101 |  | 
| 106 102 | 
             
                ks = split_deep_path(k)
         | 
| 107 103 | 
             
                key = ks.pop
         | 
| 104 | 
            +
                col = deep_get(o, ks)
         | 
| 108 105 |  | 
| 109 | 
            -
                 | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
                   | 
| 115 | 
            -
                   | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
                   | 
| 120 | 
            -
             | 
| 121 | 
            -
                  else
         | 
| 122 | 
            -
                    return [ false, nil ]
         | 
| 123 | 
            -
                  end
         | 
| 124 | 
            -
             | 
| 125 | 
            -
                [ true, v ]
         | 
| 106 | 
            +
                case col
         | 
| 107 | 
            +
                when Symbol
         | 
| 108 | 
            +
                  col
         | 
| 109 | 
            +
                when Array
         | 
| 110 | 
            +
                  i = to_array_index(key)
         | 
| 111 | 
            +
                  return ks.join('.').to_sym unless i
         | 
| 112 | 
            +
                  col.delete_at(i)
         | 
| 113 | 
            +
                when Hash
         | 
| 114 | 
            +
                  col.delete(key)
         | 
| 115 | 
            +
                else
         | 
| 116 | 
            +
                  return ks.join('.').to_sym
         | 
| 117 | 
            +
                end
         | 
| 126 118 | 
             
              end
         | 
| 127 119 |  | 
| 128 120 | 
             
              def self.deep_has_key?(o, k)
         | 
| @@ -137,14 +129,14 @@ module Flor | |
| 137 129 | 
             
                  case val
         | 
| 138 130 | 
             
                  when Array
         | 
| 139 131 | 
             
                    i = to_array_index(kk)
         | 
| 140 | 
            -
                     | 
| 141 | 
            -
                     | 
| 132 | 
            +
                    break false unless i
         | 
| 133 | 
            +
                    break (i < 0 ? -i < val.length : i < val.length) if ks.empty?
         | 
| 142 134 | 
             
                    val = val[i]
         | 
| 143 135 | 
             
                  when Hash
         | 
| 144 | 
            -
                     | 
| 145 | 
            -
                    val = val[kk]
         | 
| 136 | 
            +
                    break val.has_key?(kk.to_s) if ks.empty? # nota bene: #to_s
         | 
| 137 | 
            +
                    val = val[kk.to_s]
         | 
| 146 138 | 
             
                  else
         | 
| 147 | 
            -
                     | 
| 139 | 
            +
                    break false
         | 
| 148 140 | 
             
                  end
         | 
| 149 141 | 
             
                end
         | 
| 150 142 | 
             
              end
         | 
    
        data/lib/flor/dollar.rb
    CHANGED
    
    | @@ -61,7 +61,7 @@ module Flor | |
| 61 61 | 
             
                  def rewrite_span(t)
         | 
| 62 62 | 
             
                    t.children.collect { |c| rewrite(c) }
         | 
| 63 63 | 
             
                  end
         | 
| 64 | 
            -
                end
         | 
| 64 | 
            +
                end # module Parser
         | 
| 65 65 |  | 
| 66 66 | 
             
                module PipeParser include Raabro
         | 
| 67 67 |  | 
| @@ -72,7 +72,7 @@ module Flor | |
| 72 72 | 
             
                  def rewrite_elt(t); t.string; end
         | 
| 73 73 | 
             
                  def rewrite_pipe(t); t.string == '|' ? :pipe : :dpipe; end
         | 
| 74 74 | 
             
                  def rewrite_elts(t); t.children.collect { |e| rewrite(e) }; end
         | 
| 75 | 
            -
                end
         | 
| 75 | 
            +
                end # module PipeParser
         | 
| 76 76 |  | 
| 77 77 | 
             
                #def lookup(s)
         | 
| 78 78 | 
             
                #  # ...
         | 
| @@ -196,7 +196,6 @@ module Flor | |
| 196 196 |  | 
| 197 197 | 
             
                    result =
         | 
| 198 198 | 
             
                      if mode == :lookup
         | 
| 199 | 
            -
                        #k[0, 1] == "'" ? k[1..-1] : do_lookup(k)
         | 
| 200 199 | 
             
                        k[0, 1] == "'" ? k[1..-1] : lookup(k)
         | 
| 201 200 | 
             
                      else # :call
         | 
| 202 201 | 
             
                        call(k, result)
         | 
    
        data/lib/flor/flor.rb
    CHANGED
    
    | @@ -264,16 +264,26 @@ module Flor | |
| 264 264 | 
             
                t[2].is_a?(Integer)
         | 
| 265 265 | 
             
              end
         | 
| 266 266 |  | 
| 267 | 
            +
              def self.is_string_tree?(t, s=nil)
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                t.is_a?(Array) &&
         | 
| 270 | 
            +
                t[2].is_a?(Integer) &&
         | 
| 271 | 
            +
                %w[ _sqs _dqs ].include?(t[0]) &&
         | 
| 272 | 
            +
                (s ? (t[1] == s) : t[1].is_a?(String))
         | 
| 273 | 
            +
              end
         | 
| 274 | 
            +
             | 
| 267 275 | 
             
              def self.is_att_tree?(t)
         | 
| 268 276 |  | 
| 269 277 | 
             
                t.is_a?(Array) &&
         | 
| 278 | 
            +
                t[2].is_a?(Integer) &&
         | 
| 270 279 | 
             
                t[0] == '_att' &&
         | 
| 271 280 | 
             
                t[1].is_a?(Array)
         | 
| 272 281 | 
             
              end
         | 
| 273 282 |  | 
| 274 283 | 
             
              def self.is_array_of_trees?(o)
         | 
| 275 284 |  | 
| 276 | 
            -
                o.is_a?(Array) && | 
| 285 | 
            +
                o.is_a?(Array) &&
         | 
| 286 | 
            +
                o.all? { |e| Flor.is_tree?(e) }
         | 
| 277 287 | 
             
              end
         | 
| 278 288 |  | 
| 279 289 | 
             
            #  # Array, object or atom tree
         | 
| @@ -311,14 +321,6 @@ module Flor | |
| 311 321 | 
             
                o[1]['task'].is_a?(String)
         | 
| 312 322 | 
             
              end
         | 
| 313 323 |  | 
| 314 | 
            -
              def self.is_tree_head_tree?(o)
         | 
| 315 | 
            -
             | 
| 316 | 
            -
                o.is_a?(Array) &&
         | 
| 317 | 
            -
                Flor.is_tree?(o[0]) &&
         | 
| 318 | 
            -
                Flor.is_array_of_trees?(o[1]) &&
         | 
| 319 | 
            -
                o[2].is_a?(Integer)
         | 
| 320 | 
            -
              end
         | 
| 321 | 
            -
             | 
| 322 324 | 
             
              # Returns [ st, i ], the parent subtree for the final i index of the nid
         | 
| 323 325 | 
             
              # Used when inserting updated subtrees.
         | 
| 324 326 | 
             
              #
         | 
| @@ -343,5 +345,32 @@ module Flor | |
| 343 345 | 
             
                return st if i == nil
         | 
| 344 346 | 
             
                st[1][i]
         | 
| 345 347 | 
             
              end
         | 
| 348 | 
            +
             | 
| 349 | 
            +
             | 
| 350 | 
            +
              #
         | 
| 351 | 
            +
              # splat
         | 
| 352 | 
            +
             | 
| 353 | 
            +
              SPLAT_REGEX = /\A(.*)__(_|\d+)\z/.freeze
         | 
| 354 | 
            +
             | 
| 355 | 
            +
              def self.splat(keys, array)
         | 
| 356 | 
            +
             | 
| 357 | 
            +
                ks = keys.dup
         | 
| 358 | 
            +
                a = array.dup
         | 
| 359 | 
            +
                h = {}
         | 
| 360 | 
            +
             | 
| 361 | 
            +
                while k = ks.shift
         | 
| 362 | 
            +
             | 
| 363 | 
            +
                  if m = SPLAT_REGEX.match(k)
         | 
| 364 | 
            +
                    r, l = m[1, 2]
         | 
| 365 | 
            +
                    l = (l == '_') ? a.length - ks.length : l.to_i
         | 
| 366 | 
            +
                    h[r] = a.take(l) if r.length > 0
         | 
| 367 | 
            +
                    a = a.drop(l)
         | 
| 368 | 
            +
                  else
         | 
| 369 | 
            +
                    h[k] = a.shift
         | 
| 370 | 
            +
                  end
         | 
| 371 | 
            +
                end
         | 
| 372 | 
            +
             | 
| 373 | 
            +
                h
         | 
| 374 | 
            +
              end
         | 
| 346 375 | 
             
            end
         | 
| 347 376 |  | 
    
        data/lib/flor/parser.rb
    CHANGED
    
    | @@ -19,7 +19,10 @@ module Flor | |
| 19 19 | 
             
                def pbend(i); str(nil, i, '}'); end
         | 
| 20 20 |  | 
| 21 21 | 
             
                def null(i); str(:null, i, 'null'); end
         | 
| 22 | 
            -
             | 
| 22 | 
            +
             | 
| 23 | 
            +
                def number(i)
         | 
| 24 | 
            +
                  rex(:number, i, /[-+]?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?/)
         | 
| 25 | 
            +
                end
         | 
| 23 26 |  | 
| 24 27 | 
             
                def tru(i); str(nil, i, 'true'); end
         | 
| 25 28 | 
             
                def fls(i); str(nil, i, 'false'); end
         | 
| @@ -99,13 +102,15 @@ module Flor | |
| 99 102 | 
             
                #  %w[ or or ], %w[ and and ],
         | 
| 100 103 | 
             
                #  %w[ equ == != <> ], %w[ lgt < > <= >= ], %w[ sum + - ], %w[ prd * / % ],
         | 
| 101 104 |  | 
| 102 | 
            -
                def  | 
| 105 | 
            +
                def ssmod(i); str(:sop, i, /%/); end
         | 
| 106 | 
            +
                def ssprd(i); rex(:sop, i, /[\*\/]/); end
         | 
| 103 107 | 
             
                def sssum(i); rex(:sop, i, /[+-]/); end
         | 
| 104 108 | 
             
                def sslgt(i); rex(:sop, i, /(<=?|>=?)/); end
         | 
| 105 109 | 
             
                def ssequ(i); rex(:sop, i, /(==?|!=|<>)/); end
         | 
| 106 110 | 
             
                def ssand(i); str(:sop, i, 'and'); end
         | 
| 107 111 | 
             
                def ssor(i); str(:sop, i, 'or'); end
         | 
| 108 112 |  | 
| 113 | 
            +
                def smod(i); seq(nil, i, :ssmod, :eol, '?'); end
         | 
| 109 114 | 
             
                def sprd(i); seq(nil, i, :ssprd, :eol, '?'); end
         | 
| 110 115 | 
             
                def ssum(i); seq(nil, i, :sssum, :eol, '?'); end
         | 
| 111 116 | 
             
                def slgt(i); seq(nil, i, :sslgt, :eol, '?'); end
         | 
| @@ -113,7 +118,8 @@ module Flor | |
| 113 118 | 
             
                def sand(i); seq(nil, i, :ssand, :eol, '?'); end
         | 
| 114 119 | 
             
                def sor(i); seq(nil, i, :ssor, :eol, '?'); end
         | 
| 115 120 |  | 
| 116 | 
            -
                def  | 
| 121 | 
            +
                def emod(i); jseq(:exp, i, :val_ws, :smod); end
         | 
| 122 | 
            +
                def eprd(i); jseq(:exp, i, :emod, :sprd); end
         | 
| 117 123 | 
             
                def esum(i); jseq(:exp, i, :eprd, :ssum); end
         | 
| 118 124 | 
             
                def elgt(i); jseq(:exp, i, :esum, :slgt); end
         | 
| 119 125 | 
             
                def eequ(i); jseq(:exp, i, :elgt, :sequ); end
         | 
| @@ -208,37 +214,52 @@ module Flor | |
| 208 214 | 
             
                  rewrite(t.c0)
         | 
| 209 215 | 
             
                end
         | 
| 210 216 |  | 
| 217 | 
            +
                def invert(operation, operand)
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                  l = operand[2]
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                  case operation
         | 
| 222 | 
            +
                  when '+'
         | 
| 223 | 
            +
                    if operand[0] == '_num' && operand[1].is_a?(Numeric)
         | 
| 224 | 
            +
                      [ operand[0], - operand[1], l ]
         | 
| 225 | 
            +
                    else
         | 
| 226 | 
            +
                      [ '-', [ operand ], l ]
         | 
| 227 | 
            +
                    end
         | 
| 228 | 
            +
                  when '*'
         | 
| 229 | 
            +
                    [ '/', [ [ 'num', 1, l ], operand ], l ]
         | 
| 230 | 
            +
                  else
         | 
| 231 | 
            +
            fail "don't know how to invert #{operation.inspect}" # FIXME
         | 
| 232 | 
            +
                  end
         | 
| 233 | 
            +
                end
         | 
| 234 | 
            +
             | 
| 211 235 | 
             
                def rewrite_exp(t)
         | 
| 212 236 |  | 
| 213 237 | 
             
                  return rewrite(t.c0) if t.children.size == 1
         | 
| 214 238 |  | 
| 215 | 
            -
                  cn =  | 
| 216 | 
            -
                  op = t.lookup(:sop).string
         | 
| 239 | 
            +
                  cn = t.children.collect { |ct| ct.lookup(nil) }
         | 
| 217 240 |  | 
| 218 | 
            -
                   | 
| 241 | 
            +
                  operation = cn.find { |ct| ct.name == :sop }.string
         | 
| 219 242 |  | 
| 220 | 
            -
                   | 
| 221 | 
            -
             | 
| 222 | 
            -
                    cn << rewrite(c)
         | 
| 223 | 
            -
                    o = tcn.shift; break unless o
         | 
| 224 | 
            -
                    o = o.lookup(:sop).string
         | 
| 225 | 
            -
                    next if o == op
         | 
| 226 | 
            -
                    cn = [ [ op, cn, cn.first[2] ] ]
         | 
| 227 | 
            -
                    op = o
         | 
| 228 | 
            -
                  end
         | 
| 243 | 
            +
                  operator = operation
         | 
| 244 | 
            +
                  operands = []
         | 
| 229 245 |  | 
| 230 | 
            -
                   | 
| 231 | 
            -
                     | 
| 232 | 
            -
             | 
| 246 | 
            +
                  cn.each do |ct|
         | 
| 247 | 
            +
                    if ct.name == :sop
         | 
| 248 | 
            +
                      operator = ct.string
         | 
| 249 | 
            +
                    else
         | 
| 250 | 
            +
                      o = rewrite(ct)
         | 
| 251 | 
            +
                      o = invert(operation, o) if operator != operation
         | 
| 252 | 
            +
                      operands << o
         | 
| 253 | 
            +
                    end
         | 
| 233 254 | 
             
                  end
         | 
| 234 255 |  | 
| 235 | 
            -
                  [  | 
| 256 | 
            +
                  [ operation, operands, operands.first[2] ]
         | 
| 236 257 | 
             
                end
         | 
| 237 258 |  | 
| 238 259 | 
             
                class Nod
         | 
| 239 260 |  | 
| 240 261 | 
             
                  attr_accessor :parent, :indent
         | 
| 241 | 
            -
                  attr_reader :children
         | 
| 262 | 
            +
                  attr_reader :type, :children
         | 
| 242 263 |  | 
| 243 264 | 
             
                  def initialize(tree, outdent)
         | 
| 244 265 |  | 
| @@ -275,64 +296,65 @@ module Flor | |
| 275 296 |  | 
| 276 297 | 
             
                  def to_a
         | 
| 277 298 |  | 
| 299 | 
            +
                    return [ @head, @children, @line ] unless @children.is_a?(Array)
         | 
| 278 300 | 
             
                    return @head if @head.is_a?(Array) && @children.empty?
         | 
| 279 301 |  | 
| 280 302 | 
             
                    cn = @children.collect(&:to_a)
         | 
| 281 303 |  | 
| 282 | 
            -
                     | 
| 283 | 
            -
                     | 
| 304 | 
            +
                    as, non_atts = cn.partition { |c| c[0] == '_att' }
         | 
| 305 | 
            +
                    atts, suff = [], nil
         | 
| 284 306 |  | 
| 285 | 
            -
                     | 
| 286 | 
            -
                      @head.is_a?(Array) &&
         | 
| 287 | 
            -
                      (@head[0] == '_arr' || @head[0] == '_obj') &&
         | 
| 288 | 
            -
                      #Flor.is_array_of_trees?(@head[1]) &&
         | 
| 289 | 
            -
                      cn.all? { |c| c[0] == '_att' && c[1].size > 1 }
         | 
| 290 | 
            -
                    )
         | 
| 291 | 
            -
                      cn = @head[1] + cn
         | 
| 292 | 
            -
                      @head = @head[0]
         | 
| 293 | 
            -
                      att, non_att = cn.partition { |c| c[0] == '_att' }
         | 
| 294 | 
            -
                      cn = att + non_att
         | 
| 295 | 
            -
                    end
         | 
| 307 | 
            +
                    as.each do |c|
         | 
| 296 308 |  | 
| 297 | 
            -
             | 
| 309 | 
            +
                      c1 = c[1]; c10 = c1.size == 1 && c1[0]
         | 
| 310 | 
            +
                      suff = [] if c10 && c10[1] == [] && %w[ if unless ].include?(c10[0])
         | 
| 298 311 |  | 
| 299 | 
            -
             | 
| 300 | 
            -
             | 
| 301 | 
            -
                    i =
         | 
| 302 | 
            -
                      atts.index { |c|
         | 
| 303 | 
            -
                        c.size == 1 && %w[ if unless ].include?(c[0][0]) && c[0][1] == []
         | 
| 304 | 
            -
                      }
         | 
| 312 | 
            +
                      (suff || atts) << c
         | 
| 313 | 
            +
                    end
         | 
| 305 314 |  | 
| 306 | 
            -
                     | 
| 315 | 
            +
                    atts, non_atts = ta_rework_arr_or_obj(atts, non_atts)
         | 
| 307 316 |  | 
| 308 | 
            -
                     | 
| 317 | 
            +
                    core = [ @head, atts + non_atts, @line ]
         | 
| 318 | 
            +
                    core = core[0] if core[0].is_a?(Array) && core[1].empty?
         | 
| 319 | 
            +
                    core = ta_rework_core(core) if core[0].is_a?(Array)
         | 
| 309 320 |  | 
| 310 | 
            -
                     | 
| 311 | 
            -
                    t[1].concat(atts[i + 1..-1].collect(&:first))
         | 
| 321 | 
            +
                    return core unless suff
         | 
| 312 322 |  | 
| 313 | 
            -
                     | 
| 314 | 
            -
                      t[1].push(@head)
         | 
| 315 | 
            -
                    else
         | 
| 316 | 
            -
                      t[1].push([ @head, cn0i, @line ])
         | 
| 317 | 
            -
                    end
         | 
| 323 | 
            +
                    iou = suff.shift[1][0][0]
         | 
| 318 324 |  | 
| 319 | 
            -
                     | 
| 325 | 
            +
                    [ iou, [ suff.first[1].first, core ], @line ]
         | 
| 320 326 | 
             
                  end
         | 
| 321 327 |  | 
| 322 328 | 
             
                  protected
         | 
| 323 329 |  | 
| 330 | 
            +
                  def ta_rework_arr_or_obj(atts, non_atts)
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                    return [ atts, non_atts ] unless (
         | 
| 333 | 
            +
                      @head.is_a?(Array) &&
         | 
| 334 | 
            +
                      non_atts.empty? &&
         | 
| 335 | 
            +
                      %w[ _arr _obj ].include?(@head[0]))
         | 
| 336 | 
            +
             | 
| 337 | 
            +
                    cn = @head[1] + atts + non_atts
         | 
| 338 | 
            +
                    @head = @head[0]
         | 
| 339 | 
            +
             | 
| 340 | 
            +
                    cn.partition { |c| c[0] == '_att' }
         | 
| 341 | 
            +
                  end
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                  def ta_rework_core(core)
         | 
| 344 | 
            +
             | 
| 345 | 
            +
                    l = core[2]
         | 
| 346 | 
            +
             | 
| 347 | 
            +
                    [ 'sequence', [
         | 
| 348 | 
            +
                      [ 'set', [
         | 
| 349 | 
            +
                        [ 'head_', [], l ],
         | 
| 350 | 
            +
                        core[0]
         | 
| 351 | 
            +
                      ], l ],
         | 
| 352 | 
            +
                      [ 'head_', core[1], l ]
         | 
| 353 | 
            +
                    ], l ]
         | 
| 354 | 
            +
                  end
         | 
| 355 | 
            +
             | 
| 324 356 | 
             
                  def read(tree)
         | 
| 325 357 |  | 
| 326 | 
            -
                    #if it = tree.lookup(:indent)
         | 
| 327 | 
            -
                    #  #s = it.string
         | 
| 328 | 
            -
                    #  #semicount = s.count(';')
         | 
| 329 | 
            -
                    #  #pipe = s.index('|')
         | 
| 330 | 
            -
                    #  #
         | 
| 331 | 
            -
                    #  #@indent =
         | 
| 332 | 
            -
                    #  #  if semicount == 1 then :east
         | 
| 333 | 
            -
                    #  #  elsif semicount > 1 || pipe then :south
         | 
| 334 | 
            -
                    #  #  else s.length; end
         | 
| 335 | 
            -
                    #end
         | 
| 336 358 | 
             
                    @indent = tree.lookup(:indent).string.length
         | 
| 337 359 |  | 
| 338 360 | 
             
                    ht = tree.lookup(:head)
         | 
| @@ -341,8 +363,8 @@ module Flor | |
| 341 363 | 
             
                    @head = Flor::Lang.rewrite(ht.c0)
         | 
| 342 364 | 
             
                    @head = @head[0] if @head[0].is_a?(String) && @head[1] == []
         | 
| 343 365 |  | 
| 344 | 
            -
                    atts =
         | 
| 345 | 
            -
                       | 
| 366 | 
            +
                    atts = tree.children[2..-1]
         | 
| 367 | 
            +
                      .inject([]) { |as, ct|
         | 
| 346 368 |  | 
| 347 369 | 
             
                        kt = ct.children.size == 3 ? ct.children[1].lookup(:key) : nil
         | 
| 348 370 | 
             
                        v = Flor::Lang.rewrite(ct.clast)
         | 
| @@ -350,20 +372,50 @@ module Flor | |
| 350 372 | 
             
                        if kt
         | 
| 351 373 | 
             
                          k = Flor::Lang.rewrite(kt.c0)
         | 
| 352 374 | 
             
                          as << [ '_att', [ k, v ], k[2] ]
         | 
| 353 | 
            -
                        elsif %w[ - + ].include?(@head) && v[0, 2] != [ '_', [] ]
         | 
| 354 | 
            -
                          if v[0] == '+'
         | 
| 355 | 
            -
                            as.concat(v[1])
         | 
| 356 | 
            -
                          else
         | 
| 357 | 
            -
                            as << v
         | 
| 358 | 
            -
                          end
         | 
| 359 375 | 
             
                        else
         | 
| 360 376 | 
             
                          as << [ '_att', [ v ], v[2] ]
         | 
| 361 377 | 
             
                        end
         | 
| 362 378 |  | 
| 363 | 
            -
                        as
         | 
| 364 | 
            -
                      end
         | 
| 379 | 
            +
                        as }
         | 
| 365 380 |  | 
| 366 381 | 
             
                    @children.concat(atts)
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                    rework_subtraction if @head == '-'
         | 
| 384 | 
            +
                    rework_addition if @head == '+' || @head == '-'
         | 
| 385 | 
            +
                  end
         | 
| 386 | 
            +
             | 
| 387 | 
            +
                  def rework_subtraction
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                    return unless @children.size == 1
         | 
| 390 | 
            +
             | 
| 391 | 
            +
                    c = @children.first
         | 
| 392 | 
            +
                    return unless c[0] == '_att' && c[1].size == 1
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                    c = c[1].first
         | 
| 395 | 
            +
             | 
| 396 | 
            +
                    if c[0] == '_num'
         | 
| 397 | 
            +
                      @head = '_num'
         | 
| 398 | 
            +
                      @children = - c[1]
         | 
| 399 | 
            +
                    elsif %w[ - + ].include?(c[0])
         | 
| 400 | 
            +
                      @head = c[0]
         | 
| 401 | 
            +
                      @children = c[1]
         | 
| 402 | 
            +
                      @children[0] = Flor::Lang.invert('+', @children[0])
         | 
| 403 | 
            +
                    end
         | 
| 404 | 
            +
                  end
         | 
| 405 | 
            +
             | 
| 406 | 
            +
                  def rework_addition
         | 
| 407 | 
            +
             | 
| 408 | 
            +
                    katts, atts, cn = @children
         | 
| 409 | 
            +
                      .inject([ [], [], [] ]) { |cn, ct|
         | 
| 410 | 
            +
                        if ct[0] == '_att'
         | 
| 411 | 
            +
                          cn[ct[1].size == 2 ? 0 : 1] << ct
         | 
| 412 | 
            +
                        else
         | 
| 413 | 
            +
                          cn[2] << ct
         | 
| 414 | 
            +
                        end
         | 
| 415 | 
            +
                        cn }
         | 
| 416 | 
            +
             | 
| 417 | 
            +
                    @children =
         | 
| 418 | 
            +
                      katts + atts.collect { |ct| ct[1].first } + cn
         | 
| 367 419 | 
             
                  end
         | 
| 368 420 | 
             
                end
         | 
| 369 421 |  | 
| @@ -371,10 +423,9 @@ module Flor | |
| 371 423 |  | 
| 372 424 | 
             
                  prev = root = Nod.new(nil, nil)
         | 
| 373 425 |  | 
| 374 | 
            -
                  #t.gather(:node).each do |nt|
         | 
| 375 426 | 
             
                  t.gather(:line).each do |lt|
         | 
| 376 427 | 
             
                    nt = lt.lookup(:node); next unless nt
         | 
| 377 | 
            -
                    ot = lt. | 
| 428 | 
            +
                    ot = lt.children.last.string
         | 
| 378 429 | 
             
                    n = Nod.new(nt, ot)
         | 
| 379 430 | 
             
                    prev.append(n)
         | 
| 380 431 | 
             
                    prev = n
         |