package main
import (
"bufio"
"errors"
"fmt"
"os"
"os/exec"
"runtime"
)
var (
dirSeparator string = "/"
tempDir string
)
func init() {
if runtime.GOOS == "windows" {
dirSeparator = "\\"
}
tempDir = os.TempDir() + dirSeparator + "goeval"
os.Mkdir(tempDir, os.ModePerm)
}
func main() {
result, err := eval(`println(math.Floor(1234))`, "math")
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(result)
}
func eval(code string, imports ...string) (result string, err error) {
tmpfile, err := os.Create(tempDir + dirSeparator + "temp.go")
if err != nil {
return "", err
}
w := bufio.NewWriter(tmpfile)
w.WriteString("package main\r\n")
w.WriteString("\r\n")
if len(imports) > 0 {
tmpArgs := []string{"get"}
tmpArgs = append(tmpArgs, imports...)
goget := exec.Command("go", tmpArgs...)
_, err = goget.Output()
if err != nil {
return "", err
}
w.WriteString("import (\r\n")
for _, v := range imports {
w.WriteString("\t" + `"` + v + `"` + "\r\n")
}
w.WriteString(")\r\n")
w.WriteString("\r\n")
}
w.WriteString("func main() {\r\n")
w.WriteString("\t" + code + "\r\n")
w.WriteString("}\r\n")
w.Flush()
tmpfile.Close()
cmd := exec.Command("go", "run", tmpfile.Name())
res, err := cmd.CombinedOutput()
if err != nil {
return "", errors.New(string(res) + err.Error())
}
os.Remove(tmpfile.Name())
return string(res), nil
}