Switch to go/loader
This does typechecking internally and makes importing packages a whole lot easier in the future.
Этот коммит содержится в:
родитель
bc28975c8c
коммит
7ffb73b407
1 изменённых файлов: 35 добавлений и 15 удалений
50
tgo.go
50
tgo.go
|
@ -7,10 +7,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/constant"
|
"go/constant"
|
||||||
"go/parser"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/loader"
|
||||||
"llvm.org/llvm/bindings/go/llvm"
|
"llvm.org/llvm/bindings/go/llvm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,23 +46,41 @@ func NewCompiler(path, triplet string) (*Compiler, error) {
|
||||||
putsType := llvm.FunctionType(llvm.Int32Type(), []llvm.Type{llvm.PointerType(llvm.Int8Type(), 0)}, false)
|
putsType := llvm.FunctionType(llvm.Int32Type(), []llvm.Type{llvm.PointerType(llvm.Int8Type(), 0)}, false)
|
||||||
c.putsFunc = llvm.AddFunction(c.mod, "puts", putsType)
|
c.putsFunc = llvm.AddFunction(c.mod, "puts", putsType)
|
||||||
|
|
||||||
mainType := llvm.FunctionType(llvm.Int32Type(), nil, false)
|
|
||||||
mainFunc := llvm.AddFunction(c.mod, "main", mainType)
|
|
||||||
start := c.ctx.AddBasicBlock(mainFunc, "start")
|
|
||||||
c.builder.SetInsertPointAtEnd(start)
|
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) Parse(path string) error {
|
func (c *Compiler) Parse(path string) error {
|
||||||
fset := token.NewFileSet()
|
config := loader.Config {
|
||||||
file, err := parser.ParseFile(fset, path, nil, 0)
|
// TODO: TypeChecker.Sizes
|
||||||
|
// TODO: Build (build.Context) - GOOS, GOARCH, GOPATH, etc
|
||||||
|
}
|
||||||
|
config.CreateFromFilenames("main", path)
|
||||||
|
program, err := config.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("package:", file.Name.Name)
|
pkgInfo := program.Created[0] // main?
|
||||||
|
if len(pkgInfo.Errors) != 0 {
|
||||||
|
return pkgInfo.Errors[0] // TODO: better error checking
|
||||||
|
}
|
||||||
|
fmt.Println("package:", pkgInfo.Pkg.Name())
|
||||||
|
for _, file := range pkgInfo.Files {
|
||||||
|
err := c.parseFile(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Compiler) IR() string {
|
||||||
|
return c.mod.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (c *Compiler) parseFile(file *ast.File) error {
|
||||||
for _, decl := range file.Decls {
|
for _, decl := range file.Decls {
|
||||||
switch v := decl.(type) {
|
switch v := decl.(type) {
|
||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
|
@ -75,17 +93,17 @@ func (c *Compiler) Parse(path string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.builder.CreateRet(llvm.ConstInt(llvm.Int32Type(), 0, false))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) IR() string {
|
|
||||||
return c.mod.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Compiler) parseFunc(f *ast.FuncDecl) error {
|
func (c *Compiler) parseFunc(f *ast.FuncDecl) error {
|
||||||
fmt.Println("func:", f.Name)
|
fmt.Println("func:", f.Name)
|
||||||
|
|
||||||
|
fnType := llvm.FunctionType(llvm.Int32Type(), nil, false)
|
||||||
|
fn := llvm.AddFunction(c.mod, f.Name.Name, fnType)
|
||||||
|
start := c.ctx.AddBasicBlock(fn, "start")
|
||||||
|
c.builder.SetInsertPointAtEnd(start)
|
||||||
|
|
||||||
// TODO: external functions
|
// TODO: external functions
|
||||||
for _, stmt := range f.Body.List {
|
for _, stmt := range f.Body.List {
|
||||||
err := c.parseStmt(stmt)
|
err := c.parseStmt(stmt)
|
||||||
|
@ -93,6 +111,8 @@ func (c *Compiler) parseFunc(f *ast.FuncDecl) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.builder.CreateRet(llvm.ConstInt(llvm.Int32Type(), 0, false))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче