Last active
July 28, 2017 04:02
-
-
Save elliott5/7578605 to your computer and use it in GitHub Desktop.
Go Interpreter (in 35 lines) - CURRENTLY NOT WORKING
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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