From c0c5a6b6dc85ab415ba9ea99f5d7408f5c8d4fe2 Mon Sep 17 00:00:00 2001 From: Aleksander Einarsen <aleksace@stud.ntnu.no> Date: Wed, 9 Oct 2024 19:29:54 +0200 Subject: [PATCH] Made a new shorter version of the go compiler --- modules/compiler_V2/compiler2.go | 82 +++++++++++++++++++ .../compiler_V2/go-compiler2/go_compiler.go | 46 +++++++++++ .../go-compiler2/go_compiler_test.go | 52 ++++++++++++ .../compiler_V2/go-compiler2/should_compile | 7 ++ .../should_compile_with_external_dependencies | 37 +++++++++ ...compile_with_standard_library_dependencies | 19 +++++ .../go-compiler2/should_not_compile | 8 ++ 7 files changed, 251 insertions(+) create mode 100644 modules/compiler_V2/go-compiler2/go_compiler.go create mode 100644 modules/compiler_V2/go-compiler2/go_compiler_test.go create mode 100644 modules/compiler_V2/go-compiler2/should_compile create mode 100644 modules/compiler_V2/go-compiler2/should_compile_with_external_dependencies create mode 100644 modules/compiler_V2/go-compiler2/should_compile_with_standard_library_dependencies create mode 100644 modules/compiler_V2/go-compiler2/should_not_compile diff --git a/modules/compiler_V2/compiler2.go b/modules/compiler_V2/compiler2.go index b42f93f..bf28ce0 100644 --- a/modules/compiler_V2/compiler2.go +++ b/modules/compiler_V2/compiler2.go @@ -1 +1,83 @@ package compiler_V2 + +import ( + "os" + "os/exec" +) + +type LanguageData struct { + Name Language + FileSuffix string // Like .go or .rs +} + +type Language string + +const ( + Go Language = "go" + Rust Language = "rust" +) + +type OS string + +const ( + Windows OS = "windows" + Linux OS = "linux" + MacOS OS = "darwin" +) + +type SourceCode string +type Dependencies []string + +type Compiler struct { + OS OS + Language Language + Dependencies Dependencies +} + +type GoCompilerCmd struct { + cmd string +} + +type ICompiler interface { + CheckCompileErrors(srcCode []byte) ([]byte, error) +} + +//func NewCompiler(os OS, language Language) ICompiler { +// switch language { +// case Go: +// return NewGoCompiler(os) +// case Rust: +// //return RustCompiler{}.New(os) +// panic("Rust compiler not implemented") +// default: +// return nil +// } +//} + +func MakeCommand(OS OS, cmd string) *exec.Cmd { + switch OS { + case Windows: + return exec.Command("cmd", "/c", cmd) + case Linux, MacOS: + return exec.Command("bash", "-c", cmd) + default: + panic("Unsupported OS") + } +} + +// SetupTempFolders creates the temp output directory for compiled files, panics if it fails +func SetupTempFolders(tempOutputDir string) { + // 0777 are the permissions for the directory, everyone can read, write and execute + err := os.MkdirAll(tempOutputDir, os.ModePerm) + if err != nil { + panic("Error creating temp output directory:\n\n" + err.Error()) + } +} + +// RemoveTempFolders removes the temp output directory for compiled files, panics if it fails +func RemoveTempFolders(tempOutputDir string) { + err := os.RemoveAll(tempOutputDir) + if err != nil { + panic("Error removing temp output directory:\n\n" + err.Error()) + } +} diff --git a/modules/compiler_V2/go-compiler2/go_compiler.go b/modules/compiler_V2/go-compiler2/go_compiler.go new file mode 100644 index 0000000..4494e22 --- /dev/null +++ b/modules/compiler_V2/go-compiler2/go_compiler.go @@ -0,0 +1,46 @@ +package go_compiler2 + +import ( + c2 "compiler_V2" + "os" +) + +type GoCompiler struct { + c2.Compiler +} + +const TempOutputDir = "tempOutput/" +const fileName = "main.go" + +func NewGoCompiler(OS c2.OS) *GoCompiler { + return &GoCompiler{ + Compiler: c2.Compiler{ + OS: OS, + Language: c2.Go, + Dependencies: nil, + }, + } +} + +func (gb *GoCompiler) CheckCompileErrors(srcCode []byte) ([]byte, error) { + // Make temp folders + + c2.SetupTempFolders(TempOutputDir) + defer c2.RemoveTempFolders(TempOutputDir) + + // Write code to file + err := os.WriteFile(TempOutputDir+fileName, srcCode, 0644) + if err != nil { + return nil, err + } + // Init go mod and tidy + cmdString := "go mod init tempOutput && go mod tidy " + + // Run go build + cmdString += " && go build -o main " + fileName + + //cmdSlice := strings.Fields(cmdString) + cmd := c2.MakeCommand(gb.OS, cmdString) + cmd.Dir = TempOutputDir + return cmd.CombinedOutput() +} diff --git a/modules/compiler_V2/go-compiler2/go_compiler_test.go b/modules/compiler_V2/go-compiler2/go_compiler_test.go new file mode 100644 index 0000000..3d6c57f --- /dev/null +++ b/modules/compiler_V2/go-compiler2/go_compiler_test.go @@ -0,0 +1,52 @@ +package go_compiler2 + +import ( + c2 "compiler_V2" + "os" + "testing" +) + +func TestCompileStringToGo(t *testing.T) { + + tests := []struct { + filename string + shouldCompile bool + }{ + { + filename: "should_compile", + shouldCompile: true, + }, + { + filename: "should_not_compile", + shouldCompile: false, + }, + { + filename: "should_compile_with_standard_library_dependencies", + shouldCompile: true, + }, + { + filename: "should_compile_with_external_dependencies", + shouldCompile: true, + }, + } + + for _, test := range tests { + t.Run(test.filename, func(t *testing.T) { + // Read the code from the file + code, err := os.ReadFile(test.filename) + + output, err := NewGoCompiler(c2.Windows).CheckCompileErrors(code) + + if err != nil && test.shouldCompile { + t.Errorf("Expected the code to compile, but got an error: %v", err) + } else if err == nil && !test.shouldCompile { + t.Errorf("Expected the code to not compile, but got no error") + } + + // Check if the output is empty when the code shouldn't compile + if output == nil && !test.shouldCompile { + t.Errorf("Expected compiler error output, but got none") + } + }) + } +} diff --git a/modules/compiler_V2/go-compiler2/should_compile b/modules/compiler_V2/go-compiler2/should_compile new file mode 100644 index 0000000..2d35af1 --- /dev/null +++ b/modules/compiler_V2/go-compiler2/should_compile @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello, World!") +} \ No newline at end of file diff --git a/modules/compiler_V2/go-compiler2/should_compile_with_external_dependencies b/modules/compiler_V2/go-compiler2/should_compile_with_external_dependencies new file mode 100644 index 0000000..3a047ae --- /dev/null +++ b/modules/compiler_V2/go-compiler2/should_compile_with_external_dependencies @@ -0,0 +1,37 @@ +// These are dependencies that are **NOT** part of the standard library +package main + +import ( + "fmt" + "golang.org/x/net/http2" + "golang.org/x/crypto/bcrypt" + "net/http" +) + +func main() { + // Setting up a simple HTTP/2 server + srv := &http.Server{ + Addr: ":8080", + } + + // Register a simple handler + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // Hashing a password + password := "mysecretpassword" + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + http.Error(w, "Could not hash password", http.StatusInternalServerError) + return + } + fmt.Fprintf(w, "Hashed Password: %s\n", hashedPassword) + }) + + // Enable HTTP/2 + http2.ConfigureServer(srv, nil) + + // Start the server + fmt.Println("Starting server on https://localhost:8080") + if err := srv.ListenAndServeTLS("server.crt", "server.key"); err != nil { + fmt.Println("Error starting server:", err) + } +} diff --git a/modules/compiler_V2/go-compiler2/should_compile_with_standard_library_dependencies b/modules/compiler_V2/go-compiler2/should_compile_with_standard_library_dependencies new file mode 100644 index 0000000..7134eea --- /dev/null +++ b/modules/compiler_V2/go-compiler2/should_compile_with_standard_library_dependencies @@ -0,0 +1,19 @@ +// These are dependencies that are part of the standard library +package main + +import ( + "fmt" + "math/rand" + "time" +) + +func main() { + // Seed the random number generator + rand.Seed(time.Now().UnixNano()) + + // Generate a random number between 1 and 100 + randomNum := rand.Intn(100) + 1 // rand.Intn(100) generates a number from 0 to 99 + + // Print the random number + fmt.Println("Random Number:", randomNum) +} \ No newline at end of file diff --git a/modules/compiler_V2/go-compiler2/should_not_compile b/modules/compiler_V2/go-compiler2/should_not_compile new file mode 100644 index 0000000..8c5b2be --- /dev/null +++ b/modules/compiler_V2/go-compiler2/should_not_compile @@ -0,0 +1,8 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello, World!") + } +} \ No newline at end of file -- GitLab