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.
-
#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 |
#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.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/liquidscript/compiler/base/helpers.rb', line 134 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 |