Skip to content

Instantly share code, notes, and snippets.

@geraldstanje
Created September 20, 2014 21:44
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 geraldstanje/2517a923d6a75f7a4d2e to your computer and use it in GitHub Desktop.
Save geraldstanje/2517a923d6a75f7a4d2e to your computer and use it in GitHub Desktop.
parser fun
package main
import "fmt"
import "go/parser"
import "go/ast"
const debug = true
// Define one of these for each translation you need.
type Translator func(node *ast.CallExpr) string
// Should be loaded from the database or csv file...
var Database = map[string]string{
"SwitchOnLight": "buildRfidCmd(MAIN,Frame1,CL=clear,RW=WRITE);\nbuildRfidCmd(MAIN,Frame2,TIME1=%[1]sus,TIME2=%[1]sus,TIME3=%[2]sus,TIME4=0ms,RW=WRITE);",
"SwitchOffLight": "buildRfidCmd(MAIN,Frame1,CL=clear,RW=WRITE);",
}
// Represents a basic identifier such as int_lit | float_lit | imaginary_lit | rune_lit | string_lit
func isBasicLit(node *ast.CallExpr) bool {
for i, _ := range node.Args {
_, ok := node.Args[i].(*ast.BasicLit)
if !ok {
return false
}
}
return true
}
// Represents an identifier
func isIdent(name *ast.Expr) bool {
if _, ok := (*name).(*ast.Ident); ok {
return true
}
return false
}
// Map from input language to translators
var mapping = map[string]Translator{
"SwitchOnLight": func(node *ast.CallExpr) string {
var out string
// Check this type assertion first
if isBasicLit(node) {
value1 := node.Args[0].(*ast.BasicLit).Value
value2 := node.Args[1].(*ast.BasicLit).Value
out = fmt.Sprintf(Database["SwitchOnLight"], value1, value2)
}
return out
},
"SwitchOffLight": func(node *ast.CallExpr) string {
out := fmt.Sprintf(Database["SwitchOffLight"])
return out
},
}
func main() {
fileContent := []string{"SwitchOnLight(700, 200);", "SwitchOffLight();"}
for _, line := range fileContent {
expr, err := parser.ParseExpr(line)
if err != nil {
fmt.Println(err.Error)
return
}
if debug {
fmt.Println("\n",expr)
fmt.Printf("Expression Type: %T\n\n", expr)
}
if call, ok := expr.(*ast.CallExpr); ok {
if debug {
fmt.Println("Function Call:")
fmt.Println("Function:", call.Fun)
}
// Check to make sure it's an *ast.Ident, so you don't get a panic here
if isIdent(&call.Fun) {
translator, ok := mapping[call.Fun.(*ast.Ident).Name]
if ok {
fmt.Println("Result:\n", translator(call))
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment