gloss 0.0.5 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +3 -0
  3. data/.github/workflows/{crystal.yml → crystal_specs.yml} +1 -1
  4. data/.github/workflows/{ruby.yml → ruby_specs.yml} +2 -2
  5. data/.github/workflows/self_build.yml +45 -0
  6. data/.gloss.yml +1 -0
  7. data/Gemfile.lock +3 -3
  8. data/README.md +35 -5
  9. data/Rakefile +1 -1
  10. data/exe/gloss +13 -2
  11. data/ext/gloss/Makefile +8 -19
  12. data/ext/gloss/lib/cr_ruby.cr +5 -4
  13. data/ext/gloss/src/cr_ast.cr +61 -77
  14. data/ext/gloss/src/gloss.cr +7 -3
  15. data/ext/gloss/src/rb_ast.cr +37 -36
  16. data/lib/gloss.rb +11 -7
  17. data/lib/gloss/cli.rb +61 -23
  18. data/lib/gloss/config.rb +3 -1
  19. data/lib/gloss/errors.rb +1 -1
  20. data/lib/gloss/initializer.rb +2 -1
  21. data/lib/gloss/logger.rb +29 -0
  22. data/lib/gloss/parser.rb +17 -2
  23. data/lib/gloss/prog_loader.rb +141 -0
  24. data/lib/gloss/scope.rb +1 -1
  25. data/lib/gloss/source.rb +1 -1
  26. data/lib/gloss/type_checker.rb +80 -32
  27. data/lib/gloss/utils.rb +44 -0
  28. data/lib/gloss/version.rb +4 -4
  29. data/lib/gloss/{builder.rb → visitor.rb} +93 -54
  30. data/lib/gloss/watcher.rb +41 -19
  31. data/lib/gloss/writer.rb +21 -10
  32. data/sig/core.rbs +2 -0
  33. data/sig/fast_blank.rbs +4 -0
  34. data/sig/{gloss.rbs → gls.rbs} +0 -0
  35. data/sig/optparse.rbs +6 -0
  36. data/sig/rubygems.rbs +9 -0
  37. data/sig/yaml.rbs +3 -0
  38. data/src/exe/gloss +19 -0
  39. data/src/lib/gloss.gl +25 -0
  40. data/src/lib/gloss/cli.gl +40 -14
  41. data/src/lib/gloss/config.gl +2 -2
  42. data/src/lib/gloss/initializer.gl +1 -1
  43. data/src/lib/gloss/logger.gl +21 -0
  44. data/src/lib/gloss/parser.gl +17 -5
  45. data/src/lib/gloss/prog_loader.gl +133 -0
  46. data/src/lib/gloss/scope.gl +0 -2
  47. data/src/lib/gloss/type_checker.gl +85 -39
  48. data/src/lib/gloss/utils.gl +38 -0
  49. data/src/lib/gloss/version.gl +1 -1
  50. data/src/lib/gloss/{builder.gl → visitor.gl} +80 -49
  51. data/src/lib/gloss/watcher.gl +42 -24
  52. data/src/lib/gloss/writer.gl +15 -13
  53. metadata +22 -7
@@ -4,14 +4,13 @@ require "./cr_ast"
4
4
  require "./rb_ast"
5
5
  require "./parser"
6
6
 
7
- def parse_string(self : CrRuby::VALUE, str : CrRuby::VALUE)
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
 
@@ -22,5 +21,10 @@ fun init = Init_gls
22
21
  GC.init
23
22
  LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null)
24
23
  gloss = CrRuby.rb_define_module("Gloss");
25
- CrRuby.rb_define_singleton_method(gloss, "parse_buffer", ->parse_string(CrRuby::VALUE, CrRuby::VALUE), 1);
24
+ CrRuby.rb_define_singleton_method(
25
+ gloss,
26
+ "parse_buffer",
27
+ ->parse_string(CrRuby::VALUE, CrRuby::VALUE),
28
+ 1
29
+ );
26
30
  end
@@ -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,
@@ -45,7 +45,7 @@ module Rb
45
45
  class Block < Node
46
46
  @info : NamedTuple(type: String, positional_args: Array(Var), body: Node, rest_p_args: Node?)
47
47
 
48
- def initialize(args, splat, 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,
@@ -63,7 +63,7 @@ module Rb
63
63
  class ClassNode < Node
64
64
  @info : NamedTuple(type: String, name: Path, body: Node, superclass: Node?, type_vars: Array(String)?, abstract: Bool)
65
65
 
66
- 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?)
67
67
  @info = {
68
68
  type: self.class.name.split("::").last,
69
69
  name: name,
@@ -81,7 +81,7 @@ module Rb
81
81
  class ModuleNode < Node
82
82
  @info : NamedTuple(type: String, name: Path, body: Node, type_vars: Array(String)?)
83
83
 
84
- def initialize(name : Path, body : Node, type_vars : Array(String)?)
84
+ def initialize(name : Path, body : Node, type_vars : Array(String)?, location : Crystal::Location?)
85
85
  @info = {
86
86
  type: self.class.name.split("::").last,
87
87
  name: name,
@@ -107,7 +107,8 @@ module Rb
107
107
  body : Node,
108
108
  return_type : Node?,
109
109
  yields : Int32?,
110
- block_arg : Node?
110
+ block_arg : Node?,
111
+ location : Crystal::Location?
111
112
  )
112
113
  @info = {
113
114
  type: self.class.name.split("::").last,
@@ -130,7 +131,8 @@ module Rb
130
131
  @info : NamedTuple(type: String, name: String, external_name: String, value: Node?,
131
132
  restriction: Node?, keyword_arg: Bool)
132
133
 
133
- def initialize(name : String, external_name : String, restriction : Node?, value : Node?, keyword_arg)
134
+ def initialize(name : String, external_name : String, restriction : Node?, value : Node?,
135
+ keyword_arg, location : Crystal::Location?)
134
136
  @info = {
135
137
  type: self.class.name.split("::").last,
136
138
  name: name,
@@ -147,7 +149,7 @@ module Rb
147
149
  class LiteralNode < Node
148
150
  @info : NamedTuple(type: String, value: String | Int32 | Bool | Nil, rb_type: String)
149
151
 
150
- def initialize(value, rb_type : RbLiteral)
152
+ def initialize(value, rb_type : RbLiteral, location : Crystal::Location?)
151
153
  val = case rb_type
152
154
  when Rb::AST::RbLiteral::TrueClass
153
155
  true
@@ -173,7 +175,7 @@ module Rb
173
175
  class ArrayLiteral < Node
174
176
  @info : NamedTuple(type: String, elements: Array(Node), frozen: Bool)
175
177
 
176
- def initialize(elems, frozen = false)
178
+ def initialize(elems, location : Crystal::Location?, frozen = false)
177
179
  @info = {
178
180
  type: self.class.name.split("::").last,
179
181
  elements: elems,
@@ -187,7 +189,7 @@ module Rb
187
189
  class HashLiteral < Node
188
190
  @info : NamedTuple(type: String, elements: Array(Tuple(Node, Node)) | Array(Tuple(String, Node)), frozen: Bool)
189
191
 
190
- def initialize(elems, frozen = false)
192
+ def initialize(elems, location : Crystal::Location?, frozen = false)
191
193
  @info = {
192
194
  type: self.class.name.split("::").last,
193
195
  elements: elems,
@@ -201,7 +203,7 @@ module Rb
201
203
  class RangeLiteral < Node
202
204
  @info : NamedTuple(type: String, from: Node, to: Node, exclusive: Bool)
203
205
 
204
- def initialize(from, to, exclusive)
206
+ def initialize(from, to, exclusive, location : Crystal::Location?)
205
207
  @info = {
206
208
  type: self.class.name.split("::").last,
207
209
  from: from,
@@ -216,7 +218,7 @@ module Rb
216
218
  class RegexLiteral < Node
217
219
  @info : NamedTuple(type: String, value: Node)
218
220
 
219
- def initialize(value)
221
+ def initialize(value, location : Crystal::Location?)
220
222
  @info = {
221
223
  type: self.class.name.split("::").last,
222
224
  value: value,
@@ -237,7 +239,7 @@ module Rb
237
239
  end
238
240
 
239
241
  class EmptyNode < Nop
240
- def initialize(class_name : String)
242
+ def initialize(class_name : String, location : Crystal::Location?)
241
243
  STDERR.puts "Encountered a ruby EmptyNode class name: #{class_name}"
242
244
  @info = {
243
245
  type: self.class.name.split("::").last,
@@ -248,7 +250,7 @@ module Rb
248
250
  class Var < Node
249
251
  @info : NamedTuple(type: String, name: String)
250
252
 
251
- def initialize(@name : String)
253
+ def initialize(@name : String, location : Crystal::Location?)
252
254
  @info = {
253
255
  type: self.class.name.split("::").last,
254
256
  name: @name,
@@ -267,7 +269,7 @@ module Rb
267
269
  abstract class Conditional < Node
268
270
  @info : NamedTuple(type: String, condition: Node, then: Node, else: Node)
269
271
 
270
- def initialize(@condition : Node, @thn : Node, @els : Node)
272
+ def initialize(@condition : Node, @thn : Node, @els : Node, location : Crystal::Location?)
271
273
  @info = {
272
274
  type: self.class.name.split("::").last,
273
275
  condition: @condition,
@@ -288,7 +290,7 @@ module Rb
288
290
  class Case < Node
289
291
  @info : NamedTuple(type: String, condition: Node?, whens: Array(When), else: Node?, exhaustive: Bool)
290
292
 
291
- 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?)
292
294
  @info = {
293
295
  type: self.class.name.split("::").last,
294
296
  condition: cond,
@@ -304,7 +306,7 @@ module Rb
304
306
  class When < Node
305
307
  @info : NamedTuple(type: String, conditions: Array(Node), body: Node, exhaustive: Bool)
306
308
 
307
- def initialize(conds : Array(Node), body : Node, exhaustive : Bool)
309
+ def initialize(conds : Array(Node), body : Node, exhaustive : Bool, location : Crystal::Location?)
308
310
  @info = {
309
311
  type: self.class.name.split("::").last,
310
312
  conditions: conds,
@@ -319,7 +321,7 @@ module Rb
319
321
  class Enum < Node
320
322
  @info : NamedTuple(type: String, name: Crystal::Path, members: Array(Node))
321
323
 
322
- def initialize(@name : Crystal::Path, @members : Array(Node))
324
+ def initialize(@name : Crystal::Path, @members : Array(Node), location : Crystal::Location?)
323
325
  @info = {
324
326
  type: self.class.name.split("::").last,
325
327
  name: @name,
@@ -333,8 +335,7 @@ module Rb
333
335
  class Call < Node
334
336
  @info : NamedTuple(type: String, name: String, args: Array(Node), object: Node?, block: Block?, block_arg: Node?, named_args: Array(Arg)?, has_parentheses: Bool)
335
337
 
336
- def initialize(object : Node?, name : String, args : Array(Node), named_args, block,
337
- block_arg, has_parentheses)
338
+ def initialize(object : Node?, name : String, args : Array(Node), named_args, block, block_arg, has_parentheses, location : Crystal::Location?)
338
339
  @info = {
339
340
  type: self.class.name.split("::").last,
340
341
  name: name,
@@ -359,7 +360,7 @@ module Rb
359
360
  class StringInterpolation < Node
360
361
  @info : NamedTuple(type: String, contents: Array(Node))
361
362
 
362
- def initialize(contents)
363
+ def initialize(contents, location : Crystal::Location?)
363
364
  @info = {
364
365
  type: self.class.name.split("::").last,
365
366
  contents: contents,
@@ -372,7 +373,7 @@ module Rb
372
373
  class UnaryExpr < Node
373
374
  @info : NamedTuple(type: String, op: String, value: Node, with_parens: Bool)
374
375
 
375
- def initialize(val, op, parens)
376
+ def initialize(val, op, parens, location : Crystal::Location?)
376
377
  @info = {
377
378
  type: self.class.name.split("::").last,
378
379
  value: val,
@@ -387,7 +388,7 @@ module Rb
387
388
  class BinaryOp < Node
388
389
  @info : NamedTuple(type: String, op: String, left: Node, right: Node)
389
390
 
390
- def initialize(op, left, right)
391
+ def initialize(op, left, right, location : Crystal::Location?)
391
392
  @info = {
392
393
  type: self.class.name.split("::").last,
393
394
  left: left,
@@ -402,7 +403,7 @@ module Rb
402
403
  class Assign < Node
403
404
  @info : NamedTuple(type: String, op: String?, target: Node, value: Node)
404
405
 
405
- def initialize(target, value, op = nil)
406
+ def initialize(target, value, op, location : Crystal::Location?)
406
407
  @info = {
407
408
  type: self.class.name.split("::").last,
408
409
  target: target,
@@ -417,7 +418,7 @@ module Rb
417
418
  class MultiAssign < Node
418
419
  @info : NamedTuple(type: String, targets: Array(Node), values: Array(Node))
419
420
 
420
- def initialize(targets, values)
421
+ def initialize(targets, values, location : Crystal::Location?)
421
422
  @info = {
422
423
  type: self.class.name.split("::").last,
423
424
  targets: targets,
@@ -431,7 +432,7 @@ module Rb
431
432
  class TypeDeclaration < Node
432
433
  @info : NamedTuple(type: String, var: Node, declared_type: Node, value: Node?, var_type: String)
433
434
 
434
- def initialize(@var : Node, @declared_type : Node, @value : Node?)
435
+ def initialize(@var : Node, @declared_type : Node, @value : Node?, location : Crystal::Location?)
435
436
  @info = {
436
437
  type: self.class.name.split("::").last,
437
438
  var: @var,
@@ -447,7 +448,7 @@ module Rb
447
448
  class MacroFor < Node
448
449
  @info : NamedTuple(type: String, vars: Array(Var), expr: Node, body: Node)
449
450
 
450
- def initialize(vars, expr, body)
451
+ def initialize(vars, expr, body, location : Crystal::Location?)
451
452
  @info = {
452
453
  type: self.class.name.split("::").last,
453
454
  vars: vars,
@@ -468,7 +469,7 @@ module Rb
468
469
  class MacroExpression < Node
469
470
  @info : NamedTuple(type: String, expr: Node, output: Bool)
470
471
 
471
- def initialize(expr, output)
472
+ def initialize(expr, output, location : Crystal::Location?)
472
473
  @info = {
473
474
  type: self.class.name.split("::").last,
474
475
  expr: expr,
@@ -482,7 +483,7 @@ module Rb
482
483
  class ControlExpression < Node
483
484
  @info : NamedTuple(type: String, value: Node?)
484
485
 
485
- def initialize(value)
486
+ def initialize(value, location : Crystal::Location?)
486
487
  @info = {
487
488
  type: self.class.name.split("::").last,
488
489
  value: value,
@@ -505,7 +506,7 @@ module Rb
505
506
  @info : NamedTuple(type: String, body: Node, rescues: Array(Rescue)?, else: Node?,
506
507
  ensure: Node?)
507
508
 
508
- def initialize(body, rescues, else_node, ensure_node)
509
+ def initialize(body, rescues, else_node, ensure_node, location : Crystal::Location?)
509
510
  @info = {
510
511
  type: self.class.name.split("::").last,
511
512
  body: body,
@@ -521,7 +522,7 @@ module Rb
521
522
  class Rescue < Node
522
523
  @info : NamedTuple(type: String, body: Node, types: Array(Node)?, name: String?)
523
524
 
524
- def initialize(body, types, name)
525
+ def initialize(body, types, name, location : Crystal::Location?)
525
526
  @info = {
526
527
  type: self.class.name.split("::").last,
527
528
  body: body,
@@ -536,7 +537,7 @@ module Rb
536
537
  class Union < Node
537
538
  @info : NamedTuple(type: String, types: Array(Node))
538
539
 
539
- def initialize(types)
540
+ def initialize(types, location : Crystal::Location?)
540
541
  @info = {
541
542
  type: self.class.name.split("::").last,
542
543
  types: types,
@@ -549,7 +550,7 @@ module Rb
549
550
  class Generic < Node
550
551
  @info : NamedTuple(type: String, name: Node, args: Array(Node))
551
552
 
552
- def initialize(name, args)
553
+ def initialize(name, args, location : Crystal::Location?)
553
554
  @info = {
554
555
  type: self.class.name.split("::").last,
555
556
  name: name,
@@ -563,7 +564,7 @@ module Rb
563
564
  class Proc < Node
564
565
  @info : NamedTuple(type: String, function: DefNode)
565
566
 
566
- def initialize(function)
567
+ def initialize(function, location : Crystal::Location?)
567
568
  @info = {
568
569
  type: self.class.name.split("::").last,
569
570
  function: function,
@@ -576,7 +577,7 @@ module Rb
576
577
  class NodeWithNameNode < Node
577
578
  @info : NamedTuple(type: String, name: Node)
578
579
 
579
- def initialize(name)
580
+ def initialize(name, location : Crystal::Location?)
580
581
  @info = {
581
582
  type: self.class.name.split("::").last,
582
583
  name: name,
@@ -595,7 +596,7 @@ module Rb
595
596
  class VisibilityModifier < Node
596
597
  @info : NamedTuple(type: String, visibility: String, exp: Node)
597
598
 
598
- def initialize(visibility : Crystal::Visibility, exp : Node)
599
+ def initialize(visibility : Crystal::Visibility, exp : Node, location : Crystal::Location?)
599
600
  vis = case visibility
600
601
  when Crystal::Visibility::Public
601
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,12 @@ require "gloss/config"
15
17
  require "gloss/writer"
16
18
  require "gloss/source"
17
19
  require "gloss/scope"
18
- require "gloss/builder"
20
+ require "gloss/visitor"
19
21
  require "gloss/errors"
20
-
21
- require "gls" unless ENV["CI"] # a bit of a hack for now
22
-
23
- EMPTY_ARRAY = [].freeze
22
+ require "gloss/logger"
23
+ require "gloss/prog_loader"
24
+ require "gloss/utils"
25
+ require "gls"
26
+ EMPTY_ARRAY = Array.new
27
+ .freeze
24
28
  EMPTY_HASH = {}.freeze
data/lib/gloss/cli.rb CHANGED
@@ -11,31 +11,9 @@ module Gloss
11
11
  end
12
12
  def run()
13
13
  command = @argv.first
14
- files = @argv.[]((1..-1))
14
+ files = @argv.[](((1)..(-1)))
15
15
  err_msg = catch(:"error") { ||
16
16
  case command
17
- when "watch"
18
- Watcher.new(files)
19
- .watch
20
- when "build"
21
- (if files.empty?
22
- Dir.glob("#{Config.src_dir}/**/*.gl")
23
- else
24
- files
25
- end)
26
- .each() { |fp|
27
- puts("=====> Building #{fp}")
28
- content = File.read(fp)
29
- tree_hash = Parser.new(content)
30
- .run
31
- type_checker = TypeChecker.new
32
- rb_output = Builder.new(tree_hash, type_checker)
33
- .run
34
- type_checker.run(rb_output)
35
- puts("=====> Writing #{fp}")
36
- Writer.new(rb_output, fp)
37
- .run
38
- }
39
17
  when "init"
40
18
  force = false
41
19
  OptionParser.new() { |opt|
@@ -46,6 +24,66 @@ case command
46
24
  .parse(@argv)
47
25
  Initializer.new(force)
48
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)
48
+ .watch
49
+ else
50
+ (if command.==("build")
51
+ entry_tree = Parser.new(File.read(Config.entrypoint))
52
+ .run
53
+ Visitor.new(entry_tree, type_checker)
54
+ .run
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)
69
+ .run
70
+ rb_output = Visitor.new(tree_hash, type_checker)
71
+ .run
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)
49
87
  else
50
88
  throw(:"error", "Gloss doesn't know how to #{command}")
51
89
  end