Class: XfOOrth::Parser
- Defined in:
- lib/fOOrth/compiler/parser.rb,
lib/fOOrth/compiler/parser/skip.rb,
lib/fOOrth/compiler/parser/normal.rb,
lib/fOOrth/compiler/parser/special.rb,
lib/fOOrth/compiler/parser/get_string.rb
Overview
-
compiler/parser/get_string.rb - Extract string literals from code source.
Instance Attribute Summary collapse
-
#source ⇒ Object
readonly
The source of the text to be parsed.
Instance Method Summary collapse
-
#get_string ⇒ Object
Get the balance of a string from the source code source.
-
#get_word ⇒ Object
Get the next forth word from the source code source.
-
#get_word_or_string ⇒ Object
Get the next forth word and any embedded string data.
-
#get_word_raw ⇒ Object
Get the next forth word from the source code source.
-
#initialize(source) ⇒ Parser
constructor
Initialize this parser.
-
#process_16_bit ⇒ Object
Process a 16 bit hex character constant.
-
#process_8_bit ⇒ Object
Process an 8 bit hex character constant.
-
#process_backslash(buffer) ⇒ Object
Process a backlash character found with a string in the source text.
-
#process_hex_character ⇒ Object
Get a hex character from the input stream.
-
#skip_over_comment ⇒ Object
Skip over a portion of the source text until a ‘)’ detected.
-
#skip_to_eoln ⇒ Object
Skip over a portion of the source text until end of line detected.
-
#skip_white_space ⇒ Object
Skip over any white space.
-
#skip_white_space_or_to_eoln ⇒ Object
Skip till a non-white space or an end of line.
Constructor Details
#initialize(source) ⇒ Parser
Initialize this parser.
Parameters
-
source - The source of the text to be parsed.
20 21 22 |
# File 'lib/fOOrth/compiler/parser.rb', line 20 def initialize(source) @source = source end |
Instance Attribute Details
#source ⇒ Object (readonly)
The source of the text to be parsed.
15 16 17 |
# File 'lib/fOOrth/compiler/parser.rb', line 15 def source @source end |
Instance Method Details
#get_string ⇒ Object
Get the balance of a string from the source code source.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 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_word ⇒ Object
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.
14 15 16 17 18 19 20 21 22 23 24 25 26 |
# 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_word_or_string ⇒ Object
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
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# 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_word_raw ⇒ Object
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.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# 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_16_bit ⇒ Object
Process a 16 bit hex character constant.
59 60 61 62 63 |
# 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_8_bit ⇒ Object
Process an 8 bit hex character constant.
53 54 55 56 |
# 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_backslash(buffer) ⇒ Object
Process a backlash character found with a string in the source text.
Endemic Code Smells
-
:reek:TooManyStatements
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# 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 |
#process_hex_character ⇒ Object
Get a hex character from the input stream.
66 67 68 69 70 71 |
# 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_comment ⇒ Object
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
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# 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_to_eoln ⇒ Object
Skip over a portion of the source text until end of line detected.
Returns:
-
true
23 24 25 26 |
# File 'lib/fOOrth/compiler/parser/skip.rb', line 23 def skip_to_eoln @source.get until @source.eoln? true end |
#skip_white_space ⇒ Object
Skip over any white space.
Returns:
-
The first non-white space character or nil if none were found.
12 13 14 15 16 17 18 |
# 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_white_space_or_to_eoln ⇒ Object
Skip till a non-white space or an end of line
54 55 56 57 58 |
# 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 |