# Path: luna/objects.py
# class LuaValue(object):
# class LBoolean(LuaValue):
# class LNil(LuaValue):
# class LNumber(LuaValue):
# class LString(LuaValue):
# class LVar(LuaValue):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __iter__(self):
#     def __repr__(self):
#     def __init__(self, value):
#     def __hash__(self):
#     def __init__(self, value):
#     def __hash__(self):
#     def __init__(self, value):
#     def __hash__(self):
#     def __init__(self, value):
#     def __hash__(self):
# 
# Path: luna/ast/visitors.py
# class GenericVisitor(object):
#     def visit(self, node):
#         if isinstance(node, six.string_types):
#             return node
# 
#         clsname = node.__class__.__name__.lower()
#         method = getattr(self, 'visit_%s' % clsname, self.generic_visit)
# 
#         vc = [self.visit(c) for c in node]
#         return method(node, vc)
# 
#     def generic_visit(self, node, vc):
#         raise NotImplementedError
# 
# Path: luna/vm/opcodes.py
# class OpCode(object):
# class BinaryAdd(OpCode):
# class BinarySubtract(OpCode):
# class Call(OpCode):
# class LoadConst(OpCode):
# class LoadName(OpCode):
# class PopBlock(OpCode):
# class SetupDo(OpCode):
# class StoreName(OpCode):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __iter__(self):
#     def __repr__(self):
#     def __init__(self, index):
#     def __init__(self, index):
#     def __init__(self, index):
# 
# Path: luna/vm/frame.py
# class Frame(object):
#     def __init__(self, code, consts, vars):
#         self.code = code
#         self.consts = consts
#         self.vars = vars
# 
#         self.pc = 0
#         self.env = {}
#         self.stack = []
# 
#     def run(self):
#         while self.pc < len(self.code):
#             op = self.code[self.pc]
# 
#             if type(op) == ops.BinaryAdd:
#                 x = self.stack.pop()
#                 y = self.stack.pop()
#                 v = obj.LNumber(y.value + x.value)
#                 self.stack.append(v)
# 
#             elif type(op) == ops.BinarySubtract:
#                 x = self.stack.pop()
#                 y = self.stack.pop()
#                 v = obj.LNumber(y.value - x.value)
#                 self.stack.append(v)
# 
#             elif type(op) == ops.Call:
#                 func = self.stack.pop()
#                 arg = self.stack.pop()
#                 if type(arg) == obj.LVar:
#                     arg = self.env[arg]
#                 func(arg)
# 
#             elif type(op) == ops.LoadConst:
#                 self.stack.append(self.consts[op.index])
# 
#             elif type(op) == ops.LoadName:
#                 lvar = self.vars[op.index]
#                 value = self.env.get(lvar)
#                 if value is None:
#                     value = getattr(builtin, 'lua_' + lvar.value)
#                 self.stack.append(value)
# 
#             elif type(op) == ops.StoreName:
#                 var = self.vars[op.index]
#                 val = self.stack.pop()
#                 if type(val) == obj.LVar:
#                     val = self.env[val]
#                 self.env[var] = val
# 
#             self.pc += 1
# 
#         return self


from luna import objects as obj
from luna.ast.visitors import GenericVisitor
from luna.vm import opcodes as ops
from luna.vm.frame import Frame
            '-': ops.BinarySubtract,
        }

    def compile(self, node):
        self.visit(node)
        return Frame(self.code, self.consts, self.vars)

    def generic_visit(self, node, vc):
        return vc


    def add_const(self, luavalue):
        try:
            return self.consts.index(luavalue)
        except ValueError:
            self.consts.append(luavalue)
            return len(self.consts) - 1

    def add_var(self, luavalue):
        try:
            return self.vars.index(luavalue)
        except ValueError:
            self.vars.append(luavalue)
            return len(self.vars) - 1

    def emit(self, opcode):
        self.code.append(opcode)


    def add_operand(self, val):

# Path: luna/objects.py
# class LuaValue(object):
# class LBoolean(LuaValue):
# class LNil(LuaValue):
# class LNumber(LuaValue):
# class LString(LuaValue):
# class LVar(LuaValue):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __iter__(self):
#     def __repr__(self):
#     def __init__(self, value):
#     def __hash__(self):
#     def __init__(self, value):
#     def __hash__(self):
#     def __init__(self, value):
#     def __hash__(self):
#     def __init__(self, value):
#     def __hash__(self):
# 
# Path: luna/ast/visitors.py
# class GenericVisitor(object):
#     def visit(self, node):
#         if isinstance(node, six.string_types):
#             return node
# 
#         clsname = node.__class__.__name__.lower()
#         method = getattr(self, 'visit_%s' % clsname, self.generic_visit)
# 
#         vc = [self.visit(c) for c in node]
#         return method(node, vc)
# 
#     def generic_visit(self, node, vc):
#         raise NotImplementedError
# 
# Path: luna/vm/opcodes.py
# class OpCode(object):
# class BinaryAdd(OpCode):
# class BinarySubtract(OpCode):
# class Call(OpCode):
# class LoadConst(OpCode):
# class LoadName(OpCode):
# class PopBlock(OpCode):
# class SetupDo(OpCode):
# class StoreName(OpCode):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __iter__(self):
#     def __repr__(self):
#     def __init__(self, index):
#     def __init__(self, index):
#     def __init__(self, index):
# 
# Path: luna/vm/frame.py
# class Frame(object):
#     def __init__(self, code, consts, vars):
#         self.code = code
#         self.consts = consts
#         self.vars = vars
# 
#         self.pc = 0
#         self.env = {}
#         self.stack = []
# 
#     def run(self):
#         while self.pc < len(self.code):
#             op = self.code[self.pc]
# 
#             if type(op) == ops.BinaryAdd:
#                 x = self.stack.pop()
#                 y = self.stack.pop()
#                 v = obj.LNumber(y.value + x.value)
#                 self.stack.append(v)
# 
#             elif type(op) == ops.BinarySubtract:
#                 x = self.stack.pop()
#                 y = self.stack.pop()
#                 v = obj.LNumber(y.value - x.value)
#                 self.stack.append(v)
# 
#             elif type(op) == ops.Call:
#                 func = self.stack.pop()
#                 arg = self.stack.pop()
#                 if type(arg) == obj.LVar:
#                     arg = self.env[arg]
#                 func(arg)
# 
#             elif type(op) == ops.LoadConst:
#                 self.stack.append(self.consts[op.index])
# 
#             elif type(op) == ops.LoadName:
#                 lvar = self.vars[op.index]
#                 value = self.env.get(lvar)
#                 if value is None:
#                     value = getattr(builtin, 'lua_' + lvar.value)
#                 self.stack.append(value)
# 
#             elif type(op) == ops.StoreName:
#                 var = self.vars[op.index]
#                 val = self.stack.pop()
#                 if type(val) == obj.LVar:
#                     val = self.env[val]
#                 self.env[var] = val
# 
#             self.pc += 1
# 
#         return self


# Path: luna/compiler.py
from luna import objects as obj
from luna.ast.visitors import GenericVisitor
from luna.vm import opcodes as ops
from luna.vm.frame import Frame

            '-': ops.BinarySubtract,
        }

    def compile(self, node):
        self.visit(node)
        return Frame(self.code, self.consts, self.vars)

    def generic_visit(self, node, vc):
        return vc


    def add_const(self, luavalue):
        try:
            return self.consts.index(luavalue)
        except ValueError:
            self.consts.append(luavalue)
            return len(self.consts) - 1

    def add_var(self, luavalue):
        try:
            return self.vars.index(luavalue)
        except ValueError:
            self.vars.append(luavalue)
            return len(self.vars) - 1

    def emit(self, opcode):
        self.code.append(opcode)


    def add_operand(self, val):

        if type(val) == obj.LVar: