class Rucc::IntEvaluator
Public Class Methods
eval(node)
click to toggle source
@param [Node] node @return [<Integer, (Node
, NilClass)>]
# File lib/rucc/int_evaluator.rb, line 6 def eval(node) i, addr = do_eval(node) case i when TrueClass r = 1 when FalseClass r = 0 when Integer r = i else raise "Integer expression expected, but got #{node}" end return r, addr end
Private Class Methods
do_eval(node)
click to toggle source
@param [Node] node @return [<Integer, (Node
, NilClass)>]
# File lib/rucc/int_evaluator.rb, line 27 def do_eval(node) case node.kind when AST::LITERAL if Type.is_inttype(node.ty) return [node.ival, nil] end raise_error(node) when '!' i, addr = self.eval(node.operand) r = (i == 0) ? 1 : 0 return [r, addr] when '~' r, addr = self.eval(node.operand) return [~r, addr] when OP::CAST then return self.eval(node.operand) when AST::CONV then return self.eval(node.operand) when AST::ADDR if node.operand.kind == AST::STRUCT_REF return eval_struct_ref(node.operand, 0) end return 0, Node.conv(node) when AST::GVAR return 0, Node.conv(node) when AST::DEREF if node.operand.ty.kind == Kind::PTR return self.eval(node.operand) end raise_error!(node) when AST::TERNARY cond, addr = self.eval(node.cond) if cond return node.thn ? self.eval(node.thn) : [cond, addr] end return self.eval(node.els) when '+' then return eval_binary_expr(node, &:+) when '-' then return eval_binary_expr(node, &:-) when '*' then return eval_binary_expr(node, &:*) when '/' then return eval_binary_expr(node, &:/) when '<' then return eval_binary_expr(node, &:<) when '^' then return eval_binary_expr(node, &:^) when '&' then return eval_binary_expr(node, &:&) when '|' then return eval_binary_expr(node, &:|) when '%' then return eval_binary_expr(node, &:%) when OP::EQ then return eval_binary_expr(node, &:==) when OP::GE then return eval_binary_expr(node, &:>=) when OP::LE then return eval_binary_expr(node, &:<=) when OP::NE then return eval_binary_expr(node, &:!=) when OP::SAL then return eval_binary_expr(node, &:<<) when OP::SAR then return eval_binary_expr(node, &:>>) when OP::SHR then return eval_binary_expr(node, &:>>) when OP::LOGAND then return eval_binary_expr(node) { |a, b| (a != 0) && (b != 0)} # [Integer] a, [Integer] b when OP::LOGOR then return eval_binary_expr(node) { |a, b| (a != 0) || (b != 0)} # [Integer] a, [Integer] b else raise_error(node) # error("Integer expression expected, but got %s", node2s(node)); end end
eval_binary_expr(node) { |left, right| ... }
click to toggle source
@param [Node] node @return [<Integer, (Node
, NilClass)>]
# File lib/rucc/int_evaluator.rb, line 94 def eval_binary_expr(node, &block) left, addr_l = self.eval(node.left) right, addr_r = self.eval(node.right) addr = addr_r || addr_l r = yield(left, right) return r, addr end
eval_struct_ref(node, offset)
click to toggle source
@param [Node] node @param [Integer] offset @return [<Integer, (Node
, NilClass)>]
# File lib/rucc/int_evaluator.rb, line 105 def eval_struct_ref(node, offset) if node.kind == AST::STRUCT_REF return eval_struct_ref(node.struct, node.ty.offset + offset) end n, addr = self.eval(node) return n + offset, addr end
raise_error(node)
click to toggle source
@param [Node] node
# File lib/rucc/int_evaluator.rb, line 88 def raise_error(node) raise "Integer expression expected, but got #{node}" end