Skip to content

Instantly share code, notes, and snippets.

@xiaq
Created September 15, 2017 14:17
Show Gist options
  • Select an option

  • Save xiaq/c6495932b94aaecd464b4eaea727aeed to your computer and use it in GitHub Desktop.

Select an option

Save xiaq/c6495932b94aaecd464b4eaea727aeed to your computer and use it in GitHub Desktop.
An illustration of compiling-to-closure
// Suppose you have a simple language with three possible tokens: + - p. The runtime of your language keeps a counter.
// The command + increments the counter, - decrements, and p prints.
type Runtime struct {
Counter int
}
// An interpreter.
func interprete(r *Runtime, program string) {
for _, r := range program {
switch r {
case '+':
r.counter++
case '-':
r.counter--
case 'p':
fmt.Println(r.counter)
default:
panic("bad program")
}
}
}
// Compile to closure.
func compileProgram(program string) func(*Runtime) {
var ops []func(*Runtime)
for _, r := range program {
ops = append(ops, compileCommand(r))
}
return func(r *Runtime) {
for _, op := range ops {
op(r)
}
}
}
func compileCommand(r rune) func(*Runtime) {
switch r {
case '+':
return func(r *Runtime) { r.counter++ }
case '-':
return func(r *Runtime) { r.counter-- }
case 'p':
return func(r *Runtime) { fmt.Println(r.counter) }
default:
panic("bad program")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment