forked from google/skylark
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
skylark: create GitHub repository from google3@170697745
- Loading branch information
0 parents
commit 312d1a5
Showing
45 changed files
with
19,417 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
|
||
<!-- This file is the project homepage at github.com/google/skylark --> | ||
|
||
# Skylark in Go | ||
|
||
This is the home of the _Skylark in Go_ project. | ||
Skylark in Go is an interpreter for Skylark, implemented in Go. | ||
|
||
Skylark is a dialect of Python intended for use as a configuration language. | ||
Like Python, it is an untyped dynamic language with high-level data | ||
types, first-class functions with lexical scope, and garbage collection. | ||
Unlike CPython, independent Skylark threads execute in parallel, so | ||
Skylark workloads scale well on parallel machines. | ||
Skylark is a small and simple language with a familiar and highly | ||
readable syntax. You can use it as an expressive notation for | ||
structured data, defining functions to eliminate repetition, or you | ||
can use it to add scripting capabilities to an existing application. | ||
|
||
A Skylark interpreter is typically embedded within a larger | ||
application, and the application may define additional domain-specific | ||
functions and data types beyond those provided by the core language. | ||
For example, Skylark was originally developed for the | ||
[Bazel build tool](https://bazel.build). | ||
Bazel uses Skylark as the notation both for its BUILD files (like | ||
Makefiles, these declare the executables, libraries, and tests in a | ||
directory) and for [its macro | ||
language](https://docs.bazel.build/versions/master/skylark/language.html), | ||
through which Bazel is extended with custom logic to support new | ||
languages and compilers. | ||
|
||
|
||
## Documentation | ||
|
||
* Language definition: [doc/spec.md](doc/spec.md) | ||
|
||
* About the Go implementation: [doc/impl.md](doc/impl.md) | ||
|
||
* API documentation: [godoc.org/github.com/google/skylark](https://godoc.org/github.com/google/skylark) | ||
|
||
* Mailing list: [skylark-go](https://groups.google.com/forum/#!forum/skylark-go) | ||
|
||
* Issue tracker: [https://github.com/google/skylark/issues](https://github.com/google/skylark/issues) | ||
|
||
### Getting started | ||
|
||
Build the code: | ||
|
||
```shell | ||
$ go get github.com/google/skylark | ||
$ go build github.com/google/skylark/cmd/skylark | ||
``` | ||
|
||
Run the interpreter: | ||
|
||
``` | ||
$ cat coins.sky | ||
coins = { | ||
'dime': 10, | ||
'nickel': 5, | ||
'penny': 1, | ||
'quarter': 25, | ||
} | ||
print('By name:\t' + ', '.join(sorted(coins.keys()))) | ||
print('By value:\t' + ', '.join(sorted(coins.keys(), cmp=lambda x, y: coins[x] - coins[y]))) | ||
$ ./skylark -lambda coins.sky | ||
By name: dime, nickel, penny, quarter | ||
By value: penny, nickel, dime, quarter | ||
``` | ||
|
||
Interact with the read-eval-print loop (REPL): | ||
|
||
``` | ||
$ ./skylark | ||
>>> def fibonacci(n): | ||
... res = range(n) | ||
... for i in res[2:]: | ||
... res[i] = res[i-2] + res[i-1] | ||
... return res | ||
... | ||
>>> fibonacci(10) | ||
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34] | ||
>>> | ||
``` | ||
|
||
### Contributing | ||
|
||
We welcome submissions but please let us know what you're working on | ||
if you want to change or add to the Skylark repository. | ||
|
||
Before undertaking to write something new for the Skylark project, | ||
please file an issue or claim an existing issue. | ||
All significant changes to the language or to the interpreter's Go | ||
API must be discussed before they can be accepted. | ||
This gives all participants a chance to validate the design and to | ||
avoid duplication of effort. | ||
|
||
Despite some differences, the Go implementation of Skylark strives to | ||
match the behavior of the Java implementation used by Bazel. | ||
For that reason, proposals to change the language itself should | ||
generally be directed to the Bazel team, not to the maintainers of | ||
this project. | ||
Only once there is consensus that a language change is desirable may | ||
its Go implementation proceed. | ||
|
||
We use GitHub pull requests for contributions. | ||
|
||
Please complete Google's contributor license agreement (CLA) before | ||
sending your first change to the project. If you are the copyright | ||
holder, you will need to agree to the | ||
[individual contributor license agreement](https://cla.developers.google.com/about/google-individual), | ||
which can be completed online. | ||
If your organization is the copyright holder, the organization will | ||
need to agree to the [corporate contributor license agreement](https://cla.developers.google.com/about/google-corporate). | ||
If the copyright holder for your contribution has already completed | ||
the agreement in connection with another Google open source project, | ||
it does not need to be completed again. | ||
|
||
|
||
### Credits | ||
|
||
Skylark was designed and implemented in Java by Laurent Le Brun, | ||
Dmitry Lomov, Jon Brandvin, and Damien Martin-Guillerez, standing on | ||
the shoulders of the Python community. | ||
The Go implementation was written by Alan Donovan and Jay Conrod; | ||
its scanner was derived from one written by Russ Cox. | ||
|
||
### Legal | ||
|
||
Skylark in Go is Copyright (c) 2017 The Bazel Authors. | ||
All rights reserved. | ||
|
||
It is provided under an Apache license. | ||
|
||
The name "Skylark" is a code name of the Bazel project. | ||
We plan to rename the language before the end of 2017 to reflect its | ||
applicability to projects unrelated to Bazel. | ||
|
||
Skylark in Go is not an official Google product. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
// Copyright 2017 The Bazel Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// The skylark command interprets a Skylark file. | ||
// With no arguments, it starts a read-eval-print loop (REPL). | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"flag" | ||
"fmt" | ||
"log" | ||
"os" | ||
"runtime/pprof" | ||
"sort" | ||
"strings" | ||
|
||
"github.com/google/skylark" | ||
"github.com/google/skylark/resolve" | ||
"github.com/google/skylark/syntax" | ||
) | ||
|
||
// flags | ||
var ( | ||
cpuprofile = flag.String("cpuprofile", "", "gather CPU profile in this file") | ||
showenv = flag.Bool("showenv", false, "on success, print final global environment") | ||
) | ||
|
||
// non-standard dialect flags | ||
func init() { | ||
flag.BoolVar(&resolve.AllowFloat, "fp", resolve.AllowFloat, "allow floating-point numbers") | ||
flag.BoolVar(&resolve.AllowFreeze, "freeze", resolve.AllowFreeze, "add freeze built-in function") | ||
flag.BoolVar(&resolve.AllowSet, "set", resolve.AllowSet, "allow set data type") | ||
flag.BoolVar(&resolve.AllowLambda, "lambda", resolve.AllowLambda, "allow lambda expressions") | ||
flag.BoolVar(&resolve.AllowNestedDef, "nesteddef", resolve.AllowNestedDef, "allow nested def statements") | ||
} | ||
|
||
func main() { | ||
log.SetPrefix("skylark: ") | ||
log.SetFlags(0) | ||
flag.Parse() | ||
|
||
if *cpuprofile != "" { | ||
f, err := os.Create(*cpuprofile) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
if err := pprof.StartCPUProfile(f); err != nil { | ||
log.Fatal(err) | ||
} | ||
defer pprof.StopCPUProfile() | ||
} | ||
|
||
switch len(flag.Args()) { | ||
case 0: | ||
repl() | ||
case 1: | ||
execfile(flag.Args()[0]) | ||
default: | ||
log.Fatal("want at most one Skylark file name") | ||
} | ||
} | ||
|
||
func execfile(filename string) { | ||
thread := new(skylark.Thread) | ||
globals := make(skylark.StringDict) | ||
if err := skylark.ExecFile(thread, filename, nil, globals); err != nil { | ||
printError(err) | ||
os.Exit(1) | ||
} | ||
|
||
// Print the global environment. | ||
if *showenv { | ||
var names []string | ||
for name := range globals { | ||
if !strings.HasPrefix(name, "_") { | ||
names = append(names, name) | ||
} | ||
} | ||
sort.Strings(names) | ||
for _, name := range names { | ||
fmt.Fprintf(os.Stderr, "%s = %s\n", name, globals[name]) | ||
} | ||
} | ||
} | ||
|
||
func repl() { | ||
thread := new(skylark.Thread) | ||
globals := make(skylark.StringDict) | ||
|
||
sc := bufio.NewScanner(os.Stdin) | ||
outer: | ||
for { | ||
fmt.Fprintf(os.Stderr, ">>> ") | ||
if !sc.Scan() { | ||
break | ||
} | ||
line := sc.Text() | ||
if l := strings.TrimSpace(line); l == "" || l[0] == '#' { | ||
continue // blank or comment | ||
} | ||
|
||
// If the line contains a well-formed | ||
// expression, evaluate it. | ||
if _, err := syntax.ParseExpr("<stdin>", line); err == nil { | ||
if v, err := skylark.Eval(thread, "<stdin>", line, globals); err != nil { | ||
printError(err) | ||
} else if v != skylark.None { | ||
fmt.Println(v) | ||
} | ||
continue | ||
} | ||
|
||
// Otherwise assume it is the first of several | ||
// comprising a file, followed by a blank line. | ||
var buf bytes.Buffer | ||
fmt.Fprintln(&buf, line) | ||
for { | ||
fmt.Fprintf(os.Stderr, "... ") | ||
if !sc.Scan() { | ||
break outer | ||
} | ||
line := sc.Text() | ||
if l := strings.TrimSpace(line); l == "" { | ||
break // blank | ||
} | ||
fmt.Fprintln(&buf, line) | ||
} | ||
if err := skylark.ExecFile(thread, "<stdin>", &buf, globals); err != nil { | ||
printError(err) | ||
} | ||
} | ||
fmt.Println() | ||
} | ||
|
||
func printError(err error) { | ||
if evalErr, ok := err.(*skylark.EvalError); ok { | ||
fmt.Fprintln(os.Stderr, evalErr.Backtrace()) | ||
} else { | ||
fmt.Fprintln(os.Stderr, err) | ||
} | ||
} |
Oops, something went wrong.