Skip to content
Snippets Groups Projects
Commit c0c5a6b6 authored by Aleksander Einarsen's avatar Aleksander Einarsen
Browse files

Made a new shorter version of the go compiler

parent f9d9fdf3
No related branches found
No related tags found
No related merge requests found
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())
}
}
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()
}
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")
}
})
}
}
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
\ No newline at end of file
// 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)
}
}
// 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
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment