From e9b014b6abedd84dc407d2080ac69181a4a5f36d Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Sun, 20 Oct 2019 22:23:31 +0300 Subject: [PATCH 1/9] prepare test --- testdata/main.f | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/testdata/main.f b/testdata/main.f index 0f26c735..9862051d 100644 --- a/testdata/main.f +++ b/testdata/main.f @@ -298,6 +298,9 @@ subroutine test_do() integer IR, JR, HR, iterator integer ab_min, funarr, funcell integer A(2,2) +C INTEGER LEN, NP1, INCX +C COMPLEX CTRUE5(8,5,2), CX(8) +C REAL SFAC JR = 1 iterator = 1 DO 140 IR = 1,2 @@ -353,6 +356,11 @@ subroutine test_do() GO TO 144 END IF call test_do2() + +C CALL CTEST(LEN,CX,CTRUE5(1,NP1,INCX),CTRUE5(1,NP1,INCX), +C + SFAC) + + return 142 FORMAT ('Do with inc ', I2) 146 FORMAT ('Do ', I2) @@ -363,6 +371,12 @@ subroutine test_do() 151 FORMAT (' iterator = ', I2) end +C SUBROUTINE CTEST(LEN, SCOMP, STRUE, SSIZE, SFAC) +C REAL SFAC +C INTEGER LEN +C COMPLEX SCOMP(20), SSIZE(20), STRUE(20) +C END SUBROUTINE + SUBROUTINE funcwrt(LEN, a) INTEGER LEN INTEGER a(LEN) From 440230cefcb06405f19b6c84b17a9a6ace4af13e Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Sun, 20 Oct 2019 23:17:26 +0300 Subject: [PATCH 2/9] step --- fortran/function_definition.go | 107 +++++++++++++++++---------------- intrinsic/math.go | 4 +- testdata/main.f | 3 +- 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/fortran/function_definition.go b/fortran/function_definition.go index c524f226..16d3ce6f 100644 --- a/fortran/function_definition.go +++ b/fortran/function_definition.go @@ -11,20 +11,22 @@ type callArgumentSimplification struct { func (c callArgumentSimplification) Visit(node goast.Node) (w goast.Visitor) { // from : &((*a)) // to : a - if id, ok := node.(*goast.Ident); ok { - if len(id.Name) > 6 && id.Name[:4] == "&((*" { - id.Name = id.Name[4 : len(id.Name)-2] - } - - if len(id.Name) > 11 && id.Name[:11] == "*func()*int" { - // *func()*int{y:=6;return &y}() - id.Name = id.Name[15:] - id.Name = id.Name[:len(id.Name)-13] - } - if len(id.Name) > 8 && id.Name[:8] == "*func()*" { - // TODO : for other types - // fmt.Println("Simply : ", id.Name) - } + if id, ok := node.(*goast.Ident); ok && strings.Contains(id.Name, "*func()") { + // TODO: simplify + // if len(id.Name) > 6 && id.Name[:4] == "&((*" { + // id.Name = id.Name[4 : len(id.Name)-2] + // } + // + // if len(id.Name) > 11 && id.Name[:11] == "*func()*int" { + // // *func()*int{y:=6;return &y}() + // id.Name = id.Name[15:] + // id.Name = id.Name[:len(id.Name)-13] + // } + // + // if len(id.Name) > 8 && id.Name[:8] == "*func()*" { + // // TODO : for other types + // // fmt.Println("Simply : ", id.Name) + // } } return c @@ -36,57 +38,60 @@ type intrinsic struct { func (in intrinsic) Visit(node goast.Node) (w goast.Visitor) { - if call, ok := node.(*goast.CallExpr); ok { - if n, ok := call.Fun.(*goast.Ident); ok { - if f, ok := intrinsicFunction[strings.ToUpper(n.Name)]; ok { - f(in.p, call) - } else if n.Name != "make" && n.Name != "append" && n.Name != "panic" { - n.Name = strings.ToUpper(n.Name) - } + call, ok := node.(*goast.CallExpr) + if !ok { + return in + } + + if n, ok := call.Fun.(*goast.Ident); ok { + if f, ok := intrinsicFunction[strings.ToUpper(n.Name)]; ok { + f(in.p, call) + } else if n.Name != "make" && n.Name != "append" && n.Name != "panic" { + n.Name = strings.ToUpper(n.Name) } } - if call, ok := node.(*goast.CallExpr); ok { - if sel, ok := call.Fun.(*goast.SelectorExpr); ok { - if x, ok := sel.X.(*goast.Ident); ok && x.Name == "intrinsic" { - var isRead bool = sel.Sel.Name == "READ" + if sel, ok := call.Fun.(*goast.SelectorExpr); ok { + if x, ok := sel.X.(*goast.Ident); ok && x.Name == "intrinsic" { + + var isRead bool = sel.Sel.Name == "READ" - for i := range call.Args { - if isRead && i > 1 { - // for READ command other arguments is pointer always + for i := range call.Args { + if isRead && i > 1 { + // for READ command other arguments is pointer always + continue + } + if arg, ok := call.Args[i].(*goast.Ident); ok { + if len(arg.Name) > 3 && arg.Name[:2] == "&(" { + arg.Name = arg.Name[2 : len(arg.Name)-1] continue } - if arg, ok := call.Args[i].(*goast.Ident); ok { - if len(arg.Name) > 3 && arg.Name[:2] == "&(" { - arg.Name = arg.Name[2 : len(arg.Name)-1] - continue - } - if strings.Contains(arg.Name, "func()*[]byte{y:=[]byte(") { - arg.Name = arg.Name[17:] - index := strings.LastIndex(arg.Name, "\")") - arg.Name = arg.Name[:index+2] - if i > 1 { - arg.Name = arg.Name[7 : len(arg.Name)-1] - } - continue - } - if len(arg.Name) > 10 && arg.Name[:7] == "func()*" { - arg.Name = "*" + arg.Name - continue + if strings.Contains(arg.Name, "func()*[]byte{y:=[]byte(") { + arg.Name = arg.Name[17:] + index := strings.LastIndex(arg.Name, "\")") + arg.Name = arg.Name[:index+2] + if i > 1 { + arg.Name = arg.Name[7 : len(arg.Name)-1] } + continue } - if un, ok := call.Args[i].(*goast.UnaryExpr); ok { - if par, ok := un.X.(*goast.ParenExpr); ok { - if id, ok := par.X.(*goast.IndexExpr); ok { - call.Args[i] = id - continue - } + if len(arg.Name) > 10 && arg.Name[:7] == "func()*" { + arg.Name = "*" + arg.Name + continue + } + } + if un, ok := call.Args[i].(*goast.UnaryExpr); ok { + if par, ok := un.X.(*goast.ParenExpr); ok { + if id, ok := par.X.(*goast.IndexExpr); ok { + call.Args[i] = id + continue } } } } } } + return in } diff --git a/intrinsic/math.go b/intrinsic/math.go index e484be11..f56ff000 100644 --- a/intrinsic/math.go +++ b/intrinsic/math.go @@ -86,8 +86,8 @@ func DBLE(a interface{}) float64 { panic(fmt.Errorf("Cannot find type : %T", a)) } -func ABS(a float64) float64 { - return math.Abs(a) +func ABS(a interface{}) float64 { + return math.Abs(castToFloat64(a)) } func CABS(a complex128) float64 { diff --git a/testdata/main.f b/testdata/main.f index 9862051d..2a6e2fae 100644 --- a/testdata/main.f +++ b/testdata/main.f @@ -341,8 +341,7 @@ subroutine test_do() call NOPAREN -C Do IR = 1,ab_min(ab_min(3,13),1000) - Do IR = 1,ab_min(3,13) + Do IR = 1,ab_min(ab_min(3,13),1000) write (*,FMT=149) IR enddo DO 145, HR = 1,2 From 9060efa37ca14a242536c751d894efd3a3b541dc Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Sun, 20 Oct 2019 23:31:30 +0300 Subject: [PATCH 3/9] step --- fortran/function_definition.go | 17 ++++++++++++++++- fortran/parser.go | 10 ++++------ testdata/main.f | 3 ++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/fortran/function_definition.go b/fortran/function_definition.go index 16d3ce6f..e0efea3f 100644 --- a/fortran/function_definition.go +++ b/fortran/function_definition.go @@ -36,6 +36,21 @@ type intrinsic struct { p *parser } +func isGoFunc(name string) bool { + var list = [...]string{ + "panic", + "make", + "real", + "append", + } + for i := range list { + if list[i] == name { + return true + } + } + return false +} + func (in intrinsic) Visit(node goast.Node) (w goast.Visitor) { call, ok := node.(*goast.CallExpr) @@ -46,7 +61,7 @@ func (in intrinsic) Visit(node goast.Node) (w goast.Visitor) { if n, ok := call.Fun.(*goast.Ident); ok { if f, ok := intrinsicFunction[strings.ToUpper(n.Name)]; ok { f(in.p, call) - } else if n.Name != "make" && n.Name != "append" && n.Name != "panic" { + } else if !isGoFunc(n.Name) { n.Name = strings.ToUpper(n.Name) } } diff --git a/fortran/parser.go b/fortran/parser.go index 71a4bb4b..b3a212af 100644 --- a/fortran/parser.go +++ b/fortran/parser.go @@ -891,10 +891,7 @@ func (c callArg) Visit(node goast.Node) (w goast.Visitor) { } if call, ok := node.(*goast.CallExpr); ok { if id, ok := call.Fun.(*goast.Ident); ok { - if id.Name == "append" { - return nil - } - if id.Name == "panic" { + if isGoFunc(id.Name) { return nil } } @@ -940,11 +937,12 @@ func (c callArg) Visit(node goast.Node) (w goast.Visitor) { } case *goast.CallExpr: - // var ident goast.Ident + // var ident *goast.Ident // ident, ok := a.Fun.(*goast.Ident) - // if ok { + // if !ok { // continue // } + // fmt.Println(">>>>>>", ident) // returnType, ok := p.functionReturnType[ident.Name] // if ok { // continue diff --git a/testdata/main.f b/testdata/main.f index 2a6e2fae..9862051d 100644 --- a/testdata/main.f +++ b/testdata/main.f @@ -341,7 +341,8 @@ subroutine test_do() call NOPAREN - Do IR = 1,ab_min(ab_min(3,13),1000) +C Do IR = 1,ab_min(ab_min(3,13),1000) + Do IR = 1,ab_min(3,13) write (*,FMT=149) IR enddo DO 145, HR = 1,2 From 225effdf42cd347d54909d91ccb961f109c0889e Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Fri, 18 Oct 2019 17:32:20 +0300 Subject: [PATCH 4/9] step --- fortran/function_definition.go | 40 +++++++++++++++++------------ main.go | 31 +++++++++++++++-------- main_test.go | 46 ++++++++++++++++++++++++++-------- 3 files changed, 80 insertions(+), 37 deletions(-) diff --git a/fortran/function_definition.go b/fortran/function_definition.go index e0efea3f..737ce945 100644 --- a/fortran/function_definition.go +++ b/fortran/function_definition.go @@ -11,23 +11,31 @@ type callArgumentSimplification struct { func (c callArgumentSimplification) Visit(node goast.Node) (w goast.Visitor) { // from : &((*a)) // to : a - if id, ok := node.(*goast.Ident); ok && strings.Contains(id.Name, "*func()") { - // TODO: simplify - // if len(id.Name) > 6 && id.Name[:4] == "&((*" { - // id.Name = id.Name[4 : len(id.Name)-2] - // } - // - // if len(id.Name) > 11 && id.Name[:11] == "*func()*int" { - // // *func()*int{y:=6;return &y}() - // id.Name = id.Name[15:] - // id.Name = id.Name[:len(id.Name)-13] - // } - // - // if len(id.Name) > 8 && id.Name[:8] == "*func()*" { - // // TODO : for other types - // // fmt.Println("Simply : ", id.Name) - // } + id, ok := node.(*goast.Ident) + if !ok { + return c + } + + if len(id.Name) > 6 && id.Name[:4] == "&((*" { + id.Name = id.Name[4 : len(id.Name)-2] + return c + } + + if !strings.Contains(id.Name, "*func()") { + return c + } + + // *func()*int{y:=6;return &y}() + // *func()*byte{y:=byte('K');return &y}() + index := strings.Index(id.Name, "=") + if index < 0 { + return c + } + last := strings.LastIndex(id.Name, ";") + if last < 0 { + return c } + id.Name = id.Name[index+1 : last] return c } diff --git a/main.go b/main.go index 2078ca10..3a105298 100644 --- a/main.go +++ b/main.go @@ -15,11 +15,19 @@ import ( "github.com/Konstantin8105/f4go/fortran" ) -var packageFlag *string +var ( + packageFlag string + verboseFlag bool +) func main() { - packageFlag = flag.String("p", - "main", "set the name of the generated package") + pntPack := &packageFlag + pntPack = flag.String("p", "main", "set the name of the generated package") + _ = pntPack + + pntVerbose := &verboseFlag + pntVerbose = flag.Bool("v", false, "verbose all stages of transpilation and all errors") + _ = pntVerbose run() } @@ -35,14 +43,11 @@ func run() { return } - if packageFlag == nil { - var s string - packageFlag = &s - } - - es := parseParallel(flag.Args(), *packageFlag) - for _, e := range es { - fmt.Printf("%20s : %s\n", e.filename, e.err.Error()) + es := parseParallel(flag.Args(), packageFlag) + if verboseFlag { + for _, e := range es { + fmt.Printf("%20s : %s\n", e.filename, e.err.Error()) + } } } @@ -51,6 +56,10 @@ type errorRow struct { filename string } +func (e errorRow) Error() string { + return fmt.Sprintf("%s : %v", e.filename, e.err) +} + // parsing to Go code func parse(filename, packageName, goFilename string) (errR []errorRow) { if packageName == "" { diff --git a/main_test.go b/main_test.go index 0d23112e..80cdde08 100644 --- a/main_test.go +++ b/main_test.go @@ -122,7 +122,14 @@ func ShowDiff(a, b string) string { func TestFail(t *testing.T) { - fortran.Debug = testing.Verbose() + { + oldVerbose := verboseFlag + defer func() { + verboseFlag = oldVerbose + }() + fortran.Debug = testing.Verbose() + verboseFlag = testing.Verbose() + } // wrong source errs := parse("./testdata/fortran_fail.f", "", "") @@ -181,7 +188,7 @@ func getFortranTestFiles(dir string) (files []string, err error) { return } -func parsingBlas(filename string) (failed bool) { +func parsingBlas(filename string) (err error) { filename = "./" + filename // Go name @@ -192,7 +199,17 @@ func parsingBlas(filename string) (failed bool) { goname = strings.Replace(goname, "SRC", "TESTING", 1) // parse - return len(parse(filename, "main", goname)) > 0 + errR := parse(filename, "main", goname) + if len(errR) == 0 { + return nil + } + + var str string + for i := range errR { + str += errR[i].Error() + "\n" + } + + return fmt.Errorf(str) } func TestBlas(t *testing.T) { @@ -215,9 +232,10 @@ func TestBlas(t *testing.T) { var amount int for i := range ss { - failed := parsingBlas(ss[i]) - if failed { + err := parsingBlas(ss[i]) + if err != nil { t.Logf("Error is not empty in file: %s", ss[i]) + t.Logf("%v", err) amount++ } } @@ -249,7 +267,7 @@ func TestBlas(t *testing.T) { } } if !found { - t.Errorf("Cannot find fortran line %d: %s", i, fortran[i]) + t.Errorf("Cannot find FORTRAN line %d: %s", i, fortran[i]) } } @@ -264,7 +282,7 @@ func TestBlas(t *testing.T) { } } if !found { - t.Errorf("Cannot find go line %d: %s", i, gof[i]) + t.Errorf("Cannot find GO line %d: %s", i, gof[i]) } } } @@ -312,9 +330,10 @@ func TestBlasTesting(t *testing.T) { for i := range tcs { t.Run(fmt.Sprintf("TESTING%3d", i), func(t *testing.T) { for j := range tcs[i].fortranFiles { - failed := parsingBlas(tcs[i].fortranFiles[j]) - if failed { + err := parsingBlas(tcs[i].fortranFiles[j]) + if err != nil { t.Logf("failed file: %s", tcs[i].fortranFiles[j]) + t.Logf("%v", err) } } @@ -493,7 +512,14 @@ func TestComments(t *testing.T) { func TestCrash(t *testing.T) { - fortran.Debug = testing.Verbose() + { + oldVerbose := verboseFlag + defer func() { + verboseFlag = oldVerbose + }() + fortran.Debug = testing.Verbose() + verboseFlag = testing.Verbose() + } var ( in = "./testdata/min_crash.f" From 56e97d581ee425e35ebd279913e9639a98064c4a Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Fri, 18 Oct 2019 19:21:32 +0300 Subject: [PATCH 5/9] add test --- fortran/function_definition.go | 4 ++-- testdata/main.f | 34 ++++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/fortran/function_definition.go b/fortran/function_definition.go index 737ce945..6e761555 100644 --- a/fortran/function_definition.go +++ b/fortran/function_definition.go @@ -9,14 +9,14 @@ type callArgumentSimplification struct { } func (c callArgumentSimplification) Visit(node goast.Node) (w goast.Visitor) { - // from : &((*a)) - // to : a id, ok := node.(*goast.Ident) if !ok { return c } if len(id.Name) > 6 && id.Name[:4] == "&((*" { + // from : &((*a)) + // to : a id.Name = id.Name[4 : len(id.Name)-2] return c } diff --git a/testdata/main.f b/testdata/main.f index 9862051d..762f6b64 100644 --- a/testdata/main.f +++ b/testdata/main.f @@ -298,9 +298,20 @@ subroutine test_do() integer IR, JR, HR, iterator integer ab_min, funarr, funcell integer A(2,2) -C INTEGER LEN, NP1, INCX -C COMPLEX CTRUE5(8,5,2), CX(8) -C REAL SFAC + INTEGER NP1, INCX + COMPLEX CTRUE5(8,5,2) + + iterator = 9 + DO IR = 1,8 + DO JR = 1,5 + DO HR = 1,2 + CTRUE5(IR,JR,HR) = CMPLX(iterator) + iterator = iterator + 3 + WRITE (*,'(F8.2)') REAL(CTRUE5(IR,JR,HR)) + END DO + END DO + END DO + JR = 1 iterator = 1 DO 140 IR = 1,2 @@ -357,8 +368,9 @@ subroutine test_do() END IF call test_do2() -C CALL CTEST(LEN,CX,CTRUE5(1,NP1,INCX),CTRUE5(1,NP1,INCX), -C + SFAC) + NP1 = 1 + INCX = 1 + CALL CTEST(CTRUE5(1,NP1,INCX)) return @@ -371,11 +383,13 @@ subroutine test_do() 151 FORMAT (' iterator = ', I2) end -C SUBROUTINE CTEST(LEN, SCOMP, STRUE, SSIZE, SFAC) -C REAL SFAC -C INTEGER LEN -C COMPLEX SCOMP(20), SSIZE(20), STRUE(20) -C END SUBROUTINE + SUBROUTINE CTEST(STRUE) + COMPLEX STRUE(20) + Integer i + DO i = 1,20 + WRITE (*,'(F8.2)') REAL(STRUE(I)) + ENd do + END SUBROUTINE SUBROUTINE funcwrt(LEN, a) INTEGER LEN From b245eb0e96921441b121e7fe9d0fd0123df77a10 Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Fri, 18 Oct 2019 19:31:30 +0300 Subject: [PATCH 6/9] CMPLX --- fortran/function_definition.go | 5 +++++ intrinsic/math.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/fortran/function_definition.go b/fortran/function_definition.go index 6e761555..395c2d81 100644 --- a/fortran/function_definition.go +++ b/fortran/function_definition.go @@ -197,6 +197,11 @@ var intrinsicFunction = map[string]func(*parser, *goast.CallExpr){ p.addImport("github.com/Konstantin8105/f4go/intrinsic") intrinsicArgumentCorrection(p, f, "intrinsic.EPSILON", typeNames) }, + "CMPLX": func(p *parser, f *goast.CallExpr) { + typeNames := []string{"any"} + p.addImport("github.com/Konstantin8105/f4go/intrinsic") + intrinsicArgumentCorrection(p, f, "intrinsic.CMPLX", typeNames) + }, "SQRT": func(p *parser, f *goast.CallExpr) { typeNames := []string{"any"} p.addImport("github.com/Konstantin8105/f4go/intrinsic") diff --git a/intrinsic/math.go b/intrinsic/math.go index f56ff000..04e5d0d3 100644 --- a/intrinsic/math.go +++ b/intrinsic/math.go @@ -40,6 +40,11 @@ func castToFloat64(w interface{}) float64 { } } +func CMPLX(a interface{}) complex128 { + A := castToFloat64(a) + return complex(A, 0) +} + func SQRT(a interface{}) float64 { A := castToFloat64(a) return math.Sqrt(A) From 2777d519f1fcf5fe65681b5c0e191a5811237165 Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Fri, 18 Oct 2019 22:14:56 +0300 Subject: [PATCH 7/9] step --- fortran/parser.go | 77 +++++++++++++++++++++++++++++++++++++++++++++++ testdata/main.f | 2 ++ 2 files changed, 79 insertions(+) diff --git a/fortran/parser.go b/fortran/parser.go index b3a212af..41ef95af 100644 --- a/fortran/parser.go +++ b/fortran/parser.go @@ -247,6 +247,8 @@ func Parse(b []byte, packageName string) (_ goast.File, errs []error) { p.ident = 0 decls = p.parseNodes() + correctCellVector(decls) + // add packages for pkg := range p.pkgs { p.ast.Decls = append(p.ast.Decls, &goast.GenDecl{ @@ -344,6 +346,81 @@ func Parse(b []byte, packageName string) (_ goast.File, errs []error) { return p.ast, p.errs } +type callCorrection struct { + args map[string][]*goast.Field +} + +func (cc callCorrection) Visit(node goast.Node) (w goast.Visitor) { + call, ok := node.(*goast.CallExpr) + if !ok { + return cc + } + + ident, ok := call.Fun.(*goast.Ident) + if !ok { + return cc + } + + name := ident.Name + + args, ok := cc.args[name] + if !ok { + return cc + } + + if len(args) != len(call.Args) { + return cc + } + + for i := range call.Args { + var count int + goast.Inspect(call.Args[i], func(node goast.Node) bool { + if _, ok := node.(*goast.IndexExpr); ok { + count++ + } + return true + }) + ident, ok := args[i].Type.(*goast.Ident) + if !ok { + continue + } + nameCount := strings.Count(ident.Name, "[") + if count == nameCount { + continue + } + if count < nameCount { + continue + } + if nameCount == 0 { + continue + } + // TODO: replace cell to vector information + fmt.Println(">>", name, count, nameCount) + } + + return cc +} + +func correctCellVector(decls []goast.Decl) { + // get all goast.FuncDecl arguments + var cc callCorrection + cc.args = map[string][]*goast.Field{} + for i := range decls { + decl, ok := decls[i].(*goast.FuncDecl) + if !ok { + continue + } + name := decl.Name.Name + typ := decl.Type.Params.List + cc.args[name] = typ + } + + // iteration by all goast.CallExpr + for i := range decls { + goast.Walk(cc, decls[i]) + } +} + // go/ast Visitor for comment label type commentLabel struct { labels map[string]bool diff --git a/testdata/main.f b/testdata/main.f index 762f6b64..9926f6ea 100644 --- a/testdata/main.f +++ b/testdata/main.f @@ -387,6 +387,8 @@ SUBROUTINE CTEST(STRUE) COMPLEX STRUE(20) Integer i DO i = 1,20 + WRITE (*,* ) "CTEST" + WRITE (*,'(I2)' ) I WRITE (*,'(F8.2)') REAL(STRUE(I)) ENd do END SUBROUTINE From 69987cd4b69f96fec8987f8253bfee747889f3d4 Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Fri, 18 Oct 2019 23:42:03 +0300 Subject: [PATCH 8/9] todo --- fortran/parser.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fortran/parser.go b/fortran/parser.go index 41ef95af..4d3a9b6f 100644 --- a/fortran/parser.go +++ b/fortran/parser.go @@ -396,6 +396,13 @@ func (cc callCorrection) Visit(node goast.Node) (w goast.Visitor) { } // TODO: replace cell to vector information fmt.Println(">>", name, count, nameCount) + // preliminary code: + // CTEST(M[2][3][4]) + // + // transform cell to vector + // CTEST((*[1000000]float64)(unsafe.Pointer(M[2][3][4]))[:]) + // ------- ---------- + // TYPE CELL } return cc From 2850b9991126a31ea15222dd6aaaf7ef90ae95e3 Mon Sep 17 00:00:00 2001 From: Konstantin8105 Date: Sat, 19 Oct 2019 00:25:14 +0300 Subject: [PATCH 9/9] step --- fortran/parser.go | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/fortran/parser.go b/fortran/parser.go index 4d3a9b6f..98d3f8ae 100644 --- a/fortran/parser.go +++ b/fortran/parser.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" goast "go/ast" + "go/format" goparser "go/parser" "go/token" "os" @@ -247,7 +248,7 @@ func Parse(b []byte, packageName string) (_ goast.File, errs []error) { p.ident = 0 decls = p.parseNodes() - correctCellVector(decls) + p.correctCellVector(decls) // add packages for pkg := range p.pkgs { @@ -348,6 +349,7 @@ func Parse(b []byte, packageName string) (_ goast.File, errs []error) { type callCorrection struct { args map[string][]*goast.Field + p *parser } func (cc callCorrection) Visit(node goast.Node) (w goast.Visitor) { @@ -394,24 +396,51 @@ func (cc callCorrection) Visit(node goast.Node) (w goast.Visitor) { if nameCount == 0 { continue } - // TODO: replace cell to vector information - fmt.Println(">>", name, count, nameCount) + if nameCount != 1 { + // TODO: not clear - is it happend? + continue + } // preliminary code: // CTEST(M[2][3][4]) + // ---------- + // CELL // // transform cell to vector // CTEST((*[1000000]float64)(unsafe.Pointer(M[2][3][4]))[:]) // ------- ---------- // TYPE CELL + + var cell string // M[2][3][4] + { + // func Fprint(w io.Writer, fset *token.FileSet, x interface{}, f FieldFilter) error + var buf bytes.Buffer + err := format.Node(&buf, token.NewFileSet(), call.Args[i]) + if err != nil { + panic(err) + } + cell = buf.String() + } + + var typ = args[i].Type.(*goast.Ident).Name // "*[ ]complex128" + var typSize = strings.Replace(typ, "[", "[1000000", -1) + + // func () ( output *[]TYPE) { + // output = (*[1000000]TYPE)(unsafe.Pointer(M[2][3][4]))[:] + // return + // } + + call.Args[i] = goast.NewIdent(fmt.Sprintf(` func () ( _ %s) { output := (%s)(unsafe.Pointer(%s))[:]; return &output}() `, typ, typSize, cell)) + cc.p.addImport("unsafe") } return cc } -func correctCellVector(decls []goast.Decl) { +func (p *parser) correctCellVector(decls []goast.Decl) { // get all goast.FuncDecl arguments var cc callCorrection cc.args = map[string][]*goast.Field{} + cc.p = p for i := range decls { decl, ok := decls[i].(*goast.FuncDecl) if !ok {