Class: Gloo::Core::Parser
- Inherits:
-
Object
- Object
- Gloo::Core::Parser
- Defined in:
- lib/gloo/core/parser.rb
Instance Method Summary collapse
-
#initialize(engine) ⇒ Parser
constructor
Set up the parser.
-
#inline_call_opener?(cmd, paren_index) ⇒ Boolean
Is the '(' at the given index immediately preceded (no space) by an inline-call keyword, eg. invoke( or ~>( ? Shares its keyword list with Gloo::Core::Tokens, which is where such a call actually gets recognized as one token..
-
#matching_open_paren_index(cmd) ⇒ Object
Find the index of the '(' that balances the command's final ')', counting depth from the end so an inline call earlier in the command (or nested parens) doesn't confuse the match.
-
#parse_immediate(full_cmd) ⇒ Object
Parse a command from the immediate execution context.
-
#run(cmd) ⇒ Object
Parse a command and then run it if it parsed correctly.
-
#split_params(cmd) ⇒ Object
If additional params were provided, split them out from the token list.
Constructor Details
#initialize(engine) ⇒ Parser
Set up the parser.
15 16 17 18 |
# File 'lib/gloo/core/parser.rb', line 15 def initialize( engine ) @engine = engine @engine.log.debug 'parser intialized...' end |
Instance Method Details
#inline_call_opener?(cmd, paren_index) ⇒ Boolean
Is the '(' at the given index immediately preceded (no space) by an inline-call keyword, eg. invoke( or ~>( ? Shares its keyword list with Gloo::Core::Tokens, which is where such a call actually gets recognized as one token.
88 89 90 91 92 |
# File 'lib/gloo/core/parser.rb', line 88 def inline_call_opener?( cmd, paren_index ) before = cmd[ 0...paren_index ] word = before[ /\S*\z/ ] return Gloo::Core::Tokens::CALL_OPENERS.include?( word ) end |
#matching_open_paren_index(cmd) ⇒ Object
Find the index of the '(' that balances the command's final ')', counting depth from the end so an inline call earlier in the command (or nested parens) doesn't confuse the match. Returns nil if the command doesn't end with ')', or the parens aren't balanced.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/gloo/core/parser.rb', line 67 def matching_open_paren_index( cmd ) return nil unless cmd.strip.end_with?( ')' ) depth = 0 ( cmd.length - 1 ).downto( 0 ) do |idx| case cmd[ idx ] when ')' then depth += 1 when '(' depth -= 1 return idx if depth.zero? end end return nil end |
#parse_immediate(full_cmd) ⇒ Object
Parse a command from the immediate execution context.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/gloo/core/parser.rb', line 23 def parse_immediate( full_cmd ) # Break the full command into verb and params cmd, params = split_params full_cmd # Params are the parenthetical part of the command at the end params = Gloo::Core::Tokens.new( params ) if params tokens = Gloo::Core::Tokens.new( cmd ) dic = Gloo::Core::Dictionary.instance verb = dic.find_verb( tokens.verb ) return verb.new( @engine, tokens, params ) if verb @engine.err "Verb '#{tokens.verb}' was not found." return nil end |
#run(cmd) ⇒ Object
Parse a command and then run it if it parsed correctly.
97 98 99 100 |
# File 'lib/gloo/core/parser.rb', line 97 def run( cmd ) v = parse_immediate( cmd ) Gloo::Exec::Runner.go( @engine, v ) if v end |
#split_params(cmd) ⇒ Object
If additional params were provided, split them out from the token list.
A trailing (...) is normally the optional-param convention (eg. show "text" (color)) and gets split off here. But a trailing (...) can also be an inline function call that happens to be the last thing in the command (eg. show invoke( functions.add 3 4 )) - that must be left alone so it flows into tokenizing as part of the main command.
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/gloo/core/parser.rb', line 49 def split_params( cmd ) i = matching_open_paren_index( cmd ) return cmd, nil unless i return cmd, nil if inline_call_opener?( cmd, i ) pstr = cmd[ i + 1..-1 ] params = pstr.strip[ 0..-2 ] if pstr cmd = cmd[ 0, i ].strip return cmd, params end |