From e191e59cf9d4565a39d5f30313d4ff973a9da0c4 Mon Sep 17 00:00:00 2001 From: ryotaro oda Date: Sat, 7 Dec 2019 22:13:51 +0900 Subject: [PATCH] feat: cmd --- cmd/exec.go | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/repl.go | 61 +++++++++++++++++++++++++++++++++++++ cmd/root.go | 70 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 cmd/exec.go create mode 100644 cmd/repl.go create mode 100644 cmd/root.go diff --git a/cmd/exec.go b/cmd/exec.go new file mode 100644 index 0000000..8c3e428 --- /dev/null +++ b/cmd/exec.go @@ -0,0 +1,87 @@ +/* +Copyright © 2019 NAME HERE + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "flag" + "fmt" + "io" + "io/ioutil" + "os" + + "github.com/0daryo/ody/evaluator" + "github.com/0daryo/ody/lexer" + "github.com/0daryo/ody/object" + "github.com/0daryo/ody/parser" + "github.com/spf13/cobra" +) + +// execCmd represents the exec command +var execCmd = &cobra.Command{ + Use: "exec", + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + Run: func(cmd *cobra.Command, args []string) { + flag.Parse() + // ファイルをOpenする + f, err := os.Open(fmt.Sprintf("%s.od", flag.Arg(1))) + if err != nil { + fmt.Println("error") + } + defer f.Close() + + b, _ := ioutil.ReadAll(f) + l := lexer.New(string(b)) + p := parser.New(l) + + program := p.ParseProgram() + out := os.Stdout + if len(p.Errors()) != 0 { + printParserErrors(out, p.Errors()) + } + env := object.NewEnvironment() + evaluated := evaluator.Eval(program, env) + if evaluated != nil && evaluated.Inspect() != "null" { + io.WriteString(out, evaluated.Inspect()) + io.WriteString(out, "\n") + } + }, +} + +func init() { + rootCmd.AddCommand(execCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // execCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // execCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} + +func printParserErrors(out io.Writer, errors []string) { + for _, msg := range errors { + io.WriteString(out, "\t"+msg+"\n") + } +} diff --git a/cmd/repl.go b/cmd/repl.go new file mode 100644 index 0000000..dddab76 --- /dev/null +++ b/cmd/repl.go @@ -0,0 +1,61 @@ +/* +Copyright © 2019 NAME HERE + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "fmt" + "os" + "os/user" + + "github.com/0daryo/ody/repl" + "github.com/spf13/cobra" +) + +// replCmd represents the repl command +var replCmd = &cobra.Command{ + Use: "repl", + Short: "repl", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + Run: func(cmd *cobra.Command, args []string) { + user, err := user.Current() + if err != nil { + panic(err) + } + fmt.Printf("Hello %s! This is the ody programming language!\n", + user.Username) + fmt.Printf("Feel free to type in commands\n") + repl.Start(os.Stdin, os.Stdout) + }, +} + +func init() { + rootCmd.AddCommand(replCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // replCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // replCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..0909642 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,70 @@ +package cmd + +import ( + "fmt" + "os" + + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var cfgFile string + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "ody", + Short: "interpreter", + Long: `interprete txt file`, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + cobra.OnInitialize(initConfig) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.hoge.yaml)") + + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in home directory with name ".hoge" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".hoge") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } +}