diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | src/PythonIDE/run_windows.bat | 1 | ||||
| -rw-r--r-- | src/PythonIDE/src/esotericFORTRANIDE.py | 169 | ||||
| -rw-r--r-- | src/PythonIDE/src/fortranText.py | 20 | ||||
| -rw-r--r-- | src/PythonIDE/src/resultsPane.py | 45 | 
5 files changed, 237 insertions, 0 deletions
| @@ -3,6 +3,8 @@ src/.vscode/  src/build/  *.jar  src/IDE/.idea/ +src/PythonIDE/build/ +src/PythonIDE/src/__pycache__  *.class  code/simpleSableCCCalulator/sableCCCalculator/analysis/ diff --git a/src/PythonIDE/run_windows.bat b/src/PythonIDE/run_windows.bat new file mode 100644 index 0000000..c021b1f --- /dev/null +++ b/src/PythonIDE/run_windows.bat @@ -0,0 +1 @@ +python .\src\esotericFORTRANIDE.py ..\esotericFORTRAN.jar diff --git a/src/PythonIDE/src/esotericFORTRANIDE.py b/src/PythonIDE/src/esotericFORTRANIDE.py new file mode 100644 index 0000000..4270a35 --- /dev/null +++ b/src/PythonIDE/src/esotericFORTRANIDE.py @@ -0,0 +1,169 @@ +import tkinter as tk +from tkinter import ttk +from tkinter import filedialog as filedialogue +from tkinter import messagebox +import datetime +import subprocess +import fortranText +import resultsPane +import shutil +import sys +import os + +class Application(tk.Tk): + +    def __init__(self, program_jar, current_file = "unsaved program", *args, **kwargs): +        super().__init__(*args, **kwargs) +        self.title("esotericFORTRAN IDE - %s" % current_file) +        self.program_jar = program_jar +        self.current_file = current_file + +        # setup menubar +        self.menu = ApplicationMenu(self) +        self.config(menu = self.menu) + +        # add widgets +        self.mainpain = ttk.PanedWindow(self, orient = tk.HORIZONTAL) +        self.mainpain.pack(fill = tk.BOTH, expand = True, side = tk.TOP) + +        self.fortran_frame = fortranText.FortranText(self) +        self.mainpain.add(self.fortran_frame) + +        self.results_pane = resultsPane.ResultsPane(self) +        self.mainpain.add(self.results_pane) + +        # set up bindings etc +        self.bind('<Control-n>', lambda a: self.new_file()) +        self.bind('<Control-o>', lambda a: self.open_file()) +        self.bind('<Control-s>', lambda a: self.save_file()) +        self.bind('<Control-S>', lambda a: self.save_file_as()) +        self.bind('<F5>', lambda a: self.execute()) +        self.protocol("WM_DELETE_WINDOW", self.exit) + +    def new_file(self): +        print("new file") + +    def open_file(self): +        dia = filedialogue.askopenfilename( +            initialdir = self.__get_initial_dir(), +            filetypes = (("FORTRAN Files", ".ft"), ("Text Files", ".txt"), ("All files", "*.*")) +        ) +        if os.path.exists(dia): +            self.current_file = dia +            self.title("esotericFORTRAN IDE - %s" % str(dia)) + +            with open(dia, "r") as f: +                self.fortran_frame.replace_text_with("".join(f.readlines())) + +    def save_file(self): +        if self.current_file == "unsaved program": +            self.save_file_as() +        else: +            with open(self.current_file, "w") as f: +                f.write(self.fortran_frame.get_text()) + +    def save_file_as(self): +        print("save file as") + +    def exit(self): +        print("exit") +        exit() + +    def execute(self): +        if self.current_file == "unsaved program": +            messagebox.showwarning("Error",  "You need to make a file before it can be executed") +            return + +        with open(self.current_file, "r") as f: +            unsaved_version = "".join(f.readlines()) +         +        if unsaved_version != self.fortran_frame.get_text(): +            if messagebox.askyesno("Save?", "You need to save before executing. Save now?"): +                self.save_file() +            else: +                return + +        if os.path.exists("build"): +            shutil.rmtree("build") + +        self.results_pane.clear_c_code() +        proc = subprocess.Popen(["java", "-jar", self.program_jar, self.current_file, "-c", "-e"], stdout=subprocess.PIPE) +        while True: +            line = proc.stdout.readline() +            if not line: +                break +            self.results_pane.append_results_line(line.rstrip().decode()) + +        if os.path.exists("build"): +            self.results_pane.append_results_line("Build Completed %s\n" % str(datetime.datetime.now())) +            for file_ in os.listdir("build"): +                if os.path.splitext(file_)[1] == ".c": +                    c_file_path = os.path.join(os.getcwd(), "build", file_) +                    with open(c_file_path, "r") as f: +                        self.results_pane.write_c_code("".join(f.readlines())) +                     +                    return + +        else: +            self.results_pane.append_results_line("Build Failed %s\n" % str(datetime.datetime.now())) + +         + + +    def __get_initial_dir(self): +        examples_path = os.path.join("..", "examples") +        if not os.path.exists(examples_path): +            return os.path.expanduser("~") +        return examples_path + + +class ApplicationMenu(tk.Menu): +    def __init__(self, parent, *args, **kwargs): +        super().__init__(parent, *args, **kwargs) +        self.parent = parent + +        self.file_menu = tk.Menu(self, tearoff = 0) +        self.add_cascade(label = "File", menu = self.file_menu) +        self.file_menu.add_command( +            label = "New FORTRAN file",  +            accelerator = "Ctrl+N", +            command = self.parent.new_file +        ) +        self.file_menu.add_command( +            label = "Open FORTRAN file...",  +            accelerator = "Ctrl+O", +            command = self.parent.open_file +        ) +        self.file_menu.add_separator() +        self.file_menu.add_command( +            label = "Save",  +            accelerator = "Ctrl+S", +            command = self.parent.save_file +        ) +        self.file_menu.add_command( +            label = "Save As...",  +            accelerator = "Ctrl+Shift+S", +            command = self.parent.save_file_as +        ) +        self.file_menu.add_separator() +        self.file_menu.add_command( +            label = "Exit",  +            accelerator = "Alt+F4", +            command = self.parent.exit +        ) + +        self.run_menu = tk.Menu(self, tearoff = 0) +        self.add_cascade(label = "Run", menu = self.run_menu) +        self.run_menu.add_command( +            label = "Execute file",  +            accelerator = "F5", +            command = self.parent.execute +        ) + +if __name__ == "__main__":  +    try: +        app = Application(sys.argv[1]) +        app.mainloop()   +    except IndexError: +        print("You need to specify the path to the .jar as the first argument") +         diff --git a/src/PythonIDE/src/fortranText.py b/src/PythonIDE/src/fortranText.py new file mode 100644 index 0000000..381b41a --- /dev/null +++ b/src/PythonIDE/src/fortranText.py @@ -0,0 +1,20 @@ +import tkinter as tk +from tkinter import ttk +from tkinter.scrolledtext import ScrolledText + +class FortranText(tk.Frame): +    def __init__(self, parent, *args, **kwargs): +        super().__init__(parent, *args, **kwargs) +        self.parent = parent + +        tk.Label(self, text = "FORTRAN Code:").pack(fill = tk.X) +        self.txt_fortran = ScrolledText(self) +        self.txt_fortran.pack(fill = tk.BOTH, expand = True) + +    def replace_text_with(self, newtext): +        self.txt_fortran.delete(0.0, tk.END) +        self.txt_fortran.insert(tk.END, newtext) + +    def get_text(self): +        return self.txt_fortran.get(0.0, tk.END).rstrip() + diff --git a/src/PythonIDE/src/resultsPane.py b/src/PythonIDE/src/resultsPane.py new file mode 100644 index 0000000..0e37cbc --- /dev/null +++ b/src/PythonIDE/src/resultsPane.py @@ -0,0 +1,45 @@ +import tkinter as tk +from tkinter import ttk +from tkinter.scrolledtext import ScrolledText + +class ResultsPane(tk.Frame): +    def __init__(self, parent, *args, **kwargs): +        super().__init__(parent, *args, **kwargs) +        self.parent = parent + +        ttk.Separator(self, orient = tk.VERTICAL).pack(fill = tk.Y, pady = 3, side = tk.LEFT) + +        self.right_pane = ttk.PanedWindow(self, orient = tk.VERTICAL) +        self.right_pane.pack(fill = tk.BOTH, expand = True) + +        frm_c_code = tk.Frame(self) +        tk.Label(frm_c_code, text = "Produced C Code:").pack(fill = tk.X) +        self.txt_c_code = ScrolledText(frm_c_code) +        self.txt_c_code.pack(fill = tk.BOTH, expand = True) +        self.right_pane.add(frm_c_code) + +        frm_results = tk.Frame(self) +        ttk.Separator(frm_results, orient = tk.HORIZONTAL).pack(fill = tk.X, padx = 3) +        tk.Label(frm_results, text = "Results:").pack(fill = tk.X) +        self.txt_results = ScrolledText(frm_results) +        self.txt_results.pack(fill = tk.BOTH, expand = True) +        self.right_pane.add(frm_results) + +        self.txt_c_code.configure(state = tk.DISABLED) +        self.txt_results.configure(state = tk.DISABLED) + +    def append_results_line(self, line): +        self.txt_results.configure(state = tk.NORMAL) +        self.txt_results.insert(tk.END, line + "\n") +        self.txt_results.see(tk.END) +        self.txt_results.configure(state = tk.DISABLED) + +    def clear_c_code(self): +        self.txt_c_code.configure(state = tk.NORMAL) +        self.txt_c_code.delete(0.0, tk.END) +        self.txt_c_code.configure(state = tk.DISABLED) + +    def write_c_code(self, c_code): +        self.txt_c_code.configure(state = tk.NORMAL) +        self.txt_c_code.insert(tk.END, c_code) +        self.txt_c_code.configure(state = tk.DISABLED)
\ No newline at end of file | 
