module Tildeath::Parser
Public Class Methods
parse(tokens)
click to toggle source
program: statements
# File lib/tildeath/parser.rb, line 132 def self.parse(tokens) ASTNodes::Program.new(parse_statements(tokens)) end
parse_array(tokens)
click to toggle source
array: LBRACKET expression (COMMA expression)* RBRACKET
# File lib/tildeath/parser.rb, line 60 def self.parse_array(tokens) elements = [] elements << tokens.shift(2)[1].value.to_sym ASTNodes::Array.new(elements) end
parse_bang(tokens)
click to toggle source
bang: BANG value
# File lib/tildeath/parser.rb, line 29 def self.parse_bang(tokens) # shift off BANG tokens.shift value = parse_value(tokens) ASTNodes::Bang.new(operand) end
parse_bifurcate(tokens)
click to toggle source
bifurcate: BIFURC8 IDENT LBRACKET IDENT COMMA IDENT RBRACKET
# File lib/tildeath/parser.rb, line 75 def self.parse_bifurcate(tokens) orig = tokens.shift(3)[1].value.to_sym parts = tokens.shift(4).values_at(0, 2).map do |token| token.value.to_sym end ASTNodes::Bifurcate.new(orig, parts) end
parse_dot_die(tokens)
click to toggle source
dot_die: expression DOT DIE LPAREN RPAREN
# File lib/tildeath/parser.rb, line 67 def self.parse_dot_die(tokens) # shift off all the tokens, keeping the IDENT's value victim = tokens.shift(5)[0] victim = victim.name == :THIS ? victim.name.to_sym : victim.value.to_sym ASTNodes::DotDie.new(victim) end
parse_expression(tokens)
click to toggle source
expression: bang | value
# File lib/tildeath/parser.rb, line 37 def self.parse_expression(tokens) return parse_bang(tokens) if tokens[0].name == :BANG parse_value(tokens) end
parse_import(tokens)
click to toggle source
import: IMPORT IDENT IDENT
# File lib/tildeath/parser.rb, line 15 def self.parse_import(tokens) # Shift the IMPORT IDENT IDENT tokens off the queue, saving the type and # name as symbols type, name = tokens.shift(3)[1..2].map{|token| token.value.to_sym} # return a new Import with the given type and name ASTNodes::Import.new(type, name) end
parse_null(tokens)
click to toggle source
null: NULL
# File lib/tildeath/parser.rb, line 7 def self.parse_null(tokens) # shift the NULL off the token queue tokens.shift # return a new Null object ASTNodes::Null.new end
parse_split(tokens)
click to toggle source
split: SPLIT IDENT LBRACKET IDENT (COMMA IDENT)* RBRACKET
# File lib/tildeath/parser.rb, line 84 def self.parse_split(tokens) orig = tokens.shift(3)[1].value.to_sym parts = [tokens.shift.value.to_sym] while true part = tokens.shift case part.name when :COMMA parts << tokens.shift.value.to_sym when :RBRACKET break end end ASTNodes::Split.new(orig, parts) end
parse_statement(tokens)
click to toggle source
statement: (import | tildeath | dot_die | bifurcate | split) SEMI TODO: make [THIS, THIS].DIE() legal
# File lib/tildeath/parser.rb, line 101 def self.parse_statement(tokens) # Determine statement type based on first token, and parse it token = tokens[0].name ret = case token when :IMPORT then parse_import(tokens) when :TILDEATH then parse_tildeath(tokens) when :THIS, :IDENT then parse_dot_die(tokens) when :BIFURC8 then parse_bifucate(tokens) when :SPLIT then parse_split(tokens) when :RBRACE then return else fail TildeathError.new(token.line_number, token.column), "error: unexpected token #{token}" end # shift off SEMI fail TildeathError.new(tokens[0].line_number, tokens[0].column), 'missing semicolon' unless tokens[0].name == :SEMI tokens.shift ret end
parse_statements(tokens)
click to toggle source
statements: statement*
# File lib/tildeath/parser.rb, line 120 def self.parse_statements(tokens) statements = [] # while there are tokens left and parse_statement returns non-nil... while tokens.length > 0 && statement = parse_statement(tokens) # add parsed statement to list of parsed statements statements << statement end # return a new Statements object with the list of parsed statements ASTNodes::Statements.new(statements) end
parse_tildeath(tokens)
click to toggle source
tildeath: TILDEATH LPAREN expression RPAREN LBRACE statements RBRACE EXECUTE LPAREN statements RPAREN
# File lib/tildeath/parser.rb, line 43 def self.parse_tildeath(tokens) # shift off the first five tokens, saving the IDENT victim = tokens.shift(5)[2] victim = victim == :THIS ? victim.name : victim.value.to_sym # parse the first statements tildeath_body = parse_statements(tokens) # shift off some punctuation tokens.shift(3) # parse the EXECUTE statements (or NULL) execute_body = tokens[0].name == :NULL ? parse_null(tokens) : parse_statements(tokens) # shift off the last RPAREN tokens.shift # return a new Tildeath with the parsed victim and statements ASTNodes::Tildeath.new(victim, tildeath_body, execute_body) end
parse_value(tokens)
click to toggle source
value: THIS | IDENT
# File lib/tildeath/parser.rb, line 24 def self.parse_value(tokens) ASTNodes::Value.new(tokens.shift.value.to_sym) end