Реализована конвертация в Python/Skidl
Этот коммит содержится в:
родитель
085459f69f
коммит
555cd10631
2 изменённых файлов: 347 добавлений и 548 удалений
|
@ -7,6 +7,8 @@ import (
|
||||||
"go/token"
|
"go/token"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Service specifies the api logic of transforming a source code format into another target format.
|
// Service specifies the api logic of transforming a source code format into another target format.
|
||||||
|
@ -27,6 +29,8 @@ type defaultService struct {
|
||||||
out io.Writer
|
out io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ind int
|
||||||
|
|
||||||
// NewService creates a a new transpile and returns its address.
|
// NewService creates a a new transpile and returns its address.
|
||||||
func NewService(in io.Reader, out io.Writer) Service {
|
func NewService(in io.Reader, out io.Writer) Service {
|
||||||
return &defaultService{
|
return &defaultService{
|
||||||
|
@ -43,15 +47,16 @@ func (s *defaultService) Start() error {
|
||||||
if s.out == nil {
|
if s.out == nil {
|
||||||
return fmt.Errorf("Error: %s", ErrorWorkerWriterIsNil)
|
return fmt.Errorf("Error: %s", ErrorWorkerWriterIsNil)
|
||||||
}
|
}
|
||||||
|
ind = 0
|
||||||
// Read tokens from file by using Go's parser.
|
// Read tokens from file by using Go's parser.
|
||||||
fset := token.NewFileSet()
|
fset := token.NewFileSet()
|
||||||
file, err := parser.ParseFile(fset, "source.go", s.in, 0)
|
file, err := parser.ParseFile(fset, "source.go", s.in, parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ParseFile failed! %v", err)
|
return fmt.Errorf("ParseFile failed! %v", err)
|
||||||
}
|
}
|
||||||
// If source has no declarations then main it to an empty for loop.
|
// If source has no declarations then main it to an empty for loop.
|
||||||
if file.Decls == nil {
|
if file.Decls == nil {
|
||||||
fmt.Fprint(s.out, "void loop() {} void setup() {}")
|
fmt.Fprint(s.out, "from skidl import *\n")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Use Goroutines to work concurrently.
|
// Use Goroutines to work concurrently.
|
||||||
|
@ -62,15 +67,20 @@ func (s *defaultService) Start() error {
|
||||||
dst[i] = make(chan string, 1)
|
dst[i] = make(chan string, 1)
|
||||||
}
|
}
|
||||||
// Start a transpile with an individual channel for each declaration in the source file.
|
// Start a transpile with an individual channel for each declaration in the source file.
|
||||||
|
go func() {
|
||||||
for i, decl := range file.Decls {
|
for i, decl := range file.Decls {
|
||||||
go handleDecl(i, decl, dst[i], done)
|
handleDecl(i, decl, dst[i], done)
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
// Wait for all workers are done.
|
// Wait for all workers are done.
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.out.Write([]byte("from skidl import *\n"))
|
||||||
|
|
||||||
// Print the ordered result.
|
// Print the ordered result.
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
for content := range dst[i] {
|
for content := range dst[i] {
|
||||||
|
@ -78,17 +88,37 @@ func (s *defaultService) Start() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.out.Write([]byte("\n"))
|
s.out.Write([]byte("main()\n"))
|
||||||
|
|
||||||
// Print the AST.
|
// Print the AST.
|
||||||
// ast.Fprint(os.Stderr, fset, file, nil)
|
// ast.Fprint(os.Stderr, fset, file, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func increaseInd() {
|
||||||
|
ind++
|
||||||
|
}
|
||||||
|
func decreaseInd() {
|
||||||
|
ind--
|
||||||
|
}
|
||||||
|
func indSpaces() string {
|
||||||
|
res := ""
|
||||||
|
for i := 0; i < ind; i++ {
|
||||||
|
res += " "
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
func handleAssignStmt(as *ast.AssignStmt) string {
|
func handleAssignStmt(as *ast.AssignStmt) string {
|
||||||
code := handleAssignStmtExpr(as.Lhs)
|
code := handleAssignStmtExpr(as.Lhs)
|
||||||
code += as.Tok.String()
|
switch as.Tok {
|
||||||
|
case token.DEFINE:
|
||||||
|
code += " = "
|
||||||
|
default:
|
||||||
|
code += " " + as.Tok.String() + " "
|
||||||
|
}
|
||||||
code += handleAssignStmtExpr(as.Rhs)
|
code += handleAssignStmtExpr(as.Rhs)
|
||||||
|
code += "\n"
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +145,12 @@ func handleUnaryExpr(expr *ast.UnaryExpr) string {
|
||||||
func handleBinaryExpr(expr ast.Expr) string {
|
func handleBinaryExpr(expr ast.Expr) string {
|
||||||
be := expr.(*ast.BinaryExpr)
|
be := expr.(*ast.BinaryExpr)
|
||||||
code := handleExpr(be.X)
|
code := handleExpr(be.X)
|
||||||
code += be.Op.String()
|
switch be.Op {
|
||||||
|
case token.EQL:
|
||||||
|
code += "="
|
||||||
|
default:
|
||||||
|
code += " " + be.Op.String() + " "
|
||||||
|
}
|
||||||
code += handleExpr(be.Y)
|
code += handleExpr(be.Y)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
@ -171,6 +206,11 @@ func handleExpr(expr ast.Expr) string {
|
||||||
code += handleParenExpr(e)
|
code += handleParenExpr(e)
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
code += handleSelectorExpr(e)
|
code += handleSelectorExpr(e)
|
||||||
|
case *ast.IndexExpr:
|
||||||
|
code += handleIndexExpr(e)
|
||||||
|
default:
|
||||||
|
spew.Dump(e)
|
||||||
|
code += "Unknown in handleExpr"
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
@ -186,7 +226,13 @@ func handleExprStmt(stmt *ast.ExprStmt) string {
|
||||||
switch x := stmt.X.(type) {
|
switch x := stmt.X.(type) {
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
code += handleCallExpr(x)
|
code += handleCallExpr(x)
|
||||||
|
case *ast.BinaryExpr:
|
||||||
|
code += handleBinaryExpr(x)
|
||||||
|
default:
|
||||||
|
spew.Dump(stmt.X)
|
||||||
|
code += "unknown in handleExprStmt"
|
||||||
}
|
}
|
||||||
|
code += "\n"
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +242,16 @@ func handleFuncDecl(decl ast.Decl) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
code := ""
|
code := ""
|
||||||
|
if fd.Doc != nil {
|
||||||
|
t := fd.Doc.Text()
|
||||||
|
switch t {
|
||||||
|
case "@package\n":
|
||||||
|
code += t
|
||||||
|
case "@subcircuit\n":
|
||||||
|
code += t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code += "def "
|
||||||
name := ""
|
name := ""
|
||||||
code += handleFuncDeclType(fd.Type)
|
code += handleFuncDeclType(fd.Type)
|
||||||
code += ""
|
code += ""
|
||||||
|
@ -206,9 +262,11 @@ func handleFuncDecl(decl ast.Decl) string {
|
||||||
code += name
|
code += name
|
||||||
code += "("
|
code += "("
|
||||||
code += handleFuncDeclParams(fd.Type)
|
code += handleFuncDeclParams(fd.Type)
|
||||||
code += ") {"
|
code += "):\n"
|
||||||
|
increaseInd()
|
||||||
code += handleBlockStmt(fd.Body)
|
code += handleBlockStmt(fd.Body)
|
||||||
code += "}"
|
decreaseInd()
|
||||||
|
code += ""
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
func shouldSkipFunction(t *ast.FuncType) (res bool) {
|
func shouldSkipFunction(t *ast.FuncType) (res bool) {
|
||||||
|
@ -268,6 +326,9 @@ func handleBlockStmt(body *ast.BlockStmt) string {
|
||||||
if body == nil {
|
if body == nil {
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
if len(body.List) == 0 {
|
||||||
|
return indSpaces() + "None\n"
|
||||||
|
}
|
||||||
for _, stmt := range body.List {
|
for _, stmt := range body.List {
|
||||||
code += handleStmt(stmt, false)
|
code += handleStmt(stmt, false)
|
||||||
}
|
}
|
||||||
|
@ -307,7 +368,7 @@ func handleFuncDeclName(ident *ast.Ident) string {
|
||||||
func handleFuncDeclType(t *ast.FuncType) string {
|
func handleFuncDeclType(t *ast.FuncType) string {
|
||||||
code := ""
|
code := ""
|
||||||
if t.Results == nil {
|
if t.Results == nil {
|
||||||
code = "void"
|
code = ""
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
@ -330,7 +391,7 @@ func handleIdent(expr ast.Expr) string {
|
||||||
code := ""
|
code := ""
|
||||||
switch ident.Name {
|
switch ident.Name {
|
||||||
case "string":
|
case "string":
|
||||||
code += "char*"
|
code += ""
|
||||||
default:
|
default:
|
||||||
code += ident.Name
|
code += ident.Name
|
||||||
}
|
}
|
||||||
|
@ -339,11 +400,16 @@ func handleIdent(expr ast.Expr) string {
|
||||||
|
|
||||||
func handleIfStmt(stmt *ast.IfStmt) string {
|
func handleIfStmt(stmt *ast.IfStmt) string {
|
||||||
cond := handleExpr(stmt.Cond)
|
cond := handleExpr(stmt.Cond)
|
||||||
|
increaseInd()
|
||||||
body := handleBlockStmt(stmt.Body)
|
body := handleBlockStmt(stmt.Body)
|
||||||
code := fmt.Sprintf(`if (%s) { %s }`, cond, body)
|
decreaseInd()
|
||||||
|
code := fmt.Sprintf("if %s:\n%s", cond, body)
|
||||||
if stmt.Else != nil {
|
if stmt.Else != nil {
|
||||||
|
increaseInd()
|
||||||
tail := handleBlockStmt(stmt.Else.(*ast.BlockStmt))
|
tail := handleBlockStmt(stmt.Else.(*ast.BlockStmt))
|
||||||
code += fmt.Sprintf(" else { %s }", tail)
|
decreaseInd()
|
||||||
|
code += indSpaces()
|
||||||
|
code += fmt.Sprintf("else:\n%s", tail)
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
@ -380,6 +446,14 @@ func handleSelectorExpr(expr ast.Expr) string {
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleIndexExpr(expr *ast.IndexExpr) string {
|
||||||
|
code := expr.X.(*ast.Ident).String()
|
||||||
|
code += "["
|
||||||
|
code += expr.Index.(*ast.BasicLit).Value
|
||||||
|
code += "]"
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
func handleSpecs(specs []ast.Spec) string {
|
func handleSpecs(specs []ast.Spec) string {
|
||||||
code := ""
|
code := ""
|
||||||
for _, spec := range specs {
|
for _, spec := range specs {
|
||||||
|
@ -394,12 +468,12 @@ func handleSpecs(specs []ast.Spec) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleStmt(stmt ast.Stmt, standaloneAssignment bool) string {
|
func handleStmt(stmt ast.Stmt, standaloneAssignment bool) string {
|
||||||
code := ""
|
code := indSpaces()
|
||||||
switch s := stmt.(type) {
|
switch s := stmt.(type) {
|
||||||
case *ast.AssignStmt:
|
case *ast.AssignStmt:
|
||||||
code += handleAssignStmt(s)
|
code += handleAssignStmt(s)
|
||||||
if !standaloneAssignment {
|
if !standaloneAssignment {
|
||||||
code += ";"
|
code += ""
|
||||||
}
|
}
|
||||||
case *ast.BranchStmt:
|
case *ast.BranchStmt:
|
||||||
code += handleBranchStmt(s)
|
code += handleBranchStmt(s)
|
||||||
|
@ -409,7 +483,6 @@ func handleStmt(stmt ast.Stmt, standaloneAssignment bool) string {
|
||||||
code += handleDeclStmt(s)
|
code += handleDeclStmt(s)
|
||||||
case *ast.ExprStmt:
|
case *ast.ExprStmt:
|
||||||
code += handleExprStmt(s)
|
code += handleExprStmt(s)
|
||||||
code += ";"
|
|
||||||
case *ast.ForStmt:
|
case *ast.ForStmt:
|
||||||
code += handleForStmt(s)
|
code += handleForStmt(s)
|
||||||
case *ast.IfStmt:
|
case *ast.IfStmt:
|
||||||
|
@ -418,6 +491,9 @@ func handleStmt(stmt ast.Stmt, standaloneAssignment bool) string {
|
||||||
code += handleSwitchStmt(s)
|
code += handleSwitchStmt(s)
|
||||||
case *ast.ReturnStmt:
|
case *ast.ReturnStmt:
|
||||||
code += handleReturnStmt(s)
|
code += handleReturnStmt(s)
|
||||||
|
default:
|
||||||
|
spew.Dump(stmt)
|
||||||
|
code += "unknown handleStmt"
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,635 +7,361 @@ import (
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
gomega_format "github.com/onsi/gomega/format"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUtils(t *testing.T) {
|
func TestUtils(t *testing.T) {
|
||||||
RegisterFailHandler(Fail)
|
RegisterFailHandler(Fail)
|
||||||
RunSpecs(t, "Go Translator")
|
gomega_format.CharactersAroundMismatchToInclude = 20
|
||||||
|
RunSpecs(t, "Go Translator to Python/Skidl")
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("Go Translator", func() {
|
var _ = Describe("Go Translator to Python/Skidl", func() {
|
||||||
Describe("All", func() {
|
Describe("All", func() {
|
||||||
It("Empty_Package", func() {
|
It("Empty Package", func() {
|
||||||
source := `package test`
|
source := `package test`
|
||||||
expected := `void loop(){}
|
expected := `from skidl import *
|
||||||
void setup(){}`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Function_Declaration", func() {
|
|
||||||
source := `package test
|
|
||||||
func foo() {}
|
|
||||||
func bar() {}
|
|
||||||
`
|
|
||||||
expected := `void foo(){}
|
|
||||||
void bar() {}`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Function_Declaration_With_Args", func() {
|
|
||||||
source := `package test
|
|
||||||
func foo(x int) {}
|
|
||||||
func bar(y int) {}
|
|
||||||
`
|
|
||||||
expected := `void foo(int x){}
|
|
||||||
void bar(int y) {}`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Const_String_Declaration", func() {
|
|
||||||
source := `package test
|
|
||||||
const foo string = "bar"
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
const char* foo = "bar";
|
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Var_String_Declaration", func() {
|
It("Function Declaration", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
var client wifi.Client
|
func main() {}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
WiFiClient client;
|
def main():
|
||||||
|
None
|
||||||
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Function_With_Const_String_Declaration", func() {
|
It("Func call", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func foo() {
|
func main() {
|
||||||
const foo string = "bar"
|
generate_netlist()
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void foo() {
|
def main():
|
||||||
const char* foo = "bar";
|
generate_netlist()
|
||||||
}
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Function_With_Var_String_Declaration", func() {
|
It("Net Declaration", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func foo() {
|
func main() {
|
||||||
var foo string = "bar"
|
vin := Net("3.3v")
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void foo() {
|
def main():
|
||||||
char* foo = "bar";
|
vin = Net("3.3v")
|
||||||
}
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Function_With_Function_Call", func() {
|
It("Nets Declaration", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func foo() {
|
func main() {
|
||||||
bar()
|
vin := Net("3.3v")
|
||||||
|
gnd := Net("GND")
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void foo() {
|
def main():
|
||||||
bar();
|
vin = Net("3.3v")
|
||||||
}
|
gnd = Net("GND")
|
||||||
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Function_With_Function_Call_With_Args", func() {
|
It("Part Declaration", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func foo() {
|
func main() {
|
||||||
bar(1,2,3)
|
ESP32 := Part("RF_Module", "ESP32-WROOM-32", TEMPLATE, footprint == "RF_Module:ESP32-WROOM-32")
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void foo() {
|
def main():
|
||||||
bar(1,2,3);
|
ESP32 = Part("RF_Module","ESP32-WROOM-32",TEMPLATE,footprint="RF_Module:ESP32-WROOM-32")
|
||||||
}
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Function_With_Function_Call_With_String", func() {
|
It("Parts Declaration", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func foo() {
|
func main() {
|
||||||
bar("foo")
|
ESP32 := Part("RF_Module", "ESP32-WROOM-32", TEMPLATE, footprint == "RF_Module:ESP32-WROOM-32")
|
||||||
|
Klema := Part("Connector_Generic_MountingPin", "Conn_01x01_MountingPin", TEMPLATE, footprint == "TestPoint_Pad_2.0x2.0mm")
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void foo() {
|
def main():
|
||||||
bar("foo");
|
ESP32 = Part("RF_Module","ESP32-WROOM-32",TEMPLATE,footprint="RF_Module:ESP32-WROOM-32")
|
||||||
}
|
Klema = Part("Connector_Generic_MountingPin","Conn_01x01_MountingPin",TEMPLATE,footprint="TestPoint_Pad_2.0x2.0mm")
|
||||||
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Function_With_Package_Function_Call", func() {
|
It("Values Declaration", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func foo() {
|
func main() {
|
||||||
foo.Bar(1,"2")
|
esp32 := ESP32(value == "ESP32")
|
||||||
|
k_vin, k_gnd := Klema(2)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void foo() {
|
def main():
|
||||||
foo.Bar(1,"2");
|
esp32 = ESP32(value="ESP32")
|
||||||
}
|
k_vin,k_gnd = Klema(2)
|
||||||
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Function_With_Assignments", func() {
|
It("Values with params Declaration", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func foo() {
|
func main() {
|
||||||
|
tr_tok_verh := tr_npn(value == "tr Tok verh NPN")
|
||||||
|
}
|
||||||
|
`
|
||||||
|
expected := `from skidl import *
|
||||||
|
def main():
|
||||||
|
tr_tok_verh = tr_npn(value="tr Tok verh NPN")
|
||||||
|
main()
|
||||||
|
`
|
||||||
|
Compare(source, expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Assignments += by name ", func() {
|
||||||
|
source := `package test
|
||||||
|
func main() {
|
||||||
|
esp32["GND"] += gnd
|
||||||
|
esp32["VDD"] += vin
|
||||||
|
}
|
||||||
|
`
|
||||||
|
expected := `from skidl import *
|
||||||
|
def main():
|
||||||
|
esp32["GND"] += gnd
|
||||||
|
esp32["VDD"] += vin
|
||||||
|
main()
|
||||||
|
`
|
||||||
|
Compare(source, expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Assignments += by index", func() {
|
||||||
|
source := `package test
|
||||||
|
func main() {
|
||||||
|
esp32[1] += gnd
|
||||||
|
vin += r_fb[1]
|
||||||
|
tr1[1] += tr2[2]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
expected := `from skidl import *
|
||||||
|
def main():
|
||||||
|
esp32[1] += gnd
|
||||||
|
vin += r_fb[1]
|
||||||
|
tr1[1] += tr2[2]
|
||||||
|
main()
|
||||||
|
`
|
||||||
|
Compare(source, expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Assignments &", func() {
|
||||||
|
source := `package test
|
||||||
|
func main() {
|
||||||
|
tr_vkl["G"] & vkl
|
||||||
|
tr_vkl["G"] & tr2["S"]
|
||||||
|
tr_vkl & tr2["S"]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
expected := `from skidl import *
|
||||||
|
def main():
|
||||||
|
tr_vkl["G"] & vkl
|
||||||
|
tr_vkl["G"] & tr2["S"]
|
||||||
|
tr_vkl & tr2["S"]
|
||||||
|
main()
|
||||||
|
`
|
||||||
|
Compare(source, expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Value Assignment", func() {
|
||||||
|
source := `package test
|
||||||
|
func main() {
|
||||||
|
vkl_iface.value = "k vkl"
|
||||||
|
vkl_iface.value = 19
|
||||||
|
vkl_iface.value = 19 / 3
|
||||||
|
vkl_iface.value = 19 * 2
|
||||||
|
}
|
||||||
|
`
|
||||||
|
expected := `from skidl import *
|
||||||
|
def main():
|
||||||
|
vkl_iface.value = "k vkl"
|
||||||
|
vkl_iface.value = 19
|
||||||
|
vkl_iface.value = 19 / 3
|
||||||
|
vkl_iface.value = 19 * 2
|
||||||
|
main()
|
||||||
|
`
|
||||||
|
Compare(source, expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Condition", func() {
|
||||||
|
source := `package test
|
||||||
|
func main() {
|
||||||
|
if a > 2 {
|
||||||
x = 1
|
x = 1
|
||||||
y = 2
|
y = 5
|
||||||
z = x + y
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void foo() {
|
|
||||||
x = 1;
|
|
||||||
y = 2;
|
|
||||||
z = x + y;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Function_With_Package_Selector_Assignments", func() {
|
|
||||||
source := `package test
|
|
||||||
func foo() {
|
|
||||||
x = bar()
|
|
||||||
y = pkg.Bar()
|
|
||||||
z = x + y
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void foo() {
|
|
||||||
x = bar();
|
|
||||||
y = pkg.Bar();
|
|
||||||
z = x + y;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Function_Ident_Mapping", func() {
|
|
||||||
source := `package test
|
|
||||||
func foo() {
|
|
||||||
serial.Begin()
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void foo() {
|
|
||||||
Serial.begin();
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Function_With_Ident_Param", func() {
|
|
||||||
source := `package test
|
|
||||||
func foo() {
|
|
||||||
foo.Bar(1,"2",digital.Low)
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void foo() {
|
|
||||||
foo.Bar(1,"2",LOW);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Function_With_Function_Param", func() {
|
|
||||||
source := `package test
|
|
||||||
func foo() {
|
|
||||||
serial.Println(wifi.LocalIP())
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void foo() {
|
|
||||||
Serial.println(WiFi.localIP());
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Function_Should_Be_Skipped", func() {
|
|
||||||
source := `package test
|
|
||||||
func foo() (s ShouldBeSkipped) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := ``
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Package_Import", func() {
|
|
||||||
source := `package test
|
|
||||||
import "github.com/andygeiss/esp32-mqtt/api/controller"
|
|
||||||
import "github.com/andygeiss/esp32-mqtt/api/controller/serial"
|
|
||||||
import "github.com/andygeiss/esp32/api/controller/timer"
|
|
||||||
import wifi "github.com/andygeiss/esp32/api/controller/wifi"
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
#include <WiFi.h>
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("Package_Import_But_Ignore_Controller", func() {
|
|
||||||
source := `package test
|
|
||||||
import controller "my/go-controller"
|
|
||||||
import "github.com/andygeiss/esp32-mqtt/api/controller/serial"
|
|
||||||
import "github.com/andygeiss/esp32/api/controller/timer"
|
|
||||||
import wifi "github.com/andygeiss/esp32/api/controller/wifi"
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
#include <WiFi.h>
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("IfStmt_With_Condition_BasicLit_And_BasicLit", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
if 1 == 1 {
|
|
||||||
serial.Println("1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
if (1 == 1) {
|
|
||||||
Serial.println("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("IfStmt_With_Condition_Ident_And_BasicLit", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
if x == 1 {
|
|
||||||
serial.Println("1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
if (x == 1) {
|
|
||||||
Serial.println("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("IfStmt_With_Condition_CallExpr_And_BasicLit", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
if x() == 1 {
|
|
||||||
serial.Println("1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
if (x() == 1) {
|
|
||||||
Serial.println("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("IfStmt_With_Condition_Const_And_BasicLit", func() {
|
|
||||||
source := `package test
|
|
||||||
const maxX = 1
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
if x == maxX {
|
|
||||||
serial.Println("1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
const maxX = 1;
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
if (x == maxX) {
|
|
||||||
Serial.println("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("IfStmt_With_Else", func() {
|
|
||||||
source := `package test
|
|
||||||
const maxX = 1
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
if x == maxX {
|
|
||||||
serial.Println("1")
|
|
||||||
} else {
|
} else {
|
||||||
serial.Println("2")
|
x = 6
|
||||||
|
y = 9
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
const maxX = 1;
|
def main():
|
||||||
void setup() {}
|
if a > 2:
|
||||||
void loop() {
|
x = 1
|
||||||
if (x == maxX) {
|
y = 5
|
||||||
Serial.println("1");
|
else:
|
||||||
|
x = 6
|
||||||
|
y = 9
|
||||||
|
main()
|
||||||
|
`
|
||||||
|
Compare(source, expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Condition complex", func() {
|
||||||
|
source := `package test
|
||||||
|
func main() {
|
||||||
|
if a > 2 {
|
||||||
|
x = 1
|
||||||
|
y = 5
|
||||||
|
if b > 5 {
|
||||||
|
x = 6
|
||||||
|
y = 9
|
||||||
} else {
|
} else {
|
||||||
Serial.println("2");
|
x = 15
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("SwitchStmt_With_Ident_And_BasicLit", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
switch x {
|
|
||||||
case 1:
|
|
||||||
serial.Println("1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
switch (x) {
|
|
||||||
case 1:
|
|
||||||
Serial.println("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("SwitchStmt_With_Break", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("ForLoop_WithoutInit_And_Post_Transpiles_To_While", func() {
|
|
||||||
source := `package test
|
|
||||||
import wifi "github.com/andygeiss/esp32/api/controller/wifi"
|
|
||||||
func Setup() {
|
|
||||||
serial.Begin(serial.BaudRate115200)
|
|
||||||
wifi.BeginEncrypted("SSID", "PASS")
|
|
||||||
for wifi.Status() != wifi.StatusConnected {
|
|
||||||
serial.Println("Connecting ...")
|
|
||||||
}
|
|
||||||
serial.Println("Connected!")
|
|
||||||
}
|
|
||||||
func Loop() {}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
#include <WiFi.h>
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
WiFi.begin("SSID","PASS");
|
|
||||||
while(WiFi.status()!=WL_CONNECTED){
|
|
||||||
Serial.println("Connecting...");
|
|
||||||
}
|
|
||||||
Serial.println("Connected!");
|
|
||||||
}
|
|
||||||
void loop() {}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("WiFiWebClient", func() {
|
|
||||||
source := `package test
|
|
||||||
import wifi "github.com/andygeiss/esp32/api/controller/wifi"
|
|
||||||
var client wifi.Client
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
serial.Print("Connecting to ")
|
|
||||||
serial.Println(host)
|
|
||||||
serial.Print(" ...")
|
|
||||||
if (client.Connect(host, 443) == true) {
|
|
||||||
serial.Println(" Connected!")
|
|
||||||
} else {
|
} else {
|
||||||
serial.Println(" Failed!")
|
x = 18
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `#include <WiFi.h>
|
expected := `from skidl import *
|
||||||
WiFiClient client;
|
def main():
|
||||||
voidsetup(){}
|
if a > 2:
|
||||||
voidloop(){
|
x = 1
|
||||||
Serial.print("Connecting to");
|
y = 5
|
||||||
Serial.println(host);
|
if b > 5:
|
||||||
Serial.print(" ...");
|
x = 6
|
||||||
if(client.connect(host, 443) == true){
|
y = 9
|
||||||
Serial.println(" Connected!");
|
else:
|
||||||
} else {
|
x = 15
|
||||||
Serial.println(" Failed!");
|
else:
|
||||||
}
|
x = 18
|
||||||
}`
|
main()
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Describe("Arduino", func() {
|
|
||||||
It("Maps constants", func() {
|
|
||||||
source := `package test
|
|
||||||
var analogInPin int = arduino.A0
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
int analogInPin = A0;
|
|
||||||
void setup() {}
|
|
||||||
void loop() {}
|
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
Describe("Функции", func() {
|
It("Function decl/call", func() {
|
||||||
It("Объявление void функции", func() {
|
|
||||||
source := `package test
|
source := `package test
|
||||||
func Setup() {}
|
func vdiv(inp, outp, param string) {
|
||||||
func Loop() {
|
r1 := r(value == 1000)
|
||||||
|
r2 := r(value == param)
|
||||||
|
inp & r1
|
||||||
|
r1 & outp
|
||||||
|
outp & r2
|
||||||
|
r2 & gnd
|
||||||
}
|
}
|
||||||
|
|
||||||
func MyFunction() {
|
func main() {
|
||||||
|
v := vdiv(inp, outp, "500")
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void setup() {}
|
def vdiv(inp,outp,param):
|
||||||
void loop() {
|
r1 = r(value=1000)
|
||||||
}
|
r2 = r(value=param)
|
||||||
void MyFunction() {
|
inp & r1
|
||||||
}
|
r1 & outp
|
||||||
|
outp & r2
|
||||||
|
r2 & gnd
|
||||||
|
def main():
|
||||||
|
v = vdiv(inp,outp,"500")
|
||||||
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
It("Объявление void функции с return", func() {
|
|
||||||
|
It("Subcircuit function decorator", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func Setup() {}
|
//@subcircuit
|
||||||
func Loop() {
|
func vdiv(inp, outp, param string) {
|
||||||
|
r1 := r(value == 1000)
|
||||||
|
r2 := r(value == param)
|
||||||
|
inp & r1
|
||||||
|
r1 & outp
|
||||||
|
outp & r2
|
||||||
|
r2 & gnd
|
||||||
}
|
}
|
||||||
|
|
||||||
func MyFunction() {
|
func main() {
|
||||||
return
|
v := vdiv(inp, outp, "500")
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void setup() {}
|
@subcircuit
|
||||||
void loop() {
|
def vdiv(inp,outp,param):
|
||||||
}
|
r1 = r(value=1000)
|
||||||
void MyFunction() {
|
r2 = r(value=param)
|
||||||
return;
|
inp & r1
|
||||||
}
|
r1 & outp
|
||||||
|
outp & r2
|
||||||
|
r2 & gnd
|
||||||
|
def main():
|
||||||
|
v = vdiv(inp,outp,"500")
|
||||||
|
main()
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
It("Объявление int функции", func() {
|
|
||||||
|
It("Package function decorator", func() {
|
||||||
source := `package test
|
source := `package test
|
||||||
func Setup() {}
|
//@package
|
||||||
func Loop() {
|
func vdiv(inp, outp, param string) {
|
||||||
|
r1 := r(value == 1000)
|
||||||
|
r2 := r(value == param)
|
||||||
|
inp & r1
|
||||||
|
r1 & outp
|
||||||
|
outp & r2
|
||||||
|
r2 & gnd
|
||||||
}
|
}
|
||||||
|
|
||||||
func MyFunction() int {
|
func main() {
|
||||||
|
v := vdiv(inp, outp, "500")
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
expected := `
|
expected := `from skidl import *
|
||||||
void setup() {}
|
@package
|
||||||
void loop() {
|
def vdiv(inp,outp,param):
|
||||||
}
|
r1 = r(value=1000)
|
||||||
MyFunction() {
|
r2 = r(value=param)
|
||||||
}
|
inp & r1
|
||||||
`
|
r1 & outp
|
||||||
Compare(source, expected)
|
outp & r2
|
||||||
})
|
r2 & gnd
|
||||||
It("Объявление int функции с return 0", func() {
|
def main():
|
||||||
source := `package test
|
v = vdiv(inp,outp,"500")
|
||||||
func Setup() {}
|
main()
|
||||||
func Loop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func MyFunction() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
}
|
|
||||||
MyFunction() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
It("Объявление int функции с return -1", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func MyFunction() int {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
}
|
|
||||||
MyFunction() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
It("Объявляет и вызывает функцию", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
var x int = MyFunction()
|
|
||||||
}
|
|
||||||
|
|
||||||
func MyFunction() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
int x = MyFunction();
|
|
||||||
}
|
|
||||||
MyFunction() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
Compare(source, expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Describe("Циклы", func() {
|
|
||||||
It("for i=0; i<10; i+=1", func() {
|
|
||||||
source := `package test
|
|
||||||
func Setup() {}
|
|
||||||
func Loop() {
|
|
||||||
var i int
|
|
||||||
for i=0; i<10; i+=1 {
|
|
||||||
i = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
expected := `
|
|
||||||
void setup() {}
|
|
||||||
void loop() {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<10; i+=1) {
|
|
||||||
i = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
`
|
||||||
Compare(source, expected)
|
Compare(source, expected)
|
||||||
})
|
})
|
||||||
|
@ -655,9 +381,6 @@ func Compare(source, expected string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Trim(s string) string {
|
func Trim(s string) string {
|
||||||
s = strings.Replace(s, " ", "", -1)
|
|
||||||
s = strings.Replace(s, "\n", "", -1)
|
|
||||||
s = strings.Replace(s, "\r", "", -1)
|
|
||||||
s = strings.Replace(s, "\t", " ", -1)
|
s = strings.Replace(s, "\t", " ", -1)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче