translators-will/SyntaxShift
6
1# Gradio UI2import re3import gradio as gr4import tempfile5import os6from openai import OpenAI7from dotenv import load_dotenv8import subprocess9import shutil10from timeit import default_timer as timer11 12def install_rust():13 subprocess.run("curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y", shell=True)14 subprocess.run("source $HOME/.cargo/env", shell=True)15 16install_rust()17 18# Load environment variables19 20os.environ['PATH'] += f':{os.path.expanduser("~/.cargo/bin")}'21 22load_dotenv()23os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')24OPENAI_MODEL = "gpt-4o"25 26# TranslateCode and ExecuteCode class implementations27 28class TranslateCode:29 def __init__(self, openai_client, model):30 self.openai = openai_client31 self.model = model32 33 def user_prompt_for(self, python, lang_select):34 user_prompt = f"Rewrite this Python code in {lang_select} with the fastest possible implementation that produces identical output in the least time. "35 user_prompt += f"Respond only with {lang_select} code; do not explain your work; only return {lang_select} code. "36 user_prompt += "Pay attention to number types to ensure no int overflows. Remember to include all necessary dependencies and libraries.\n\n"37 user_prompt += "If translating to Rust, make sure to include the necessary packages and crates."38 user_prompt += python39 return user_prompt40 41 def messages_for(self, python, lang_select):42 # System message for OpenAI API43 system_message = "You are an assistant that reimplements Python code in high performance code for a Windows PC. "44 system_message += "Respond only with code; do not provide any explanations. "45 system_message += "The response needs to produce an identical output in the fastest possible time."46 47 return [48 {"role": "system", "content": system_message},49 {"role": "user", "content": self.user_prompt_for(python, lang_select)}50 ]51 52 def translate_code(self, code_file, lang_select):53 stream = self.openai.chat.completions.create(model=self.model, messages=self.messages_for(code_file, lang_select), stream=True)54 code = ""55 for chunk in stream:56 fragment = chunk.choices[0].delta.content or ""57 code += fragment58 pattern = r"```(c|cpp|rust|javascript)\n"59 code = re.sub(pattern, "", code).replace("```", "")60 return code61 62 63class ExecuteCode:64 def __init__(self, translator):65 self.translator = translator66 67 def extract_dependencies(self, code):68 try:69 dependency_pattern = r"""70 (?:use\s+(?!std::)[a-zA-Z_][a-zA-Z0-9_]*::|extern\s+crate\s+(?!std)[a-zA-Z_][a-zA-Z0-9_]*);?71 |72 \#include\s*<([a-zA-Z_][a-zA-Z0-9_/.]*)>73 |74 (?:import\s+.*\s+from\s+['"]([a-zA-Z_][a-zA-Z0-9_/.]*)['"]75 |require\s*\(\s*['"]([a-zA-Z_][a-zA-Z0-9_/.]*)['"]\s*\))76 """77 matches = re.findall(dependency_pattern, code, re.VERBOSE)78 dependencies = [match for match in matches if any(match)]79 return dependencies if matches else []80 except re.error as e:81 raise ValueError(f"Regex error while extracting dependencies: {e}")82 83 def execute_code(self, code_file, lang_select):84 if lang_select == "Rust":85 rust_code = self.translator.translate_code(code_file, lang_select)86 try:87 dependencies = self.extract_dependencies(rust_code)88 temp_dir = tempfile.mkdtemp()89 src_dir = os.path.join(temp_dir, "src")90 os.makedirs(src_dir, exist_ok=True)91 cargo_toml = f"""92 [package]93 name = "temp_project"94 version = "0.1.0"95 edition = "2021"96 97 [dependencies]98 """99 for dependency in dependencies:100 crate = dependency[0]101 cargo_toml += f"{crate} = \"*\"\n"102 with open(os.path.join(temp_dir, "Cargo.toml"), "w") as f:103 f.write(cargo_toml)104 main_rs_path = os.path.join(src_dir, "main.rs")105 with open(main_rs_path, "w", encoding="utf-8") as f:106 f.write(rust_code)107 cargo_build = subprocess.run(["cargo", "build", "--release"],108 cwd=temp_dir,109 stdout=subprocess.PIPE,110 stderr=subprocess.PIPE,111 text=True)112 if cargo_build.returncode != 0:113 return f"Cargo build failed:\n{cargo_build.stderr}", 0114 executable_path = os.path.join(temp_dir, "target", "release", "temp_project")115 start_time = timer()116 run_result = subprocess.run([executable_path],117 stdout=subprocess.PIPE,118 stderr=subprocess.PIPE,119 text=True)120 end_time = timer()121 execution_time = end_time - start_time122 if run_result.returncode != 0:123 print(f"Execution failed: {run_result.stderr}")124 return run_result.stdout, execution_time125 finally:126 if temp_dir:127 shutil.rmtree(temp_dir, ignore_errors=True)128 elif lang_select in ["C", "C++"]:129 code = self.translator.translate_code(code_file, lang_select)130 with tempfile.TemporaryDirectory() as temp_dir:131 file_extension = "c" if lang_select == "C" else "cpp"132 file_path = os.path.join(temp_dir, f"translated_code.{file_extension}")133 with open(file_path, "w") as f:134 f.write(code)135 executable_path = os.path.join(temp_dir, "translated_code")136 compiler = "gcc" if lang_select == "C" else "g++"137 compile_result = subprocess.run([compiler, file_path, "-o", executable_path],138 stdout=subprocess.PIPE,139 stderr=subprocess.PIPE,140 text=True)141 if compile_result.returncode != 0:142 return f"Compilation failed:\n{compile_result.stderr}", 0143 start_time = timer()144 run_result = subprocess.run([executable_path],145 stdout=subprocess.PIPE,146 stderr=subprocess.PIPE,147 text=True)148 end_time = timer()149 execution_time = end_time - start_time150 return run_result.stdout, execution_time151 elif lang_select == "Javascript":152 js_code = self.translator.translate_code(code_file, lang_select)153 with tempfile.NamedTemporaryFile(suffix='.js', delete=False) as js_file:154 js_file.write(js_code.encode("utf-8"))155 js_file.flush()156 js_file_path = js_file.name157 try:158 start_time = timer()159 run_result = subprocess.run(["node", js_file_path],160 stdout=subprocess.PIPE,161 stderr=subprocess.PIPE,162 text=True)163 end_time = timer()164 execution_time = end_time - start_time165 return run_result.stdout, execution_time166 finally:167 os.remove(js_file_path)168 else:169 return "Language not supported", 0170 171 172def process_code(python_code: str, target_language: str):173 """Process the uploaded Python code and return both original and translated outputs"""174 # Initialize components175 openai_client = OpenAI()176 translator = TranslateCode(openai_client, OPENAI_MODEL)177 executor = ExecuteCode(translator)178 179 # Run Python code180 python_output = ""181 python_time = 0182 try:183 with tempfile.NamedTemporaryFile(delete=False, suffix=".py") as temp_py_file:184 temp_py_file.write(python_code.encode('utf-8'))185 temp_py_file_path = temp_py_file.name186 187 start_time = timer()188 result = subprocess.run(["python", temp_py_file_path], 189 capture_output=True, 190 text=True)191 end_time = timer()192 193 python_output = result.stdout if result.returncode == 0 else result.stderr194 python_time = end_time - start_time195 except Exception as e:196 python_output = str(e)197 finally:198 if 'temp_py_file_path' in locals() and os.path.exists(temp_py_file_path):199 os.remove(temp_py_file_path)200 201 # Translate and run the code202 translated_code = translator.translate_code(python_code, target_language)203 translated_output, translated_time = executor.execute_code(translated_code, target_language)204 205 # Format the outputs206 python_output = python_output.replace("Â", "")207 translated_output = translated_output.replace("Â", "")208 python_result = f"Output:\n{python_output}\nExecution time: {python_time:.4f} seconds"209 translated_result = f"Output:\n{translated_output}\nExecution time: {translated_time:.4f} seconds"210 211 return python_code, translated_code, python_result, translated_result212 213def create_gradio_interface():214 with gr.Blocks(title="SyntaxShift: Code Translator") as interface:215 gr.Markdown("# SyntaxShift: Code Translator")216 gr.Markdown("It's like Google Translate, but for code. Upload a Python file or paste Python code to translate it to C, C++, Rust, or Javascript, and run the code.")217 218 with gr.Row():219 with gr.Column():220 python_code = gr.Code(221 label="Python Code",222 language="python",223 lines=20224 )225 target_language = gr.Dropdown(226 choices=["C", "C++", "Rust", "Javascript"],227 label="Target Language",228 value="C"229 )230 translate_button = gr.Button("Translate and Run")231 232 with gr.Row():233 with gr.Column():234 translated_code = gr.Code(235 label="Translated Code",236 language="python", # This will update dynamically237 lines=20238 )239 240 with gr.Row():241 with gr.Column():242 python_output = gr.Textbox(243 label="Python Execution Result",244 lines=5245 )246 with gr.Column():247 translated_output = gr.Textbox(248 label="Translated Code Execution Result",249 lines=5250 )251 252 # Update language display based on selection253 def update_language(lang):254 lang_map = {255 "C": "c",256 "C++": "cpp",257 "Rust": "rust",258 "Javascript": "javascript"259 }260 return {"language": lang_map[lang]}261 262 target_language.change(263 fn=update_language,264 inputs=[target_language],265 outputs=[translated_code]266 )267 268 # Main translation and execution flow269 translate_button.click(270 fn=process_code,271 inputs=[python_code, target_language],272 outputs=[python_code, translated_code, python_output, translated_output]273 )274 275 return interface276 277if __name__ == "__main__":278 demo = create_gradio_interface()279 demo.launch()