class XfOOrth::Parser
-
parser.rb - Parse source code from a code source.
-
compiler/parser/get_string.rb - Extract string literals from code source.
-
compiler/parser/normal.rb - Parse source code when not in quote mode.
-
compiler/parser/skip.rb - Skip over stuff in the source code.
-
compiler/parser/special.rb - Parse source code in special quoted mode.
Attributes
The source of the text to be parsed.
Public Class Methods
Initialize this parser.
Parameters
-
source - The source of the text to be parsed.
# File lib/fOOrth/compiler/parser.rb, line 20 def initialize(source) @source = source end
Public Instance Methods
Get the balance of a string from the source code source.
# File lib/fOOrth/compiler/parser/get_string.rb, line 10 def get_string vm = Thread.current[:vm] vm.quotes, done, result = 1, false, '' begin next_char = @source.get if next_char == "\\" break if process_backslash(result) elsif next_char == '"' || @source.eoln? vm.quotes, done = 0, true elsif next_char >= ' ' result << next_char end end until done result end
Get the next forth word from the source code source. This method recognizes and skips over comments in the source code.
Returns:
-
A string with the next non-comment language element or nil if none could be found.
# File lib/fOOrth/compiler/parser/normal.rb, line 14 def get_word loop do return nil unless (word = get_word_raw) if word == '(' skip_over_comment elsif word == '//' skip_to_eoln else return word end end end
Get the next forth word and any embedded string data. This is used to support the quoted compiler mode.
Returns:
-
A string with the next non-comment language element or nil if none could be found.
Endemic Code Smells
-
:reek:TooManyStatements
# File lib/fOOrth/compiler/parser/special.rb, line 16 def get_word_or_string return nil unless (word = get_word) if word[-1] == '"' vm = Thread.current[:vm] vm.quotes, skip, done = 1, false, false until done return nil unless (next_char = @source.get) word << next_char if skip skip = false elsif next_char == '"' vm.quotes, done = 0, true else skip = (next_char == '\\') end end end word end
Get the next forth word from the source code source. Recognizes, but does not process comments in the source code.
Returns:
-
A string with the next language element or nil if none could be found.
# File lib/fOOrth/compiler/parser/normal.rb, line 32 def get_word_raw #Skip white space. return nil unless (next_char = skip_white_space) #Gather the word token. word = '' begin word << next_char #Check for the three special cases. break if ['(', '//'].include?(word) || (next_char == '"') next_char = @source.get end while next_char && next_char > ' ' word end
Process a 16 bit hex character constant.
# File lib/fOOrth/compiler/parser/get_string.rb, line 59 def process_16_bit hex = process_hex_character + process_hex_character + process_hex_character + process_hex_character eval("\"\\u#{hex}\"") end
Process an 8 bit hex character constant.
# File lib/fOOrth/compiler/parser/get_string.rb, line 53 def process_8_bit hex = process_hex_character + process_hex_character eval("\"\\x#{hex}\"") end
Process a backlash character found with a string in the source text.
Endemic Code Smells
-
:reek:TooManyStatements
# File lib/fOOrth/compiler/parser/get_string.rb, line 32 def process_backslash(buffer) next_char = @source.get if next_char == ' ' && @source.eoln? next_char = skip_white_space_or_to_eoln return true if ['"', ' '].include?(next_char) elsif next_char == 'n' next_char = "\n" elsif next_char == 'x' next_char = process_8_bit elsif next_char == 'u' next_char = process_16_bit elsif next_char != "\\" && next_char != '"' error "F10: Invalid string literal value: '\\#{next_char}'" end buffer << next_char false end
Get a hex character from the input stream.
# File lib/fOOrth/compiler/parser/get_string.rb, line 66 def process_hex_character next_char = @source.get error "F10: Invalid hex character: '#{next_char}'" unless /\h/ =~ next_char next_char end
Skip over a portion of the source text until a ')' detected.
Returns:
-
true
Note:
-
Raises an
XfOOrthError
exception on an unterminated comment.
Endemic Code Smells
-
:reek:DuplicateMethodCall – false positive
# File lib/fOOrth/compiler/parser/skip.rb, line 35 def skip_over_comment vm = Thread.current[:vm] vm.parens += 1 until @source.eof? input = @source.get if input == ')' vm.parens -= 1 return true elsif input == '(' skip_over_comment end end error "F10: Unbalanced comment detected." end
Skip over a portion of the source text until end of line detected.
Returns:
-
true
# File lib/fOOrth/compiler/parser/skip.rb, line 23 def skip_to_eoln @source.get until @source.eoln? true end
Skip over any white space.
Returns:
-
The first non-white space character or nil if none were found.
# File lib/fOOrth/compiler/parser/skip.rb, line 12 def skip_white_space begin return nil unless (next_char = @source.get) end while next_char <= ' ' next_char end
Skip till a non-white space or an end of line
# File lib/fOOrth/compiler/parser/skip.rb, line 54 def skip_white_space_or_to_eoln while (next_char = @source.get) return next_char if (next_char > ' ') || @source.eoln? end end