def compile_program(self, tree, module_prefix='', explicit_board=None):
        """Given an AST for a full program, compile it to virtual machine
code, returning an instance of gbs_vm.GbsCompiledProgram.
The Main module should be given the empty module prefix ''.
Every other module should be given the module name as a prefix.
"""
        if explicit_board is None:
            entrypoint_tree = def_helper.find_def(tree.children[2], def_helper.is_entrypoint_def)
            self.explicit_board = len(entrypoint_tree.children[2].children) != 0
        else:
            self.explicit_board = explicit_board
        self.module_handler = tree.module_handler
        self.compile_imported_modules(tree)

        imports = tree.children[1].children
        defs = tree.children[2]

        self.code = gbs_vm.GbsCompiledProgram(
                        tree, module_prefix=module_prefix)
        self.compile_imports(imports)
        self.user_defined_routine_names = list(self.code.external_routines.keys())
        self.user_defined_routine_names += def_helper.get_routine_names(defs)

        self.compile_defs(defs)

        return self.code
    def _explode_interactive(self, program_tree):
        """ Replaces interactive macro with it's implementation in the program tree """
        interactive = defhelper.find_def(program_tree.children[2], defhelper.is_interactive_def)
        if interactive != None:
            if self.explicit_board:
                macro_filename = "interactive_program.gbs"
            else:
                macro_filename = "interactive_program_implicit.gbs"
            implementation_program = self._load_implementation(macro_filename, ["lastKey", "read", "Show", "FreeVars"])
            if self.explicit_board:
                refParam = interactive.children[2].children[0].value
                defhelper.recursive_replace_token(implementation_program, "t", refParam)

            interactive_impl = defhelper.find_def(implementation_program.children[2], defhelper.is_entrypoint_def)
            interactive_impl_case = defhelper.recursive_find_node(interactive_impl, functools.partial(defhelper.is_node, 'case'))
            interactive_impl_case.children = [interactive_impl_case.children[0], interactive_impl_case.children[1]]
            interactive_impl_case.children.append(defhelper.get_def_body(interactive))
            defhelper.set_def_body(interactive, defhelper.get_def_body(interactive_impl))
            defhelper.set_def_token_name(interactive, 'program')
 def explode(self, program_tree):
     entrypoint_tree = defhelper.find_def(program_tree.children[2], defhelper.is_entrypoint_def)
     if not entrypoint_tree is None:
         self.explicit_board = len(entrypoint_tree.children[2].children) != 0
         """ Explodes program macros """
         self._explode_interactive(program_tree)