go-translator/pkg/service/expr.go

165 строки
3 КиБ
Go

package service
import (
"go/ast"
"go/token"
)
func handleExpr(expr ast.Expr) (code string) {
// println()
// spew.Dump(expr)
switch e := expr.(type) {
case *ast.BasicLit:
code += handleBasicLit(e)
case *ast.UnaryExpr:
code += handleUnaryExpr(e)
case *ast.BinaryExpr:
code += handleBinaryExpr(e)
case *ast.CallExpr:
code += handleCallExpr(e)
case *ast.Ident:
code += handleIdentExpr(e)
case *ast.ParenExpr:
code += handleParenExpr(e)
case *ast.SelectorExpr:
code += handleSelectorExpr(e)
case *ast.IndexExpr:
code += handleIndexExpr(e)
case *ast.StructType:
code += handleStructType(e)
case *ast.InterfaceType:
code += handleInterfaceType(e)
case *ast.ArrayType:
code += handleArray(e)
}
return
}
func handleBasicLit(bl *ast.BasicLit) string {
return bl.Value
}
func handleBasicLitType(bl *ast.BasicLit) string {
switch bl.Kind {
case token.INT:
return "int"
case token.CHAR:
return "char"
case token.FLOAT:
return "double"
case token.STRING:
return "std::string"
}
return ""
}
func handleUnaryExpr(expr *ast.UnaryExpr) (code string) {
cl, ok := expr.X.(*ast.CompositeLit)
if ok {
code += "new "
code += handleIdentExpr(cl.Type.(*ast.Ident))
code += "()"
} else {
code += expr.Op.String()
code += handleExpr(expr.X)
}
return
}
func handleBinaryExpr(expr ast.Expr) string {
be := expr.(*ast.BinaryExpr)
code := handleExpr(be.X)
code += be.Op.String()
code += handleExpr(be.Y)
return code
}
func handleIdentExpr(ident *ast.Ident) (code string) {
switch ident.Name {
case "nil":
code += "NULL"
case "uint32":
code += "unsigned long"
case "uint64":
code += "unsigned long long"
case "float64":
code += "double"
case "string":
code += "std::string"
default:
code += ident.Name
}
return
}
func handleParenExpr(stmt *ast.ParenExpr) (code string) {
code += handleExpr(stmt.X)
return
}
func handleSelectorExpr(s *ast.SelectorExpr) (code string) {
// println()
// spew.Dump(s)
switch x := s.X.(type) {
case *ast.Ident:
if isInMethod {
if x.Name == currentReceiverName {
code += "this"
} else {
code += handleIdentExpr(x)
}
code += "->"
} else {
code += handleIdentExpr(x)
code += "->"
}
case *ast.SelectorExpr:
code += "this"
code += "->"
code += handleIdentExpr(x.Sel)
code += "->"
}
code += handleIdentExpr(s.Sel)
code = RemapCode(code)
return
}
func handleIndexExpr(ind *ast.IndexExpr) (code string) {
// println()
// spew.Dump(ind)
switch x := ind.X.(type) {
case *ast.SelectorExpr:
if isInMethod {
code += "this"
} else {
code += handleExpr(x.X)
}
code += "->"
code += handleIdentExpr(x.Sel)
code += "["
code += handleExpr(ind.Index)
code += "]"
}
return
}
func handleStarExpr(s *ast.StarExpr) (code string) {
switch x := s.X.(type) {
case *ast.Ident:
code += handleIdentExpr(x)
}
return
}
func handleArray(s *ast.ArrayType) (code string) {
switch x := s.Elt.(type) {
case *ast.Ident:
code += handleIdentExpr(x)
}
return
}