main.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package main
  2. import (
  3. grt "runtime"
  4. "os"
  5. "fmt"
  6. "reflect"
  7. "kumachan/standalone/qt"
  8. "kumachan/standalone/util"
  9. "kumachan/standalone/util/gcr"
  10. "kumachan/standalone/util/argv"
  11. "kumachan/standalone/util/fatal"
  12. "kumachan/lang/textual"
  13. "kumachan/lang/textual/syntax"
  14. "kumachan/interpreter"
  15. )
  16. var Help string
  17. const Version = "0.0.0 pre-alpha"
  18. const NoProgramFilePrompt = "** No Program File or Directory Specified **\n" +
  19. "input a path or press enter to start REPL:"
  20. type Args struct {
  21. Positional [] string `arg:"positional" hint:"[PATH [ARGUMENT]...]"`
  22. Command string `arg:"command" key:"help-0; version-0; atom-0; mnfst-0; gcr-1; parse; run" default:"run" desc:"show this help; show version; start plugin backend service for the Atom Editor; start module manifest editor; exec another program with GUI-based crash report; parse the file at PATH; run the file or directory at PATH"`
  23. EnableRepl bool `arg:"flag-enable" key:"repl" desc:"enable REPL"`
  24. DebugUI bool `arg:"flag-enable" key:"debug-ui" desc:"enable ui debugging"`
  25. AsmDumpPath string `arg:"value-string" key:"asm-dump" hint:"FILE" desc:"dump assembly code to FILE"`
  26. }
  27. var Commands = map[string] func(*Args) {
  28. "help": func(_ *Args) {
  29. fmt.Fprintf(os.Stderr, "%s\n", Help)
  30. },
  31. "version": func(_ *Args) {
  32. fmt.Fprintf(os.Stderr, "%s\n", Version)
  33. },
  34. "atom": func(_ *Args) {
  35. // TODO
  36. // var err = atom.LangServer(os.Stdin, os.Stdout, os.Stderr)
  37. // if err != nil { fatal.CrashGoError(err, "Crashed") }
  38. },
  39. "mnfst": WithQt(func(_ *Args) {
  40. // TODO: remove this command
  41. // mnfstedit.Setup()
  42. }),
  43. "gcr": WithQt(func(args *Args) {
  44. var another_argv = args.Positional
  45. gcr.Exec(another_argv)
  46. }),
  47. "parse": func(args *Args) {
  48. const default_root = syntax.DefaultRootPartName
  49. const repl_root = syntax.ReplRootPartName
  50. var L = len(args.Positional)
  51. if L == 0 {
  52. textual.DebugParser(os.Stdin, "(stdin)", repl_root)
  53. } else if L >= 1 {
  54. for _, file := range args.Positional {
  55. f, err := os.Open(file)
  56. if err != nil { fatal.CrashGoError(err, "Crashed") }
  57. textual.DebugParser(f, f.Name(), default_root)
  58. err = f.Close()
  59. if err != nil { fatal.CrashGoError(err, "Crashed") }
  60. }
  61. }
  62. },
  63. "run": WithQt(func(args *Args) {
  64. var entry_path, no_file_specified, program_args =
  65. (func() (string, bool, ([] string)) {
  66. var L = len(args.Positional)
  67. if L == 0 {
  68. return "", true, nil
  69. } else {
  70. var entry_path = args.Positional[0]
  71. var program_args = args.Positional[1:]
  72. return entry_path, false, program_args
  73. }
  74. })()
  75. if no_file_specified {
  76. fmt.Fprintf(os.Stderr, "%s\n", NoProgramFilePrompt)
  77. var line, _, err = util.WellBehavedFscanln(os.Stdin)
  78. if err != nil { panic(err) }
  79. if line != "" {
  80. entry_path = line
  81. no_file_specified = false
  82. }
  83. }
  84. var repl_enabled = (args.EnableRepl || no_file_specified)
  85. var repl_config = interpreter.ReplConfig {
  86. Input: os.Stdin,
  87. Output: os.Stderr,
  88. }
  89. var p, ctx, exe, err = interpreter.Compile(entry_path)
  90. if err != nil {
  91. fatal.Crash(err, "Failed to Compile")
  92. }
  93. var env = interpreter.OrdinaryEnvironment(program_args)
  94. if repl_enabled {
  95. interpreter.Repl(p, ctx, exe, env, repl_config)
  96. } else {
  97. interpreter.Run(p, env)
  98. }
  99. os.Exit(0)
  100. }),
  101. }
  102. func WithQt(cmd func(*Args)) func(*Args) {
  103. return func(args *Args) {
  104. qt.Init()
  105. go cmd(args)
  106. qt.Main()
  107. }
  108. }
  109. func main() {
  110. grt.LockOSThread() // ensures Qt event loop running on main thread
  111. var args Args
  112. var err error
  113. Help, err = argv.ParseArgs(os.Args, reflect.ValueOf(&args))
  114. if err != nil {
  115. fatal.BadArgs(err, Help)
  116. }
  117. Commands[args.Command](&args)
  118. }