OSDN Git Service

optimise equity commandline (#36)
[bytom/equity.git] / equity / main.go
1 package main
2
3 import (
4         "bufio"
5         "encoding/hex"
6         "fmt"
7         "os"
8         "runtime"
9
10         "github.com/spf13/cobra"
11
12         "github.com/equity/compiler"
13         equ "github.com/equity/equity/util"
14 )
15
16 const (
17         strBin      string = "bin"
18         strShift    string = "shift"
19         strInstance string = "instance"
20         strAst      string = "ast"
21         strVersion  string = "version"
22 )
23
24 var (
25         bin      = false
26         shift    = false
27         instance = false
28         ast      = false
29         version  = false
30 )
31
32 func init() {
33         equityCmd.PersistentFlags().BoolVar(&bin, strBin, false, "Binary of the contracts in hex.")
34         equityCmd.PersistentFlags().BoolVar(&shift, strShift, false, "Function shift of the contracts.")
35         equityCmd.PersistentFlags().BoolVar(&instance, strInstance, false, "Object of the Instantiated contracts.")
36         equityCmd.PersistentFlags().BoolVar(&ast, strAst, false, "AST of the contracts.")
37         equityCmd.PersistentFlags().BoolVar(&version, strVersion, false, "Version of equity compiler.")
38 }
39
40 func main() {
41         runtime.GOMAXPROCS(runtime.NumCPU())
42         if err := equityCmd.Execute(); err != nil {
43                 os.Exit(0)
44         }
45 }
46
47 var equityCmd = &cobra.Command{
48         Use:     "equity <input_file>",
49         Short:   "equity commandline compiler",
50         Example: "equity contract_name [contract_args...] --bin --instance",
51         Args:    cobra.RangeArgs(0, 100),
52         Run: func(cmd *cobra.Command, args []string) {
53                 if version {
54                         version := compiler.VersionWithCommit(compiler.GitCommit)
55                         fmt.Println("equity, the equity compiler commandline interface")
56                         fmt.Println("Version:", version)
57                         os.Exit(0)
58                 }
59
60                 if len(args) < 1 {
61                         cmd.Usage()
62                         os.Exit(0)
63                 }
64
65                 if err := handleCompiled(args); err != nil {
66                         os.Exit(-1)
67                 }
68         },
69 }
70
71 func handleCompiled(args []string) error {
72         contractFile, err := os.Open(args[0])
73         if err != nil {
74                 fmt.Printf("An error [%v] occurred on opening the file, please check whether the file exists or can be accessed.\n", err)
75                 return err
76         }
77         defer contractFile.Close()
78
79         reader := bufio.NewReader(contractFile)
80         contracts, err := compiler.Compile(reader)
81         if err != nil {
82                 fmt.Println("Compile contract failed:", err)
83                 return err
84         }
85
86         // Print the result for all contracts
87         for i, contract := range contracts {
88                 fmt.Printf("======= %v =======\n", contract.Name)
89                 if bin {
90                         fmt.Println("Binary:")
91                         fmt.Printf("%v\n\n", hex.EncodeToString(contract.Body))
92                 }
93
94                 if shift {
95                         fmt.Println("Clause shift:")
96                         clauseMap, err := equ.Shift(contract)
97                         if err != nil {
98                                 fmt.Println("Statistics contract clause shift error:", err)
99                                 return err
100                         }
101
102                         for clause, shift := range clauseMap {
103                                 fmt.Printf("    %s:  %v\n", clause, shift)
104                         }
105                         fmt.Printf("\nNOTE: \n    If the contract contains only one clause, Users don't need clause selector when unlock contract." +
106                                 "\n    Furthermore, there is no signification for ending clause shift except for display.\n\n")
107                 }
108
109                 if instance {
110                         if i != len(contracts)-1 {
111                                 continue
112                         }
113
114                         fmt.Println("Instantiated program:")
115                         if len(args)-1 < len(contract.Params) {
116                                 fmt.Printf("Error: The number of input arguments %d is less than the number of contract parameters %d\n", len(args)-1, len(contract.Params))
117                                 usage := fmt.Sprintf("Usage:\n  equity %s", args[0])
118                                 for _, param := range contract.Params {
119                                         usage = usage + " <" + param.Name + ">"
120                                 }
121                                 fmt.Printf("%s\n\n", usage)
122                                 return err
123                         }
124
125                         contractArgs, err := equ.ConvertArguments(contract, args[1:len(contract.Params)+1])
126                         if err != nil {
127                                 fmt.Println("Convert arguments into contract parameters error:", err)
128                                 return err
129                         }
130
131                         instantProg, err := equ.InstantiateContract(contract, contractArgs)
132                         if err != nil {
133                                 fmt.Println("Instantiate contract error:", err)
134                                 return err
135                         }
136                         fmt.Printf("%v\n\n", hex.EncodeToString(instantProg))
137                 }
138
139                 if ast {
140                         fmt.Println("Ast:")
141                         rawData, err := equ.JSONMarshal(contract, true)
142                         if err != nil {
143                                 fmt.Println("Marshal the struct of contract to json error:", err)
144                                 return err
145                         }
146                         fmt.Println(string(rawData))
147                 }
148         }
149
150         return nil
151 }