Сценарий: Последовательность блоков: инклюды, константы, типы, абстрактные классы, классы, переменные, определения функций, функции
Этот коммит содержится в:
родитель
7ffcf77114
коммит
88229f2bd5
11 изменённых файлов: 326 добавлений и 143 удалений
|
@ -21,8 +21,7 @@ func (c *Const) String() (code string) {
|
|||
|
||||
func (c *Const) generate() (code string) {
|
||||
code += "const "
|
||||
code += handleValueSpec(c.s)
|
||||
code += ";"
|
||||
code += handleLocalVariable(c.s)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -302,10 +302,10 @@ func main() {
|
|||
```
|
||||
* Результат:
|
||||
```
|
||||
void main();
|
||||
class device {
|
||||
public:
|
||||
};
|
||||
void main();
|
||||
device *dev1,*dev2;
|
||||
void main() {
|
||||
dev1=new device();
|
||||
|
@ -333,11 +333,11 @@ func main() {
|
|||
```
|
||||
* Результат:
|
||||
```
|
||||
Device* NewDevice();
|
||||
void main();
|
||||
class Device {
|
||||
public:
|
||||
};
|
||||
Device* NewDevice();
|
||||
void main();
|
||||
Device *dev1,*dev2;
|
||||
Device* NewDevice() {
|
||||
return new Device();
|
||||
|
@ -347,11 +347,21 @@ dev1=NewDevice();
|
|||
}
|
||||
```
|
||||
|
||||
Сценарий: Последовательность блоков: константы, типы, абстрактные классы, классы, переменные, функции
|
||||
Сценарий: Последовательность блоков: инклюды, константы, типы, абстрактные классы, классы, переменные, определения функций, функции
|
||||
* Исходник:
|
||||
```
|
||||
package test
|
||||
|
||||
import wifi "some/wifi"
|
||||
|
||||
func someFunc() {}
|
||||
|
||||
var a = 1
|
||||
var b = 1
|
||||
|
||||
type device struct {}
|
||||
func (d *device) doSomething() {}
|
||||
|
||||
type Device interface {
|
||||
Name() string
|
||||
}
|
||||
|
@ -362,10 +372,61 @@ const c1 = 4
|
|||
```
|
||||
* Результат:
|
||||
```
|
||||
#include <WiFi.h>
|
||||
|
||||
const int c1 = 4;
|
||||
|
||||
typedef int Mera;
|
||||
|
||||
void someFunc();
|
||||
|
||||
class Device {
|
||||
public:
|
||||
virtual std::string Name() = 0;
|
||||
};
|
||||
|
||||
class device {
|
||||
public:
|
||||
void doSomething();
|
||||
};
|
||||
void device::doSomething() {
|
||||
}
|
||||
|
||||
int a = 1;
|
||||
int b = 1;
|
||||
|
||||
void someFunc() {
|
||||
}
|
||||
```
|
||||
|
||||
Сценарий: Конвертация "while" в "for"
|
||||
* Исходник:
|
||||
```
|
||||
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() {}
|
||||
```
|
||||
* Результат:
|
||||
```
|
||||
#include <WiFi.h>
|
||||
void setup();
|
||||
void loop();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin("SSID","PASS");
|
||||
while(WiFi.status()!=WL_CONNECTED) {
|
||||
Serial.println("Connecting ...");
|
||||
}
|
||||
Serial.println("Connected!");
|
||||
}
|
||||
void loop() {}
|
||||
```
|
||||
|
|
40
pkg/service/features/includes.feature
Обычный файл
40
pkg/service/features/includes.feature
Обычный файл
|
@ -0,0 +1,40 @@
|
|||
# Во имя Бога Милостивого, Милосердного!!!
|
||||
# language: ru
|
||||
Функциональность: Преобразование в C++: инклюды
|
||||
|
||||
Сценарий: Инклюд
|
||||
* Исходник:
|
||||
```
|
||||
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 {
|
||||
serial.Println(" Failed!")
|
||||
}
|
||||
}
|
||||
```
|
||||
* Результат:
|
||||
```
|
||||
#include <WiFi.h>
|
||||
void setup();
|
||||
void loop();
|
||||
WiFiClient client;
|
||||
void setup() {}
|
||||
void loop() {
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(host);
|
||||
Serial.print(" ...");
|
||||
if (client.connect(host,443)==true) {
|
||||
Serial.println(" Connected!");
|
||||
} else {
|
||||
Serial.println(" Failed!");
|
||||
}
|
||||
}
|
||||
```
|
|
@ -71,4 +71,20 @@ type GPIOS [GPIO_count]bool
|
|||
```
|
||||
typedef int Mera;
|
||||
typedef bool GPIOS[GPIO_count];
|
||||
```
|
||||
|
||||
Сценарий: Переменные в функциях
|
||||
* Исходник:
|
||||
```
|
||||
package test
|
||||
func foo() {
|
||||
var foo string = "bar"
|
||||
}
|
||||
```
|
||||
* Результат:
|
||||
```
|
||||
void foo();
|
||||
void foo() {
|
||||
std::string foo = "bar";
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,11 +1,32 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
inFunctionDepth = 0
|
||||
)
|
||||
|
||||
func incInFunctionDepth() {
|
||||
inFunctionDepth++
|
||||
}
|
||||
func decInFunctionDepth() {
|
||||
inFunctionDepth--
|
||||
if inFunctionDepth < 0 {
|
||||
panic(fmt.Sprintf("inFunctionDepth: %v", inFunctionDepth))
|
||||
}
|
||||
}
|
||||
func IsInFunction() bool {
|
||||
return inFunctionDepth > 0
|
||||
}
|
||||
|
||||
func handleFuncDecl(decl ast.Decl) string {
|
||||
incInFunctionDepth()
|
||||
defer decInFunctionDepth()
|
||||
|
||||
fd := decl.(*ast.FuncDecl)
|
||||
if fd.Recv != nil {
|
||||
return handleMethodDeclaration(fd)
|
||||
|
|
46
pkg/service/includes.go
Обычный файл
46
pkg/service/includes.go
Обычный файл
|
@ -0,0 +1,46 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
)
|
||||
|
||||
var (
|
||||
includeDeclarations []*Include
|
||||
)
|
||||
|
||||
type Include struct {
|
||||
i *ast.ImportSpec
|
||||
}
|
||||
|
||||
func NewInclude(i *ast.ImportSpec) *Include {
|
||||
return &Include{i: i}
|
||||
}
|
||||
|
||||
func (i *Include) String() (code string) {
|
||||
code += i.genString(i.i)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Include) genString(s *ast.ImportSpec) (code string) {
|
||||
if s.Name != nil {
|
||||
name := handleIdentExpr(s.Name)
|
||||
if val, ok := mapping[name]; ok {
|
||||
name = val
|
||||
}
|
||||
if name != "" {
|
||||
if name != "controller" {
|
||||
code = "#include <" + name + ".h>\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func handleImportSpec(s *ast.ImportSpec) (code string) {
|
||||
addInclude(s)
|
||||
return
|
||||
}
|
||||
func addInclude(s *ast.ImportSpec) {
|
||||
c := NewInclude(s)
|
||||
includeDeclarations = append(includeDeclarations, c)
|
||||
}
|
|
@ -86,10 +86,12 @@ func (s *defaultService) Start() error {
|
|||
dst[i] = make(chan string, 1)
|
||||
}
|
||||
|
||||
includeDeclarations = nil
|
||||
constDeclarations = nil
|
||||
typeDeclarations = nil
|
||||
abstractClassDeclarations = nil
|
||||
classDeclarations = nil
|
||||
variableDeclarations = nil
|
||||
funcDeclarations = nil
|
||||
helpersForDeclarations = nil
|
||||
|
||||
|
@ -106,12 +108,14 @@ func (s *defaultService) Start() error {
|
|||
}
|
||||
}
|
||||
|
||||
s.printIncludeHeaders()
|
||||
s.printIncludeAdruinoHeader()
|
||||
s.printIncludes()
|
||||
s.printConstDeclarations()
|
||||
s.printTypeDeclarations()
|
||||
s.printFunctionDeclarations()
|
||||
s.printAbstractClassDeclarations()
|
||||
s.printClassDeclarations()
|
||||
s.printFunctionDeclarations()
|
||||
s.printVariableDeclarations()
|
||||
s.printGoHelperDeclarations()
|
||||
|
||||
// Print the ordered result.
|
||||
|
@ -128,7 +132,7 @@ func (s *defaultService) Start() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *defaultService) printIncludeHeaders() {
|
||||
func (s *defaultService) printIncludeAdruinoHeader() {
|
||||
if !s.addIncludeArduinoH {
|
||||
return
|
||||
}
|
||||
|
@ -136,6 +140,19 @@ func (s *defaultService) printIncludeHeaders() {
|
|||
h := "#include <Arduino.h>\n\n"
|
||||
s.out.Write([]byte(h))
|
||||
}
|
||||
func (s *defaultService) printIncludes() {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
||||
for _, c := range includeDeclarations {
|
||||
d := c.String()
|
||||
s.out.Write([]byte(d + "\n"))
|
||||
if s.header != nil {
|
||||
s.header.Write([]byte(d + "\n"))
|
||||
}
|
||||
}
|
||||
s.out.Write([]byte("\n"))
|
||||
}
|
||||
func (s *defaultService) printConstDeclarations() {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
@ -162,6 +179,18 @@ func (s *defaultService) printTypeDeclarations() {
|
|||
}
|
||||
s.out.Write([]byte("\n"))
|
||||
}
|
||||
func (s *defaultService) printFunctionDeclarations() {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
||||
for _, f := range funcDeclarations {
|
||||
s.out.Write([]byte(f + "\n"))
|
||||
if s.header != nil {
|
||||
s.header.Write([]byte(f + "\n"))
|
||||
}
|
||||
}
|
||||
s.out.Write([]byte("\n"))
|
||||
}
|
||||
func (s *defaultService) printAbstractClassDeclarations() {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
@ -188,14 +217,15 @@ func (s *defaultService) printClassDeclarations() {
|
|||
}
|
||||
s.out.Write([]byte("\n"))
|
||||
}
|
||||
func (s *defaultService) printFunctionDeclarations() {
|
||||
func (s *defaultService) printVariableDeclarations() {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
||||
for _, f := range funcDeclarations {
|
||||
s.out.Write([]byte(f + "\n"))
|
||||
for _, c := range variableDeclarations {
|
||||
d := c.String()
|
||||
s.out.Write([]byte(d + "\n"))
|
||||
if s.header != nil {
|
||||
s.header.Write([]byte(f + "\n"))
|
||||
s.header.Write([]byte(d + "\n"))
|
||||
}
|
||||
}
|
||||
s.out.Write([]byte("\n"))
|
||||
|
|
|
@ -90,22 +90,6 @@ var _ = Describe("Go Translator", func() {
|
|||
Compare(source, expected)
|
||||
})
|
||||
|
||||
It("Function_With_Var_String_Declaration", func() {
|
||||
source := `package test
|
||||
func foo() {
|
||||
var foo string = "bar"
|
||||
}
|
||||
`
|
||||
expected := `
|
||||
void foo();
|
||||
|
||||
void foo() {
|
||||
std::string foo = "bar";
|
||||
}
|
||||
`
|
||||
Compare(source, expected)
|
||||
})
|
||||
|
||||
It("Function_With_Function_Call", func() {
|
||||
source := `package test
|
||||
func foo() {
|
||||
|
@ -497,73 +481,6 @@ var _ = Describe("Go Translator", func() {
|
|||
`
|
||||
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 := `
|
||||
void setup();
|
||||
void loop();
|
||||
|
||||
#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 {
|
||||
serial.Println(" Failed!")
|
||||
}
|
||||
}
|
||||
`
|
||||
expected := `
|
||||
void setup();
|
||||
void loop();
|
||||
|
||||
#include <WiFi.h>
|
||||
WiFiClient client;
|
||||
voidsetup(){}
|
||||
voidloop(){
|
||||
Serial.print("Connecting to");
|
||||
Serial.println(host);
|
||||
Serial.print(" ...");
|
||||
if(client.connect(host, 443) == true){
|
||||
Serial.println(" Connected!");
|
||||
} else {
|
||||
Serial.println(" Failed!");
|
||||
}
|
||||
}`
|
||||
Compare(source, expected)
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Arduino", func() {
|
||||
|
|
|
@ -32,9 +32,9 @@ func handleSpecsVariables(specs []ast.Spec) (code string) {
|
|||
for _, spec := range specs {
|
||||
switch s := spec.(type) {
|
||||
case *ast.ImportSpec:
|
||||
code += handleImportSpec(spec)
|
||||
code += handleImportSpec(s)
|
||||
case *ast.ValueSpec:
|
||||
code += handleValueSpec(s) + ";"
|
||||
code += handleGlobalOrLocalVariable(s)
|
||||
case *ast.TypeSpec:
|
||||
code += handleTypeSpec(s)
|
||||
}
|
||||
|
@ -42,19 +42,10 @@ func handleSpecsVariables(specs []ast.Spec) (code string) {
|
|||
return
|
||||
}
|
||||
|
||||
func handleImportSpec(spec ast.Spec) string {
|
||||
s := spec.(*ast.ImportSpec)
|
||||
code := ""
|
||||
if s.Name != nil {
|
||||
name := handleIdentExpr(s.Name)
|
||||
if val, ok := mapping[name]; ok {
|
||||
name = val
|
||||
}
|
||||
if name != "" {
|
||||
if name != "controller" {
|
||||
code = "#include <" + name + ".h>\n"
|
||||
}
|
||||
}
|
||||
func handleGlobalOrLocalVariable(s *ast.ValueSpec) (code string) {
|
||||
if IsInFunction() {
|
||||
return handleLocalVariable(s)
|
||||
}
|
||||
return code
|
||||
|
||||
return handleGlobalVariable(s)
|
||||
}
|
||||
|
|
|
@ -4,37 +4,6 @@ import (
|
|||
"go/ast"
|
||||
)
|
||||
|
||||
func handleValueSpec(s *ast.ValueSpec) (code string) {
|
||||
if s.Type == nil {
|
||||
code += addTypeByValue(s)
|
||||
}
|
||||
|
||||
code += handleValueSpecType(s.Type)
|
||||
code += " "
|
||||
|
||||
_, ok := s.Type.(*ast.StarExpr)
|
||||
if ok {
|
||||
isPointerType = true
|
||||
}
|
||||
code += handleValueSpecNames(s.Names)
|
||||
isPointerType = false
|
||||
|
||||
if s.Values != nil {
|
||||
code += " = "
|
||||
code += handleValueSpecValues(s.Values)
|
||||
}
|
||||
|
||||
l, ok := s.Type.(*ast.ArrayType)
|
||||
if ok {
|
||||
code += "["
|
||||
if l.Len != nil {
|
||||
code += handleExpr(l.Len)
|
||||
}
|
||||
code += "]"
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
func addTypeByValue(s *ast.ValueSpec) (code string) {
|
||||
if len(s.Values) == 0 {
|
||||
return
|
||||
|
|
93
pkg/service/variables.go
Обычный файл
93
pkg/service/variables.go
Обычный файл
|
@ -0,0 +1,93 @@
|
|||
package service
|
||||
|
||||
import "go/ast"
|
||||
|
||||
var (
|
||||
variableDeclarations []*Variable
|
||||
)
|
||||
|
||||
type Variable struct {
|
||||
s *ast.ValueSpec
|
||||
}
|
||||
|
||||
func NewVariable(s *ast.ValueSpec) *Variable {
|
||||
return &Variable{s: s}
|
||||
}
|
||||
|
||||
func (c *Variable) String() (code string) {
|
||||
code += c.genString(c.s)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Variable) genString(s *ast.ValueSpec) (code string) {
|
||||
if s.Type == nil {
|
||||
code += addTypeByValue(s)
|
||||
}
|
||||
|
||||
code += handleValueSpecType(s.Type)
|
||||
code += " "
|
||||
|
||||
_, ok := s.Type.(*ast.StarExpr)
|
||||
if ok {
|
||||
isPointerType = true
|
||||
}
|
||||
code += handleValueSpecNames(s.Names)
|
||||
isPointerType = false
|
||||
|
||||
if s.Values != nil {
|
||||
code += " = "
|
||||
code += handleValueSpecValues(s.Values)
|
||||
}
|
||||
|
||||
l, ok := s.Type.(*ast.ArrayType)
|
||||
if ok {
|
||||
code += "["
|
||||
if l.Len != nil {
|
||||
code += handleExpr(l.Len)
|
||||
}
|
||||
code += "]"
|
||||
}
|
||||
code += ";"
|
||||
return
|
||||
}
|
||||
|
||||
func handleLocalVariable(s *ast.ValueSpec) (code string) {
|
||||
if s.Type == nil {
|
||||
code += addTypeByValue(s)
|
||||
}
|
||||
|
||||
code += handleValueSpecType(s.Type)
|
||||
code += " "
|
||||
|
||||
_, ok := s.Type.(*ast.StarExpr)
|
||||
if ok {
|
||||
isPointerType = true
|
||||
}
|
||||
code += handleValueSpecNames(s.Names)
|
||||
isPointerType = false
|
||||
|
||||
if s.Values != nil {
|
||||
code += " = "
|
||||
code += handleValueSpecValues(s.Values)
|
||||
}
|
||||
|
||||
l, ok := s.Type.(*ast.ArrayType)
|
||||
if ok {
|
||||
code += "["
|
||||
if l.Len != nil {
|
||||
code += handleExpr(l.Len)
|
||||
}
|
||||
code += "]"
|
||||
}
|
||||
code += ";"
|
||||
return code
|
||||
}
|
||||
|
||||
func handleGlobalVariable(s *ast.ValueSpec) (code string) {
|
||||
addVariable(s)
|
||||
return
|
||||
}
|
||||
func addVariable(s *ast.ValueSpec) {
|
||||
c := NewVariable(s)
|
||||
variableDeclarations = append(variableDeclarations, c)
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче