Skip to content

Instantly share code, notes, and snippets.

@yoppi
Last active December 30, 2015 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoppi/7853138 to your computer and use it in GitHub Desktop.
Save yoppi/7853138 to your computer and use it in GitHub Desktop.
Ottoを使った計算機
package main
import (
"bufio"
"fmt"
"github.com/robertkrimen/otto"
"io/ioutil"
"os"
"regexp"
"strconv"
"strings"
)
type Calculator struct {
Operators map[string]func(int, int) int
Parser *regexp.Regexp
}
func (c *Calculator) Run() {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print(c.Prompt())
input, _ := reader.ReadString('\n')
if len(input) > 0 {
if strings.HasPrefix(input, "load ") {
var cmd, file string
fmt.Sscanf(input, "%s %s", &cmd, &file)
c.LoadScript(file)
continue
}
tokens := c.Parser.FindStringSubmatch(input)
if len(tokens) < 4 { continue }
x, _ := strconv.Atoi(tokens[1])
operator := tokens[2]
y, _ := strconv.Atoi(tokens[3])
if f, ok := c.Operators[operator]; ok {
fmt.Println(f(x, y))
}
}
}
}
func (c *Calculator) AddOperator(operator string, f func(int, int) int) {
c.Operators[operator] = f
}
func (c *Calculator) LoadScript(file string) {
Otto := otto.New()
buffer, _ := ioutil.ReadFile(file)
Otto.Run(string(buffer))
_operator, _ := Otto.Get("operator")
operator, _ := _operator.ToString()
script, _:= Otto.Get("script")
c.AddOperator(operator, func(x, y int) int {
_ret, _ := script.Call(script, x, y)
ret, _ := _ret.ToInteger()
return int(ret)
})
}
func (c *Calculator) Prompt() string {
keys := make([]string, len(c.Operators))
i := 0
for k, _ := range c.Operators {
keys[i] = k
i++
}
return strings.Join(keys, "") + "> "
}
func NewCalculator() *Calculator {
operators := map[string]func(int, int)int {
"+": func(x, y int) int {
return x + y
},
"-": func(x, y int) int {
return x - y
},
"*": func(x, y int) int {
return x * y
},
"/": func(x, y int) int {
return x / y
},
}
parser := regexp.MustCompile(`(\d+)\s*(\W)\s*(\d+)\n`)
return &Calculator{operators, parser}
}
func main() {
c := NewCalculator()
c.Run()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment