def translate_expr(node, code='', level=0)
case tkn = node.token
when :string
value_str = node.left
code << "'"
code << value_str.gsub(/'/, "\\\\'")
code << "'"
when :variable, :number
value_str = node.left
code << value_str
when :true, :false, :null
code << encode(tkn)
when :function
funcname = node.left
obj = encode(funcname)
if !obj
translate(node.right, code)
elsif obj.is_a?(Array)
code << obj[0]
translate(node.right, code)
code << obj[1]
elsif obj.is_a?(Proc)
obj.call(self, node.right, code)
else
translate(node.right, code)
end
when '[]'
translate(node.left, code)
code << encode('[')
translate(node.right, code)
code << encode(']')
when '{}'
translate(node.left, code)
code << encode('{')
translate(node.right, code)
code << encode('}')
when '[:]'
translate(node.left, code)
code << encode('[:')
code << node.right
code << encode(':]')
when '.'
translate(node.left, code)
code << encode('.')
code << node.right
when '+', '-', '*', '/', '%', '^', '.+'
if node.right
_translate_child_expr(code, tkn, node.left)
code << encode(tkn)
_translate_child_expr(code, tkn, node.right)
else
code << encode('(')
code << encode(tkn)
_translate_child_expr(code, tkn, node.left)
code << encode(')')
end
when :empty, :notempty
op1, op2 = '==', '||'
op1, op2 = '!=', '&&' if tkn == :notempty
str_node = ExprNode.new(:string, '', nil)
null_node = ExprNode.new(:null, nil, nil)
l_node = ExprNode.new(op1, node.left, null_node)
r_node = ExprNode.new(op1, node.left, str_node)
node2 = ExprNode.new(op2, l_node, r_node)
code << encode('(')
translate_expr(node2, code, level)
code << encode(')')
when '==', '!=', '<', '<=', '>', '>='
_translate_child_expr(code, tkn, node.left)
code << encode(tkn)
_translate_child_expr(code, tkn, node.right)
when '.==', '.!=', '.<', '.<=', '.>', '.>='
_translate_child_expr(code, tkn, node.left)
code << encode(tkn)
_translate_child_expr(code, tkn, node.right)
when '=', '+=', '-=', '*=', '/=', '%=', '^=', '.+='
translate(node.left, code)
code << encode(tkn)
translate(node.right, code)
when '!'
code << encode(tkn)
_translate_child_expr(code, tkn, node.left)
when '?'
code << encode('(')
translate(node.condition, code)
code << encode('?')
translate(node.left, code)
code << encode(':')
translate(node.right, code)
code << encode(')')
when ','
_translate_child_expr(code, tkn, node.left)
code << encode(tkn)
_translate_child_expr(code, tkn, node.right)
when '&&', '||'
flag_l = tkn == '||' && node.left.token == '&&'
flag_r = tkn == '||' && node.right.token == '&&'
code << encode('(') if flag_l
_translate_child_expr(code, tkn, node.left)
code << encode(')') if flag_l
code << encode(tkn)
code << encode('(') if flag_r
_translate_child_expr(code, tkn, node.right)
code << encode(')') if flag_r
else
Kwartz::assert("node.token=#{node.token.inspect}")
end
return code
end