Class: Carbon::Compiler::Metanostic::State
- Inherits:
-
Object
- Object
- Carbon::Compiler::Metanostic::State
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/carbon/compiler/metanostic/state.rb
Overview
A “State” object. This manages the state of metanostic modes at any point in the program. This is useful for something like the diagnostic directives, in which ‘pop`/`push`/`set` operations need to be available for the metanostic modes. This manages the metanostic modes.
The Carbon::Compiler::Metanostics are first loaded using Defaults.defaults. They are then used to generate a “beginning” state or “blank” state. Their modes are extracted, resulting in a hash of ‘=> (Integer, Metanostic)`. Then, a “current” state is generated; this is the same hash type as the “beginning” state, and initially, the same contents. However, when the `push` operation occurs, a new “state” is added to the stack, and a new “current” state is generated, using the beginning state and the stack as a reference. Whenever a set occurs, it sets to the last state added to the stack, and a new current state is generated.
The point of all this is to have a hash at all times that accurately represents the set modes of all diagnostics.
Instance Method Summary collapse
-
#[](name) ⇒ (Integer, Metanostic)?
Indexes the state.
-
#current ⇒ {String => (Integer, Metanostic)}
The current state.
-
#each {|name, data| ... } ⇒ Enumerator
Iterates over each key-value pair in the current state.
-
#fetch(name, default = CANARY) ⇒ (Integer, Metanostic), Object
Fetches the Carbon::Compiler::Metanostic information with the name ‘name`.
-
#initialize ⇒ State
constructor
Initialize the state.
-
#initialize_copy(state) ⇒ Object
Initializes a copy of the given state.
-
#pop ⇒ void
Pops the last state from the stack.
-
#push ⇒ void
Pushes to the stack.
-
#reset(name) ⇒ void
This resets the given metanostic to its default metanostic mode.
-
#set(name, mode) ⇒ void
Sets the given metanostic name to the given metanostic value in the last state in the stack.
Constructor Details
#initialize ⇒ State
Initialize the state. It sets the defaults using Defaults.defaults, and generates the beginning state.
64 65 66 67 68 69 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 64 def initialize @monitor = Monitor.new @defaults = Defaults.defaults @stack = Concurrent::Array.new([Concurrent::Hash.new]) generate_beginning end |
Instance Method Details
#[](name) ⇒ (Integer, Metanostic)?
Indexes the state. Returns an array containing information about the mode and the metanostic for the corresponding name, otherwise it returns ‘nil`.
37 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 37 def_delegator :current, :[] |
#current ⇒ {String => (Integer, Metanostic)}
The current state. This is frozen and cached, since it is a derived value of the beginning state and the stack.
146 147 148 149 150 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 146 def current @_current ||= @monitor.synchronize do @stack.inject(@beginning) { |a, e| a.merge(e) }.freeze end end |
#each {|name, data| ... } ⇒ Enumerator
Iterates over each key-value pair in the current state.
60 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 60 def_delegator :current, :each |
#fetch(name, default = CANARY) ⇒ (Integer, Metanostic), Object
Fetches the Carbon::Compiler::Metanostic information with the name ‘name`. If no key exists with the given name, the method will attempt to do the following: if a block is given, yield to that; otherwise, if a default is given, return that; otherwise, throw a `KeyError`.
51 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 51 def_delegator :current, :fetch |
#initialize_copy(state) ⇒ Object
Initializes a copy of the given state. This is called by ‘#clone` and `#dup`, and as such should not be used outside of either of these things.
76 77 78 79 80 81 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 76 def initialize_copy(state) @defaults = state.defaults @stack = state.stack.map(&:clone) @monitor = Monitor.new @beginning = state.beginning end |
#pop ⇒ void
This may change the current state.
This method returns an undefined value.
Pops the last state from the stack. This could potentially change the state, since the last state may have a new diagnostic setting inside of it.
100 101 102 103 104 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 100 def pop @monitor.synchronize do clear! if @stack.pop.any? end end |
#push ⇒ void
This method returns an undefined value.
Pushes to the stack. This pushes a clean state to the stack. This does not change the current state at all, since the new state is empty.
88 89 90 91 92 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 88 def push @monitor.synchronize do @stack.push(Concurrent::Hash.new) end end |
#reset(name) ⇒ void
This changes the current state.
This method returns an undefined value.
This resets the given metanostic to its default metanostic mode. It does this by taking the definition from the beginning state and copying it to the last stack frame.
138 139 140 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 138 def reset(name) set(name, @beginning.fetch(name)) end |
#set(name, mode) ⇒ void
This changes the current state.
This method returns an undefined value.
Sets the given metanostic name to the given metanostic value in the last state in the stack. If the metanostic is not found in any of the defaults, a ‘KeyError` is raised. If the new mode is not allowed for the given metanostic, a DiagnosticError is raised.
116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/carbon/compiler/metanostic/state.rb', line 116 def set(name, mode) @monitor.synchronize do mode = Mode.from(mode) = @defaults.fetch(name) unless .can_be?(mode) fail DiagnosticError, "Diagnostic #{name} cannot be #{Mode.to_s(mode)}" end @stack.last[.name] = [mode, ] clear! end end |