Module: Liquidscript::Compiler::Base::Helpers
- Included in:
- Liquidscript::Compiler::Base
- Defined in:
- lib/liquidscript/compiler/base/helpers.rb
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
Instance Method Summary collapse
-
#action(act = nil) { ... } ⇒ Proc, Action
Normalizes an action for the hash passed to #expect.
-
#collect_compiles(*end_on) ⇒ Object
last element of ‘end_on` is a Hash, it is merged with the default actions that this takes and passes it to `expect`.
-
#expect(*args) ⇒ Object
The meat and potatos of the compiler.
-
#loop ⇒ void
Performs a loop while the yield returns true.
-
#maybe(*types) ⇒ #type
Shifts a token if its one of the given types; if it’s not, it returns the value of #scanner_nil.
-
#peek?(*types) ⇒ Boolean
Checks to see if the next token is of any of the given types.
-
#shift(*types) ⇒ #type
Shift a token over.
Class Method Details
.included(base) ⇒ Object
21 22 23 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 21 def self.included(base) base.extend ClassMethods end |
Instance Method Details
#action(act = nil) { ... } ⇒ Proc, Action
33 34 35 36 37 38 39 40 41 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 33 def action(act = nil) if block_given? Proc.new elsif act.is_a? Proc act else @action end end |
#collect_compiles(compile, *end_on) ⇒ Array<Object> #collect_compiles(*end_on, &block) ⇒ Object
last element of ‘end_on` is a Hash, it is merged with the
default actions that this takes and passes it to `expect`.
@example
collect_compiles(:test) { shift :_ }
@yieldreturn The value you want to be placed in the
array.
@param end_on [Array<Symbol>] an array of symbols to end
the loop.
@return [Array<Object>] the results of all of the block
calls.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 124 def collect_compiles(*end_on) compiles = [] if block_given? compile = Proc.new else compile = end_on.shift end block = Callable.new(self, compile) hash = if end_on.last.is_a? Hash end_on.pop.dup else {} end do_compile = action do compiles << block.call end hash.merge! end_on => action.end_loop, :_ => do_compile loop do expect hash end compiles end |
#expect(*args) ⇒ Object
The meat and potatos of the compiler. This maps actions to tokens. In its basic form, it is passed a hash, with the keys being token types, and the values the corresponding actions to take. It can be passed individual types, from which it’ll assume the method name (normally, ‘compile_<type>`); or, you can pass it a symbol key, which is the last part of the method name (i.e., not including `compile_`). It will check the next token, and look for the correct action; if the next token doesn’t match any of the given keys, it checks for the special type ‘:_` (which is basically a catch-all), and if it still doesn’t get it, it raises an UnexpectedError. From there, it calls the corresponding block.
If the block or method accepts one argument, it Liquidscript::Compiler::Base#pops the token, and passes it in as an argument. If it accepts no arguments, it doesn’t.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 203 def expect(*args) hash = normalize_arguments(args) allowable = false block = hash.fetch(peek.type) do hash.fetch(:_) do allowable = true self.allowable.fetch(peek.type) end end out = if block.arity == 1 block.call pop else block.call end if allowable expect(*args) else out end rescue KeyError raise UnexpectedError.new(hash.keys, peek) end |
#loop ⇒ void
This method returns an undefined value.
Performs a loop while the yield returns true. This overwrites the core loop on purpose.
48 49 50 51 52 53 54 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 48 def loop result = true while result result = yield end end |
#maybe(*types) ⇒ #type
Shifts a token if its one of the given types; if it’s not, it returns the value of Liquidscript::Compiler::Base#scanner_nil.
72 73 74 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 72 def maybe(*types) expect types => action.shift, :_ => action { scanner_nil } end |
#peek?(*types) ⇒ Boolean
Checks to see if the next token is of any of the given types. Note that the special type ‘:_` does not work here.
82 83 84 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 82 def peek?(*types) types.any? { |type| peek.type == type } end |
#shift(*types) ⇒ #type
Shift a token over. The given types can be any types. If the next token’s type doesn’t match any of the types, then it will raise an error. In order to shift any token, use the special type ‘:_`.
63 64 65 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 63 def shift(*types) expect types => action.shift end |