Этот коммит содержится в:
andygeiss 2018-04-10 14:52:50 +02:00
родитель da7a66f467
коммит 2d7ff8234c
2 изменённых файлов: 164 добавлений и 77 удалений

Просмотреть файл

@ -78,83 +78,41 @@ func (w *Worker) Start() error {
return nil return nil
} }
func handleAssignStmt(stmt ast.Stmt) string { func handleAssignStmt(as *ast.AssignStmt) string {
a := stmt.(*ast.AssignStmt) code := handleAssignStmtExpr(as.Lhs)
code := "" code += as.Tok.String()
code += handleAssignStmtExpr(a.Lhs) code += handleAssignStmtExpr(as.Rhs)
code += a.Tok.String()
code += handleAssignStmtExpr(a.Rhs)
return code return code
} }
func handleAssignStmtExpr(expr []ast.Expr) string { func handleAssignStmtExpr(e []ast.Expr) string {
code := ""
ops := make([]string, 0) ops := make([]string, 0)
for _, op := range expr { code := ""
switch o := op.(type) { for _, op := range e {
case *ast.BasicLit: ops = append(ops, handleExpr(op))
ops = append(ops, handleBasicLit(o))
case *ast.BinaryExpr:
ops = append(ops, handleBinaryExpr(o))
case *ast.CallExpr:
ops = append(ops, handleCallExpr(o))
case *ast.Ident:
ops = append(ops, handleIdent(o))
}
} }
code += strings.Join(ops, ",") code += strings.Join(ops, ",")
return code return code
} }
func handleBasicLit(expr ast.Expr) string { func handleBasicLit(bl *ast.BasicLit) string {
bl := expr.(*ast.BasicLit) return bl.Value
code := ""
code += bl.Value
return code
} }
func handleBinaryExpr(expr ast.Expr) string { func handleBinaryExpr(expr ast.Expr) string {
e := expr.(*ast.BinaryExpr) be := expr.(*ast.BinaryExpr)
code := "" code := handleExpr(be.X)
switch x := e.X.(type) { code += be.Op.String()
case *ast.BasicLit: code += handleExpr(be.Y)
code += handleBasicLit(x)
case *ast.CallExpr:
code += handleCallExpr(x)
case *ast.Ident:
code += handleIdent(x)
}
code += e.Op.String()
switch y := e.Y.(type) {
case *ast.BasicLit:
code += handleBasicLit(y)
case *ast.CallExpr:
code += handleCallExpr(y)
case *ast.Ident:
code += handleIdent(y)
}
return code return code
} }
func handleCallExpr(expr *ast.CallExpr) string { func handleCallExpr(expr *ast.CallExpr) string {
code := "" code := handleExpr(expr.Fun)
switch e := expr.Fun.(type) {
case *ast.Ident:
code += handleIdent(e)
case *ast.SelectorExpr:
code += handleSelectorExpr(e)
}
code += "(" code += "("
args := make([]string, 0) args := make([]string, 0)
for _, arg := range expr.Args { for _, arg := range expr.Args {
switch a := arg.(type) { args = append(args, handleExpr(arg))
case *ast.BasicLit:
args = append(args, handleBasicLit(a))
case *ast.CallExpr:
args = append(args, handleCallExpr(a))
case *ast.SelectorExpr:
args = append(args, handleSelectorExpr(a))
}
} }
code += strings.Join(args, ",") code += strings.Join(args, ",")
code += ")" code += ")"
@ -183,6 +141,23 @@ func handleDeclStmt(stmt *ast.DeclStmt) string {
return code return code
} }
func handleExpr(expr ast.Expr) string {
code := ""
switch e := expr.(type) {
case *ast.BasicLit:
code += handleBasicLit(e)
case *ast.BinaryExpr:
code += handleBinaryExpr(e)
case *ast.CallExpr:
code += handleCallExpr(e)
case *ast.Ident:
code += handleIdent(e)
case *ast.SelectorExpr:
code += handleSelectorExpr(e)
}
return code
}
func handleExprStmt(stmt *ast.ExprStmt) string { func handleExprStmt(stmt *ast.ExprStmt) string {
code := "" code := ""
switch x := stmt.X.(type) { switch x := stmt.X.(type) {
@ -237,26 +212,26 @@ func handleBlockStmt(body *ast.BlockStmt) string {
return code return code
} }
for _, stmt := range body.List { for _, stmt := range body.List {
switch s := stmt.(type) { code += handleStmt(stmt)
case *ast.AssignStmt:
code += handleAssignStmt(s)
code += ";"
case *ast.IfStmt:
code += handleIfStmt(s)
case *ast.DeclStmt:
code += handleDeclStmt(s)
case *ast.ExprStmt:
code += handleExprStmt(s)
code += ";"
}
} }
return code return code
} }
func handleIfStmt(stmt *ast.IfStmt) string { func handleBranchStmt(stmt *ast.BranchStmt) string {
cond := handleBinaryExpr(stmt.Cond) return "break;"
body := handleBlockStmt(stmt.Body) }
code := fmt.Sprintf(`if (%s) { %s }`, cond, body)
func handleCaseClause(cc *ast.CaseClause) string {
code := "case "
clauses := make([]string, 0)
for _, clause := range cc.List {
clauses = append(clauses, handleExpr(clause))
}
code += strings.Join(clauses, ",")
code += ":"
for _, body := range cc.Body {
code += handleStmt(body)
}
return code return code
} }
@ -301,6 +276,13 @@ func handleIdent(expr ast.Expr) string {
return code return code
} }
func handleIfStmt(stmt *ast.IfStmt) string {
cond := handleBinaryExpr(stmt.Cond)
body := handleBlockStmt(stmt.Body)
code := fmt.Sprintf(`if (%s) { %s }`, cond, body)
return code
}
func handleImportSpec(spec ast.Spec) string { func handleImportSpec(spec ast.Spec) string {
s := spec.(*ast.ImportSpec) s := spec.(*ast.ImportSpec)
code := "" code := ""
@ -342,6 +324,38 @@ func handleSpecs(specs []ast.Spec) string {
return code return code
} }
func handleStmt(stmt ast.Stmt) string {
code := ""
switch s := stmt.(type) {
case *ast.AssignStmt:
code += handleAssignStmt(s)
code += ";"
case *ast.BranchStmt:
code += handleBranchStmt(s)
case *ast.CaseClause:
code += handleCaseClause(s)
case *ast.DeclStmt:
code += handleDeclStmt(s)
case *ast.ExprStmt:
code += handleExprStmt(s)
code += ";"
case *ast.IfStmt:
code += handleIfStmt(s)
case *ast.SwitchStmt:
code += handleSwitchStmt(s)
}
return code
}
func handleSwitchStmt(stmt *ast.SwitchStmt) string {
code := "switch ("
code += handleExpr(stmt.Tag)
code += "){"
code += handleBlockStmt(stmt.Body)
code += "}"
return code
}
func handleValueSpec(spec ast.Spec) string { func handleValueSpec(spec ast.Spec) string {
s := spec.(*ast.ValueSpec) s := spec.(*ast.ValueSpec)
code := "" code := ""

Просмотреть файл

@ -159,6 +159,7 @@ func Test_Function_With_Assignments(t *testing.T) {
` `
Validate(source, expected, t) Validate(source, expected, t)
} }
func Test_Function_With_Package_Selector_Assignments(t *testing.T) { func Test_Function_With_Package_Selector_Assignments(t *testing.T) {
source := `package test source := `package test
func foo() { func foo() {
@ -244,7 +245,7 @@ func Test_Package_Import_But_Ignore_Controller(t *testing.T) {
Validate(source, expected, t) Validate(source, expected, t)
} }
func Test_BlockStmt_With_Condition_BasicLit_And_BasicLit(t *testing.T) { func Test_IfStmt_With_Condition_BasicLit_And_BasicLit(t *testing.T) {
source := `package test source := `package test
func Setup() error {} func Setup() error {}
func Loop() error { func Loop() error {
@ -264,7 +265,7 @@ func Test_BlockStmt_With_Condition_BasicLit_And_BasicLit(t *testing.T) {
Validate(source, expected, t) Validate(source, expected, t)
} }
func Test_BlockStmt_With_Condition_Ident_And_BasicLit(t *testing.T) { func Test_IfStmt_With_Condition_Ident_And_BasicLit(t *testing.T) {
source := `package test source := `package test
func Setup() error {} func Setup() error {}
func Loop() error { func Loop() error {
@ -284,7 +285,7 @@ func Test_BlockStmt_With_Condition_Ident_And_BasicLit(t *testing.T) {
Validate(source, expected, t) Validate(source, expected, t)
} }
func Test_BlockStmt_With_Condition_CallExpr_And_BasicLit(t *testing.T) { func Test_IfStmt_With_Condition_CallExpr_And_BasicLit(t *testing.T) {
source := `package test source := `package test
func Setup() error {} func Setup() error {}
func Loop() error { func Loop() error {
@ -303,3 +304,75 @@ func Test_BlockStmt_With_Condition_CallExpr_And_BasicLit(t *testing.T) {
` `
Validate(source, expected, t) Validate(source, expected, t)
} }
func Test_IfStmt_With_Condition_Const_And_BasicLit(t *testing.T) {
source := `package test
const maxX = 1
func Setup() error {}
func Loop() error {
if x == maxX {
serial.Println("1")
}
}
`
expected := `
const maxX = 1;
void setup() {}
void loop() {
if (x == maxX) {
Serial.println("1");
}
}
`
Validate(source, expected, t)
}
func Test_SwitchStmt_With_Ident_And_BasicLit(t *testing.T) {
source := `package test
func Setup() error {}
func Loop() error {
switch x {
case 1:
serial.Println("1")
}
}
`
expected := `
void setup() {}
void loop() {
switch (x) {
case 1:
Serial.println("1");
}
}
`
Validate(source, expected, t)
}
func Test_SwitchStmt_With_Break(t *testing.T) {
source := `package test
func Setup() error {}
func Loop() error {
switch x {
case 1:
serial.Println("1")
break
case 2:
serial.Println("1")
}
}
`
expected := `
void setup() {}
void loop() {
switch (x) {
case 1:
Serial.println("1");
break;
case 2:
Serial.println("1");
}
}
`
Validate(source, expected, t)
}