Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 1 | // Copyright 2017 The Bazel Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
Alan Donovan | e3deafe | 2018-10-23 11:05:09 -0400 | [diff] [blame] | 5 | // The starlark command interprets a Starlark file. |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 6 | // With no arguments, it starts a read-eval-print loop (REPL). |
Alan Donovan | 551f300 | 2018-11-01 09:44:00 -0400 | [diff] [blame] | 7 | package main // import "go.starlark.net/cmd/starlark" |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 8 | |
| 9 | import ( |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 10 | "flag" |
| 11 | "fmt" |
| 12 | "log" |
| 13 | "os" |
| 14 | "runtime/pprof" |
| 15 | "sort" |
| 16 | "strings" |
| 17 | |
Alan Donovan | 6beab7e | 2018-10-31 17:53:09 -0400 | [diff] [blame] | 18 | "go.starlark.net/repl" |
| 19 | "go.starlark.net/resolve" |
Alan Donovan | 551f300 | 2018-11-01 09:44:00 -0400 | [diff] [blame] | 20 | "go.starlark.net/starlark" |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 21 | ) |
| 22 | |
| 23 | // flags |
| 24 | var ( |
| 25 | cpuprofile = flag.String("cpuprofile", "", "gather CPU profile in this file") |
| 26 | showenv = flag.Bool("showenv", false, "on success, print final global environment") |
Josh Bleecher Snyder | d1cdecf | 2018-12-07 14:21:37 -0800 | [diff] [blame] | 27 | execprog = flag.String("c", "", "execute program `prog`") |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 28 | ) |
| 29 | |
| 30 | // non-standard dialect flags |
| 31 | func init() { |
| 32 | flag.BoolVar(&resolve.AllowFloat, "fp", resolve.AllowFloat, "allow floating-point numbers") |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 33 | flag.BoolVar(&resolve.AllowSet, "set", resolve.AllowSet, "allow set data type") |
| 34 | flag.BoolVar(&resolve.AllowLambda, "lambda", resolve.AllowLambda, "allow lambda expressions") |
| 35 | flag.BoolVar(&resolve.AllowNestedDef, "nesteddef", resolve.AllowNestedDef, "allow nested def statements") |
Hittorp | 0a5e39a | 2018-08-09 15:02:30 +0300 | [diff] [blame] | 36 | flag.BoolVar(&resolve.AllowBitwise, "bitwise", resolve.AllowBitwise, "allow bitwise operations (&, |, ^, ~, <<, and >>)") |
Alessandro Arzilli | 678bafe | 2018-12-07 17:28:35 +0100 | [diff] [blame] | 37 | flag.BoolVar(&resolve.AllowRecursion, "recursion", resolve.AllowRecursion, "allow while statements and recursive functions") |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | func main() { |
Alan Donovan | e3deafe | 2018-10-23 11:05:09 -0400 | [diff] [blame] | 41 | log.SetPrefix("starlark: ") |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 42 | log.SetFlags(0) |
| 43 | flag.Parse() |
| 44 | |
| 45 | if *cpuprofile != "" { |
| 46 | f, err := os.Create(*cpuprofile) |
| 47 | if err != nil { |
| 48 | log.Fatal(err) |
| 49 | } |
| 50 | if err := pprof.StartCPUProfile(f); err != nil { |
| 51 | log.Fatal(err) |
| 52 | } |
| 53 | defer pprof.StopCPUProfile() |
| 54 | } |
| 55 | |
Alan Donovan | e3deafe | 2018-10-23 11:05:09 -0400 | [diff] [blame] | 56 | thread := &starlark.Thread{Load: repl.MakeLoad()} |
| 57 | globals := make(starlark.StringDict) |
alandonovan | 5596825 | 2017-12-22 15:50:31 -0500 | [diff] [blame] | 58 | |
Josh Bleecher Snyder | d1cdecf | 2018-12-07 14:21:37 -0800 | [diff] [blame] | 59 | switch { |
| 60 | case flag.NArg() == 1 || *execprog != "": |
| 61 | var ( |
| 62 | filename string |
| 63 | src interface{} |
| 64 | err error |
| 65 | ) |
| 66 | if *execprog != "" { |
| 67 | // Execute provided program. |
| 68 | filename = "cmdline" |
| 69 | src = *execprog |
| 70 | } else { |
| 71 | // Execute specified file. |
| 72 | filename = flag.Arg(0) |
| 73 | } |
alandonovan | 2c1f362 | 2018-12-17 13:10:16 -0500 | [diff] [blame^] | 74 | thread.Name = "exec " + filename |
Josh Bleecher Snyder | d1cdecf | 2018-12-07 14:21:37 -0800 | [diff] [blame] | 75 | globals, err = starlark.ExecFile(thread, filename, src, nil) |
alandonovan | a1b28d8 | 2018-03-13 10:59:24 -0400 | [diff] [blame] | 76 | if err != nil { |
alandonovan | 5596825 | 2017-12-22 15:50:31 -0500 | [diff] [blame] | 77 | repl.PrintError(err) |
| 78 | os.Exit(1) |
| 79 | } |
Josh Bleecher Snyder | d1cdecf | 2018-12-07 14:21:37 -0800 | [diff] [blame] | 80 | case flag.NArg() == 0: |
| 81 | fmt.Println("Welcome to Starlark (go.starlark.net)") |
alandonovan | 2c1f362 | 2018-12-17 13:10:16 -0500 | [diff] [blame^] | 82 | thread.Name = "REPL" |
Josh Bleecher Snyder | d1cdecf | 2018-12-07 14:21:37 -0800 | [diff] [blame] | 83 | repl.REPL(thread, globals) |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 84 | default: |
Alan Donovan | e3deafe | 2018-10-23 11:05:09 -0400 | [diff] [blame] | 85 | log.Fatal("want at most one Starlark file name") |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 86 | } |
Alan Donovan | 312d1a5 | 2017-10-02 10:10:28 -0400 | [diff] [blame] | 87 | |
| 88 | // Print the global environment. |
| 89 | if *showenv { |
| 90 | var names []string |
| 91 | for name := range globals { |
| 92 | if !strings.HasPrefix(name, "_") { |
| 93 | names = append(names, name) |
| 94 | } |
| 95 | } |
| 96 | sort.Strings(names) |
| 97 | for _, name := range names { |
| 98 | fmt.Fprintf(os.Stderr, "%s = %s\n", name, globals[name]) |
| 99 | } |
| 100 | } |
| 101 | } |