From 873fa4dee004a3252e5e0e42aecd08909c5b2286 Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Sun, 13 Aug 2023 19:47:48 +0300 Subject: [PATCH] feat: get rid of useless cmds --- cmd/hl2go/main.go.tmp | 233 -------- cmd/ll2go/main.go | 225 ------- cmd/parser/main.go | 643 --------------------- examples/0_do_nothing.neva | 7 + examples/1_hello_world.neva | 23 + internal/compiler/backend/golang/golang.go | 331 +++++++---- internal/compiler/compiler.go | 15 +- internal/embedruntime.go | 6 + test/e2e/ir2go/hello_world/main.go | 1 - 9 files changed, 261 insertions(+), 1223 deletions(-) delete mode 100644 cmd/hl2go/main.go.tmp delete mode 100644 cmd/ll2go/main.go delete mode 100644 cmd/parser/main.go create mode 100644 examples/0_do_nothing.neva create mode 100644 examples/1_hello_world.neva create mode 100644 internal/embedruntime.go delete mode 100644 test/e2e/ir2go/hello_world/main.go diff --git a/cmd/hl2go/main.go.tmp b/cmd/hl2go/main.go.tmp deleted file mode 100644 index 4c9d877e..00000000 --- a/cmd/hl2go/main.go.tmp +++ /dev/null @@ -1,233 +0,0 @@ -package main - -import ( - "bytes" - "io/fs" - "os" - - "github.com/nevalang/neva/internal/compiler" - "github.com/nevalang/neva/internal/compiler/backend/golang" - "github.com/nevalang/neva/internal/compiler/middleend/llrgen" - "github.com/nevalang/neva/internal/compiler/middleend/llrgen/helper" -) - -var efs = golang.Efs -var basePath = "/home/evaleev/projects/tmp" - -func main() { - if err := os.RemoveAll(basePath); err != nil { - panic(err) - } - - if err := os.MkdirAll(basePath, os.ModePerm); err != nil { - panic(err) - } - - putGoMod() - - putRuntime() - - h := helper.Helper{} - - prog := compiler.HighLvlProgram{ - "io": { - Entities: map[string]compiler.Entity{ - "Print": { - Exported: true, - Kind: compiler.ComponentEntity, - Component: compiler.Component{ - IO: compiler.IO{ - In: map[string]compiler.Port{ - "v": {}, - }, - Out: map[string]compiler.Port{ - "v": {}, - }, - }, - }, - }, - }, - }, - "flow": { - Entities: map[string]compiler.Entity{ - "Trigger": { - Exported: true, - Kind: compiler.ComponentEntity, - Component: compiler.Component{ - IO: compiler.IO{ - In: map[string]compiler.Port{ - "sigs": {IsArr: true}, - "v": {}, - }, - Out: map[string]compiler.Port{ - "v": {}, - }, - }, - }, - }, - }, - }, - "main": { - Imports: h.Imports("io", "flow"), - Entities: map[string]compiler.Entity{ - "code": h.IntMsg(false, 0), - "main": h.MainComponent(map[string]compiler.Node{ - "print": h.Node( - h.NodeInstance( - "io", "Print", - h.Inst("str"), - ), - ), - "trigger": h.NodeWithStaticPorts( - h.NodeInstance("flow", "Trigger", h.Rec(nil)), - map[compiler.RelPortAddr]compiler.EntityRef{ - {Name: "v"}: {Name: "code"}, - }, - ), - }, []compiler.Connection{ - { - SenderSide: compiler.SenderConnectionSide{ - PortConnectionSide: compiler.PortConnectionSide{ - PortAddr: compiler.ConnPortAddr{ - Node: "in", - RelPortAddr: compiler.RelPortAddr{ - Name: "start", - Idx: 0, - }, - }, - Selectors: []compiler.Selector{}, - }, - }, - ReceiverSides: []compiler.PortConnectionSide{ - { - PortAddr: compiler.ConnPortAddr{ - Node: "print", - RelPortAddr: compiler.RelPortAddr{ - Name: "v", - Idx: 0, - }, - }, - Selectors: []compiler.Selector{}, - }, - }, - }, - // { - // SenderSide: compiler.PortConnectionSide{ - // PortAddr: compiler.ConnPortAddr{ - // Node: "print", - // RelPortAddr: compiler.RelPortAddr{ - // Name: "v", - // Idx: 0, - // }, - // }, - // Selectors: []compiler.Selector{}, - // }, - // ReceiverSides: []compiler.PortConnectionSide{ - // { - // PortAddr: compiler.ConnPortAddr{ - // Node: "trigger", - // RelPortAddr: compiler.RelPortAddr{ - // Name: "sig", - // Idx: 0, - // }, - // }, - // Selectors: []compiler.Selector{}, - // }, - // }, - // }, - { - // SenderSide: compiler.PortConnectionSide{ - // PortAddr: compiler.ConnPortAddr{ - // Node: "trigger", - // RelPortAddr: compiler.RelPortAddr{ - // Name: "v", - // Idx: 0, - // }, - // }, - // Selectors: []compiler.Selector{}, - // }, - ReceiverSides: []compiler.PortConnectionSide{ - { - PortAddr: compiler.ConnPortAddr{ - Node: "out", - RelPortAddr: compiler.RelPortAddr{ - Name: "exit", - Idx: 0, - }, - }, - Selectors: []compiler.Selector{}, - }, - }, - }, - }), - }, - }, - } - - irProg, err := llrgen.Generator{}.Generate(nil, prog) - if err != nil { - panic(err) - } - - bb, err := golang.Backend{}.GenerateTarget(nil, irProg) - if err != nil { - panic(err) - } - - // write main.go - var buf bytes.Buffer - if _, err := buf.Write(bb); err != nil { - panic(err) - } - if err := os.WriteFile(basePath+"/"+"main.go", buf.Bytes(), os.ModePerm); err != nil { - panic(err) - } -} - -func putRuntime() { - // prepare directory structure and collect files to create - files := map[string][]byte{} - if err := fs.WalkDir(efs, "runtime", func(path string, d fs.DirEntry, err error) error { - fullPath := basePath + "/internal/compiler/backend/golang/" + path - if d.IsDir() { - if err := os.MkdirAll(fullPath, os.ModePerm); err != nil { - return err - } - return nil - } - - bb, err := efs.ReadFile(path) - if err != nil { - return err - } - - files[fullPath] = bb - return nil - }); err != nil { - panic(err) - } - // create files - for path, bb := range files { - if err := os.WriteFile(path, bb, os.ModePerm); err != nil { - panic(err) - } - } -} - -func putGoMod() { - f, err := os.Create(basePath + "/go.mod") - if err != nil { - panic(err) - } - - defer func() { - if err := f.Close(); err != nil { - panic(err) - } - }() - - _, err = f.WriteString("module github.com/nevalang/neva") - if err != nil { - panic(err) - } -} diff --git a/cmd/ll2go/main.go b/cmd/ll2go/main.go deleted file mode 100644 index 2eb22294..00000000 --- a/cmd/ll2go/main.go +++ /dev/null @@ -1,225 +0,0 @@ -package main - -// import ( -// "bytes" -// "io/fs" -// "os" - -// "github.com/nevalang/neva/internal/compiler" -// "github.com/nevalang/neva/internal/compiler/backend/golang" -// ) - -// var efs = golang.Efs -// var basePath = "/home/evaleev/projects/tmp" - -// func main() { -// if err := os.RemoveAll(basePath); err != nil { -// panic(err) -// } - -// if err := os.MkdirAll(basePath, os.ModePerm); err != nil { -// panic(err) -// } - -// putGoMod() - -// putRuntime() - -// bb, err := (golang.Backend{}).GenerateTarget(nil, compiler.LowLvlProgram{ -// Ports: map[compiler.LLPortAddr]uint8{ -// {Name: "start"}: 0, -// {Name: "exit"}: 0, -// {Path: "printer.in", Name: "v", Idx: 0}: 0, -// {Path: "printer.out", Name: "v", Idx: 0}: 0, -// {Path: "trigger.in", Name: "sigs", Idx: 0}: 0, -// {Path: "trigger.in", Name: "v", Idx: 0}: 0, -// {Path: "trigger.out", Name: "v", Idx: 0}: 0, -// {Path: "giver.out", Name: "code", Idx: 0}: 0, -// }, -// // Routines: compiler.LLRoutines{ -// // Giver: map[compiler.LLPortAddr]compiler.LLMsg{ -// // { -// // Path: "giver.out", -// // Name: "code", -// // Idx: 0, -// // }: { -// // Type: compiler.LLIntMsg, -// // Int: 0, -// // }, -// // }, -// // Func: []compiler.LLFunc{ -// // { -// // Ref: compiler.LLFuncRef{ -// // Pkg: "io", -// // Name: "Print", -// // }, -// // IO: compiler.LLFuncIO{ -// // In: []compiler.LLPortAddr{ -// // {Path: "printer.in", Name: "v", Idx: 0}, -// // }, -// // Out: []compiler.LLPortAddr{ -// // {Path: "printer.out", Name: "v", Idx: 0}, -// // }, -// // }, -// // }, -// // { -// // Ref: compiler.LLFuncRef{ -// // Pkg: "flow", -// // Name: "Trigger", -// // }, -// // IO: compiler.LLFuncIO{ -// // In: []compiler.LLPortAddr{ -// // {Path: "trigger.in", Name: "sigs", Idx: 0}, -// // {Path: "trigger.in", Name: "v", Idx: 0}, -// // }, -// // Out: []compiler.LLPortAddr{ -// // {Path: "trigger.out", Name: "v", Idx: 0}, -// // }, -// // }, -// // }, -// // }, -// // }, -// Net: []compiler.LLConnection{ -// { -// SenderSide: compiler.LLConnectionSide{ -// PortAddr: compiler.LLPortAddr{ -// Path: "", -// Name: "start", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// ReceiverSides: []compiler.LLConnectionSide{ -// { -// PortAddr: compiler.LLPortAddr{ -// Path: "printer.in", -// Name: "v", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// }, -// }, -// { -// SenderSide: compiler.LLConnectionSide{ -// PortAddr: compiler.LLPortAddr{ -// Path: "printer.out", -// Name: "v", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// ReceiverSides: []compiler.LLConnectionSide{ -// { -// PortAddr: compiler.LLPortAddr{ -// Path: "trigger.in", -// Name: "sigs", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// }, -// }, -// { -// SenderSide: compiler.LLConnectionSide{ -// PortAddr: compiler.LLPortAddr{ -// Path: "giver.out", -// Name: "code", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// ReceiverSides: []compiler.LLConnectionSide{ -// { -// PortAddr: compiler.LLPortAddr{ -// Path: "trigger.in", -// Name: "v", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// }, -// }, -// { -// SenderSide: compiler.LLConnectionSide{ -// PortAddr: compiler.LLPortAddr{ -// Path: "trigger.out", -// Name: "v", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// ReceiverSides: []compiler.LLConnectionSide{ -// { -// PortAddr: compiler.LLPortAddr{ -// Path: "", -// Name: "exit", -// Idx: 0, -// }, -// Selectors: []compiler.LLSelector{}, -// }, -// }, -// }, -// }, -// }) -// if err != nil { -// panic(err) -// } - -// // write main.go -// var buf bytes.Buffer -// if _, err := buf.Write(bb); err != nil { -// panic(err) -// } -// if err := os.WriteFile(basePath+"/"+"main.go", buf.Bytes(), os.ModePerm); err != nil { -// panic(err) -// } -// } - -// func putRuntime() { -// // prepare directory structure and collect files to create -// files := map[string][]byte{} -// if err := fs.WalkDir(efs, "runtime", func(path string, d fs.DirEntry, err error) error { -// fullPath := basePath + "/internal/compiler/backend/golang/" + path -// if d.IsDir() { -// if err := os.MkdirAll(fullPath, os.ModePerm); err != nil { -// return err -// } -// return nil -// } - -// bb, err := efs.ReadFile(path) -// if err != nil { -// return err -// } - -// files[fullPath] = bb -// return nil -// }); err != nil { -// panic(err) -// } -// // create files -// for path, bb := range files { -// if err := os.WriteFile(path, bb, os.ModePerm); err != nil { -// panic(err) -// } -// } -// } - -// func putGoMod() { -// f, err := os.Create(basePath + "/go.mod") -// if err != nil { -// panic(err) -// } - -// defer func() { -// if err := f.Close(); err != nil { -// panic(err) -// } -// }() - -// _, err = f.WriteString("module github.com/nevalang/neva") -// if err != nil { -// panic(err) -// } -// } diff --git a/cmd/parser/main.go b/cmd/parser/main.go deleted file mode 100644 index 4aab2c7d..00000000 --- a/cmd/parser/main.go +++ /dev/null @@ -1,643 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/antlr4-go/antlr/v4" - parser "github.com/nevalang/neva/internal/parser/generated" -) - -type TreeShapeListener struct { - *parser.BasenevaListener -} - -func NewTreeShapeListener() *TreeShapeListener { - return new(TreeShapeListener) -} - -// // VisitTerminal is called when a terminal node is visited. -// func (s *TreeShapeListener) VisitTerminal(node antlr.TerminalNode) { -// fmt.Println("VisitTerminal", node) -// } - -// // VisitErrorNode is called when an error node is visited. -// func (s *TreeShapeListener) VisitErrorNode(node antlr.ErrorNode) { -// fmt.Println("VisitErrorNode", node) -// } - -// EnterEveryRule is called when any rule is entered. -func (s *TreeShapeListener) EnterEveryRule(actx antlr.ParserRuleContext) { - // fmt.Println("EnterEveryRule", actx.GetText()) -} - -// ExitEveryRule is called when any rule is exited. -// func (s *TreeShapeListener) ExitEveryRule(actx antlr.ParserRuleContext) { -// fmt.Println("ExitEveryRule", actx) -// } - -// // EnterProg is called when production prog is entered. -// func (s *TreeShapeListener) EnterProg(actx *parser.ProgContext) { -// fmt.Println("EnterProg", actx) -// } - -// // ExitProg is called when production prog is exited. -// func (s *TreeShapeListener) ExitProg(actx *parser.ProgContext) { -// fmt.Println("ExitProg", actx) -// } - -// // EnterComment is called when production comment is entered. -// func (s *TreeShapeListener) EnterComment(actx *parser.CommentContext) { -// fmt.Println("EnterComment", actx) -// } - -// // ExitComment is called when production comment is exited. -// func (s *TreeShapeListener) ExitComment(actx *parser.CommentContext) { -// fmt.Println("ExitComment", actx) -// } - -// // EnterSingleLineComment is called when production singleLineComment is entered. -// func (s *TreeShapeListener) EnterSingleLineComment(actx *parser.SingleLineCommentContext) { -// fmt.Println("EnterSingleLineComment", actx) -// } - -// // ExitSingleLineComment is called when production singleLineComment is exited. -// func (s *TreeShapeListener) ExitSingleLineComment(actx *parser.SingleLineCommentContext) { -// fmt.Println("ExitSingleLineComment", actx) -// } - -// // EnterBlockComment is called when production blockComment is entered. -// func (s *TreeShapeListener) EnterBlockComment(actx *parser.BlockCommentContext) { -// fmt.Println("EnterBlockComment", actx) -// } - -// // ExitBlockComment is called when production blockComment is exited. -// func (s *TreeShapeListener) ExitBlockComment(actx *parser.BlockCommentContext) { -// fmt.Println("ExitBlockComment", actx) -// } - -// // EnterStmt is called when production stmt is entered. -// func (s *TreeShapeListener) EnterStmt(actx *parser.StmtContext) { -// fmt.Println("EnterStmt", actx) -// } - -// // ExitStmt is called when production stmt is exited. -// func (s *TreeShapeListener) ExitStmt(actx *parser.StmtContext) { -// fmt.Println("ExitStmt", actx) -// } - -// EnterUseStmt is called when production useStmt is entered. -func (s *TreeShapeListener) EnterUseStmt(actx *parser.UseStmtContext) { - fmt.Println("EnterUseStmt", actx) -} - -// // ExitUseStmt is called when production useStmt is exited. -// func (s *TreeShapeListener) ExitUseStmt(actx *parser.UseStmtContext) { -// fmt.Println("ExitUseStmt", actx) -// } - -// // EnterImportDef is called when production importDef is entered. -// func (s *TreeShapeListener) EnterImportDef(actx *parser.ImportDefContext) { -// fmt.Println("EnterImportDef", actx) -// } - -// // ExitImportDef is called when production importDef is exited. -// func (s *TreeShapeListener) ExitImportDef(actx *parser.ImportDefContext) { -// fmt.Println("ExitImportDef", actx) -// } - -// // EnterImportPath is called when production importPath is entered. -// func (s *TreeShapeListener) EnterImportPath(actx *parser.ImportPathContext) { -// fmt.Println("EnterImportPath", actx) -// } - -// // ExitImportPath is called when production importPath is exited. -// func (s *TreeShapeListener) ExitImportPath(actx *parser.ImportPathContext) { -// fmt.Println("ExitImportPath", actx) -// } - -// // EnterTypeStmt is called when production typeStmt is entered. -// func (s *TreeShapeListener) EnterTypeStmt(actx *parser.TypeStmtContext) { -// fmt.Println("EnterTypeStmt", actx) -// } - -// // ExitTypeStmt is called when production typeStmt is exited. -// func (s *TreeShapeListener) ExitTypeStmt(actx *parser.TypeStmtContext) { -// fmt.Println("ExitTypeStmt", actx) -// } - -// // EnterTypeDefList is called when production typeDefList is entered. -// func (s *TreeShapeListener) EnterTypeDefList(actx *parser.TypeDefListContext) { -// fmt.Println("EnterTypeDefList", actx) -// } - -// // ExitTypeDefList is called when production typeDefList is exited. -// func (s *TreeShapeListener) ExitTypeDefList(actx *parser.TypeDefListContext) { -// fmt.Println("ExitTypeDefList", actx) -// } - -// // EnterTypeDef is called when production typeDef is entered. -// func (s *TreeShapeListener) EnterTypeDef(actx *parser.TypeDefContext) { -// fmt.Println("EnterTypeDef", actx) -// } - -// // ExitTypeDef is called when production typeDef is exited. -// func (s *TreeShapeListener) ExitTypeDef(actx *parser.TypeDefContext) { -// fmt.Println("ExitTypeDef", actx) -// } - -// // EnterTypeParams is called when production typeParams is entered. -// func (s *TreeShapeListener) EnterTypeParams(actx *parser.TypeParamsContext) { -// fmt.Println("EnterTypeParams", actx) -// } - -// // ExitTypeParams is called when production typeParams is exited. -// func (s *TreeShapeListener) ExitTypeParams(actx *parser.TypeParamsContext) { -// fmt.Println("ExitTypeParams", actx) -// } - -// // EnterTypeParam is called when production typeParam is entered. -// func (s *TreeShapeListener) EnterTypeParam(actx *parser.TypeParamContext) { -// fmt.Println("EnterTypeParam", actx) -// } - -// // ExitTypeParam is called when production typeParam is exited. -// func (s *TreeShapeListener) ExitTypeParam(actx *parser.TypeParamContext) { -// fmt.Println("ExitTypeParam", actx) -// } - -// // EnterTypeExpr is called when production typeExpr is entered. -// func (s *TreeShapeListener) EnterTypeExpr(actx *parser.TypeExprContext) { -// fmt.Println("EnterTypeExpr", actx) -// } - -// // ExitTypeExpr is called when production typeExpr is exited. -// func (s *TreeShapeListener) ExitTypeExpr(actx *parser.TypeExprContext) { -// fmt.Println("ExitTypeExpr", actx) -// } - -// // EnterTypeInstExpr is called when production typeInstExpr is entered. -// func (s *TreeShapeListener) EnterTypeInstExpr(actx *parser.TypeInstExprContext) { -// fmt.Println("EnterTypeInstExpr", actx) -// } - -// // ExitTypeInstExpr is called when production typeInstExpr is exited. -// func (s *TreeShapeListener) ExitTypeInstExpr(actx *parser.TypeInstExprContext) { -// fmt.Println("ExitTypeInstExpr", actx) -// } - -// // EnterTypeArgs is called when production typeArgs is entered. -// func (s *TreeShapeListener) EnterTypeArgs(actx *parser.TypeArgsContext) { -// fmt.Println("EnterTypeArgs", actx) -// } - -// // ExitTypeArgs is called when production typeArgs is exited. -// func (s *TreeShapeListener) ExitTypeArgs(actx *parser.TypeArgsContext) { -// fmt.Println("ExitTypeArgs", actx) -// } - -// // EnterTypeLitExpr is called when production typeLitExpr is entered. -// func (s *TreeShapeListener) EnterTypeLitExpr(actx *parser.TypeLitExprContext) { -// fmt.Println("EnterTypeLitExpr", actx) -// } - -// // ExitTypeLitExpr is called when production typeLitExpr is exited. -// func (s *TreeShapeListener) ExitTypeLitExpr(actx *parser.TypeLitExprContext) { -// fmt.Println("ExitTypeLitExpr", actx) -// } - -// // EnterArrTypeExpr is called when production arrTypeExpr is entered. -// func (s *TreeShapeListener) EnterArrTypeExpr(actx *parser.ArrTypeExprContext) { -// fmt.Println("EnterArrTypeExpr", actx) -// } - -// // ExitArrTypeExpr is called when production arrTypeExpr is exited. -// func (s *TreeShapeListener) ExitArrTypeExpr(actx *parser.ArrTypeExprContext) { -// fmt.Println("ExitArrTypeExpr", actx) -// } - -// // EnterRecTypeExpr is called when production recTypeExpr is entered. -// func (s *TreeShapeListener) EnterRecTypeExpr(actx *parser.RecTypeExprContext) { -// fmt.Println("EnterRecTypeExpr", actx) -// } - -// // ExitRecTypeExpr is called when production recTypeExpr is exited. -// func (s *TreeShapeListener) ExitRecTypeExpr(actx *parser.RecTypeExprContext) { -// fmt.Println("ExitRecTypeExpr", actx) -// } - -// // EnterRecTypeFields is called when production recTypeFields is entered. -// func (s *TreeShapeListener) EnterRecTypeFields(actx *parser.RecTypeFieldsContext) { -// fmt.Println("EnterRecTypeFields", actx) -// } - -// // ExitRecTypeFields is called when production recTypeFields is exited. -// func (s *TreeShapeListener) ExitRecTypeFields(actx *parser.RecTypeFieldsContext) { -// fmt.Println("ExitRecTypeFields", actx) -// } - -// // EnterRecTypeField is called when production recTypeField is entered. -// func (s *TreeShapeListener) EnterRecTypeField(actx *parser.RecTypeFieldContext) { -// fmt.Println("EnterRecTypeField", actx) -// } - -// // ExitRecTypeField is called when production recTypeField is exited. -// func (s *TreeShapeListener) ExitRecTypeField(actx *parser.RecTypeFieldContext) { -// fmt.Println("ExitRecTypeField", actx) -// } - -// // EnterUnionTypeExpr is called when production unionTypeExpr is entered. -// func (s *TreeShapeListener) EnterUnionTypeExpr(actx *parser.UnionTypeExprContext) { -// fmt.Println("EnterUnionTypeExpr", actx) -// } - -// // ExitUnionTypeExpr is called when production unionTypeExpr is exited. -// func (s *TreeShapeListener) ExitUnionTypeExpr(actx *parser.UnionTypeExprContext) { -// fmt.Println("ExitUnionTypeExpr", actx) -// } - -// // EnterEnumTypeExpr is called when production enumTypeExpr is entered. -// func (s *TreeShapeListener) EnterEnumTypeExpr(actx *parser.EnumTypeExprContext) { -// fmt.Println("EnterEnumTypeExpr", actx) -// } - -// // ExitEnumTypeExpr is called when production enumTypeExpr is exited. -// func (s *TreeShapeListener) ExitEnumTypeExpr(actx *parser.EnumTypeExprContext) { -// fmt.Println("ExitEnumTypeExpr", actx) -// } - -// // EnterNonUnionTypeExpr is called when production nonUnionTypeExpr is entered. -// func (s *TreeShapeListener) EnterNonUnionTypeExpr(actx *parser.NonUnionTypeExprContext) { -// fmt.Println("EnterNonUnionTypeExpr", actx) -// } - -// // ExitNonUnionTypeExpr is called when production nonUnionTypeExpr is exited. -// func (s *TreeShapeListener) ExitNonUnionTypeExpr(actx *parser.NonUnionTypeExprContext) { -// fmt.Println("ExitNonUnionTypeExpr", actx) -// } - -// // EnterIoStmt is called when production ioStmt is entered. -// func (s *TreeShapeListener) EnterIoStmt(actx *parser.IoStmtContext) { -// fmt.Println("EnterIoStmt", actx) -// } - -// // ExitIoStmt is called when production ioStmt is exited. -// func (s *TreeShapeListener) ExitIoStmt(actx *parser.IoStmtContext) { -// fmt.Println("ExitIoStmt", actx) -// } - -// // EnterInterfaceDefList is called when production interfaceDefList is entered. -// func (s *TreeShapeListener) EnterInterfaceDefList(actx *parser.InterfaceDefListContext) { -// fmt.Println("EnterInterfaceDefList", actx) -// } - -// // ExitInterfaceDefList is called when production interfaceDefList is exited. -// func (s *TreeShapeListener) ExitInterfaceDefList(actx *parser.InterfaceDefListContext) { -// fmt.Println("ExitInterfaceDefList", actx) -// } - -// // EnterInterfaceDef is called when production interfaceDef is entered. -// func (s *TreeShapeListener) EnterInterfaceDef(actx *parser.InterfaceDefContext) { -// fmt.Println("EnterInterfaceDef", actx) -// } - -// // ExitInterfaceDef is called when production interfaceDef is exited. -// func (s *TreeShapeListener) ExitInterfaceDef(actx *parser.InterfaceDefContext) { -// fmt.Println("ExitInterfaceDef", actx) -// } - -// // EnterPortsDef is called when production portsDef is entered. -// func (s *TreeShapeListener) EnterPortsDef(actx *parser.PortsDefContext) { -// fmt.Println("EnterPortsDef", actx) -// } - -// // ExitPortsDef is called when production portsDef is exited. -// func (s *TreeShapeListener) ExitPortsDef(actx *parser.PortsDefContext) { -// fmt.Println("ExitPortsDef", actx) -// } - -// // EnterPortDefList is called when production portDefList is entered. -// func (s *TreeShapeListener) EnterPortDefList(actx *parser.PortDefListContext) { -// fmt.Println("EnterPortDefList", actx) -// } - -// // ExitPortDefList is called when production portDefList is exited. -// func (s *TreeShapeListener) ExitPortDefList(actx *parser.PortDefListContext) { -// fmt.Println("ExitPortDefList", actx) -// } - -// // EnterPortDef is called when production portDef is entered. -// func (s *TreeShapeListener) EnterPortDef(actx *parser.PortDefContext) { -// fmt.Println("EnterPortDef", actx) -// } - -// // ExitPortDef is called when production portDef is exited. -// func (s *TreeShapeListener) ExitPortDef(actx *parser.PortDefContext) { -// fmt.Println("ExitPortDef", actx) -// } - -// // EnterConstStmt is called when production constStmt is entered. -// func (s *TreeShapeListener) EnterConstStmt(actx *parser.ConstStmtContext) { -// fmt.Println("EnterConstStmt", actx) -// } - -// // ExitConstStmt is called when production constStmt is exited. -// func (s *TreeShapeListener) ExitConstStmt(actx *parser.ConstStmtContext) { -// fmt.Println("ExitConstStmt", actx) -// } - -// // EnterConstDefList is called when production constDefList is entered. -// func (s *TreeShapeListener) EnterConstDefList(actx *parser.ConstDefListContext) { -// fmt.Println("EnterConstDefList", actx) -// } - -// // ExitConstDefList is called when production constDefList is exited. -// func (s *TreeShapeListener) ExitConstDefList(actx *parser.ConstDefListContext) { -// fmt.Println("ExitConstDefList", actx) -// } - -// // EnterConstDef is called when production constDef is entered. -// func (s *TreeShapeListener) EnterConstDef(actx *parser.ConstDefContext) { -// fmt.Println("EnterConstDef", actx) -// } - -// // ExitConstDef is called when production constDef is exited. -// func (s *TreeShapeListener) ExitConstDef(actx *parser.ConstDefContext) { -// fmt.Println("ExitConstDef", actx) -// } - -// // EnterConstValue is called when production constValue is entered. -// func (s *TreeShapeListener) EnterConstValue(actx *parser.ConstValueContext) { -// fmt.Println("EnterConstValue", actx) -// } - -// // ExitConstValue is called when production constValue is exited. -// func (s *TreeShapeListener) ExitConstValue(actx *parser.ConstValueContext) { -// fmt.Println("ExitConstValue", actx) -// } - -// // EnterArrLit is called when production arrLit is entered. -// func (s *TreeShapeListener) EnterArrLit(actx *parser.ArrLitContext) { -// fmt.Println("EnterArrLit", actx) -// } - -// // ExitArrLit is called when production arrLit is exited. -// func (s *TreeShapeListener) ExitArrLit(actx *parser.ArrLitContext) { -// fmt.Println("ExitArrLit", actx) -// } - -// // EnterArrItems is called when production arrItems is entered. -// func (s *TreeShapeListener) EnterArrItems(actx *parser.ArrItemsContext) { -// fmt.Println("EnterArrItems", actx) -// } - -// // ExitArrItems is called when production arrItems is exited. -// func (s *TreeShapeListener) ExitArrItems(actx *parser.ArrItemsContext) { -// fmt.Println("ExitArrItems", actx) -// } - -// // EnterRecLit is called when production recLit is entered. -// func (s *TreeShapeListener) EnterRecLit(actx *parser.RecLitContext) { -// fmt.Println("EnterRecLit", actx) -// } - -// // ExitRecLit is called when production recLit is exited. -// func (s *TreeShapeListener) ExitRecLit(actx *parser.RecLitContext) { -// fmt.Println("ExitRecLit", actx) -// } - -// // EnterRecValueFields is called when production recValueFields is entered. -// func (s *TreeShapeListener) EnterRecValueFields(actx *parser.RecValueFieldsContext) { -// fmt.Println("EnterRecValueFields", actx) -// } - -// // ExitRecValueFields is called when production recValueFields is exited. -// func (s *TreeShapeListener) ExitRecValueFields(actx *parser.RecValueFieldsContext) { -// fmt.Println("ExitRecValueFields", actx) -// } - -// // EnterRecValueField is called when production recValueField is entered. -// func (s *TreeShapeListener) EnterRecValueField(actx *parser.RecValueFieldContext) { -// fmt.Println("EnterRecValueField", actx) -// } - -// // ExitRecValueField is called when production recValueField is exited. -// func (s *TreeShapeListener) ExitRecValueField(actx *parser.RecValueFieldContext) { -// fmt.Println("ExitRecValueField", actx) -// } - -// // EnterCompStmt is called when production compStmt is entered. -// func (s *TreeShapeListener) EnterCompStmt(actx *parser.CompStmtContext) { -// fmt.Println("EnterCompStmt", actx) -// } - -// // ExitCompStmt is called when production compStmt is exited. -// func (s *TreeShapeListener) ExitCompStmt(actx *parser.CompStmtContext) { -// fmt.Println("ExitCompStmt", actx) -// } - -// // EnterCompDefList is called when production compDefList is entered. -// func (s *TreeShapeListener) EnterCompDefList(actx *parser.CompDefListContext) { -// fmt.Println("EnterCompDefList", actx) -// } - -// // ExitCompDefList is called when production compDefList is exited. -// func (s *TreeShapeListener) ExitCompDefList(actx *parser.CompDefListContext) { -// fmt.Println("ExitCompDefList", actx) -// } - -// // EnterCompDef is called when production compDef is entered. -// func (s *TreeShapeListener) EnterCompDef(actx *parser.CompDefContext) { -// fmt.Println("EnterCompDef", actx) -// } - -// // ExitCompDef is called when production compDef is exited. -// func (s *TreeShapeListener) ExitCompDef(actx *parser.CompDefContext) { -// fmt.Println("ExitCompDef", actx) -// } - -// // EnterCompBody is called when production compBody is entered. -// func (s *TreeShapeListener) EnterCompBody(actx *parser.CompBodyContext) { -// fmt.Println("EnterCompBody", actx) -// } - -// // ExitCompBody is called when production compBody is exited. -// func (s *TreeShapeListener) ExitCompBody(actx *parser.CompBodyContext) { -// fmt.Println("ExitCompBody", actx) -// } - -// // EnterCompNodesDef is called when production compNodesDef is entered. -// func (s *TreeShapeListener) EnterCompNodesDef(actx *parser.CompNodesDefContext) { -// fmt.Println("EnterCompNodesDef", actx) -// } - -// // ExitCompNodesDef is called when production compNodesDef is exited. -// func (s *TreeShapeListener) ExitCompNodesDef(actx *parser.CompNodesDefContext) { -// fmt.Println("ExitCompNodesDef", actx) -// } - -// // EnterCompNodeDefList is called when production compNodeDefList is entered. -// func (s *TreeShapeListener) EnterCompNodeDefList(actx *parser.CompNodeDefListContext) { -// fmt.Println("EnterCompNodeDefList", actx) -// } - -// // ExitCompNodeDefList is called when production compNodeDefList is exited. -// func (s *TreeShapeListener) ExitCompNodeDefList(actx *parser.CompNodeDefListContext) { -// fmt.Println("ExitCompNodeDefList", actx) -// } - -// // EnterAbsNodeDef is called when production absNodeDef is entered. -// func (s *TreeShapeListener) EnterAbsNodeDef(actx *parser.AbsNodeDefContext) { -// fmt.Println("EnterAbsNodeDef", actx) -// } - -// // ExitAbsNodeDef is called when production absNodeDef is exited. -// func (s *TreeShapeListener) ExitAbsNodeDef(actx *parser.AbsNodeDefContext) { -// fmt.Println("ExitAbsNodeDef", actx) -// } - -// // EnterConcreteNodeDef is called when production concreteNodeDef is entered. -// func (s *TreeShapeListener) EnterConcreteNodeDef(actx *parser.ConcreteNodeDefContext) { -// fmt.Println("EnterConcreteNodeDef", actx) -// } - -// // ExitConcreteNodeDef is called when production concreteNodeDef is exited. -// func (s *TreeShapeListener) ExitConcreteNodeDef(actx *parser.ConcreteNodeDefContext) { -// fmt.Println("ExitConcreteNodeDef", actx) -// } - -// // EnterConcreteNodeInst is called when production concreteNodeInst is entered. -// func (s *TreeShapeListener) EnterConcreteNodeInst(actx *parser.ConcreteNodeInstContext) { -// fmt.Println("EnterConcreteNodeInst", actx) -// } - -// // ExitConcreteNodeInst is called when production concreteNodeInst is exited. -// func (s *TreeShapeListener) ExitConcreteNodeInst(actx *parser.ConcreteNodeInstContext) { -// fmt.Println("ExitConcreteNodeInst", actx) -// } - -// // EnterNodeRef is called when production nodeRef is entered. -// func (s *TreeShapeListener) EnterNodeRef(actx *parser.NodeRefContext) { -// fmt.Println("EnterNodeRef", actx) -// } - -// // ExitNodeRef is called when production nodeRef is exited. -// func (s *TreeShapeListener) ExitNodeRef(actx *parser.NodeRefContext) { -// fmt.Println("ExitNodeRef", actx) -// } - -// // EnterNodeArgs is called when production nodeArgs is entered. -// func (s *TreeShapeListener) EnterNodeArgs(actx *parser.NodeArgsContext) { -// fmt.Println("EnterNodeArgs", actx) -// } - -// // ExitNodeArgs is called when production nodeArgs is exited. -// func (s *TreeShapeListener) ExitNodeArgs(actx *parser.NodeArgsContext) { -// fmt.Println("ExitNodeArgs", actx) -// } - -// // EnterNodeArgList is called when production nodeArgList is entered. -// func (s *TreeShapeListener) EnterNodeArgList(actx *parser.NodeArgListContext) { -// fmt.Println("EnterNodeArgList", actx) -// } - -// // ExitNodeArgList is called when production nodeArgList is exited. -// func (s *TreeShapeListener) ExitNodeArgList(actx *parser.NodeArgListContext) { -// fmt.Println("ExitNodeArgList", actx) -// } - -// // EnterNodeArg is called when production nodeArg is entered. -// func (s *TreeShapeListener) EnterNodeArg(actx *parser.NodeArgContext) { -// fmt.Println("EnterNodeArg", actx) -// } - -// // ExitNodeArg is called when production nodeArg is exited. -// func (s *TreeShapeListener) ExitNodeArg(actx *parser.NodeArgContext) { -// fmt.Println("ExitNodeArg", actx) -// } - -// // EnterCompNetDef is called when production compNetDef is entered. -// func (s *TreeShapeListener) EnterCompNetDef(actx *parser.CompNetDefContext) { -// fmt.Println("EnterCompNetDef", actx) -// } - -// // ExitCompNetDef is called when production compNetDef is exited. -// func (s *TreeShapeListener) ExitCompNetDef(actx *parser.CompNetDefContext) { -// fmt.Println("ExitCompNetDef", actx) -// } - -// // EnterConnDefList is called when production connDefList is entered. -// func (s *TreeShapeListener) EnterConnDefList(actx *parser.ConnDefListContext) { -// fmt.Println("EnterConnDefList", actx) -// } - -// // ExitConnDefList is called when production connDefList is exited. -// func (s *TreeShapeListener) ExitConnDefList(actx *parser.ConnDefListContext) { -// fmt.Println("ExitConnDefList", actx) -// } - -// // EnterConnDef is called when production connDef is entered. -// func (s *TreeShapeListener) EnterConnDef(actx *parser.ConnDefContext) { -// fmt.Println("EnterConnDef", actx) -// } - -// // ExitConnDef is called when production connDef is exited. -// func (s *TreeShapeListener) ExitConnDef(actx *parser.ConnDefContext) { -// fmt.Println("ExitConnDef", actx) -// } - -// // EnterPortAddr is called when production portAddr is entered. -// func (s *TreeShapeListener) EnterPortAddr(actx *parser.PortAddrContext) { -// fmt.Println("EnterPortAddr", actx) -// } - -// // ExitPortAddr is called when production portAddr is exited. -// func (s *TreeShapeListener) ExitPortAddr(actx *parser.PortAddrContext) { -// fmt.Println("ExitPortAddr", actx) -// } - -// // EnterPortDirection is called when production portDirection is entered. -// func (s *TreeShapeListener) EnterPortDirection(actx *parser.PortDirectionContext) { -// fmt.Println("EnterPortDirection", actx) -// } - -// // ExitPortDirection is called when production portDirection is exited. -// func (s *TreeShapeListener) ExitPortDirection(actx *parser.PortDirectionContext) { -// fmt.Println("ExitPortDirection", actx) -// } - -// // EnterConnReceiverSide is called when production connReceiverSide is entered. -// func (s *TreeShapeListener) EnterConnReceiverSide(actx *parser.ConnReceiverSideContext) { -// fmt.Println("EnterConnReceiverSide", actx) -// } - -// // ExitConnReceiverSide is called when production connReceiverSide is exited. -// func (s *TreeShapeListener) ExitConnReceiverSide(actx *parser.ConnReceiverSideContext) { -// fmt.Println("ExitConnReceiverSide", actx) -// } - -// // EnterConnReceivers is called when production connReceivers is entered. -// func (s *TreeShapeListener) EnterConnReceivers(actx *parser.ConnReceiversContext) { -// fmt.Println("EnterConnReceivers", actx) -// } - -// // ExitConnReceivers is called when production connReceivers is exited. -// func (s *TreeShapeListener) ExitConnReceivers(actx *parser.ConnReceiversContext) { -// fmt.Println("ExitConnReceivers", actx) -// } - -func main() { - input, err := antlr.NewFileStream(os.Args[1]) - if err != nil { - panic(err) - } - - lexer := parser.NewnevaLexer(input) - stream := antlr.NewCommonTokenStream(lexer, 0) - p := parser.NewnevaParser(stream) - p.AddErrorListener(antlr.NewDiagnosticErrorListener(true)) - p.BuildParseTrees = true - tree := p.Prog() - - antlr.ParseTreeWalkerDefault.Walk(NewTreeShapeListener(), tree) -} diff --git a/examples/0_do_nothing.neva b/examples/0_do_nothing.neva new file mode 100644 index 00000000..0d773296 --- /dev/null +++ b/examples/0_do_nothing.neva @@ -0,0 +1,7 @@ +components { + Main(start) (exit) { + net { + in.start -> out.exit + } + } +} \ No newline at end of file diff --git a/examples/1_hello_world.neva b/examples/1_hello_world.neva new file mode 100644 index 00000000..5b43c073 --- /dev/null +++ b/examples/1_hello_world.neva @@ -0,0 +1,23 @@ +use { + io + sync +} + +const { + msg string = 'Hello, World!' +} + +components { + Main(start) (exit) { + nodes { + lock = sync.Lock() + print = fmt.Print() + } + net { + in.start -> lock.sig + const.msg -> lock.v + lock.v -> print.v[0] + print.v -> out.exit + } + } +} \ No newline at end of file diff --git a/internal/compiler/backend/golang/golang.go b/internal/compiler/backend/golang/golang.go index 6d0ba353..4c8ef425 100644 --- a/internal/compiler/backend/golang/golang.go +++ b/internal/compiler/backend/golang/golang.go @@ -1,115 +1,220 @@ package golang -// import ( -// "bytes" -// "context" -// "errors" -// "fmt" -// "strings" -// "text/template" -// "unicode" - -// "github.com/nevalang/neva/internal/compiler" -// ) - -// //go:embed tmpl/main.go.tmpl runtime -// // var Efs embed.FS // TODO make private - -// type Backend struct{} - -// var ErrExecTmpl = errors.New("execute template") - -// func (b Backend) GenerateTarget(ctx context.Context, prog compiler.LowLvlProgram) ([]byte, error) { -// tmpl, err := template.New("main.go.tmpl").Funcs(template.FuncMap{ -// "getMsg": b.getMsg, -// "getPorts": b.getPortsFunc(prog.Ports), -// "getPortChVarName": b.getPortChVarName, -// "getConnComment": b.getConnComment, -// }).ParseFS(Efs, "tmpl/main.go.tmpl") -// if err != nil { -// return nil, err -// } - -// var buf bytes.Buffer -// if err := tmpl.Execute(&buf, prog); err != nil { -// return nil, errors.Join(ErrExecTmpl, err) -// } - -// return buf.Bytes(), nil -// } - -// var ErrUnknownMsgType = errors.New("unknown msg type") - -// func (b Backend) getMsg(msg compiler.LLMsg) (string, error) { -// switch msg.Type { -// case compiler.LLIntMsg: -// return fmt.Sprintf("runtime.NewIntMsg(%d)", msg.Int), nil -// } -// return "", fmt.Errorf("%w: %v", ErrUnknownMsgType, msg.Type) -// } - -// func (b Backend) getConnComment(conn compiler.LLConnection) string { -// s := b.fmtPortAddr(conn.SenderSide.PortAddr) + " -> " - -// for _, rcvr := range conn.ReceiverSides { -// s += b.fmtPortAddr(rcvr.PortAddr) -// } - -// return "// " + s -// } - -// func (b Backend) fmtPortAddr(addr compiler.LLPortAddr) string { -// return fmt.Sprintf("%s.%s[%d]", addr.Path, addr.Name, addr.Idx) -// } - -// func (b Backend) getPortChVarName(addr compiler.LLPortAddr) string { -// path := b.handleSpecialChars(addr.Path) -// port := addr.Name -// if path != "" { -// port = b.uppercaseFirstLetter(addr.Name) -// } -// return fmt.Sprintf("%s%s%dPort", path, port, addr.Idx) -// } - -// func (b Backend) getPortsFunc(ports map[compiler.LLPortAddr]uint8) func(path, port string) string { -// return func(path, port string) string { -// var s string -// for addr := range ports { -// if addr.Path == path && addr.Name == port { -// s = s + b.getPortChVarName(addr) + "," -// } -// } -// return s -// } -// } - -// func (b Backend) handleSpecialChars(portPath string) string { -// var ( -// buffer bytes.Buffer -// shouldUppercase bool -// ) - -// for i := 0; i < len(portPath); i++ { -// if portPath[i] == '.' || portPath[i] == '/' { -// shouldUppercase = true -// continue -// } -// s := string(portPath[i]) -// if shouldUppercase { -// s = strings.ToUpper(s) -// shouldUppercase = false -// } -// buffer.WriteString(s) -// } - -// return buffer.String() -// } - -// func (b Backend) uppercaseFirstLetter(s string) string { -// if len(s) == 0 { -// return s -// } -// bb := []byte(s) -// bb[0] = byte(unicode.ToUpper(rune(bb[0]))) -// return string(bb) -// } +import ( + "bytes" + "context" + "embed" + "errors" + "fmt" + "io/fs" + "os" + "os/exec" + "strings" + "text/template" + "unicode" + + "github.com/nevalang/neva/internal/compiler" +) + +//go:embed tmpl/main.go.tmpl +var efs embed.FS + +type Backend struct{} + +var errExecTmpl = errors.New("execute template") +var ErrWrongGoVersion = errors.New("wrong Go version") + +const wantGoVersion = "1.21" + +func (b Backend) GenerateTarget(ctx context.Context, prog compiler.LowLvlProgram, basePath string) error { + tmpl, err := template.New("main.go.tmpl").Funcs(template.FuncMap{ + "getMsg": getMsg, + "getPorts": getPortsFunc(prog.Ports), + "getPortChVarName": getPortChVarName, + "getConnComment": getConnComment, + }).ParseFS(efs, "tmpl/main.go.tmpl") + if err != nil { + return err + } + + var buf bytes.Buffer + if err := tmpl.Execute(&buf, prog); err != nil { + return errors.Join(errExecTmpl, err) + } + + if err := os.RemoveAll(basePath); err != nil { + return err + } + + if err := os.MkdirAll(basePath, os.ModePerm); err != nil { + return err + } + + // write main.go + if _, err := buf.Write(nil); err != nil { + return err + } + if err := os.WriteFile(basePath+"/"+"main.go", buf.Bytes(), os.ModePerm); err != nil { + return err + } + + // go.mod + if err := putGoMod(basePath); err != nil { + return err + } + + // runtime + if err := putRuntime(basePath); err != nil { + return err + } + + // check go compiler version + versionStr, err := goVersionOut() + if err != nil { + return err + } + if !strings.Contains(versionStr, "1.21") { + return fmt.Errorf("%w: want %s, got %s", ErrWrongGoVersion, wantGoVersion, versionStr) + } + + // compile go code + cmd := exec.Command("go", "build", basePath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return err + } + + return nil +} + +var errUnknownMsgType = errors.New("unknown msg type") + +func getMsg(msg compiler.LLMsg) (string, error) { + switch msg.Type { + case compiler.LLIntMsg: + return fmt.Sprintf("runtime.NewIntMsg(%d)", msg.Int), nil + } + return "", fmt.Errorf("%w: %v", errUnknownMsgType, msg.Type) +} + +func getConnComment(conn compiler.LLConnection) string { + s := fmtPortAddr(conn.SenderSide.PortAddr) + " -> " + + for _, rcvr := range conn.ReceiverSides { + s += fmtPortAddr(rcvr.PortAddr) + } + + return "// " + s +} + +func fmtPortAddr(addr compiler.LLPortAddr) string { + return fmt.Sprintf("%s.%s[%d]", addr.Path, addr.Name, addr.Idx) +} + +func getPortChVarName(addr compiler.LLPortAddr) string { + path := handleSpecialChars(addr.Path) + port := addr.Name + if path != "" { + port = uppercaseFirstLetter(addr.Name) + } + return fmt.Sprintf("%s%s%dPort", path, port, addr.Idx) +} + +func getPortsFunc(ports map[compiler.LLPortAddr]uint8) func(path, port string) string { + return func(path, port string) string { + var s string + for addr := range ports { + if addr.Path == path && addr.Name == port { + s = s + getPortChVarName(addr) + "," + } + } + return s + } +} + +func handleSpecialChars(portPath string) string { + var ( + buffer bytes.Buffer + shouldUppercase bool + ) + + for i := 0; i < len(portPath); i++ { + if portPath[i] == '.' || portPath[i] == '/' { + shouldUppercase = true + continue + } + s := string(portPath[i]) + if shouldUppercase { + s = strings.ToUpper(s) + shouldUppercase = false + } + buffer.WriteString(s) + } + + return buffer.String() +} + +func uppercaseFirstLetter(s string) string { + if len(s) == 0 { + return s + } + bb := []byte(s) + bb[0] = byte(unicode.ToUpper(rune(bb[0]))) + return string(bb) +} + +func putGoMod(basePath string) error { + f, err := os.Create(basePath + "/go.mod") + if err != nil { + return err + } + + defer f.Close() + + _, err = f.WriteString("module github.com/nevalang/neva") + if err != nil { + return err + } + + return nil +} + +func putRuntime(basePath string) error { + // prepare directory structure and collect files to create + files := map[string][]byte{} + if err := fs.WalkDir(efs, "runtime", func(path string, d fs.DirEntry, err error) error { + fullPath := basePath + "/internal/compiler/backend/golang/" + path + if d.IsDir() { + if err := os.MkdirAll(fullPath, os.ModePerm); err != nil { + return err + } + return nil + } + + bb, err := efs.ReadFile(path) + if err != nil { + return err + } + + files[fullPath] = bb + return nil + }); err != nil { + return err + } + // create files + for path, bb := range files { + if err := os.WriteFile(path, bb, os.ModePerm); err != nil { + return err + } + } + return nil +} + +func goVersionOut() (string, error) { + out, err := exec.Command("go", "version").Output() + if err != nil { + return "", err + } + return string(out), nil +} diff --git a/internal/compiler/compiler.go b/internal/compiler/compiler.go index 58666815..9db110ef 100644 --- a/internal/compiler/compiler.go +++ b/internal/compiler/compiler.go @@ -19,7 +19,7 @@ type ( Generate(context.Context, HighLvlProgram) (LowLvlProgram, error) } Backend interface { - GenerateTarget(context.Context, LowLvlProgram) ([]byte, error) + GenerateTarget(context.Context, LowLvlProgram) error } ) @@ -29,21 +29,20 @@ var ( ErrBackend = errors.New("backend") ) -func (c Compiler) Compile(ctx context.Context, prog HighLvlProgram) ([]byte, error) { +func (c Compiler) Compile(ctx context.Context, prog HighLvlProgram) error { analyzedProg, err := c.analyzer.Analyze(ctx, prog) if err != nil { - return nil, errors.Join(ErrAnalyzer, err) + return errors.Join(ErrAnalyzer, err) } irProg, err := c.llrgen.Generate(ctx, analyzedProg) if err != nil { - return nil, errors.Join(ErrIrGen, err) + return errors.Join(ErrIrGen, err) } - target, err := c.backend.GenerateTarget(ctx, irProg) - if err != nil { - return nil, errors.Join(ErrBackend, err) + if err := c.backend.GenerateTarget(ctx, irProg); err != nil { + return errors.Join(ErrBackend, err) } - return target, nil + return nil } diff --git a/internal/embedruntime.go b/internal/embedruntime.go new file mode 100644 index 00000000..93e37764 --- /dev/null +++ b/internal/embedruntime.go @@ -0,0 +1,6 @@ +package embedruntime + +import "embed" + +//go:embed runtime +var Efs embed.FS diff --git a/test/e2e/ir2go/hello_world/main.go b/test/e2e/ir2go/hello_world/main.go deleted file mode 100644 index 06ab7d0f..00000000 --- a/test/e2e/ir2go/hello_world/main.go +++ /dev/null @@ -1 +0,0 @@ -package main