/
gir.go
134 lines (121 loc) · 3.05 KB
/
gir.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main
//go:generate gir -f testdata/test.gir -o testdata/test_amd64.s -proto testdata/test_proto.go
//go:generate gir -f testdata/test1.gir -o testdata/test1_amd64.s -proto testdata/test1_proto.go
//go:generate gir -f testdata/test2.gir -o testdata/test2_amd64.s -proto testdata/test2_proto.go
//go:generate gir -f testdata/test3.gir -o testdata/test3_amd64.s -proto testdata/test3_proto.go
//go:generate gir -f testdata/test4.gir -o testdata/test4_amd64.s -proto testdata/test4_proto.go
import (
"bufio"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"strings"
"github.com/bjwbell/gir/codegen"
"github.com/bjwbell/gir/config"
"github.com/bjwbell/gir/ctx"
"github.com/bjwbell/gir/parse"
"github.com/bjwbell/gir/scan"
"github.com/bjwbell/gir/token"
"github.com/bjwbell/gir/value"
)
var (
conf config.Config
context value.Context
)
func filePath(pathName string) string {
split := strings.Split(pathName, "/")
dir := ""
if len(split) == 1 {
dir = "."
} else if len(split) == 2 {
dir = split[0] + "/"
} else {
dir = strings.Join(split[0:len(split)-2], "/")
}
return dir
}
func main() {
context = ctx.NewContext(&conf)
var f = flag.String("f", "", "input *.gir file ")
var o = flag.String("o", "", "output *.s file ")
var proto = flag.String("proto", "", "output *.go prototype file")
flag.Parse()
file := ""
outfile := ""
protofile := ""
log.SetFlags(log.Lshortfile)
if *f != "" {
file = *f
} else {
log.Fatalf("Error no file provided")
}
if *o != "" {
outfile = *o
}
if *proto != "" {
protofile = *proto
}
var fd io.Reader
var err error
fd, err = os.Open(file)
if err != nil {
fmt.Fprintf(os.Stderr, "gir: %s\n", err)
os.Exit(1)
}
var fd2 io.Reader
var err2 error
fd2, err2 = os.Open(file)
if err2 != nil {
fmt.Fprintf(os.Stderr, "gir: %s\n", err2)
os.Exit(1)
}
scanner1 := scan.New(context, file, bufio.NewReader(fd))
scanner2 := scan.New(context, file, bufio.NewReader(fd2))
fmt.Println("Tokens: ")
for tok := scanner1.Next(); tok.Type != token.EOF; tok = scanner1.Next() {
fmt.Println(tok, "type ", tok.Type)
}
parser := parse.NewParser(file, scanner2, context)
fileDecl := parser.ParseFile()
pkg := fileDecl.PkgName
fmt.Println("tree(exprs): ", parse.Tree(fileDecl))
asm := ""
protos := ""
for _, fnDecl := range fileDecl.Decls {
ssafn, ok := codegen.BuildSSA(&fnDecl, fileDecl.PkgName, false)
if ssafn == nil || !ok {
fmt.Println("Error building SSA form")
return
} else {
fmt.Println("ssa:\n", ssafn)
var ok bool
asm, ok = codegen.GenAsm(ssafn)
if !ok {
fmt.Println("Error generating assembly")
}
if fnProto, ok := codegen.GenGoProto(ssafn); ok {
protos += fnProto
} else {
fmt.Println("Error generating Go proto file")
}
}
}
if outfile != "" {
err = ioutil.WriteFile(outfile, []byte(asm), 0644)
if err != nil {
panic(err)
}
}
if protofile != "" {
protoTxt := "// +build amd64\n\n"
protoTxt += fmt.Sprintf("package %s\n", pkg)
protoTxt += protos
err = ioutil.WriteFile(protofile, []byte(protoTxt), 0644)
if err != nil {
panic(err)
}
}
}