class Whitespace::Parser
Constants
- LF
- SPACE
- TAB
Attributes
console[R]
instructions[R]
vm[R]
Public Class Methods
new(vm, console)
click to toggle source
# File lib/whitespace/parser.rb, line 5 def initialize(vm, console) @vm = vm @console = console end
Public Instance Methods
parse(src)
click to toggle source
# File lib/whitespace/parser.rb, line 10 def parse(src) parse_init(src) parse_start end
Private Instance Methods
append_and_continue(instruction)
click to toggle source
# File lib/whitespace/parser.rb, line 238 def append_and_continue(instruction) @instructions << instruction parse_start end
next_token()
click to toggle source
# File lib/whitespace/parser.rb, line 233 def next_token @index += 1 @tokens[@index - 1] end
parse_arithmetic()
click to toggle source
# File lib/whitespace/parser.rb, line 72 def parse_arithmetic case next_token when SPACE case next_token when SPACE append_and_continue ISA::Add.new(vm) when TAB append_and_continue ISA::Sub.new(vm) when LF append_and_continue ISA::Mul.new(vm) else raise ParseError, "must be an arithmetic instruction" end when TAB case next_token when SPACE append_and_continue ISA::Div.new(vm) when TAB append_and_continue ISA::Mod.new(vm) else raise ParseError, "must be an arithmetic instruction" end else raise ParseError, "must be an arithmetic instruction" end end
parse_flow_control()
click to toggle source
# File lib/whitespace/parser.rb, line 110 def parse_flow_control case next_token when SPACE case next_token when SPACE name = parse_name append_and_continue ISA::Label.new(vm, name) when TAB name = parse_name append_and_continue ISA::Call.new(vm, name) when LF name = parse_name append_and_continue ISA::Ujmp.new(vm, name) else raise ParseError, "must be a flow control instruction" end when TAB case next_token when SPACE name = parse_name append_and_continue ISA::Zjmp.new(vm, name) when TAB name = parse_name append_and_continue ISA::Njmp.new(vm, name) when LF append_and_continue ISA::Return.new(vm) else raise ParseError, "must be a flow control instruction" end when LF case next_token when LF append_and_continue ISA::End.new(vm) else raise ParseError, "must be a flow control instruction" end else raise ParseError, "must be a flow control instruction" end end
parse_heap()
click to toggle source
# File lib/whitespace/parser.rb, line 99 def parse_heap case next_token when SPACE append_and_continue ISA::Store.new(vm) when TAB append_and_continue ISA::Retrieve.new(vm) else raise ParseError, "must be a heap instruction" end end
parse_init(src)
click to toggle source
# File lib/whitespace/parser.rb, line 23 def parse_init(src) @tokens = src.to_s.gsub(/[^ \t\n]+/, '') @index = 0 @instructions = [] end
parse_io()
click to toggle source
# File lib/whitespace/parser.rb, line 151 def parse_io case next_token when SPACE case next_token when SPACE append_and_continue ISA::Putc.new(vm, console) when TAB append_and_continue ISA::Putn.new(vm, console) else raise ParseError, "must be an I/O instruction" end when TAB case next_token when SPACE append_and_continue ISA::Readc.new(vm, console) when TAB append_and_continue ISA::Readn.new(vm, console) else raise ParseError, "must be an I/O instruction" end else raise ParseError, "must be an I/O instruction" end end
parse_name()
click to toggle source
# File lib/whitespace/parser.rb, line 212 def parse_name parse_name_rec("", 0, next_token) end
parse_name_rec(name, len, token)
click to toggle source
# File lib/whitespace/parser.rb, line 216 def parse_name_rec(name, len, token) case token when SPACE parse_name_rec(name + " ", len + 1, next_token) when TAB parse_name_rec(name + "\t", len + 1, next_token) when LF if len > 0 name else raise ParseError, "name must be non-empty" end else raise ParseError, "name must be terminated by a LF" end end
parse_number()
click to toggle source
# File lib/whitespace/parser.rb, line 176 def parse_number parse_sign * parse_value end
parse_sign()
click to toggle source
# File lib/whitespace/parser.rb, line 180 def parse_sign case next_token when SPACE 1 when TAB -1 else raise ParseError, "must be a sign token" end end
parse_stack_manipulation()
click to toggle source
# File lib/whitespace/parser.rb, line 51 def parse_stack_manipulation case next_token when SPACE n = parse_number append_and_continue ISA::Push.new(vm, n) when LF case next_token when SPACE append_and_continue ISA::Dup.new(vm) when TAB append_and_continue ISA::Swap.new(vm) when LF append_and_continue ISA::Discard.new(vm) else raise ParseError, "must be a stack manipulation instruction" end else raise ParseError, "must be a stack manipulation instruction" end end
parse_start()
click to toggle source
# File lib/whitespace/parser.rb, line 29 def parse_start case next_token when SPACE parse_stack_manipulation when TAB case next_token when SPACE parse_arithmetic when TAB parse_heap when LF parse_io else raise ParseError, "must be an IMP" end when LF parse_flow_control else instructions end end
parse_value()
click to toggle source
# File lib/whitespace/parser.rb, line 191 def parse_value parse_value_rec(0, 0, next_token) end
parse_value_rec(n, len, token)
click to toggle source
# File lib/whitespace/parser.rb, line 195 def parse_value_rec(n, len, token) case token when SPACE parse_value_rec(2 * n, len + 1, next_token) when TAB parse_value_rec(2 * n + 1, len + 1, next_token) when LF if len > 0 n else raise ParseError, "number must have a value part" end else raise ParseError, "number must be terminated by a LF" end end