public function compile(CompilerConfig $config) : Compiler
    {
        $cache_dir = $config->getCacheDir();
        
        if (!$cache_dir){
            throw new CacheDirectoryConfigurationException($cache_dir);
        }
        
        // cehck cache dir
        $cache_dir = new File($cache_dir);
        
        if (!$cache_dir->exists() || !$cache_dir->isDirectory()){
            throw new CacheDirectoryNotFoundException($cache_dir);
        }
        if (!$cache_dir->canWrite()){
            throw new CacheDirectoryNotWritableException($cache_dir);
        }
        
        // check bootstrap
        $cache_filename = $config->getCacheFilename();
        $bootstrap_file = new File($cache_filename . '.php', $cache_dir);
        
        if (!$bootstrap_file->exists()){
            // compile bootstrap code
            $contents = $this->generateBootstrapCode($config);
            $bootstrap_file->putContents($contents);
        }
        
        return $this;
    }