ibex-runtime 0.2.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.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +337 -0
  4. data/lib/ibex/runtime/ast_data.rb +23 -0
  5. data/lib/ibex/runtime/cst/annotation.rb +16 -0
  6. data/lib/ibex/runtime/cst/cursor.rb +68 -0
  7. data/lib/ibex/runtime/cst/diff.rb +80 -0
  8. data/lib/ibex/runtime/cst/editing.rb +56 -0
  9. data/lib/ibex/runtime/cst/editor.rb +94 -0
  10. data/lib/ibex/runtime/cst/green/builder.rb +211 -0
  11. data/lib/ibex/runtime/cst/green/cache.rb +150 -0
  12. data/lib/ibex/runtime/cst/green/node.rb +78 -0
  13. data/lib/ibex/runtime/cst/green/token.rb +91 -0
  14. data/lib/ibex/runtime/cst/green/trivia.rb +36 -0
  15. data/lib/ibex/runtime/cst/incremental/blender.rb +233 -0
  16. data/lib/ibex/runtime/cst/incremental/lexed_syntax.rb +28 -0
  17. data/lib/ibex/runtime/cst/incremental/parse_memo.rb +95 -0
  18. data/lib/ibex/runtime/cst/incremental/relexer.rb +134 -0
  19. data/lib/ibex/runtime/cst/incremental/session.rb +229 -0
  20. data/lib/ibex/runtime/cst/incremental/token_memo.rb +66 -0
  21. data/lib/ibex/runtime/cst/kind.rb +133 -0
  22. data/lib/ibex/runtime/cst/parse_result.rb +41 -0
  23. data/lib/ibex/runtime/cst/rewriter.rb +75 -0
  24. data/lib/ibex/runtime/cst/serialize.rb +127 -0
  25. data/lib/ibex/runtime/cst/serialized_tree.rb +44 -0
  26. data/lib/ibex/runtime/cst/source_text.rb +112 -0
  27. data/lib/ibex/runtime/cst/syntax_node.rb +432 -0
  28. data/lib/ibex/runtime/cst/syntax_token.rb +160 -0
  29. data/lib/ibex/runtime/cst/text_edit.rb +77 -0
  30. data/lib/ibex/runtime/cst/typed_node.rb +87 -0
  31. data/lib/ibex/runtime/cst/validator.rb +428 -0
  32. data/lib/ibex/runtime/cst.rb +38 -0
  33. data/lib/ibex/runtime/event.rb +44 -0
  34. data/lib/ibex/runtime/event_jsonl_tracer.rb +37 -0
  35. data/lib/ibex/runtime/event_sanitizer.rb +273 -0
  36. data/lib/ibex/runtime/generated_lexer.rb +514 -0
  37. data/lib/ibex/runtime/jsonl_tracer.rb +75 -0
  38. data/lib/ibex/runtime/lexer_input.rb +107 -0
  39. data/lib/ibex/runtime/location_span.rb +114 -0
  40. data/lib/ibex/runtime/observation.rb +82 -0
  41. data/lib/ibex/runtime/parser.rb +3027 -0
  42. data/lib/ibex/runtime/parser_sync_recovery.rb +108 -0
  43. data/lib/ibex/runtime/repair.rb +126 -0
  44. data/lib/ibex/runtime/repair_priority_queue.rb +60 -0
  45. data/lib/ibex/runtime/repair_search.rb +318 -0
  46. data/lib/ibex/runtime/resource_limits.rb +64 -0
  47. data/lib/ibex/runtime/table_format.rb +11 -0
  48. data/lib/ibex/runtime/version.rb +7 -0
  49. data/lib/ibex/runtime.rb +27 -0
  50. data/lib/ibex/tables/compact.rb +186 -0
  51. data/lib/ibex/tables/compact_actions.rb +135 -0
  52. data/lib/ibex/tables/compact_productions.rb +167 -0
  53. data/sig/ibex/runtime/ast_data.rbs +12 -0
  54. data/sig/ibex/runtime/cst/annotation.rbs +13 -0
  55. data/sig/ibex/runtime/cst/cursor.rbs +34 -0
  56. data/sig/ibex/runtime/cst/diff.rbs +29 -0
  57. data/sig/ibex/runtime/cst/editing.rbs +23 -0
  58. data/sig/ibex/runtime/cst/editor.rbs +43 -0
  59. data/sig/ibex/runtime/cst/green/builder.rbs +84 -0
  60. data/sig/ibex/runtime/cst/green/cache.rbs +60 -0
  61. data/sig/ibex/runtime/cst/green/node.rbs +49 -0
  62. data/sig/ibex/runtime/cst/green/token.rbs +59 -0
  63. data/sig/ibex/runtime/cst/green/trivia.rbs +29 -0
  64. data/sig/ibex/runtime/cst/incremental/blender.rbs +114 -0
  65. data/sig/ibex/runtime/cst/incremental/lexed_syntax.rbs +20 -0
  66. data/sig/ibex/runtime/cst/incremental/parse_memo.rbs +59 -0
  67. data/sig/ibex/runtime/cst/incremental/relexer.rbs +54 -0
  68. data/sig/ibex/runtime/cst/incremental/session.rbs +89 -0
  69. data/sig/ibex/runtime/cst/incremental/token_memo.rbs +31 -0
  70. data/sig/ibex/runtime/cst/kind.rbs +93 -0
  71. data/sig/ibex/runtime/cst/parse_result.rbs +35 -0
  72. data/sig/ibex/runtime/cst/rewriter.rbs +31 -0
  73. data/sig/ibex/runtime/cst/serialize.rbs +39 -0
  74. data/sig/ibex/runtime/cst/serialized_tree.rbs +34 -0
  75. data/sig/ibex/runtime/cst/source_text.rbs +51 -0
  76. data/sig/ibex/runtime/cst/syntax_node.rbs +195 -0
  77. data/sig/ibex/runtime/cst/syntax_token.rbs +112 -0
  78. data/sig/ibex/runtime/cst/text_edit.rbs +33 -0
  79. data/sig/ibex/runtime/cst/typed_node.rbs +50 -0
  80. data/sig/ibex/runtime/cst/validator.rbs +108 -0
  81. data/sig/ibex/runtime/cst.rbs +9 -0
  82. data/sig/ibex/runtime/event.rbs +26 -0
  83. data/sig/ibex/runtime/event_jsonl_tracer.rbs +25 -0
  84. data/sig/ibex/runtime/event_sanitizer.rbs +92 -0
  85. data/sig/ibex/runtime/generated_lexer.rbs +169 -0
  86. data/sig/ibex/runtime/jsonl_tracer.rbs +42 -0
  87. data/sig/ibex/runtime/lexer_input.rbs +44 -0
  88. data/sig/ibex/runtime/location_span.rbs +64 -0
  89. data/sig/ibex/runtime/observation.rbs +35 -0
  90. data/sig/ibex/runtime/parser.rbs +926 -0
  91. data/sig/ibex/runtime/parser_sync_recovery.rbs +60 -0
  92. data/sig/ibex/runtime/repair.rbs +92 -0
  93. data/sig/ibex/runtime/repair_priority_queue.rbs +27 -0
  94. data/sig/ibex/runtime/repair_search.rbs +114 -0
  95. data/sig/ibex/runtime/resource_limits.rbs +39 -0
  96. data/sig/ibex/runtime/table_format.rbs +11 -0
  97. data/sig/ibex/runtime/version.rbs +7 -0
  98. data/sig/ibex/runtime.rbs +6 -0
  99. data/sig/ibex/tables/compact.rbs +70 -0
  100. data/sig/ibex/tables/compact_actions.rbs +57 -0
  101. data/sig/ibex/tables/compact_productions.rbs +68 -0
  102. metadata +144 -0
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ module Ibex
5
+ module Runtime
6
+ # The deterministic source span assigned to a reduced nonterminal.
7
+ #
8
+ # Terminal stack entries retain the application-owned location object
9
+ # supplied by the lexer. A reduction wraps the outer boundaries in this
10
+ # immutable value so actions can distinguish synthesized spans.
11
+ class LocationSpan
12
+ attr_reader :start #: untyped
13
+ attr_reader :finish #: untyped
14
+
15
+ # @rbs (start: untyped, finish: untyped, ?empty: bool) -> void
16
+ def initialize(start:, finish:, empty: false)
17
+ @start = start
18
+ @finish = finish
19
+ @empty = empty
20
+ freeze
21
+ end
22
+
23
+ # Build a span for an LR reduction. Nonempty reductions cover the first
24
+ # through last located RHS entry. Empty reductions are zero-width at the
25
+ # current lookahead location.
26
+ # @rbs (Array[untyped] locations, lookahead: untyped) -> LocationSpan?
27
+ def self.for_reduction(locations, lookahead:)
28
+ if locations.empty?
29
+ return unless lookahead
30
+
31
+ boundary = boundary_start(lookahead)
32
+ return new(start: boundary, finish: boundary, empty: true)
33
+ end
34
+
35
+ located = locations.compact
36
+ return if located.empty?
37
+
38
+ new(start: boundary_start(located.first), finish: boundary_finish(located.last))
39
+ end
40
+
41
+ # Whether this is the zero-width span of an empty production.
42
+ # @rbs () -> bool
43
+ def empty?
44
+ @empty
45
+ end
46
+
47
+ # @rbs () -> untyped
48
+ def file = location_value(@start, :file)
49
+
50
+ # @rbs () -> untyped
51
+ def line = location_value(@start, :line)
52
+
53
+ # @rbs () -> untyped
54
+ def column = location_value(@start, :column)
55
+
56
+ # @rbs () -> untyped
57
+ def source_line = location_value(@start, :source_line)
58
+
59
+ # @rbs () -> untyped
60
+ def end_file
61
+ return file if empty?
62
+
63
+ location_value(@finish, :end_file) || location_value(@finish, :file)
64
+ end
65
+
66
+ # @rbs () -> untyped
67
+ def end_line
68
+ return line if empty?
69
+
70
+ location_value(@finish, :end_line) || location_value(@finish, :line)
71
+ end
72
+
73
+ # @rbs () -> untyped
74
+ def end_column
75
+ return column if empty?
76
+
77
+ location_value(@finish, :end_column) || location_value(@finish, :column)
78
+ end
79
+
80
+ # @rbs () -> Hash[Symbol, untyped]
81
+ def to_h
82
+ {
83
+ file: file, line: line, column: column,
84
+ end_file: end_file, end_line: end_line, end_column: end_column,
85
+ empty: empty?
86
+ }
87
+ end
88
+
89
+ class << self
90
+ private
91
+
92
+ # @rbs (untyped location) -> untyped
93
+ def boundary_start(location)
94
+ location.is_a?(LocationSpan) ? location.start : location
95
+ end
96
+
97
+ # @rbs (untyped location) -> untyped
98
+ def boundary_finish(location)
99
+ location.is_a?(LocationSpan) ? location.finish : location
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ # @rbs (untyped location, Symbol key) -> untyped
106
+ def location_value(location, key)
107
+ return location.public_send(key) if location.respond_to?(key)
108
+ return location[key] || location[key.to_s] if location.is_a?(Hash)
109
+
110
+ nil
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative "event" unless defined?(Ibex::Runtime::Event)
5
+
6
+ module Ibex
7
+ module Runtime
8
+ # Registration and ordered synchronous dispatch for parser observers.
9
+ module Observation
10
+ # Opaque identity returned by Parser#observe.
11
+ class Subscription
12
+ class << self
13
+ private
14
+
15
+ # @rbs () -> Subscription
16
+ def new
17
+ super.freeze
18
+ end
19
+
20
+ # @rbs () -> Subscription
21
+ # rubocop:disable Lint/UselessMethodDefinition -- explicit override keeps runtime and generated RBS private.
22
+ def allocate
23
+ super
24
+ end
25
+ # rubocop:enable Lint/UselessMethodDefinition
26
+ end
27
+ end
28
+
29
+ # @rbs () { (Event) -> void } -> Subscription
30
+ def observe(&observer)
31
+ __send__(:ensure_runtime_initialized!)
32
+ raise ArgumentError, "observe requires a block" unless observer
33
+
34
+ @runtime_observation_mutex.synchronize do
35
+ ensure_observation_thread!
36
+ @runtime_fast_path = false
37
+ subscription = Subscription.__send__(:new)
38
+ @runtime_observers ||= {} #: Hash[Subscription, Proc]
39
+ @runtime_observers[subscription] = observer
40
+ subscription
41
+ end
42
+ end
43
+
44
+ # @rbs (Subscription subscription) -> bool
45
+ def unobserve(subscription)
46
+ __send__(:ensure_runtime_initialized!)
47
+ @runtime_observation_mutex.synchronize do
48
+ ensure_observation_thread!
49
+ observers = @runtime_observers
50
+ next false unless observers
51
+
52
+ removed = !observers.delete(subscription).nil?
53
+ @runtime_observers = nil if observers.empty?
54
+ removed
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ # @rbs (Symbol type, Hash[untyped, untyped] data, ?observers: Array[Proc]?) -> void
61
+ def emit_runtime_event(type, data, observers: runtime_observer_snapshot)
62
+ return unless observers
63
+
64
+ @runtime_event_sequence += 1
65
+ event = Event.new(type: type, sequence: @runtime_event_sequence, data: data)
66
+ observers.each { |observer| observer.call(event) }
67
+ end
68
+
69
+ # @rbs () -> Array[Proc]?
70
+ def runtime_observer_snapshot
71
+ @runtime_observers&.values
72
+ end
73
+
74
+ # @rbs () -> void
75
+ def ensure_observation_thread!
76
+ return if @driver_status == :idle || @runtime_driver_thread == Thread.current
77
+
78
+ raise ThreadError, "parser observers cannot be changed from another thread while a driver is active"
79
+ end
80
+ end
81
+ end
82
+ end