gloss 0.0.4 → 0.1.2
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.
- checksums.yaml +4 -4
 - data/.gitattributes +3 -0
 - data/.github/workflows/{crystal.yml → crystal_specs.yml} +1 -1
 - data/.github/workflows/{ruby.yml → ruby_specs.yml} +2 -2
 - data/.gloss.yml +1 -0
 - data/.rspec +1 -0
 - data/Gemfile.lock +9 -11
 - data/README.md +35 -5
 - data/Rakefile +1 -1
 - data/exe/gloss +13 -2
 - data/ext/gloss/Makefile +8 -19
 - data/ext/gloss/spec/parser_spec.cr +83 -83
 - data/ext/gloss/src/cr_ast.cr +63 -77
 - data/ext/gloss/src/gloss.cr +1 -2
 - data/ext/gloss/src/rb_ast.cr +40 -38
 - data/lib/gloss.rb +15 -7
 - data/lib/gloss/cli.rb +75 -32
 - data/lib/gloss/config.rb +10 -3
 - data/lib/gloss/errors.rb +1 -1
 - data/lib/gloss/initializer.rb +6 -5
 - data/lib/gloss/logger.rb +29 -0
 - data/lib/gloss/parser.rb +17 -2
 - data/lib/gloss/prog_loader.rb +141 -0
 - data/lib/gloss/scope.rb +1 -1
 - data/lib/gloss/source.rb +1 -1
 - data/lib/gloss/type_checker.rb +80 -32
 - data/lib/gloss/utils.rb +44 -0
 - data/lib/gloss/version.rb +5 -5
 - data/lib/gloss/{builder.rb → visitor.rb} +125 -74
 - data/lib/gloss/watcher.rb +47 -11
 - data/lib/gloss/writer.rb +22 -11
 - data/sig/core.rbs +2 -0
 - data/sig/fast_blank.rbs +4 -0
 - data/sig/{gloss.rbs → gls.rbs} +0 -0
 - data/sig/optparse.rbs +6 -0
 - data/sig/rubygems.rbs +9 -0
 - data/sig/yaml.rbs +3 -0
 - data/src/exe/gloss +19 -0
 - data/src/lib/gloss.gl +26 -0
 - data/src/lib/gloss/cli.gl +53 -24
 - data/src/lib/gloss/config.gl +9 -3
 - data/src/lib/gloss/initializer.gl +4 -6
 - data/src/lib/gloss/logger.gl +21 -0
 - data/src/lib/gloss/parser.gl +17 -5
 - data/src/lib/gloss/prog_loader.gl +133 -0
 - data/src/lib/gloss/scope.gl +0 -2
 - data/src/lib/gloss/type_checker.gl +85 -39
 - data/src/lib/gloss/utils.gl +38 -0
 - data/src/lib/gloss/version.gl +1 -1
 - data/src/lib/gloss/{builder.gl → visitor.gl} +123 -68
 - data/src/lib/gloss/watcher.gl +44 -10
 - data/src/lib/gloss/writer.gl +16 -14
 - metadata +23 -8
 
    
        data/ext/gloss/src/gloss.cr
    CHANGED
    
    | 
         @@ -4,14 +4,13 @@ require "./cr_ast" 
     | 
|
| 
       4 
4 
     | 
    
         
             
            require "./rb_ast"
         
     | 
| 
       5 
5 
     | 
    
         
             
            require "./parser"
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
            def parse_string( 
     | 
| 
      
 7 
     | 
    
         
            +
            def parse_string(_self : CrRuby::VALUE, str : CrRuby::VALUE)
         
     | 
| 
       8 
8 
     | 
    
         
             
              st = CrRuby.rb_str_to_str(str)
         
     | 
| 
       9 
9 
     | 
    
         
             
              string = String.new(CrRuby.rb_string_value_cstr(pointerof(st)))
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
              output = begin
         
     | 
| 
       12 
12 
     | 
    
         
             
                         Gloss.parse_string(string)
         
     | 
| 
       13 
13 
     | 
    
         
             
                       rescue e : Crystal::SyntaxException
         
     | 
| 
       14 
     | 
    
         
            -
                         pp e.backtrace
         
     | 
| 
       15 
14 
     | 
    
         
             
                         e.to_s
         
     | 
| 
       16 
15 
     | 
    
         
             
                       end
         
     | 
| 
       17 
16 
     | 
    
         | 
    
        data/ext/gloss/src/rb_ast.cr
    CHANGED
    
    | 
         @@ -19,7 +19,7 @@ module Rb 
     | 
|
| 
       19 
19 
     | 
    
         
             
                abstract class NodeWithChildren < Node
         
     | 
| 
       20 
20 
     | 
    
         
             
                  @info : NamedTuple(type: String, children: Array(Node))
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                  def initialize(@children : Array(Node))
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def initialize(@children : Array(Node), location : Crystal::Location?)
         
     | 
| 
       23 
23 
     | 
    
         
             
                    @info = {
         
     | 
| 
       24 
24 
     | 
    
         
             
                      type:     self.class.name.split("::").last,
         
     | 
| 
       25 
25 
     | 
    
         
             
                      children: @children,
         
     | 
| 
         @@ -32,7 +32,7 @@ module Rb 
     | 
|
| 
       32 
32 
     | 
    
         
             
                abstract class NodeWithValue < Node
         
     | 
| 
       33 
33 
     | 
    
         
             
                  @info : NamedTuple(type: String, value: String)
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                  def initialize(@value : String)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def initialize(@value : String, location : Crystal::Location?)
         
     | 
| 
       36 
36 
     | 
    
         
             
                    @info = {
         
     | 
| 
       37 
37 
     | 
    
         
             
                      type:  self.class.name.split("::").last,
         
     | 
| 
       38 
38 
     | 
    
         
             
                      value: @value,
         
     | 
| 
         @@ -43,13 +43,14 @@ module Rb 
     | 
|
| 
       43 
43 
     | 
    
         
             
                end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                class Block < Node
         
     | 
| 
       46 
     | 
    
         
            -
                  @info : NamedTuple(type: String,  
     | 
| 
      
 46 
     | 
    
         
            +
                  @info : NamedTuple(type: String, positional_args: Array(Var), body: Node, rest_p_args: Node?)
         
     | 
| 
       47 
47 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                  def initialize(args, body)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  def initialize(args, splat, body, location : Crystal::Location?)
         
     | 
| 
       49 
49 
     | 
    
         
             
                    @info = {
         
     | 
| 
       50 
50 
     | 
    
         
             
                      type: self.class.name.split("::").last,
         
     | 
| 
       51 
51 
     | 
    
         
             
                      body: body,
         
     | 
| 
       52 
     | 
    
         
            -
                       
     | 
| 
      
 52 
     | 
    
         
            +
                      positional_args: args,
         
     | 
| 
      
 53 
     | 
    
         
            +
                      rest_p_args: splat
         
     | 
| 
       53 
54 
     | 
    
         
             
                    }
         
     | 
| 
       54 
55 
     | 
    
         
             
                  end
         
     | 
| 
       55 
56 
     | 
    
         | 
| 
         @@ -62,7 +63,7 @@ module Rb 
     | 
|
| 
       62 
63 
     | 
    
         
             
                class ClassNode < Node
         
     | 
| 
       63 
64 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: Path, body: Node, superclass: Node?, type_vars: Array(String)?, abstract: Bool)
         
     | 
| 
       64 
65 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
                  def initialize(name : Path, body : Node, superclass : Node?, type_vars : Array(String)?, abstr : Bool)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  def initialize(name : Path, body : Node, superclass : Node?, type_vars : Array(String)?, abstr : Bool, location : Crystal::Location?)
         
     | 
| 
       66 
67 
     | 
    
         
             
                    @info = {
         
     | 
| 
       67 
68 
     | 
    
         
             
                      type:       self.class.name.split("::").last,
         
     | 
| 
       68 
69 
     | 
    
         
             
                      name:       name,
         
     | 
| 
         @@ -80,7 +81,7 @@ module Rb 
     | 
|
| 
       80 
81 
     | 
    
         
             
                class ModuleNode < Node
         
     | 
| 
       81 
82 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: Path, body: Node, type_vars: Array(String)?)
         
     | 
| 
       82 
83 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
                  def initialize(name : Path, body : Node, type_vars : Array(String)?)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  def initialize(name : Path, body : Node, type_vars : Array(String)?, location : Crystal::Location?)
         
     | 
| 
       84 
85 
     | 
    
         
             
                    @info = {
         
     | 
| 
       85 
86 
     | 
    
         
             
                      type:      self.class.name.split("::").last,
         
     | 
| 
       86 
87 
     | 
    
         
             
                      name:      name,
         
     | 
| 
         @@ -106,7 +107,8 @@ module Rb 
     | 
|
| 
       106 
107 
     | 
    
         
             
                    body : Node,
         
     | 
| 
       107 
108 
     | 
    
         
             
                    return_type : Node?,
         
     | 
| 
       108 
109 
     | 
    
         
             
                    yields : Int32?,
         
     | 
| 
       109 
     | 
    
         
            -
                    block_arg : Node 
     | 
| 
      
 110 
     | 
    
         
            +
                    block_arg : Node?,
         
     | 
| 
      
 111 
     | 
    
         
            +
                    location : Crystal::Location?
         
     | 
| 
       110 
112 
     | 
    
         
             
                  )
         
     | 
| 
       111 
113 
     | 
    
         
             
                    @info = {
         
     | 
| 
       112 
114 
     | 
    
         
             
                      type:            self.class.name.split("::").last,
         
     | 
| 
         @@ -129,7 +131,8 @@ module Rb 
     | 
|
| 
       129 
131 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: String, external_name: String, value: Node?,
         
     | 
| 
       130 
132 
     | 
    
         
             
                    restriction: Node?, keyword_arg: Bool)
         
     | 
| 
       131 
133 
     | 
    
         | 
| 
       132 
     | 
    
         
            -
                  def initialize(name : String, external_name : String, restriction : Node?, value : Node?, 
     | 
| 
      
 134 
     | 
    
         
            +
                  def initialize(name : String, external_name : String, restriction : Node?, value : Node?,
         
     | 
| 
      
 135 
     | 
    
         
            +
                      keyword_arg, location : Crystal::Location?)
         
     | 
| 
       133 
136 
     | 
    
         
             
                    @info = {
         
     | 
| 
       134 
137 
     | 
    
         
             
                      type:          self.class.name.split("::").last,
         
     | 
| 
       135 
138 
     | 
    
         
             
                      name:          name,
         
     | 
| 
         @@ -146,7 +149,7 @@ module Rb 
     | 
|
| 
       146 
149 
     | 
    
         
             
                class LiteralNode < Node
         
     | 
| 
       147 
150 
     | 
    
         
             
                  @info : NamedTuple(type: String, value: String | Int32 | Bool | Nil, rb_type: String)
         
     | 
| 
       148 
151 
     | 
    
         | 
| 
       149 
     | 
    
         
            -
                  def initialize(value, rb_type : RbLiteral)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  def initialize(value, rb_type : RbLiteral, location : Crystal::Location?)
         
     | 
| 
       150 
153 
     | 
    
         
             
                    val = case rb_type
         
     | 
| 
       151 
154 
     | 
    
         
             
                          when Rb::AST::RbLiteral::TrueClass
         
     | 
| 
       152 
155 
     | 
    
         
             
                            true
         
     | 
| 
         @@ -172,7 +175,7 @@ module Rb 
     | 
|
| 
       172 
175 
     | 
    
         
             
                class ArrayLiteral < Node
         
     | 
| 
       173 
176 
     | 
    
         
             
                  @info : NamedTuple(type: String, elements: Array(Node), frozen: Bool)
         
     | 
| 
       174 
177 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
                  def initialize(elems, frozen = false)
         
     | 
| 
      
 178 
     | 
    
         
            +
                  def initialize(elems, location : Crystal::Location?, frozen = false)
         
     | 
| 
       176 
179 
     | 
    
         
             
                    @info = {
         
     | 
| 
       177 
180 
     | 
    
         
             
                      type:     self.class.name.split("::").last,
         
     | 
| 
       178 
181 
     | 
    
         
             
                      elements: elems,
         
     | 
| 
         @@ -186,7 +189,7 @@ module Rb 
     | 
|
| 
       186 
189 
     | 
    
         
             
                class HashLiteral < Node
         
     | 
| 
       187 
190 
     | 
    
         
             
                  @info : NamedTuple(type: String, elements: Array(Tuple(Node, Node)) | Array(Tuple(String, Node)), frozen: Bool)
         
     | 
| 
       188 
191 
     | 
    
         | 
| 
       189 
     | 
    
         
            -
                  def initialize(elems, frozen = false)
         
     | 
| 
      
 192 
     | 
    
         
            +
                  def initialize(elems, location : Crystal::Location?, frozen = false)
         
     | 
| 
       190 
193 
     | 
    
         
             
                    @info = {
         
     | 
| 
       191 
194 
     | 
    
         
             
                      type:     self.class.name.split("::").last,
         
     | 
| 
       192 
195 
     | 
    
         
             
                      elements: elems,
         
     | 
| 
         @@ -200,7 +203,7 @@ module Rb 
     | 
|
| 
       200 
203 
     | 
    
         
             
                class RangeLiteral < Node
         
     | 
| 
       201 
204 
     | 
    
         
             
                  @info : NamedTuple(type: String, from: Node, to: Node, exclusive: Bool)
         
     | 
| 
       202 
205 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
                  def initialize(from, to, exclusive)
         
     | 
| 
      
 206 
     | 
    
         
            +
                  def initialize(from, to, exclusive, location : Crystal::Location?)
         
     | 
| 
       204 
207 
     | 
    
         
             
                    @info = {
         
     | 
| 
       205 
208 
     | 
    
         
             
                      type:      self.class.name.split("::").last,
         
     | 
| 
       206 
209 
     | 
    
         
             
                      from:      from,
         
     | 
| 
         @@ -215,7 +218,7 @@ module Rb 
     | 
|
| 
       215 
218 
     | 
    
         
             
                class RegexLiteral < Node
         
     | 
| 
       216 
219 
     | 
    
         
             
                  @info : NamedTuple(type: String, value: Node)
         
     | 
| 
       217 
220 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
                  def initialize(value)
         
     | 
| 
      
 221 
     | 
    
         
            +
                  def initialize(value, location : Crystal::Location?)
         
     | 
| 
       219 
222 
     | 
    
         
             
                    @info = {
         
     | 
| 
       220 
223 
     | 
    
         
             
                      type:  self.class.name.split("::").last,
         
     | 
| 
       221 
224 
     | 
    
         
             
                      value: value,
         
     | 
| 
         @@ -236,7 +239,7 @@ module Rb 
     | 
|
| 
       236 
239 
     | 
    
         
             
                end
         
     | 
| 
       237 
240 
     | 
    
         | 
| 
       238 
241 
     | 
    
         
             
                class EmptyNode < Nop
         
     | 
| 
       239 
     | 
    
         
            -
                  def initialize(class_name : String)
         
     | 
| 
      
 242 
     | 
    
         
            +
                  def initialize(class_name : String, location : Crystal::Location?)
         
     | 
| 
       240 
243 
     | 
    
         
             
                    STDERR.puts "Encountered a ruby EmptyNode class name: #{class_name}"
         
     | 
| 
       241 
244 
     | 
    
         
             
                    @info = {
         
     | 
| 
       242 
245 
     | 
    
         
             
                      type: self.class.name.split("::").last,
         
     | 
| 
         @@ -247,7 +250,7 @@ module Rb 
     | 
|
| 
       247 
250 
     | 
    
         
             
                class Var < Node
         
     | 
| 
       248 
251 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: String)
         
     | 
| 
       249 
252 
     | 
    
         | 
| 
       250 
     | 
    
         
            -
                  def initialize(@name : String)
         
     | 
| 
      
 253 
     | 
    
         
            +
                  def initialize(@name : String, location : Crystal::Location?)
         
     | 
| 
       251 
254 
     | 
    
         
             
                    @info = {
         
     | 
| 
       252 
255 
     | 
    
         
             
                      type: self.class.name.split("::").last,
         
     | 
| 
       253 
256 
     | 
    
         
             
                      name: @name,
         
     | 
| 
         @@ -266,7 +269,7 @@ module Rb 
     | 
|
| 
       266 
269 
     | 
    
         
             
                abstract class Conditional < Node
         
     | 
| 
       267 
270 
     | 
    
         
             
                  @info : NamedTuple(type: String, condition: Node, then: Node, else: Node)
         
     | 
| 
       268 
271 
     | 
    
         | 
| 
       269 
     | 
    
         
            -
                  def initialize(@condition : Node, @thn : Node, @els : Node)
         
     | 
| 
      
 272 
     | 
    
         
            +
                  def initialize(@condition : Node, @thn : Node, @els : Node, location : Crystal::Location?)
         
     | 
| 
       270 
273 
     | 
    
         
             
                    @info = {
         
     | 
| 
       271 
274 
     | 
    
         
             
                      type:      self.class.name.split("::").last,
         
     | 
| 
       272 
275 
     | 
    
         
             
                      condition: @condition,
         
     | 
| 
         @@ -287,7 +290,7 @@ module Rb 
     | 
|
| 
       287 
290 
     | 
    
         
             
                class Case < Node
         
     | 
| 
       288 
291 
     | 
    
         
             
                  @info : NamedTuple(type: String, condition: Node?, whens: Array(When), else: Node?, exhaustive: Bool)
         
     | 
| 
       289 
292 
     | 
    
         | 
| 
       290 
     | 
    
         
            -
                  def initialize(cond : Node?, whens : Array(When), els : Node?, exhaustive : Bool)
         
     | 
| 
      
 293 
     | 
    
         
            +
                  def initialize(cond : Node?, whens : Array(When), els : Node?, exhaustive : Bool, location : Crystal::Location?)
         
     | 
| 
       291 
294 
     | 
    
         
             
                    @info = {
         
     | 
| 
       292 
295 
     | 
    
         
             
                      type:       self.class.name.split("::").last,
         
     | 
| 
       293 
296 
     | 
    
         
             
                      condition:  cond,
         
     | 
| 
         @@ -303,7 +306,7 @@ module Rb 
     | 
|
| 
       303 
306 
     | 
    
         
             
                class When < Node
         
     | 
| 
       304 
307 
     | 
    
         
             
                  @info : NamedTuple(type: String, conditions: Array(Node), body: Node, exhaustive: Bool)
         
     | 
| 
       305 
308 
     | 
    
         | 
| 
       306 
     | 
    
         
            -
                  def initialize(conds : Array(Node), body : Node, exhaustive : Bool)
         
     | 
| 
      
 309 
     | 
    
         
            +
                  def initialize(conds : Array(Node), body : Node, exhaustive : Bool, location : Crystal::Location?)
         
     | 
| 
       307 
310 
     | 
    
         
             
                    @info = {
         
     | 
| 
       308 
311 
     | 
    
         
             
                      type:       self.class.name.split("::").last,
         
     | 
| 
       309 
312 
     | 
    
         
             
                      conditions: conds,
         
     | 
| 
         @@ -318,7 +321,7 @@ module Rb 
     | 
|
| 
       318 
321 
     | 
    
         
             
                class Enum < Node
         
     | 
| 
       319 
322 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: Crystal::Path, members: Array(Node))
         
     | 
| 
       320 
323 
     | 
    
         | 
| 
       321 
     | 
    
         
            -
                  def initialize(@name : Crystal::Path, @members : Array(Node))
         
     | 
| 
      
 324 
     | 
    
         
            +
                  def initialize(@name : Crystal::Path, @members : Array(Node), location : Crystal::Location?)
         
     | 
| 
       322 
325 
     | 
    
         
             
                    @info = {
         
     | 
| 
       323 
326 
     | 
    
         
             
                      type:    self.class.name.split("::").last,
         
     | 
| 
       324 
327 
     | 
    
         
             
                      name:    @name,
         
     | 
| 
         @@ -332,8 +335,7 @@ module Rb 
     | 
|
| 
       332 
335 
     | 
    
         
             
                class Call < Node
         
     | 
| 
       333 
336 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: String, args: Array(Node), object: Node?, block: Block?, block_arg: Node?, named_args: Array(Arg)?, has_parentheses: Bool)
         
     | 
| 
       334 
337 
     | 
    
         | 
| 
       335 
     | 
    
         
            -
                  def initialize(object : Node?, name : String, args : Array(Node), named_args, block,
         
     | 
| 
       336 
     | 
    
         
            -
                                 block_arg, has_parentheses)
         
     | 
| 
      
 338 
     | 
    
         
            +
                  def initialize(object : Node?, name : String, args : Array(Node), named_args, block, block_arg, has_parentheses, location : Crystal::Location?)
         
     | 
| 
       337 
339 
     | 
    
         
             
                    @info = {
         
     | 
| 
       338 
340 
     | 
    
         
             
                      type:            self.class.name.split("::").last,
         
     | 
| 
       339 
341 
     | 
    
         
             
                      name:            name,
         
     | 
| 
         @@ -358,7 +360,7 @@ module Rb 
     | 
|
| 
       358 
360 
     | 
    
         
             
                class StringInterpolation < Node
         
     | 
| 
       359 
361 
     | 
    
         
             
                  @info : NamedTuple(type: String, contents: Array(Node))
         
     | 
| 
       360 
362 
     | 
    
         | 
| 
       361 
     | 
    
         
            -
                  def initialize(contents)
         
     | 
| 
      
 363 
     | 
    
         
            +
                  def initialize(contents, location : Crystal::Location?)
         
     | 
| 
       362 
364 
     | 
    
         
             
                    @info = {
         
     | 
| 
       363 
365 
     | 
    
         
             
                      type:     self.class.name.split("::").last,
         
     | 
| 
       364 
366 
     | 
    
         
             
                      contents: contents,
         
     | 
| 
         @@ -371,7 +373,7 @@ module Rb 
     | 
|
| 
       371 
373 
     | 
    
         
             
                class UnaryExpr < Node
         
     | 
| 
       372 
374 
     | 
    
         
             
                  @info : NamedTuple(type: String, op: String, value: Node, with_parens: Bool)
         
     | 
| 
       373 
375 
     | 
    
         | 
| 
       374 
     | 
    
         
            -
                  def initialize(val, op, parens)
         
     | 
| 
      
 376 
     | 
    
         
            +
                  def initialize(val, op, parens, location : Crystal::Location?)
         
     | 
| 
       375 
377 
     | 
    
         
             
                    @info = {
         
     | 
| 
       376 
378 
     | 
    
         
             
                      type:        self.class.name.split("::").last,
         
     | 
| 
       377 
379 
     | 
    
         
             
                      value:       val,
         
     | 
| 
         @@ -386,7 +388,7 @@ module Rb 
     | 
|
| 
       386 
388 
     | 
    
         
             
                class BinaryOp < Node
         
     | 
| 
       387 
389 
     | 
    
         
             
                  @info : NamedTuple(type: String, op: String, left: Node, right: Node)
         
     | 
| 
       388 
390 
     | 
    
         | 
| 
       389 
     | 
    
         
            -
                  def initialize(op, left, right)
         
     | 
| 
      
 391 
     | 
    
         
            +
                  def initialize(op, left, right, location : Crystal::Location?)
         
     | 
| 
       390 
392 
     | 
    
         
             
                    @info = {
         
     | 
| 
       391 
393 
     | 
    
         
             
                      type:  self.class.name.split("::").last,
         
     | 
| 
       392 
394 
     | 
    
         
             
                      left:  left,
         
     | 
| 
         @@ -401,7 +403,7 @@ module Rb 
     | 
|
| 
       401 
403 
     | 
    
         
             
                class Assign < Node
         
     | 
| 
       402 
404 
     | 
    
         
             
                  @info : NamedTuple(type: String, op: String?, target: Node, value: Node)
         
     | 
| 
       403 
405 
     | 
    
         | 
| 
       404 
     | 
    
         
            -
                  def initialize(target, value, op  
     | 
| 
      
 406 
     | 
    
         
            +
                  def initialize(target, value, op, location : Crystal::Location?)
         
     | 
| 
       405 
407 
     | 
    
         
             
                    @info = {
         
     | 
| 
       406 
408 
     | 
    
         
             
                      type:   self.class.name.split("::").last,
         
     | 
| 
       407 
409 
     | 
    
         
             
                      target: target,
         
     | 
| 
         @@ -416,7 +418,7 @@ module Rb 
     | 
|
| 
       416 
418 
     | 
    
         
             
                class MultiAssign < Node
         
     | 
| 
       417 
419 
     | 
    
         
             
                  @info : NamedTuple(type: String, targets: Array(Node), values: Array(Node))
         
     | 
| 
       418 
420 
     | 
    
         | 
| 
       419 
     | 
    
         
            -
                  def initialize(targets, values)
         
     | 
| 
      
 421 
     | 
    
         
            +
                  def initialize(targets, values, location : Crystal::Location?)
         
     | 
| 
       420 
422 
     | 
    
         
             
                    @info = {
         
     | 
| 
       421 
423 
     | 
    
         
             
                      type:    self.class.name.split("::").last,
         
     | 
| 
       422 
424 
     | 
    
         
             
                      targets: targets,
         
     | 
| 
         @@ -430,7 +432,7 @@ module Rb 
     | 
|
| 
       430 
432 
     | 
    
         
             
                class TypeDeclaration < Node
         
     | 
| 
       431 
433 
     | 
    
         
             
                  @info : NamedTuple(type: String, var: Node, declared_type: Node, value: Node?, var_type: String)
         
     | 
| 
       432 
434 
     | 
    
         | 
| 
       433 
     | 
    
         
            -
                  def initialize(@var : Node, @declared_type : Node, @value : Node?)
         
     | 
| 
      
 435 
     | 
    
         
            +
                  def initialize(@var : Node, @declared_type : Node, @value : Node?, location : Crystal::Location?)
         
     | 
| 
       434 
436 
     | 
    
         
             
                    @info = {
         
     | 
| 
       435 
437 
     | 
    
         
             
                      type:          self.class.name.split("::").last,
         
     | 
| 
       436 
438 
     | 
    
         
             
                      var:           @var,
         
     | 
| 
         @@ -446,7 +448,7 @@ module Rb 
     | 
|
| 
       446 
448 
     | 
    
         
             
                class MacroFor < Node
         
     | 
| 
       447 
449 
     | 
    
         
             
                  @info : NamedTuple(type: String, vars: Array(Var), expr: Node, body: Node)
         
     | 
| 
       448 
450 
     | 
    
         | 
| 
       449 
     | 
    
         
            -
                  def initialize(vars, expr, body)
         
     | 
| 
      
 451 
     | 
    
         
            +
                  def initialize(vars, expr, body, location : Crystal::Location?)
         
     | 
| 
       450 
452 
     | 
    
         
             
                    @info = {
         
     | 
| 
       451 
453 
     | 
    
         
             
                      type: self.class.name.split("::").last,
         
     | 
| 
       452 
454 
     | 
    
         
             
                      vars: vars,
         
     | 
| 
         @@ -467,7 +469,7 @@ module Rb 
     | 
|
| 
       467 
469 
     | 
    
         
             
                class MacroExpression < Node
         
     | 
| 
       468 
470 
     | 
    
         
             
                  @info : NamedTuple(type: String, expr: Node, output: Bool)
         
     | 
| 
       469 
471 
     | 
    
         | 
| 
       470 
     | 
    
         
            -
                  def initialize(expr, output)
         
     | 
| 
      
 472 
     | 
    
         
            +
                  def initialize(expr, output, location : Crystal::Location?)
         
     | 
| 
       471 
473 
     | 
    
         
             
                    @info = {
         
     | 
| 
       472 
474 
     | 
    
         
             
                      type:   self.class.name.split("::").last,
         
     | 
| 
       473 
475 
     | 
    
         
             
                      expr:   expr,
         
     | 
| 
         @@ -481,7 +483,7 @@ module Rb 
     | 
|
| 
       481 
483 
     | 
    
         
             
                class ControlExpression < Node
         
     | 
| 
       482 
484 
     | 
    
         
             
                  @info : NamedTuple(type: String, value: Node?)
         
     | 
| 
       483 
485 
     | 
    
         | 
| 
       484 
     | 
    
         
            -
                  def initialize(value)
         
     | 
| 
      
 486 
     | 
    
         
            +
                  def initialize(value, location : Crystal::Location?)
         
     | 
| 
       485 
487 
     | 
    
         
             
                    @info = {
         
     | 
| 
       486 
488 
     | 
    
         
             
                      type:  self.class.name.split("::").last,
         
     | 
| 
       487 
489 
     | 
    
         
             
                      value: value,
         
     | 
| 
         @@ -504,7 +506,7 @@ module Rb 
     | 
|
| 
       504 
506 
     | 
    
         
             
                  @info : NamedTuple(type: String, body: Node, rescues: Array(Rescue)?, else: Node?,
         
     | 
| 
       505 
507 
     | 
    
         
             
                    ensure: Node?)
         
     | 
| 
       506 
508 
     | 
    
         | 
| 
       507 
     | 
    
         
            -
                  def initialize(body, rescues, else_node, ensure_node)
         
     | 
| 
      
 509 
     | 
    
         
            +
                  def initialize(body, rescues, else_node, ensure_node, location : Crystal::Location?)
         
     | 
| 
       508 
510 
     | 
    
         
             
                    @info = {
         
     | 
| 
       509 
511 
     | 
    
         
             
                      type:    self.class.name.split("::").last,
         
     | 
| 
       510 
512 
     | 
    
         
             
                      body:    body,
         
     | 
| 
         @@ -520,7 +522,7 @@ module Rb 
     | 
|
| 
       520 
522 
     | 
    
         
             
                class Rescue < Node
         
     | 
| 
       521 
523 
     | 
    
         
             
                  @info : NamedTuple(type: String, body: Node, types: Array(Node)?, name: String?)
         
     | 
| 
       522 
524 
     | 
    
         | 
| 
       523 
     | 
    
         
            -
                  def initialize(body, types, name)
         
     | 
| 
      
 525 
     | 
    
         
            +
                  def initialize(body, types, name, location : Crystal::Location?)
         
     | 
| 
       524 
526 
     | 
    
         
             
                    @info = {
         
     | 
| 
       525 
527 
     | 
    
         
             
                      type:  self.class.name.split("::").last,
         
     | 
| 
       526 
528 
     | 
    
         
             
                      body:  body,
         
     | 
| 
         @@ -535,7 +537,7 @@ module Rb 
     | 
|
| 
       535 
537 
     | 
    
         
             
                class Union < Node
         
     | 
| 
       536 
538 
     | 
    
         
             
                  @info : NamedTuple(type: String, types: Array(Node))
         
     | 
| 
       537 
539 
     | 
    
         | 
| 
       538 
     | 
    
         
            -
                  def initialize(types)
         
     | 
| 
      
 540 
     | 
    
         
            +
                  def initialize(types, location : Crystal::Location?)
         
     | 
| 
       539 
541 
     | 
    
         
             
                    @info = {
         
     | 
| 
       540 
542 
     | 
    
         
             
                      type:  self.class.name.split("::").last,
         
     | 
| 
       541 
543 
     | 
    
         
             
                      types: types,
         
     | 
| 
         @@ -548,7 +550,7 @@ module Rb 
     | 
|
| 
       548 
550 
     | 
    
         
             
                class Generic < Node
         
     | 
| 
       549 
551 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: Node, args: Array(Node))
         
     | 
| 
       550 
552 
     | 
    
         | 
| 
       551 
     | 
    
         
            -
                  def initialize(name, args)
         
     | 
| 
      
 553 
     | 
    
         
            +
                  def initialize(name, args, location : Crystal::Location?)
         
     | 
| 
       552 
554 
     | 
    
         
             
                    @info = {
         
     | 
| 
       553 
555 
     | 
    
         
             
                      type: self.class.name.split("::").last,
         
     | 
| 
       554 
556 
     | 
    
         
             
                      name: name,
         
     | 
| 
         @@ -562,7 +564,7 @@ module Rb 
     | 
|
| 
       562 
564 
     | 
    
         
             
                class Proc < Node
         
     | 
| 
       563 
565 
     | 
    
         
             
                  @info : NamedTuple(type: String, function: DefNode)
         
     | 
| 
       564 
566 
     | 
    
         | 
| 
       565 
     | 
    
         
            -
                  def initialize(function)
         
     | 
| 
      
 567 
     | 
    
         
            +
                  def initialize(function, location : Crystal::Location?)
         
     | 
| 
       566 
568 
     | 
    
         
             
                    @info = {
         
     | 
| 
       567 
569 
     | 
    
         
             
                      type:     self.class.name.split("::").last,
         
     | 
| 
       568 
570 
     | 
    
         
             
                      function: function,
         
     | 
| 
         @@ -575,7 +577,7 @@ module Rb 
     | 
|
| 
       575 
577 
     | 
    
         
             
                class NodeWithNameNode < Node
         
     | 
| 
       576 
578 
     | 
    
         
             
                  @info : NamedTuple(type: String, name: Node)
         
     | 
| 
       577 
579 
     | 
    
         | 
| 
       578 
     | 
    
         
            -
                  def initialize(name)
         
     | 
| 
      
 580 
     | 
    
         
            +
                  def initialize(name, location : Crystal::Location?)
         
     | 
| 
       579 
581 
     | 
    
         
             
                    @info = {
         
     | 
| 
       580 
582 
     | 
    
         
             
                      type: self.class.name.split("::").last,
         
     | 
| 
       581 
583 
     | 
    
         
             
                      name: name,
         
     | 
| 
         @@ -594,7 +596,7 @@ module Rb 
     | 
|
| 
       594 
596 
     | 
    
         
             
                class VisibilityModifier < Node
         
     | 
| 
       595 
597 
     | 
    
         
             
                  @info : NamedTuple(type: String, visibility: String, exp: Node)
         
     | 
| 
       596 
598 
     | 
    
         | 
| 
       597 
     | 
    
         
            -
                  def initialize(visibility : Crystal::Visibility, exp : Node)
         
     | 
| 
      
 599 
     | 
    
         
            +
                  def initialize(visibility : Crystal::Visibility, exp : Node, location : Crystal::Location?)
         
     | 
| 
       598 
600 
     | 
    
         
             
                    vis = case visibility
         
     | 
| 
       599 
601 
     | 
    
         
             
                          when Crystal::Visibility::Public
         
     | 
| 
       600 
602 
     | 
    
         
             
                            "public"
         
     | 
    
        data/lib/gloss.rb
    CHANGED
    
    | 
         @@ -1,10 +1,12 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
      
 1 
     | 
    
         
            +
              # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              ##### This file was generated by Gloss; any changes made here will be overwritten.
         
     | 
| 
      
 4 
     | 
    
         
            +
              ##### See src/ to make changes
         
     | 
| 
       2 
5 
     | 
    
         | 
| 
       3 
6 
     | 
    
         
             
            require "rbs"
         
     | 
| 
       4 
7 
     | 
    
         
             
            require "json"
         
     | 
| 
       5 
8 
     | 
    
         
             
            require "steep"
         
     | 
| 
       6 
9 
     | 
    
         
             
            require "fast_blank"
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
10 
     | 
    
         
             
            require "gloss/version"
         
     | 
| 
       9 
11 
     | 
    
         
             
            require "gloss/cli"
         
     | 
| 
       10 
12 
     | 
    
         
             
            require "gloss/watcher"
         
     | 
| 
         @@ -15,10 +17,16 @@ require "gloss/config" 
     | 
|
| 
       15 
17 
     | 
    
         
             
            require "gloss/writer"
         
     | 
| 
       16 
18 
     | 
    
         
             
            require "gloss/source"
         
     | 
| 
       17 
19 
     | 
    
         
             
            require "gloss/scope"
         
     | 
| 
       18 
     | 
    
         
            -
            require "gloss/ 
     | 
| 
      
 20 
     | 
    
         
            +
            require "gloss/visitor"
         
     | 
| 
       19 
21 
     | 
    
         
             
            require "gloss/errors"
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            require " 
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            require "gloss/logger"
         
     | 
| 
      
 23 
     | 
    
         
            +
            require "gloss/prog_loader"
         
     | 
| 
      
 24 
     | 
    
         
            +
            require "gloss/utils"
         
     | 
| 
      
 25 
     | 
    
         
            +
            is_ci = ENV.fetch("CI") { ||
         
     | 
| 
      
 26 
     | 
    
         
            +
            false}
         
     | 
| 
      
 27 
     | 
    
         
            +
            unless is_ci
         
     | 
| 
      
 28 
     | 
    
         
            +
              require "gls"
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
      
 30 
     | 
    
         
            +
            EMPTY_ARRAY = Array.new
         
     | 
| 
      
 31 
     | 
    
         
            +
            .freeze
         
     | 
| 
       24 
32 
     | 
    
         
             
            EMPTY_HASH = {}.freeze
         
     | 
    
        data/lib/gloss/cli.rb
    CHANGED
    
    | 
         @@ -3,7 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
              ##### This file was generated by Gloss; any changes made here will be overwritten.
         
     | 
| 
       4 
4 
     | 
    
         
             
              ##### See src/ to make changes
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 6 
     | 
    
         
            +
            require "optparse"
         
     | 
| 
       7 
7 
     | 
    
         
             
            module Gloss
         
     | 
| 
       8 
8 
     | 
    
         
             
              class CLI
         
     | 
| 
       9 
9 
     | 
    
         
             
                def initialize(argv)
         
     | 
| 
         @@ -11,43 +11,86 @@ module Gloss 
     | 
|
| 
       11 
11 
     | 
    
         
             
                end
         
     | 
| 
       12 
12 
     | 
    
         
             
                def run()
         
     | 
| 
       13 
13 
     | 
    
         
             
                  command = @argv.first
         
     | 
| 
       14 
     | 
    
         
            -
                  files = @argv.[]((1 
     | 
| 
      
 14 
     | 
    
         
            +
                  files = @argv.[](((1)..(-1)))
         
     | 
| 
      
 15 
     | 
    
         
            +
                  err_msg = catch(:"error") { ||
         
     | 
| 
       15 
16 
     | 
    
         
             
            case command
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
                      when "init"
         
     | 
| 
      
 18 
     | 
    
         
            +
                        force = false
         
     | 
| 
      
 19 
     | 
    
         
            +
                        OptionParser.new() { |opt|
         
     | 
| 
      
 20 
     | 
    
         
            +
                          opt.on("--force", "-f") { ||
         
     | 
| 
      
 21 
     | 
    
         
            +
                            force = true
         
     | 
| 
      
 22 
     | 
    
         
            +
                          }
         
     | 
| 
      
 23 
     | 
    
         
            +
                        }
         
     | 
| 
      
 24 
     | 
    
         
            +
            .parse(@argv)
         
     | 
| 
      
 25 
     | 
    
         
            +
                        Initializer.new(force)
         
     | 
| 
      
 26 
     | 
    
         
            +
            .run
         
     | 
| 
      
 27 
     | 
    
         
            +
                      when "version", "--version", "-v"
         
     | 
| 
      
 28 
     | 
    
         
            +
                        puts(Gloss::VERSION)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      when "watch", "build"
         
     | 
| 
      
 30 
     | 
    
         
            +
                        type_checker = ProgLoader.new
         
     | 
| 
      
 31 
     | 
    
         
            +
            .run
         
     | 
| 
      
 32 
     | 
    
         
            +
                        (if command.==("watch")
         
     | 
| 
      
 33 
     | 
    
         
            +
                          files = files.map() { |f|
         
     | 
| 
      
 34 
     | 
    
         
            +
                            path = (if Pathname.new(f)
         
     | 
| 
      
 35 
     | 
    
         
            +
            .absolute?
         
     | 
| 
      
 36 
     | 
    
         
            +
                              f
         
     | 
| 
      
 37 
     | 
    
         
            +
                            else
         
     | 
| 
      
 38 
     | 
    
         
            +
                              File.join(Dir.pwd, f)
         
     | 
| 
      
 39 
     | 
    
         
            +
                            end)
         
     | 
| 
      
 40 
     | 
    
         
            +
                            (if Pathname.new(path)
         
     | 
| 
      
 41 
     | 
    
         
            +
            .exist?
         
     | 
| 
      
 42 
     | 
    
         
            +
                              path
         
     | 
| 
      
 43 
     | 
    
         
            +
                            else
         
     | 
| 
      
 44 
     | 
    
         
            +
                              throw(:"error", "Pathname #{f} does not exist")
         
     | 
| 
      
 45 
     | 
    
         
            +
                            end)
         
     | 
| 
      
 46 
     | 
    
         
            +
                          }
         
     | 
| 
      
 47 
     | 
    
         
            +
                          Watcher.new(files)
         
     | 
| 
       18 
48 
     | 
    
         
             
            .watch
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                      else
         
     | 
| 
       23 
     | 
    
         
            -
                        files
         
     | 
| 
       24 
     | 
    
         
            -
                      end)
         
     | 
| 
       25 
     | 
    
         
            -
            .each() { |fp|
         
     | 
| 
       26 
     | 
    
         
            -
                        puts("=====> Building #{fp}")
         
     | 
| 
       27 
     | 
    
         
            -
                        content = File.read(fp)
         
     | 
| 
       28 
     | 
    
         
            -
                        tree_hash = Parser.new(content)
         
     | 
| 
      
 49 
     | 
    
         
            +
                        else
         
     | 
| 
      
 50 
     | 
    
         
            +
                          (if command.==("build")
         
     | 
| 
      
 51 
     | 
    
         
            +
                            entry_tree = Parser.new(File.read(Config.entrypoint))
         
     | 
| 
       29 
52 
     | 
    
         
             
            .run
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                        rb_output = Builder.new(tree_hash, type_checker)
         
     | 
| 
      
 53 
     | 
    
         
            +
                            Visitor.new(entry_tree, type_checker)
         
     | 
| 
       32 
54 
     | 
    
         
             
            .run
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
      
 55 
     | 
    
         
            +
                            (if files.empty?
         
     | 
| 
      
 56 
     | 
    
         
            +
                              files = Dir.glob("#{Config.src_dir}/**/*.gl")
         
     | 
| 
      
 57 
     | 
    
         
            +
                            end)
         
     | 
| 
      
 58 
     | 
    
         
            +
                            files.each() { |fp|
         
     | 
| 
      
 59 
     | 
    
         
            +
                              fp = File.absolute_path(fp)
         
     | 
| 
      
 60 
     | 
    
         
            +
                              preloaded_output = OUTPUT_BY_PATH.fetch(fp) { ||
         
     | 
| 
      
 61 
     | 
    
         
            +
            nil                  }
         
     | 
| 
      
 62 
     | 
    
         
            +
                              (if preloaded_output
         
     | 
| 
      
 63 
     | 
    
         
            +
                                rb_output = preloaded_output
         
     | 
| 
      
 64 
     | 
    
         
            +
                              else
         
     | 
| 
      
 65 
     | 
    
         
            +
                                Gloss.logger
         
     | 
| 
      
 66 
     | 
    
         
            +
            .info("Building #{fp}")
         
     | 
| 
      
 67 
     | 
    
         
            +
                                content = File.read(fp)
         
     | 
| 
      
 68 
     | 
    
         
            +
                                tree_hash = Parser.new(content)
         
     | 
| 
       36 
69 
     | 
    
         
             
            .run
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                    when "init"
         
     | 
| 
       39 
     | 
    
         
            -
                      force = false
         
     | 
| 
       40 
     | 
    
         
            -
                      OptionParser.new() { |opt|
         
     | 
| 
       41 
     | 
    
         
            -
                        opt.on("--force", "-f") { ||
         
     | 
| 
       42 
     | 
    
         
            -
                          force = true
         
     | 
| 
       43 
     | 
    
         
            -
                        }
         
     | 
| 
       44 
     | 
    
         
            -
                      }
         
     | 
| 
       45 
     | 
    
         
            -
            .parse(@argv)
         
     | 
| 
       46 
     | 
    
         
            -
                      Initializer.new(force)
         
     | 
| 
      
 70 
     | 
    
         
            +
                                rb_output = Visitor.new(tree_hash, type_checker)
         
     | 
| 
       47 
71 
     | 
    
         
             
            .run
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
      
 72 
     | 
    
         
            +
                              end)
         
     | 
| 
      
 73 
     | 
    
         
            +
                              Gloss.logger
         
     | 
| 
      
 74 
     | 
    
         
            +
            .info("Type checking #{fp}")
         
     | 
| 
      
 75 
     | 
    
         
            +
                              type_checker.run(fp, rb_output)
         
     | 
| 
      
 76 
     | 
    
         
            +
                            }
         
     | 
| 
      
 77 
     | 
    
         
            +
                            files.each() { |fp|
         
     | 
| 
      
 78 
     | 
    
         
            +
                              fp = File.absolute_path(fp)
         
     | 
| 
      
 79 
     | 
    
         
            +
                              rb_output = OUTPUT_BY_PATH.fetch(fp)
         
     | 
| 
      
 80 
     | 
    
         
            +
                              Gloss.logger
         
     | 
| 
      
 81 
     | 
    
         
            +
            .info("Writing #{fp}")
         
     | 
| 
      
 82 
     | 
    
         
            +
                              Writer.new(rb_output, fp)
         
     | 
| 
      
 83 
     | 
    
         
            +
            .run
         
     | 
| 
      
 84 
     | 
    
         
            +
                            }
         
     | 
| 
      
 85 
     | 
    
         
            +
                          end)
         
     | 
| 
      
 86 
     | 
    
         
            +
                        end)
         
     | 
| 
      
 87 
     | 
    
         
            +
                      else
         
     | 
| 
      
 88 
     | 
    
         
            +
                        throw(:"error", "Gloss doesn't know how to #{command}")
         
     | 
| 
      
 89 
     | 
    
         
            +
                    end
         
     | 
| 
      
 90 
     | 
    
         
            +
            nil      }
         
     | 
| 
      
 91 
     | 
    
         
            +
                  (if err_msg
         
     | 
| 
      
 92 
     | 
    
         
            +
                    abort(err_msg)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end)
         
     | 
| 
       51 
94 
     | 
    
         
             
                end
         
     | 
| 
       52 
95 
     | 
    
         
             
              end
         
     | 
| 
       53 
96 
     | 
    
         
             
            end
         
     |