class Ikra::AST::Builder
Public Class Methods
from_parser_ast(node)
click to toggle source
# File lib/ast/builder.rb, line 8 def self.from_parser_ast(node) return self.new.from_parser_ast(node) end
Public Instance Methods
from_parser_ast(node)
click to toggle source
# File lib/ast/builder.rb, line 12 def from_parser_ast(node) return RootNode.new(single_child: translate_node(node)) end
Protected Instance Methods
extract_begin_single_statement(node, should_return = false)
click to toggle source
# File lib/ast/builder.rb, line 145 def extract_begin_single_statement(node, should_return = false) next_node = node while next_node.type == :begin if next_node.children.size != 1 raise AssertionError.new("Begin node contains more than one statement") end next_node = next_node.children[0] end return next_node end
translate_and(node)
click to toggle source
# File lib/ast/builder.rb, line 115 def translate_and(node) return SendNode.new(receiver: translate_node(node.children[0]), selector: :"&&", arguments: [translate_node(node.children[1])]) end
translate_array(node)
click to toggle source
# File lib/ast/builder.rb, line 47 def translate_array(node) return ArrayNode.new(values: node.children.map do |n| translate_node(n) end) end
translate_begin(node)
click to toggle source
# File lib/ast/builder.rb, line 237 def translate_begin(node) return BeginNode.new(body_stmts: node.children.map do |stmt| translate_node(stmt) end) end
translate_bool(node)
click to toggle source
# File lib/ast/builder.rb, line 77 def translate_bool(node) return BoolLiteralNode.new(value: node.children[0]) end
translate_break(node)
click to toggle source
# File lib/ast/builder.rb, line 212 def translate_break(node) return BreakNode.new end
translate_const(node)
click to toggle source
# File lib/ast/builder.rb, line 51 def translate_const(node) full_const_string = "#{node.children[1]}" current_const = node while current_const.children[0] != nil # First receiver is enclosing class/module current_const = current_const.children[0] if current_const.type != :const raise AssertionError.new("Expected :const") end full_const_string = current_const.children[1].to_s + "::" + full_const_string end return ConstNode.new(identifier: full_const_string) end
translate_false(node)
click to toggle source
# File lib/ast/builder.rb, line 85 def translate_false(node) return BoolLiteralNode.new(value: false) end
translate_float(node)
click to toggle source
# File lib/ast/builder.rb, line 73 def translate_float(node) return FloatLiteralNode.new(value: node.children[0]) end
translate_for(node)
click to toggle source
# File lib/ast/builder.rb, line 158 def translate_for(node) if node.children[0].type == :lvasgn and extract_begin_single_statement(node.children[1]).type == :irange range = extract_begin_single_statement(node.children[1]) return ForNode.new(iterator_identifier: node.children[0].children[0], range_from: translate_node(range.children[0]), range_to: translate_node(range.children[1]), body_stmts: wrap_in_begin(translate_node(node.children[2]))) elsif node.children[0].type == :lvasgn and extract_begin_single_statement(node.children[1]).type == :erange # Convert exclusive range to inclusive range range = extract_begin_single_statement(node.children[1]) range_to = translate_node(range.children[1]) range_to_inclusive = SendNode.new( receiver: range_to, selector: :-, arguments: [IntLiteralNode.new(value: 1)]) return ForNode.new(iterator_identifier: node.children[0].children[0], range_from: translate_node(range.children[0]), range_to: range_to_inclusive, body_stmts: wrap_in_begin(translate_node(node.children[2]))) else raise NotImplementedError.new("Can only handle simple For loops at the moment") end end
translate_hash(node)
click to toggle source
# File lib/ast/builder.rb, line 101 def translate_hash(node) hash = {} node.children.each do |child| if child.type != :pair raise NotImplementedError.new("Expected :pair, found #{child.type}") end hash[translate_node(child.children[0])] = translate_node(child.children[1]) end return HashNode.new(hash: hash) end
translate_if(node)
click to toggle source
# File lib/ast/builder.rb, line 139 def translate_if(node) return IfNode.new(condition: translate_node(node.children[0]), true_body_stmts: wrap_in_begin(translate_node(node.children[1])), false_body_stmts: wrap_in_begin(translate_node(node.children[2]))) end
translate_int(node)
click to toggle source
# File lib/ast/builder.rb, line 69 def translate_int(node) return IntLiteralNode.new(value: node.children[0]) end
translate_ivar(node)
click to toggle source
# File lib/ast/builder.rb, line 135 def translate_ivar(node) return IVarReadNode.new(identifier: node.children[0]) end
translate_kwbegin(node)
click to toggle source
# File lib/ast/builder.rb, line 242 def translate_kwbegin(node) return BeginNode.new(body_stmts: node.children.map do |stmt| translate_node(stmt) end) end
translate_lvar(node)
click to toggle source
# File lib/ast/builder.rb, line 127 def translate_lvar(node) return LVarReadNode.new(identifier: node.children[0]) end
translate_lvasgn(node)
click to toggle source
# File lib/ast/builder.rb, line 131 def translate_lvasgn(node) return LVarWriteNode.new(identifier: node.children[0], value: translate_node(node.children[1])) end
translate_nil(node)
click to toggle source
# File lib/ast/builder.rb, line 89 def translate_nil(node) return NilLiteralNode.new end
translate_node(node)
click to toggle source
# File lib/ast/builder.rb, line 31 def translate_node(node) if node == nil return nil else if node.is_a?(Array) # An array of nodes return node.map do |n| send("translate_#{n.type.to_s.gsub("-", "_")}".to_sym, n) end else # A single node return send("translate_#{node.type.to_s.gsub("-", "_")}".to_sym, node) end end end
translate_or(node)
click to toggle source
# File lib/ast/builder.rb, line 121 def translate_or(node) return SendNode.new(receiver: translate_node(node.children[0]), selector: :"||", arguments: [translate_node(node.children[1])]) end
translate_return(node)
click to toggle source
# File lib/ast/builder.rb, line 216 def translate_return(node) return ReturnNode.new(value: translate_node(node.children[0])) end
translate_send(node)
click to toggle source
# File lib/ast/builder.rb, line 220 def translate_send(node) receiver = nil if node.children[0] == nil # Implicit receiver # TODO: Assuming Object for now, but this is not always correct receiver = ConstNode.new(identifier: :Object) else receiver = translate_node(node.children[0]) end return SendNode.new(receiver: receiver, selector: node.children[1], arguments: node.children[2..-1].map do |arg| translate_node(arg) end) end
translate_str(node)
click to toggle source
# File lib/ast/builder.rb, line 97 def translate_str(node) return StringLiteralNode.new(value: node.children[0]) end
translate_sym(node)
click to toggle source
# File lib/ast/builder.rb, line 93 def translate_sym(node) return SymbolLiteralNode.new(value: node.children[0]) end
translate_true(node)
click to toggle source
# File lib/ast/builder.rb, line 81 def translate_true(node) return BoolLiteralNode.new(value: true) end
translate_until(node)
click to toggle source
# File lib/ast/builder.rb, line 196 def translate_until(node) return UntilNode.new( condition: (SendNode.new(receiver: translate_node(node.children[0]), selector: :^, arguments: [BoolLiteralNode.new(value: true)])), body_stmts: wrap_in_begin(translate_node(node.children[1]))) end
translate_until_post(node)
click to toggle source
# File lib/ast/builder.rb, line 204 def translate_until_post(node) return UntilPostNode.new( condition: (SendNode.new(receiver: translate_node(node.children[0]), selector: :^, arguments: [BoolLiteralNode.new(value: true)])), body_stmts: wrap_in_begin(translate_node(node.children[1]))) end
translate_while(node)
click to toggle source
# File lib/ast/builder.rb, line 184 def translate_while(node) return WhileNode.new( condition: translate_node(node.children[0]), body_stmts: wrap_in_begin(translate_node(node.children[1]))) end
translate_while_post(node)
click to toggle source
# File lib/ast/builder.rb, line 190 def translate_while_post(node) return WhilePostNode.new( condition: translate_node(node.children[0]), body_stmts: wrap_in_begin(translate_node(node.children[1]))) end
wrap_in_begin(translated_node)
click to toggle source
# File lib/ast/builder.rb, line 18 def wrap_in_begin(translated_node) if translated_node != nil if translated_node.is_a?(BeginNode) # Is already a `BeginNode` return translated_node else return BeginNode.new(body_stmts: [translated_node]) end else return nil end end