From 5319f206238093fed3a930f5cc2e509a3e8cd95b Mon Sep 17 00:00:00 2001 From: chai2010 Date: Mon, 3 Apr 2023 20:29:30 +0800 Subject: [PATCH] =?UTF-8?q?main=20=E5=87=BD=E6=95=B0=E7=A7=BB=E5=88=B0=20w?= =?UTF-8?q?acli=20=E5=8C=85=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/wacli/wacli.go | 572 ++++++++++++++++++++++++++++++++++++ main.go | 568 +---------------------------------- 2 files changed, 574 insertions(+), 566 deletions(-) create mode 100644 internal/app/wacli/wacli.go diff --git a/internal/app/wacli/wacli.go b/internal/app/wacli/wacli.go new file mode 100644 index 0000000..54d4188 --- /dev/null +++ b/internal/app/wacli/wacli.go @@ -0,0 +1,572 @@ +// 版权 @2019 凹语言 作者。保留所有权利。 + +//go:build !wasm +// +build !wasm + +// 凹语言,The Wa Programming Language. +package wacli + +import ( + "fmt" + "os" + "runtime/debug" + "strings" + "time" + + "github.com/tetratelabs/wazero/sys" + + "wa-lang.org/wa/api" + "wa-lang.org/wa/internal/3rdparty/cli" + "wa-lang.org/wa/internal/app" + "wa-lang.org/wa/internal/app/apputil" + "wa-lang.org/wa/internal/app/yacc" + "wa-lang.org/wa/internal/config" +) + +func Main() { + cliApp := cli.NewApp() + cliApp.Name = "Wa" + cliApp.Usage = "Wa is a tool for managing Wa source code." + cliApp.Version = func() string { + if info, ok := debug.ReadBuildInfo(); ok { + if info.Main.Version != "" { + return info.Main.Version + } + } + return "devel:" + time.Now().Format("2006-01-02+15:04:05") + }() + + cliApp.Flags = []cli.Flag{ + &cli.StringFlag{ + Name: "target", + Usage: "set target os (arduino|chrome|wasi)", + Value: config.WaOS_Default, + }, + &cli.BoolFlag{ + Name: "debug", + Aliases: []string{"d"}, + Usage: "set debug mode", + }, + &cli.StringFlag{ + Name: "trace", + Aliases: []string{"t"}, + Usage: "set trace mode (*|app|compiler|loader)", + }, + } + + cliApp.Before = func(c *cli.Context) error { + switch c.String("target") { + case "wasi", "arduino", "chrome": + // OK + default: + fmt.Printf("unknown target: %s\n", c.String("target")) + os.Exit(1) + } + if c.Bool("debug") { + config.SetDebugMode() + } + if parten := c.String("trace"); parten != "" { + config.SetEnableTrace(parten) + } + return nil + } + + // 没有参数时对应 run 命令 + cliApp.Action = func(c *cli.Context) error { + cliRun(c) + return nil + } + + cliApp.Commands = []*cli.Command{ + { + // go run main.go debug + Hidden: true, + Name: "debug", + Usage: "only for dev/debug", + Action: func(c *cli.Context) error { + wat, err := api.BuildFile( + config.DefaultConfig(), + "hello.wa", "func main() { println(123) }", + ) + if err != nil { + if len(wat) != 0 { + fmt.Println(string(wat)) + } + fmt.Println(err) + os.Exit(1) + } + fmt.Println(string(wat)) + return nil + }, + }, + { + Name: "init", + Usage: "init a sketch wa module", + ArgsUsage: "app-name", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "name", + Aliases: []string{"n"}, + Usage: "set app name", + Value: "_examples/hello", + }, + &cli.StringFlag{ + Name: "pkgpath", + Aliases: []string{"p"}, + Usage: "set pkgpath file", + Value: "myapp", + }, + &cli.BoolFlag{ + Name: "update", + Aliases: []string{"u"}, + Usage: "update example", + }, + }, + + Action: func(c *cli.Context) error { + waApp := app.NewApp(build_Options(c)) + err := waApp.InitApp(c.String("name"), c.String("pkgpath"), c.Bool("update")) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + { + Name: "run", + Usage: "compile and run Wa program", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "target", + Usage: "set target os (wasi|arduino|chrome)", + Value: config.WaOS_Default, + }, + &cli.StringFlag{ + Name: "tags", + Usage: "set build tags", + }, + }, + Action: func(c *cli.Context) error { + cliRun(c) + return nil + }, + }, + { + Name: "build", + Usage: "compile Wa source code", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "output", + Aliases: []string{"o"}, + Usage: "set output file", + Value: "a.out.wasm", + }, + &cli.StringFlag{ + Name: "target", + Usage: "set target os (wasi|arduino|chrome)", + Value: config.WaOS_Default, + }, + &cli.StringFlag{ + Name: "tags", + Usage: "set build tags", + }, + &cli.IntFlag{ + Name: "ld-stack-size", + Usage: "set stack size", + }, + &cli.IntFlag{ + Name: "ld-max-memory", + Usage: "set max memory size", + }, + }, + Action: func(c *cli.Context) error { + outfile := c.String("output") + + if c.NArg() == 0 { + fmt.Fprintf(os.Stderr, "no input file") + os.Exit(1) + } + + ctx := app.NewApp(build_Options(c)) + output, err := ctx.WASM(c.Args().First()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + if outfile != "" && outfile != "-" { + watFilename := outfile + if !strings.HasSuffix(watFilename, ".wat") { + watFilename += ".wat" + } + err := os.WriteFile(watFilename, []byte(output), 0666) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + if strings.HasSuffix(outfile, ".wasm") { + if stdoutStderr, err := apputil.RunWat2Wasm(watFilename, "-o", outfile); err != nil { + fmt.Println(string(stdoutStderr)) + os.Exit(1) + } + os.Remove(watFilename) + } + } else { + fmt.Println(string(output)) + } + + return nil + }, + }, + { + Hidden: true, + Name: "native", + Usage: "compile wa source code to native executable", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "output", + Aliases: []string{"o"}, + Usage: "set output file", + Value: "", + }, + &cli.StringFlag{ + Name: "target", + Usage: "set native target", + Value: "", + }, + &cli.StringFlag{ + Name: "tags", + Usage: "set build tags", + }, + &cli.BoolFlag{ + Name: "debug", + Usage: "dump orginal intermediate representation", + }, + &cli.StringFlag{ + Name: "clang", + Usage: "set llvm/clang path", + }, + &cli.StringFlag{ + Name: "llc", + Usage: "set llvm/llc path", + }, + }, + Action: func(c *cli.Context) error { + outfile := c.String("output") + target := c.String("target") + debug := c.Bool("debug") + infile := "" + + if c.NArg() == 0 { + fmt.Fprintf(os.Stderr, "no input file") + os.Exit(1) + } + infile = c.Args().First() + + ctx := app.NewApp(build_Options(c, config.WaBackend_llvm)) + if err := ctx.LLVM(infile, outfile, target, debug); err != nil { + fmt.Println(err) + os.Exit(1) + } + + return nil + }, + }, + + { + Hidden: true, + Name: "lex", + Usage: "lex Wa source code and print token list", + Action: func(c *cli.Context) error { + if c.NArg() == 0 { + fmt.Fprintf(os.Stderr, "no input file") + os.Exit(1) + } + + waApp := app.NewApp(build_Options(c)) + err := waApp.Lex(c.Args().First()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + { + Hidden: true, + Name: "ast", + Usage: "parse Wa source code and print ast", + Action: func(c *cli.Context) error { + if c.NArg() == 0 { + fmt.Fprintf(os.Stderr, "no input file") + os.Exit(1) + } + + waApp := app.NewApp(build_Options(c)) + err := waApp.AST(c.Args().First()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + { + Hidden: true, + Name: "ssa", + Usage: "print Wa ssa code", + Action: func(c *cli.Context) error { + if c.NArg() == 0 { + fmt.Fprintf(os.Stderr, "no input file") + os.Exit(1) + } + + ctx := app.NewApp(build_Options(c)) + err := ctx.SSA(c.Args().First()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + { + Hidden: true, + Name: "cir", + Usage: "print cir code", + Action: func(c *cli.Context) error { + if c.NArg() == 0 { + fmt.Fprintf(os.Stderr, "no input file") + os.Exit(1) + } + + ctx := app.NewApp(build_Options(c)) + err := ctx.CIR(c.Args().First()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + { + Hidden: true, + Name: "test", + Usage: "test packages", + Action: func(c *cli.Context) error { + if c.NArg() < 1 { + cli.ShowAppHelpAndExit(c, 0) + } + appArgs := c.Args().Slice()[1:] + waApp := app.NewApp(build_Options(c)) + err := waApp.RunTest(c.Args().First(), appArgs...) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + { + Name: "fmt", + Usage: "format Wa package sources", + Action: func(c *cli.Context) error { + waApp := app.NewApp(build_Options(c)) + err := waApp.Fmt(c.Args().First()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + { + Hidden: true, + Name: "doc", + Usage: "show documentation for package or symbol", + Action: func(c *cli.Context) error { + fmt.Println("TODO") + return nil + }, + }, + { + Hidden: true, + Name: "install-wat2wasm", + Usage: "install-wat2wasm tool", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "dir", + Usage: "set output dir", + Value: "", + }, + }, + Action: func(c *cli.Context) error { + outdir := c.String("dir") + if err := apputil.InstallWat2wasm(outdir); err != nil { + fmt.Println(err) + os.Exit(1) + } + return nil + }, + }, + + { + Name: "yacc", + Usage: "generates parsers for LALR(1) grammars", + ArgsUsage: "", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "l", + Usage: "disable line directives", + }, + &cli.StringFlag{ + Name: "o", + Usage: "set parser output file", + Value: "y.wa", + }, + &cli.StringFlag{ + Name: "p", + Usage: "name prefix to use in generated code", + Value: "yy", + }, + &cli.StringFlag{ + Name: "v", + Usage: "create parsing tables", + Value: "y.output", + }, + &cli.StringFlag{ + Name: "c", + Usage: "set copyright file", + Value: "", + }, + }, + Action: func(c *cli.Context) error { + if c.NArg() != 1 { + cli.ShowSubcommandHelpAndExit(c, 1) + } + yacc.InitFlags(yacc.Flags{ + Oflag: c.String("o"), + Vflag: c.String("v"), + Lflag: c.Bool("l"), + Prefix: c.String("p"), + Copyright: loadCopyright(c.String("c")), + }) + yacc.Main(c.Args().First()) + return nil + }, + }, + + { + Name: "logo", + Usage: "print wa-lang text format logo", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "more", + Usage: "print more logos", + }, + }, + Action: func(c *cli.Context) error { + app.PrintLogo(c.Bool("more")) + return nil + }, + }, + } + + cliApp.Run(os.Args) +} + +func build_Options(c *cli.Context, waBackend ...string) *app.Option { + opt := &app.Option{ + Debug: c.Bool("debug"), + WaBackend: config.WaBackend_Default, + BuilgTags: strings.Fields(c.String("tags")), + Clang: c.String("clang"), + Llc: c.String("llc"), + LD_StackSize: c.Int("ld-stack-size"), + LD_MaxMemory: c.Int("ld-max-memory"), + } + + opt.TargetArch = "wasm" + if len(waBackend) > 0 { + opt.WaBackend = waBackend[0] + } + switch c.String("target") { + case "", "wa", "walang": + opt.TargetOS = config.WaOS_Default + case config.WaOS_wasi: + opt.TargetOS = config.WaOS_wasi + case config.WaOS_arduino: + opt.TargetOS = config.WaOS_arduino + case config.WaOS_chrome: + opt.TargetOS = config.WaOS_chrome + default: + fmt.Printf("unknown target: %s\n", c.String("target")) + os.Exit(1) + } + return opt +} + +func cliRun(c *cli.Context) { + if c.NArg() < 1 { + cli.ShowAppHelpAndExit(c, 0) + } + + var app = app.NewApp(build_Options(c)) + var infile = c.Args().First() + var outfile string + var output []byte + var err error + + if !c.Bool("debug") { + defer os.Remove(outfile) + } + + switch { + case strings.HasSuffix(infile, ".wat"): + outfile = infile + output, err = os.ReadFile(infile) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + case strings.HasSuffix(infile, ".wasm"): + outfile = infile + output, err = os.ReadFile(infile) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + default: + outfile = "a.out.wat" + output, err = app.WASM(infile) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + if err = os.WriteFile(outfile, []byte(output), 0666); err != nil { + fmt.Println(err) + os.Exit(1) + } + } + + appArgs := c.Args().Slice()[1:] + stdoutStderr, err := apputil.RunWasm(app.GetConfig(), outfile, appArgs...) + if err != nil { + if len(stdoutStderr) > 0 { + fmt.Println(string(stdoutStderr)) + } + if exitErr, ok := err.(*sys.ExitError); ok { + os.Exit(int(exitErr.ExitCode())) + } + fmt.Println(err) + } + if len(stdoutStderr) > 0 { + fmt.Println(string(stdoutStderr)) + } +} + +func loadCopyright(filename string) string { + data, _ := os.ReadFile(filename) + return string(data) +} diff --git a/main.go b/main.go index 20c8e92..b0053b6 100644 --- a/main.go +++ b/main.go @@ -1,572 +1,8 @@ // 版权 @2019 凹语言 作者。保留所有权利。 -//go:build !wasm -// +build !wasm - // 凹语言,The Wa Programming Language. package main -import ( - "fmt" - "os" - "runtime/debug" - "strings" - "time" +import "wa-lang.org/wa/internal/app/wacli" - "github.com/tetratelabs/wazero/sys" - - "wa-lang.org/wa/api" - "wa-lang.org/wa/internal/3rdparty/cli" - "wa-lang.org/wa/internal/app" - "wa-lang.org/wa/internal/app/apputil" - "wa-lang.org/wa/internal/app/yacc" - "wa-lang.org/wa/internal/config" -) - -func main() { - cliApp := cli.NewApp() - cliApp.Name = "Wa" - cliApp.Usage = "Wa is a tool for managing Wa source code." - cliApp.Version = func() string { - if info, ok := debug.ReadBuildInfo(); ok { - if info.Main.Version != "" { - return info.Main.Version - } - } - return "devel:" + time.Now().Format("2006-01-02+15:04:05") - }() - - cliApp.Flags = []cli.Flag{ - &cli.StringFlag{ - Name: "target", - Usage: "set target os (arduino|chrome|wasi)", - Value: config.WaOS_Default, - }, - &cli.BoolFlag{ - Name: "debug", - Aliases: []string{"d"}, - Usage: "set debug mode", - }, - &cli.StringFlag{ - Name: "trace", - Aliases: []string{"t"}, - Usage: "set trace mode (*|app|compiler|loader)", - }, - } - - cliApp.Before = func(c *cli.Context) error { - switch c.String("target") { - case "wasi", "arduino", "chrome": - // OK - default: - fmt.Printf("unknown target: %s\n", c.String("target")) - os.Exit(1) - } - if c.Bool("debug") { - config.SetDebugMode() - } - if parten := c.String("trace"); parten != "" { - config.SetEnableTrace(parten) - } - return nil - } - - // 没有参数时对应 run 命令 - cliApp.Action = func(c *cli.Context) error { - cliRun(c) - return nil - } - - cliApp.Commands = []*cli.Command{ - { - // go run main.go debug - Hidden: true, - Name: "debug", - Usage: "only for dev/debug", - Action: func(c *cli.Context) error { - wat, err := api.BuildFile( - config.DefaultConfig(), - "hello.wa", "func main() { println(123) }", - ) - if err != nil { - if len(wat) != 0 { - fmt.Println(string(wat)) - } - fmt.Println(err) - os.Exit(1) - } - fmt.Println(string(wat)) - return nil - }, - }, - { - Name: "init", - Usage: "init a sketch wa module", - ArgsUsage: "app-name", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "name", - Aliases: []string{"n"}, - Usage: "set app name", - Value: "_examples/hello", - }, - &cli.StringFlag{ - Name: "pkgpath", - Aliases: []string{"p"}, - Usage: "set pkgpath file", - Value: "myapp", - }, - &cli.BoolFlag{ - Name: "update", - Aliases: []string{"u"}, - Usage: "update example", - }, - }, - - Action: func(c *cli.Context) error { - waApp := app.NewApp(build_Options(c)) - err := waApp.InitApp(c.String("name"), c.String("pkgpath"), c.Bool("update")) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - { - Name: "run", - Usage: "compile and run Wa program", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "target", - Usage: "set target os (wasi|arduino|chrome)", - Value: config.WaOS_Default, - }, - &cli.StringFlag{ - Name: "tags", - Usage: "set build tags", - }, - }, - Action: func(c *cli.Context) error { - cliRun(c) - return nil - }, - }, - { - Name: "build", - Usage: "compile Wa source code", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "output", - Aliases: []string{"o"}, - Usage: "set output file", - Value: "a.out.wasm", - }, - &cli.StringFlag{ - Name: "target", - Usage: "set target os (wasi|arduino|chrome)", - Value: config.WaOS_Default, - }, - &cli.StringFlag{ - Name: "tags", - Usage: "set build tags", - }, - &cli.IntFlag{ - Name: "ld-stack-size", - Usage: "set stack size", - }, - &cli.IntFlag{ - Name: "ld-max-memory", - Usage: "set max memory size", - }, - }, - Action: func(c *cli.Context) error { - outfile := c.String("output") - - if c.NArg() == 0 { - fmt.Fprintf(os.Stderr, "no input file") - os.Exit(1) - } - - ctx := app.NewApp(build_Options(c)) - output, err := ctx.WASM(c.Args().First()) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - if outfile != "" && outfile != "-" { - watFilename := outfile - if !strings.HasSuffix(watFilename, ".wat") { - watFilename += ".wat" - } - err := os.WriteFile(watFilename, []byte(output), 0666) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - if strings.HasSuffix(outfile, ".wasm") { - if stdoutStderr, err := apputil.RunWat2Wasm(watFilename, "-o", outfile); err != nil { - fmt.Println(string(stdoutStderr)) - os.Exit(1) - } - os.Remove(watFilename) - } - } else { - fmt.Println(string(output)) - } - - return nil - }, - }, - { - Hidden: true, - Name: "native", - Usage: "compile wa source code to native executable", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "output", - Aliases: []string{"o"}, - Usage: "set output file", - Value: "", - }, - &cli.StringFlag{ - Name: "target", - Usage: "set native target", - Value: "", - }, - &cli.StringFlag{ - Name: "tags", - Usage: "set build tags", - }, - &cli.BoolFlag{ - Name: "debug", - Usage: "dump orginal intermediate representation", - }, - &cli.StringFlag{ - Name: "clang", - Usage: "set llvm/clang path", - }, - &cli.StringFlag{ - Name: "llc", - Usage: "set llvm/llc path", - }, - }, - Action: func(c *cli.Context) error { - outfile := c.String("output") - target := c.String("target") - debug := c.Bool("debug") - infile := "" - - if c.NArg() == 0 { - fmt.Fprintf(os.Stderr, "no input file") - os.Exit(1) - } - infile = c.Args().First() - - ctx := app.NewApp(build_Options(c, config.WaBackend_llvm)) - if err := ctx.LLVM(infile, outfile, target, debug); err != nil { - fmt.Println(err) - os.Exit(1) - } - - return nil - }, - }, - - { - Hidden: true, - Name: "lex", - Usage: "lex Wa source code and print token list", - Action: func(c *cli.Context) error { - if c.NArg() == 0 { - fmt.Fprintf(os.Stderr, "no input file") - os.Exit(1) - } - - waApp := app.NewApp(build_Options(c)) - err := waApp.Lex(c.Args().First()) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - { - Hidden: true, - Name: "ast", - Usage: "parse Wa source code and print ast", - Action: func(c *cli.Context) error { - if c.NArg() == 0 { - fmt.Fprintf(os.Stderr, "no input file") - os.Exit(1) - } - - waApp := app.NewApp(build_Options(c)) - err := waApp.AST(c.Args().First()) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - { - Hidden: true, - Name: "ssa", - Usage: "print Wa ssa code", - Action: func(c *cli.Context) error { - if c.NArg() == 0 { - fmt.Fprintf(os.Stderr, "no input file") - os.Exit(1) - } - - ctx := app.NewApp(build_Options(c)) - err := ctx.SSA(c.Args().First()) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - { - Hidden: true, - Name: "cir", - Usage: "print cir code", - Action: func(c *cli.Context) error { - if c.NArg() == 0 { - fmt.Fprintf(os.Stderr, "no input file") - os.Exit(1) - } - - ctx := app.NewApp(build_Options(c)) - err := ctx.CIR(c.Args().First()) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - { - Hidden: true, - Name: "test", - Usage: "test packages", - Action: func(c *cli.Context) error { - if c.NArg() < 1 { - cli.ShowAppHelpAndExit(c, 0) - } - appArgs := c.Args().Slice()[1:] - waApp := app.NewApp(build_Options(c)) - err := waApp.RunTest(c.Args().First(), appArgs...) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - { - Name: "fmt", - Usage: "format Wa package sources", - Action: func(c *cli.Context) error { - waApp := app.NewApp(build_Options(c)) - err := waApp.Fmt(c.Args().First()) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - { - Hidden: true, - Name: "doc", - Usage: "show documentation for package or symbol", - Action: func(c *cli.Context) error { - fmt.Println("TODO") - return nil - }, - }, - { - Hidden: true, - Name: "install-wat2wasm", - Usage: "install-wat2wasm tool", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "dir", - Usage: "set output dir", - Value: "", - }, - }, - Action: func(c *cli.Context) error { - outdir := c.String("dir") - if err := apputil.InstallWat2wasm(outdir); err != nil { - fmt.Println(err) - os.Exit(1) - } - return nil - }, - }, - - { - Name: "yacc", - Usage: "generates parsers for LALR(1) grammars", - ArgsUsage: "", - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "l", - Usage: "disable line directives", - }, - &cli.StringFlag{ - Name: "o", - Usage: "set parser output file", - Value: "y.wa", - }, - &cli.StringFlag{ - Name: "p", - Usage: "name prefix to use in generated code", - Value: "yy", - }, - &cli.StringFlag{ - Name: "v", - Usage: "create parsing tables", - Value: "y.output", - }, - &cli.StringFlag{ - Name: "c", - Usage: "set copyright file", - Value: "", - }, - }, - Action: func(c *cli.Context) error { - if c.NArg() != 1 { - cli.ShowSubcommandHelpAndExit(c, 1) - } - yacc.InitFlags(yacc.Flags{ - Oflag: c.String("o"), - Vflag: c.String("v"), - Lflag: c.Bool("l"), - Prefix: c.String("p"), - Copyright: loadCopyright(c.String("c")), - }) - yacc.Main(c.Args().First()) - return nil - }, - }, - - { - Name: "logo", - Usage: "print wa-lang text format logo", - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "more", - Usage: "print more logos", - }, - }, - Action: func(c *cli.Context) error { - app.PrintLogo(c.Bool("more")) - return nil - }, - }, - } - - cliApp.Run(os.Args) -} - -func build_Options(c *cli.Context, waBackend ...string) *app.Option { - opt := &app.Option{ - Debug: c.Bool("debug"), - WaBackend: config.WaBackend_Default, - BuilgTags: strings.Fields(c.String("tags")), - Clang: c.String("clang"), - Llc: c.String("llc"), - LD_StackSize: c.Int("ld-stack-size"), - LD_MaxMemory: c.Int("ld-max-memory"), - } - - opt.TargetArch = "wasm" - if len(waBackend) > 0 { - opt.WaBackend = waBackend[0] - } - switch c.String("target") { - case "", "wa", "walang": - opt.TargetOS = config.WaOS_Default - case config.WaOS_wasi: - opt.TargetOS = config.WaOS_wasi - case config.WaOS_arduino: - opt.TargetOS = config.WaOS_arduino - case config.WaOS_chrome: - opt.TargetOS = config.WaOS_chrome - default: - fmt.Printf("unknown target: %s\n", c.String("target")) - os.Exit(1) - } - return opt -} - -func cliRun(c *cli.Context) { - if c.NArg() < 1 { - cli.ShowAppHelpAndExit(c, 0) - } - - var app = app.NewApp(build_Options(c)) - var infile = c.Args().First() - var outfile string - var output []byte - var err error - - if !c.Bool("debug") { - defer os.Remove(outfile) - } - - switch { - case strings.HasSuffix(infile, ".wat"): - outfile = infile - output, err = os.ReadFile(infile) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - case strings.HasSuffix(infile, ".wasm"): - outfile = infile - output, err = os.ReadFile(infile) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - default: - outfile = "a.out.wat" - output, err = app.WASM(infile) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - if err = os.WriteFile(outfile, []byte(output), 0666); err != nil { - fmt.Println(err) - os.Exit(1) - } - } - - appArgs := c.Args().Slice()[1:] - stdoutStderr, err := apputil.RunWasm(app.GetConfig(), outfile, appArgs...) - if err != nil { - if len(stdoutStderr) > 0 { - fmt.Println(string(stdoutStderr)) - } - if exitErr, ok := err.(*sys.ExitError); ok { - os.Exit(int(exitErr.ExitCode())) - } - fmt.Println(err) - } - if len(stdoutStderr) > 0 { - fmt.Println(string(stdoutStderr)) - } -} - -func loadCopyright(filename string) string { - data, _ := os.ReadFile(filename) - return string(data) -} +func main() { wacli.Main() }