Create a gist now

Instantly share code, notes, and snippets.

@elliott5 /interp.go
Last active Jul 28, 2017

What would you like to do?
Go Interpreter (in 35 lines) - CURRENTLY NOT WORKING
// NOT WORKING AS AT 14-JAN-14 DUE TO API CHANGES
//
// written for the Go London User Group meeting of 21st November 2013 by Elliott Stoneham
// uses code.google.com/p/go.tools/ssa/interp which warns “It is not, and will never be, a production-quality Go interpreter.”
// main() code adapted from the example given in code.google.com/p/go.tools/ssa
// requires go version 1.2
//
package main
import (
"code.google.com/p/go.tools/importer"
"code.google.com/p/go.tools/ssa"
"code.google.com/p/go.tools/ssa/interp"
"fmt"
"go/build"
"go/parser"
)
const code = `
package main // example inspired by gobyexample.com/recursion
import _ "runtime" // required by go.tools/ssa/interp
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() { println("ten factorial is ",fact(10)) }
`
func main() {
imp := importer.New(&importer.Config{Build: &build.Default}) // Imports will be loaded as if by 'go build'.
file, err := parser.ParseFile(imp.Fset, "main.go", code, 0) // Parse the input file.
if err != nil {
fmt.Print(err) // parse error
return
}
mainInfo := imp.CreatePackage("main", file) // Create single-file main package and import its dependencies.
var mode ssa.BuilderMode
prog := ssa.NewProgram(imp.Fset, mode) // Create SSA-form program representation.
if err := prog.CreatePackages(imp); err != nil {
fmt.Print(err) // type error in some package
return
}
mainPkg := prog.Package(mainInfo.Pkg)
packages := prog.AllPackages() // Build SSA code for bodies of functions in all packages
for p := range packages {
packages[p].Build()
}
rv := interp.Interpret(mainPkg, 0, "", nil)
if rv != 0 {
fmt.Printf("Interpreter error: %d\n", rv) // show any error
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment