Module: Liquidscript::Compiler::Base::Helpers
- Included in:
- Liquidscript::Compiler::Base
- Defined in:
- lib/liquidscript/compiler/base/helpers.rb
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.
Instance Method Details
#action(act = nil) { ... } ⇒ Proc, Action
14 15 16 17 18 19 20 21 22 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 14 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.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 105 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.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 184 def expect(*args) hash = normalize_arguments(args) block = hash.fetch(peek.type) do hash.fetch(:_) end out = if block.arity == 1 block.call pop else block.call end out 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.
29 30 31 32 33 34 35 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 29 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.
53 54 55 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 53 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.
63 64 65 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 63 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 ‘:_`.
44 45 46 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 44 def shift(*types) expect types => action.shift end |