wa 命令调整目录结构

This commit is contained in:
chai2010 2023-07-24 20:19:25 +08:00
parent d4c997cc1e
commit c79fbbc593
19 changed files with 529 additions and 439 deletions

View File

@ -1,11 +1,36 @@
// 版权 @2023 凹语言 作者。保留所有权利。
package appast
import (
"fmt"
"os"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/ast"
"wa-lang.org/wa/internal/parser"
"wa-lang.org/wa/internal/token"
)
var CmdAst = &cli.Command{
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)
}
err := PrintAST(c.Args().First())
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func PrintAST(filename string) error {
fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(nil, fset, filename, nil, 0)

View File

@ -5,12 +5,99 @@ package appbuild
import (
"fmt"
"os"
"strings"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/app/appbase"
"wa-lang.org/wa/internal/backends/compiler_wat"
"wa-lang.org/wa/internal/config"
"wa-lang.org/wa/internal/loader"
"wa-lang.org/wa/internal/wabt"
)
var CmdBuild = &cli.Command{
Name: "build",
Usage: "compile Wa source code",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "output",
Aliases: []string{"o"},
Usage: "set output file",
Value: "",
},
&cli.StringFlag{
Name: "target",
Usage: fmt.Sprintf("set target os (%s)", strings.Join(config.WaOS_List, "|")),
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 {
var input string
if c.NArg() > 0 {
input = c.Args().First()
} else {
input, _ = os.Getwd()
}
outfile := c.String("output")
if outfile == "" {
if fi, _ := os.Lstat(input); fi != nil && fi.IsDir() {
// /xxx/yyy/ => /xxx/yyy/output/yyy.wat
} else {
// /xxx/yyy/zzz.wa => /xxx/yyy/zzz.wat
}
outfile = "a.out.wasm"
}
opt := appbase.BuildOptions(c)
watOutput, err := Build(opt, input)
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(watOutput), 0666)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if strings.HasSuffix(outfile, ".wasm") {
wasmBytes, err := wabt.Wat2Wasm(watOutput)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if err := os.WriteFile(outfile, wasmBytes, 0666); err != nil {
fmt.Println(err)
os.Exit(1)
}
os.Remove(watFilename)
}
} else {
fmt.Println(string(watOutput))
}
return nil
},
}
func Build(opt *appbase.Option, filename string) ([]byte, error) {
if _, err := os.Lstat(filename); err != nil {
return nil, fmt.Errorf("%q not found", filename)

View File

@ -1,13 +1,37 @@
// 版权 @2023 凹语言 作者。保留所有权利。
package appcir
import (
"fmt"
"os"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/app/appbase"
"wa-lang.org/wa/internal/backends/compiler_c"
"wa-lang.org/wa/internal/loader"
)
var CmdCir = &cli.Command{
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)
}
opt := appbase.BuildOptions(c)
err := PrintCIR(opt, c.Args().First())
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func PrintCIR(opt *appbase.Option, filename string) error {
cfg := opt.Config()
prog, err := loader.LoadProgram(cfg, filename)

View File

@ -0,0 +1,32 @@
package appdev
import (
"fmt"
"os"
"wa-lang.org/wa/api"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/config"
)
var CmdDev = &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
},
}

View File

@ -0,0 +1,17 @@
package appdoc
import (
"fmt"
"wa-lang.org/wa/internal/3rdparty/cli"
)
var CmdDoc = &cli.Command{
Hidden: true,
Name: "doc",
Usage: "show documentation for package or symbol",
Action: func(c *cli.Context) error {
fmt.Println("TODO")
return nil
},
}

View File

@ -9,9 +9,23 @@ import (
"sort"
"strings"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/format"
)
var CmdFmt = &cli.Command{
Name: "fmt",
Usage: "format Wa source code file",
Action: func(c *cli.Context) error {
err := Fmt(c.Args().First())
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func Fmt(path string) error {
if path == "" {
if _, err := os.Lstat("wa.mod.json"); err == nil {

View File

@ -12,9 +12,43 @@ import (
"time"
"unicode"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/waroot"
)
var CmdInit = &cli.Command{
Name: "init",
Usage: "init a sketch Wa module",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Usage: "set app name",
Value: "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 {
err := InitApp(c.String("name"), c.String("pkgpath"), c.Bool("update"))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func InitApp(name, pkgpath string, update bool) error {
if name == "" {
return fmt.Errorf("init failed: <%s> is empty", name)

View File

@ -9,10 +9,30 @@ import (
"io"
"os"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/scanner"
"wa-lang.org/wa/internal/token"
)
var CmdLex = &cli.Command{
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)
}
err := Lex(c.Args().First())
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func Lex(filename string) error {
src, err := readSource(filename, nil)
if err != nil {

View File

@ -9,11 +9,68 @@ import (
"path"
"strings"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/app/appbase"
"wa-lang.org/wa/internal/backends/compiler_llvm"
"wa-lang.org/wa/internal/config"
"wa-lang.org/wa/internal/loader"
)
var CmdNative = &cli.Command{
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()
opt := appbase.BuildOptions(c, config.WaBackend_llvm)
if err := LLVMRun(opt, infile, outfile, target, debug); err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func LLVMRun(opt *appbase.Option, infile string, outfile string, target string, debug bool) error {
cfg := opt.Config()

View File

@ -1,3 +1,21 @@
// 版权 @2023 凹语言 作者。保留所有权利。
package applogo
import "wa-lang.org/wa/internal/3rdparty/cli"
var CmdLogo = &cli.Command{
Name: "logo",
Usage: "print Wa text format logo",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "more",
Aliases: []string{"m"},
Usage: "print more logos",
},
},
Action: func(c *cli.Context) error {
PrintLogo(c.Bool("more"))
return nil
},
}

View File

@ -0,0 +1,23 @@
package applsp
import (
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/lsp"
)
var CmdLsp = &cli.Command{
Hidden: true,
Name: "lsp",
Usage: "run Wa langugage server",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "log-file",
Usage: "set log file",
Value: "",
},
},
Action: func(c *cli.Context) error {
lsp.NewLSPServer(&lsp.Option{}).Run()
return nil
},
}

View File

@ -4,12 +4,35 @@ package appplay
import (
"fmt"
"os"
"os/exec"
"runtime"
"strings"
"time"
"wa-lang.org/wa/internal/3rdparty/cli"
)
var CmdPlay = &cli.Command{
Name: "play",
Usage: "start Wa playground",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "http",
Value: ":2023",
Usage: "set http address",
},
},
Action: func(c *cli.Context) error {
err := RunPlayground(c.String("http"))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func RunPlayground(addr string) error {
if strings.HasPrefix(addr, ":") {
addr = "localhost" + addr

View File

@ -10,10 +10,31 @@ import (
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/app/appbase"
"wa-lang.org/wa/internal/app/appbuild"
"wa-lang.org/wa/internal/config"
"wa-lang.org/wa/internal/wabt"
"wa-lang.org/wa/internal/wazero"
)
var CmdRun = &cli.Command{
Name: "run",
Usage: "compile and run Wa program",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "target",
Usage: fmt.Sprintf("set target os (%s)", strings.Join(config.WaOS_List, "|")),
Value: config.WaOS_Default,
},
&cli.StringFlag{
Name: "tags",
Usage: "set build tags",
},
},
Action: func(c *cli.Context) error {
Run(c)
return nil
},
}
func Run(c *cli.Context) {
var infile string
if c.NArg() > 0 {

View File

@ -3,14 +3,36 @@
package appssa
import (
"fmt"
"os"
"sort"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/app/appbase"
"wa-lang.org/wa/internal/loader"
"wa-lang.org/wa/internal/ssa"
)
var CmdSsa = &cli.Command{
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)
}
opt := appbase.BuildOptions(c)
err := SSARun(opt, c.Args().First())
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
}
func SSARun(opt *appbase.Option, filename string) error {
cfg := opt.Config()
prog, err := loader.LoadProgram(cfg, filename)

View File

@ -9,6 +9,8 @@ import (
"strings"
"time"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/app/appbase"
"wa-lang.org/wa/internal/backends/compiler_wat"
"wa-lang.org/wa/internal/config"
"wa-lang.org/wa/internal/loader"
@ -17,6 +19,31 @@ import (
"wa-lang.org/wa/waroot"
)
var CmdTest = &cli.Command{
Name: "test",
Usage: "test Wa packages",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "target",
Usage: fmt.Sprintf("set target os (%s)", strings.Join(config.WaOS_List, "|")),
Value: config.WaOS_Default,
},
&cli.StringFlag{
Name: "tags",
Usage: "set build tags",
},
},
Action: func(c *cli.Context) error {
if c.NArg() < 1 {
cli.ShowAppHelpAndExit(c, 0)
}
appArgs := c.Args().Slice()[1:]
opt := appbase.BuildOptions(c)
RunTest(opt.Config(), c.Args().First(), appArgs...)
return nil
},
}
func RunTest(cfg *config.Config, pkgpath string, appArgs ...string) {
var pkgList = []string{pkgpath}
if pkgpath == "std" {

View File

@ -0,0 +1,58 @@
package appyacc
import (
"os"
"wa-lang.org/wa/internal/3rdparty/cli"
)
var CmdYacc = &cli.Command{
Name: "yacc",
Usage: "generates parsers for LALR(1) grammars",
ArgsUsage: "<input>",
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)
}
InitFlags(Flags{
Oflag: c.String("o"),
Vflag: c.String("v"),
Lflag: c.Bool("l"),
Prefix: c.String("p"),
Copyright: loadCopyright(c.String("c")),
})
Main(c.Args().First())
return nil
},
}
func loadCopyright(filename string) string {
data, _ := os.ReadFile(filename)
return string(data)
}

View File

@ -7,29 +7,26 @@
package app
import (
"fmt"
"os"
"strings"
"wa-lang.org/wa/api"
"wa-lang.org/wa/internal/3rdparty/cli"
"wa-lang.org/wa/internal/app/appast"
"wa-lang.org/wa/internal/app/appbase"
"wa-lang.org/wa/internal/app/appbuild"
"wa-lang.org/wa/internal/app/appcir"
"wa-lang.org/wa/internal/app/appdev"
"wa-lang.org/wa/internal/app/appdoc"
"wa-lang.org/wa/internal/app/appfmt"
"wa-lang.org/wa/internal/app/appinit"
"wa-lang.org/wa/internal/app/applex"
"wa-lang.org/wa/internal/app/appllvm"
"wa-lang.org/wa/internal/app/applogo"
"wa-lang.org/wa/internal/app/applsp"
"wa-lang.org/wa/internal/app/appplay"
"wa-lang.org/wa/internal/app/apprun"
"wa-lang.org/wa/internal/app/appssa"
"wa-lang.org/wa/internal/app/apptest"
"wa-lang.org/wa/internal/app/appyacc"
"wa-lang.org/wa/internal/config"
"wa-lang.org/wa/internal/lsp"
"wa-lang.org/wa/internal/wabt"
"wa-lang.org/wa/waroot"
)
@ -40,6 +37,7 @@ func Main() {
cliApp.Copyright = "Copyright 2018 The Wa Authors. All rights reserved."
cliApp.Version = waroot.GetVersion()
cliApp.EnableBashCompletion = true
cliApp.HideHelpCommand = true
cliApp.CustomAppHelpTemplate = cli.AppHelpTemplate +
"\nSee \"https://wa-lang.org\" for more information.\n"
@ -74,443 +72,30 @@ func Main() {
}
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
},
},
// 用于调试(隐藏)
appdev.CmdDev,
{
Name: "play",
Usage: "start Wa playground",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "http",
Value: ":2023",
Usage: "set http address",
},
},
Action: func(c *cli.Context) error {
err := appplay.RunPlayground(c.String("http"))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
},
// 用户可见子命令
appplay.CmdPlay,
appinit.CmdInit,
appbuild.CmdBuild,
apprun.CmdRun,
appfmt.CmdFmt,
apptest.CmdTest,
appyacc.CmdYacc,
applogo.CmdLogo,
{
Name: "init",
Usage: "init a sketch Wa module",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Usage: "set app name",
Value: "hello",
},
&cli.StringFlag{
Name: "pkgpath",
Aliases: []string{"p"},
Usage: "set pkgpath file",
Value: "myapp",
},
&cli.BoolFlag{
Name: "update",
Aliases: []string{"u"},
Usage: "update example",
},
},
// 开发者用于测试(隐藏)
applex.CmdLex,
appast.CmdAst,
appssa.CmdSsa,
Action: func(c *cli.Context) error {
err := appinit.InitApp(c.String("name"), c.String("pkgpath"), c.Bool("update"))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
},
{
Name: "build",
Usage: "compile Wa source code",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "output",
Aliases: []string{"o"},
Usage: "set output file",
Value: "",
},
&cli.StringFlag{
Name: "target",
Usage: fmt.Sprintf("set target os (%s)", strings.Join(config.WaOS_List, "|")),
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 {
var input string
if c.NArg() > 0 {
input = c.Args().First()
} else {
input, _ = os.Getwd()
}
outfile := c.String("output")
if outfile == "" {
if fi, _ := os.Lstat(input); fi != nil && fi.IsDir() {
// /xxx/yyy/ => /xxx/yyy/output/yyy.wat
} else {
// /xxx/yyy/zzz.wa => /xxx/yyy/zzz.wat
}
outfile = "a.out.wasm"
}
opt := appbase.BuildOptions(c)
watOutput, err := appbuild.Build(opt, input)
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(watOutput), 0666)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if strings.HasSuffix(outfile, ".wasm") {
wasmBytes, err := wabt.Wat2Wasm(watOutput)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if err := os.WriteFile(outfile, wasmBytes, 0666); err != nil {
fmt.Println(err)
os.Exit(1)
}
os.Remove(watFilename)
}
} else {
fmt.Println(string(watOutput))
}
return nil
},
},
{
Name: "run",
Usage: "compile and run Wa program",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "target",
Usage: fmt.Sprintf("set target os (%s)", strings.Join(config.WaOS_List, "|")),
Value: config.WaOS_Default,
},
&cli.StringFlag{
Name: "tags",
Usage: "set build tags",
},
},
Action: func(c *cli.Context) error {
apprun.Run(c)
return nil
},
},
{
Name: "fmt",
Usage: "format Wa source code file",
Action: func(c *cli.Context) error {
err := appfmt.Fmt(c.Args().First())
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return nil
},
},
{
Name: "test",
Usage: "test Wa packages",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "target",
Usage: fmt.Sprintf("set target os (%s)", strings.Join(config.WaOS_List, "|")),
Value: config.WaOS_Default,
},
&cli.StringFlag{
Name: "tags",
Usage: "set build tags",
},
},
Action: func(c *cli.Context) error {
if c.NArg() < 1 {
cli.ShowAppHelpAndExit(c, 0)
}
appArgs := c.Args().Slice()[1:]
opt := appbase.BuildOptions(c)
apptest.RunTest(opt.Config(), c.Args().First(), appArgs...)
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()
opt := appbase.BuildOptions(c, config.WaBackend_llvm)
if err := appllvm.LLVMRun(opt, 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)
}
err := applex.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)
}
err := appast.PrintAST(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)
}
opt := appbase.BuildOptions(c)
err := appssa.SSARun(opt, 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)
}
opt := appbase.BuildOptions(c)
err := appcir.PrintCIR(opt, 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
},
},
{
Name: "yacc",
Usage: "generates parsers for LALR(1) grammars",
ArgsUsage: "<input>",
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)
}
appyacc.InitFlags(appyacc.Flags{
Oflag: c.String("o"),
Vflag: c.String("v"),
Lflag: c.Bool("l"),
Prefix: c.String("p"),
Copyright: loadCopyright(c.String("c")),
})
appyacc.Main(c.Args().First())
return nil
},
},
{
Hidden: true,
Name: "lsp",
Usage: "run Wa langugage server",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "log-file",
Usage: "set log file",
Value: "",
},
},
Action: func(c *cli.Context) error {
lsp.NewLSPServer(&lsp.Option{}).Run()
return nil
},
},
{
Name: "logo",
Usage: "print Wa text format logo",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "more",
Aliases: []string{"m"},
Usage: "print more logos",
},
},
Action: func(c *cli.Context) error {
applogo.PrintLogo(c.Bool("more"))
return nil
},
},
// 待完善的子命令(隐藏)
appllvm.CmdNative,
appcir.CmdCir,
appdoc.CmdDoc,
applsp.CmdLsp,
}
cliApp.Run(os.Args)
}
func loadCopyright(filename string) string {
data, _ := os.ReadFile(filename)
return string(data)
}

View File

@ -43,5 +43,7 @@ func setEnableTrace(parten string) {
EnableTrace_app = true
EnableTrace_compiler = true
EnableTrace_loader = true
default:
panic("unknown trace flag: " + parten)
}
}

View File

@ -22,6 +22,7 @@ type PkgVFS struct {
// 通用配置信息
type Config struct {
WatOutput string // 输出的 wat 文件路径
WaBackend string // 编译器后端
WaRoot string // 凹 程序根目录, src 目录下是包代码, 为空时用内置标准库实现
WaArch string // 目标 CPU