Repository: Konstantin8105/c4go
Pull request #294 (2019-02-28 11:19:35)

transpilation


Patch:
diff --git a/transpiler/call.go b/transpiler/call.go
index c20e880..e0c1e36 100644
--- a/transpiler/call.go
+++ b/transpiler/call.go
@@ -190,6 +190,9 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 		if err != nil {
 			err = fmt.Errorf("Error in transpileCallExpr : %v", err)
 		}
+		if resultType == "" {
+			p.AddMessage(p.GenerateWarningMessage(fmt.Errorf("exprType is empty"), n))
+		}
 	}()
 
 	functionName, err := getName(p, n)
@@ -209,7 +212,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 		functionName == "__builtin_va_end" {
 		// ignore function __builtin_va_start, __builtin_va_end
 		// see "Variadic functions"
-		return nil, "", nil, nil, nil
+		return nil, n.Type, nil, nil, nil
 	}
 
 	// function "malloc" from stdlib.h
@@ -344,9 +347,33 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 			Name: functionName,
 		}
 		if len(n.Children()) > 0 {
-			if v, ok := n.Children()[0].(*ast.ImplicitCastExpr); ok &&
-				(util.IsFunction(v.Type) || types.IsTypedefFunction(p, v.Type)) {
-				t := v.Type
+
+			checker := func(t string) bool {
+				return util.IsFunction(t) || types.IsTypedefFunction(p, t)
+			}
+
+			var finder func(n ast.Node) string
+			finder = func(n ast.Node) (t string) {
+				switch v := n.(type) {
+				case *ast.ImplicitCastExpr:
+					t = v.Type
+				case *ast.ParenExpr:
+					t = v.Type
+				case *ast.CStyleCastExpr:
+					t = v.Type
+				default:
+					panic(fmt.Errorf("add type %T", n))
+				}
+				if checker(t) {
+					return t
+				}
+				if len(n.Children()) == 0 {
+					return ""
+				}
+				return finder(n.Children()[0])
+			}
+
+			if t := finder(n.Children()[0]); checker(t) {
 				if v, ok := p.TypedefType[t]; ok {
 					t = v
 				} else {
@@ -558,7 +585,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 			Rhs: []goast.Expr{realArgs[0]},
 		}
 		preStmts = append(preStmts, devNull)
-		return nil, "", preStmts, postStmts, nil
+		return nil, n.Type, preStmts, postStmts, nil
 	}
 
 	return util.NewCallExpr(functionName, realArgs...),
diff --git a/transpiler/operators.go b/transpiler/operators.go
index 277c3ba..32b7c56 100644
--- a/transpiler/operators.go
+++ b/transpiler/operators.go
@@ -59,12 +59,14 @@ func transpileConditionalOperator(n *ast.ConditionalOperator, p *program.Program
 
 	a, err = types.CastExpr(p, a, aType, "bool")
 	if err != nil {
+		err = fmt.Errorf("parameter `a` : %v", err)
 		return
 	}
 
 	// b - body
-	b, bType, newPre, newPost, err := transpileToExpr(n.Children()[1], p, false)
+	b, bType, newPre, newPost, err := atomicOperation(n.Children()[1], p)
 	if err != nil {
+		err = fmt.Errorf("parameter `b` : %v", err)
 		return
 	}
 	// Theorephly, length is must be zero
@@ -85,6 +87,7 @@ func transpileConditionalOperator(n *ast.ConditionalOperator, p *program.Program
 	// c - else body
 	c, cType, newPre, newPost, err := transpileToExpr(n.Children()[2], p, false)
 	if err != nil {
+		err = fmt.Errorf("parameter `c` : %v", err)
 		return nil, "", nil, nil, err
 	}
 	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)
@@ -92,6 +95,7 @@ func transpileConditionalOperator(n *ast.ConditionalOperator, p *program.Program
 	if n.Type != "void" {
 		c, err = types.CastExpr(p, c, cType, n.Type)
 		if err != nil {
+			err = fmt.Errorf("parameter `c` : %v", err)
 			return
 		}
 		cType = n.Type
@@ -549,6 +553,9 @@ func atomicOperation(n ast.Node, p *program.Program) (
 		if err != nil {
 			err = fmt.Errorf("Cannot create atomicOperation |%T|. err = %v", n, err)
 		}
+		if exprType == "" {
+			p.AddMessage(p.GenerateWarningMessage(fmt.Errorf("exprType is empty"), n))
+		}
 	}()
 
 	switch v := n.(type) {


Test patch:
diff --git a/tests/array.c b/tests/array.c
index e52c0e0..edc70a7 100644
--- a/tests/array.c
+++ b/tests/array.c
@@ -399,9 +399,30 @@ void test_parg_struct()
     is_streq(po_def[1].name, "optarg");
 }
 
+int function_array_field(int a)
+{
+	return a+1;
+}
+void test_function_array()
+{
+	struct fa {
+		int(* pf)(int);
+	};
+	struct fa f[10];
+	int i = 0;
+	for (i = 0; i < 10 ; i++)  {
+		f[i].pf = function_array_field;
+	}
+	int y = 42;
+	for (i = 0; i < 10; i++) {
+		y = ((f[i]).pf)(y);
+	}
+	is_eq(y , 52);
+}
+
 int main()
 {
-    plan(171);
+    plan(172);
 
     test_parg_struct();
     START_TEST(struct_init);
@@ -425,6 +446,7 @@ int main()
     START_TEST(ptrarr);
     START_TEST(stringarr_init);
     START_TEST(partialarr_init);
+    START_TEST(function_array);
 
     is_eq(arrayEx[1], 2.0);