ソースを参照

support multiple languages

python initially, because @KLINGTdotNET.
Lucas Stadler 11 年 前
コミット
962bab9c58
共有1 個のファイルを変更した50 個の追加22 個の削除を含む
  1. 50 22
      go/linguaevalia/linguaevalia.go

+ 50 - 22
go/linguaevalia/linguaevalia.go

@ -15,34 +15,24 @@ import (
15 15
)
16 16
17 17
type Language interface {
18
	Eval(code string) (result []byte, err error)
18
	RunFile(f *os.File) (result []byte, err error)
19
	Extension() string
19 20
}
20 21
21 22
type LanguageGo struct{}
23
type LanguagePython struct{}
22 24
23 25
var Go = LanguageGo{}
26
var Python = LanguagePython{}
24 27
25
func (g LanguageGo) Eval(code string) ([]byte, error) {
26
	// write code to temp file
27
	f, err := writeCode(code)
28
	defer f.Close()
29
	if err != nil {
30
		return nil, err
31
	}
32
	// `go run` it
33
	res, err := runCode(f)
34
	if err != nil {
35
		return res, err
36
	}
37
	// remove the file
38
	os.Remove(f.Name())
39
	// return output
40
	return res, nil
28
var languageMappings = map[string]Language{
29
	"go":     Go,
30
	"python": Python,
41 31
}
42 32
43
func writeCode(code string) (*os.File, error) {
33
func writeCode(code string, extension string) (*os.File, error) {
44 34
	// create tmp file
45
	f, err := os.Create("/tmp/linguaevalia-go.go") // FIXME: actually create a tmpfile
35
	f, err := os.Create(fmt.Sprintf("/tmp/linguaevalia-%s.%s", extension, extension)) // FIXME: actually create a tmpfile
46 36
	if err != nil {
47 37
		return f, err
48 38
	}
@ -54,19 +44,46 @@ func writeCode(code string) (*os.File, error) {
54 44
	return f, nil
55 45
}
56 46
57
func runCode(f *os.File) ([]byte, error) {
47
func (l LanguageGo) RunFile(f *os.File) ([]byte, error) {
58 48
	cmd := exec.Command("go", "run", f.Name())
59 49
	return cmd.CombinedOutput()
60 50
}
61 51
52
func (l LanguageGo) Extension() string { return "go" }
53
54
func (l LanguagePython) RunFile(f *os.File) ([]byte, error) {
55
	cmd := exec.Command("python", f.Name())
56
	return cmd.CombinedOutput()
57
}
58
59
func (l LanguagePython) Extension() string { return "py" }
60
61
func Eval(lang Language, code string) ([]byte, error) {
62
	// write code to temp file
63
	f, err := writeCode(code, lang.Extension())
64
	defer f.Close()
65
	if err != nil {
66
		return nil, err
67
	}
68
	// `go run` it
69
	res, err := lang.RunFile(f)
70
	if err != nil {
71
		return res, err
72
	}
73
	// remove the file
74
	os.Remove(f.Name())
75
	// return output
76
	return res, nil
77
}
78
62 79
func runCodeHandler(w http.ResponseWriter, r *http.Request) {
63 80
	code, err := ioutil.ReadAll(r.Body)
64 81
	if err != nil {
65 82
		http.Error(w, err.Error(), http.StatusBadRequest)
66 83
		return
67 84
	}
68
	//fmt.Println(string(code))
69
	res, err := Go.Eval(string(code))
85
	lang := getLanguage(r)
86
	res, err := Eval(lang, string(code))
70 87
	if err != nil {
71 88
		http.Error(w, string(res), http.StatusNotAcceptable)
72 89
		return
@ -74,6 +91,17 @@ func runCodeHandler(w http.ResponseWriter, r *http.Request) {
74 91
	w.Write(res)
75 92
}
76 93
94
func getLanguage(r *http.Request) Language {
95
	langName := r.URL.Query().Get("language")
96
	if langName != "" {
97
		lang, ok := languageMappings[langName]
98
		if ok {
99
			return lang
100
		}
101
	}
102
	return Go
103
}
104
77 105
func homePageHandler(w http.ResponseWriter, r *http.Request) {
78 106
	homePageTemplate.Execute(w, nil)
79 107
}