Сценарий: Последовательность блоков: инклюды, константы, типы, абстрактные классы, классы, переменные, определения функций, функции

Этот коммит содержится в:
Softonik 2024-02-12 04:16:15 +03:00 коммит произвёл Nobody
родитель 7ffcf77114
коммит 88229f2bd5
11 изменённых файлов: 326 добавлений и 143 удалений

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

@ -21,8 +21,7 @@ func (c *Const) String() (code string) {
func (c *Const) generate() (code string) { func (c *Const) generate() (code string) {
code += "const " code += "const "
code += handleValueSpec(c.s) code += handleLocalVariable(c.s)
code += ";"
return return
} }

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

@ -302,10 +302,10 @@ func main() {
``` ```
* Результат: * Результат:
``` ```
void main();
class device { class device {
public: public:
}; };
void main();
device *dev1,*dev2; device *dev1,*dev2;
void main() { void main() {
dev1=new device(); dev1=new device();
@ -333,11 +333,11 @@ func main() {
``` ```
* Результат: * Результат:
``` ```
Device* NewDevice();
void main();
class Device { class Device {
public: public:
}; };
Device* NewDevice();
void main();
Device *dev1,*dev2; Device *dev1,*dev2;
Device* NewDevice() { Device* NewDevice() {
return new Device(); return new Device();
@ -347,11 +347,21 @@ dev1=NewDevice();
} }
``` ```
Сценарий: Последовательность блоков: константы, типы, абстрактные классы, классы, переменные, функции Сценарий: Последовательность блоков: инклюды, константы, типы, абстрактные классы, классы, переменные, определения функций, функции
* Исходник: * Исходник:
``` ```
package test package test
import wifi "some/wifi"
func someFunc() {}
var a = 1
var b = 1
type device struct {}
func (d *device) doSomething() {}
type Device interface { type Device interface {
Name() string Name() string
} }
@ -362,10 +372,61 @@ const c1 = 4
``` ```
* Результат: * Результат:
``` ```
#include <WiFi.h>
const int c1 = 4; const int c1 = 4;
typedef int Mera; typedef int Mera;
void someFunc();
class Device { class Device {
public: public:
virtual std::string Name() = 0; 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 Обычный файл
Просмотреть файл

@ -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 int Mera;
typedef bool GPIOS[GPIO_count]; 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 package service
import ( import (
"fmt"
"go/ast" "go/ast"
"strings" "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 { func handleFuncDecl(decl ast.Decl) string {
incInFunctionDepth()
defer decInFunctionDepth()
fd := decl.(*ast.FuncDecl) fd := decl.(*ast.FuncDecl)
if fd.Recv != nil { if fd.Recv != nil {
return handleMethodDeclaration(fd) return handleMethodDeclaration(fd)

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) dst[i] = make(chan string, 1)
} }
includeDeclarations = nil
constDeclarations = nil constDeclarations = nil
typeDeclarations = nil typeDeclarations = nil
abstractClassDeclarations = nil abstractClassDeclarations = nil
classDeclarations = nil classDeclarations = nil
variableDeclarations = nil
funcDeclarations = nil funcDeclarations = nil
helpersForDeclarations = nil helpersForDeclarations = nil
@ -106,12 +108,14 @@ func (s *defaultService) Start() error {
} }
} }
s.printIncludeHeaders() s.printIncludeAdruinoHeader()
s.printIncludes()
s.printConstDeclarations() s.printConstDeclarations()
s.printTypeDeclarations() s.printTypeDeclarations()
s.printFunctionDeclarations()
s.printAbstractClassDeclarations() s.printAbstractClassDeclarations()
s.printClassDeclarations() s.printClassDeclarations()
s.printFunctionDeclarations() s.printVariableDeclarations()
s.printGoHelperDeclarations() s.printGoHelperDeclarations()
// Print the ordered result. // Print the ordered result.
@ -128,7 +132,7 @@ func (s *defaultService) Start() error {
return nil return nil
} }
func (s *defaultService) printIncludeHeaders() { func (s *defaultService) printIncludeAdruinoHeader() {
if !s.addIncludeArduinoH { if !s.addIncludeArduinoH {
return return
} }
@ -136,6 +140,19 @@ func (s *defaultService) printIncludeHeaders() {
h := "#include <Arduino.h>\n\n" h := "#include <Arduino.h>\n\n"
s.out.Write([]byte(h)) 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() { func (s *defaultService) printConstDeclarations() {
dlock.Lock() dlock.Lock()
defer dlock.Unlock() defer dlock.Unlock()
@ -162,6 +179,18 @@ func (s *defaultService) printTypeDeclarations() {
} }
s.out.Write([]byte("\n")) 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() { func (s *defaultService) printAbstractClassDeclarations() {
dlock.Lock() dlock.Lock()
defer dlock.Unlock() defer dlock.Unlock()
@ -188,14 +217,15 @@ func (s *defaultService) printClassDeclarations() {
} }
s.out.Write([]byte("\n")) s.out.Write([]byte("\n"))
} }
func (s *defaultService) printFunctionDeclarations() { func (s *defaultService) printVariableDeclarations() {
dlock.Lock() dlock.Lock()
defer dlock.Unlock() defer dlock.Unlock()
for _, f := range funcDeclarations { for _, c := range variableDeclarations {
s.out.Write([]byte(f + "\n")) d := c.String()
s.out.Write([]byte(d + "\n"))
if s.header != nil { if s.header != nil {
s.header.Write([]byte(f + "\n")) s.header.Write([]byte(d + "\n"))
} }
} }
s.out.Write([]byte("\n")) s.out.Write([]byte("\n"))

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

@ -90,22 +90,6 @@ var _ = Describe("Go Translator", func() {
Compare(source, expected) 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() { It("Function_With_Function_Call", func() {
source := `package test source := `package test
func foo() { func foo() {
@ -497,73 +481,6 @@ var _ = Describe("Go Translator", func() {
` `
Compare(source, expected) 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() { Describe("Arduino", func() {

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

@ -32,9 +32,9 @@ func handleSpecsVariables(specs []ast.Spec) (code string) {
for _, spec := range specs { for _, spec := range specs {
switch s := spec.(type) { switch s := spec.(type) {
case *ast.ImportSpec: case *ast.ImportSpec:
code += handleImportSpec(spec) code += handleImportSpec(s)
case *ast.ValueSpec: case *ast.ValueSpec:
code += handleValueSpec(s) + ";" code += handleGlobalOrLocalVariable(s)
case *ast.TypeSpec: case *ast.TypeSpec:
code += handleTypeSpec(s) code += handleTypeSpec(s)
} }
@ -42,19 +42,10 @@ func handleSpecsVariables(specs []ast.Spec) (code string) {
return return
} }
func handleImportSpec(spec ast.Spec) string { func handleGlobalOrLocalVariable(s *ast.ValueSpec) (code string) {
s := spec.(*ast.ImportSpec) if IsInFunction() {
code := "" return handleLocalVariable(s)
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 code
return handleGlobalVariable(s)
} }

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

@ -4,37 +4,6 @@ import (
"go/ast" "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) { func addTypeByValue(s *ast.ValueSpec) (code string) {
if len(s.Values) == 0 { if len(s.Values) == 0 {
return return

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)
}