diff --git a/.ci/build.sh b/.ci/build.sh
deleted file mode 100755
index 43f1ab9c..00000000
--- a/.ci/build.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-set -e
-
-case "$1" in
- format)
- cargo +nightly fmt --all -- --check
- ;;
- build)
- cargo build --all
- cargo test --all --all-targets
- # https://github.com/rust-lang/cargo/issues/6669
- cargo test --all --doc
- ;;
- doc)
- cargo doc --all
- ;;
- *)
- echo "unknown mode" >&2
- exit 1
- ;;
-esac
diff --git a/.ci/release.sh b/.ci/release.sh
deleted file mode 100755
index 5f9ceed3..00000000
--- a/.ci/release.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-set -eu
-set -o pipefail
-(cd starlark && cargo package && cargo publish)
-(cd starlark-repl && cargo package && cargo publish)
diff --git a/.ci/setup.sh b/.ci/setup.sh
deleted file mode 100755
index 308296a2..00000000
--- a/.ci/setup.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-set -e
-
-case "$1" in
- format)
- echo "Installing rustfmt..."
- rustup component add --toolchain nightly rustfmt-preview
- which rustfmt || cargo install --force rustfmt-nightly
- cargo +nightly fmt -- --version
- ;;
-esac
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index a8addd66..00000000
--- a/.editorconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-[*]
-end_of_line = lf
-insert_final_newline = true
-charset = utf-8
-indent_style = space
-indent_size = 4
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index fa8d85ac..00000000
--- a/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Cargo.lock
-target
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index e40a29e7..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-language: rust
-rust:
- - stable
- - beta
- - nightly
-env: ACTION=build
-before_script: ./.ci/setup.sh "${ACTION}"
-script: ./.ci/build.sh "${ACTION}"
-matrix:
- include:
- - name: "Rust: format"
- env: ACTION=format
- rust: nightly
- - name: "Rust: doc"
- env: ACTION=doc
- rust: stable
- allow_failures:
- - rust: nightly
- env: ACTION=build
- fast_finish: true
-# Kill cache because otherwise travis randomly times out too often
-#cache: cargo
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index ae319c70..00000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# How to Contribute
-
-We'd love to accept your patches and contributions to this project. There are
-just a few small guidelines you need to follow.
-
-## Contributor License Agreement
-
-Contributions to this project must be accompanied by a Contributor License
-Agreement. You (or your employer) retain the copyright to your contribution,
-this simply gives us permission to use and redistribute your contributions as
-part of the project. Head over to to see
-your current agreements on file or to sign a new one.
-
-You generally only need to submit a CLA once, so if you've already submitted one
-(even if it was for a different project), you probably don't need to do it
-again.
-
-## Code reviews
-
-All submissions, including submissions by project members, require review. We
-use GitHub pull requests for this purpose. Consult
-[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
-information on using pull requests.
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644
index c95acada..00000000
--- a/Cargo.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-[workspace]
-members = ["starlark", "starlark-repl", "starlark-test"]
diff --git a/README.md b/README.md
index b8135f8a..cdfa550f 100644
--- a/README.md
+++ b/README.md
@@ -1,89 +1 @@
-# Starlark in Rust
-_An implementation in Rust of the Starlark language_
-
-[![Build
-Status](https://travis-ci.org/google/starlark-rust.svg?branch=master)](https://travis-ci.org/google/starlark-rust)
-
-**Disclaimer:** This is not an officially supported Google product. This project is supported
-on a best-effort basis and [welcome contributions](CONTRIBUTING.md).
-
-[Starlark](https://github.com/bazelbuild/starlark), formerly codenamed Skylark, is a non-Turing
-complete language based on Python that was made for the [Bazel build system](https://bazel.build) to
-define compilation plugin.
-
-Starlark has at least 3 implementations: a [Java one for Bazel](
-https://github.com/bazelbuild/bazel/tree/master/src/main/java/com/google/devtools/skylark),
-a [Go one](https://github.com/google/skylark) and this one.
-
-This interpreter was made using the [specification from the go version](
-https://github.com/google/skylark/blob/a0e5de7e63b47e716cca7226662a4c95d47bf873/doc/spec.md)
-and the Python 3 documentation when things were unclear.
-
-This interpreter does not support most of the go extensions (e.g. bitwise
-operator or floating point). It optionally includes a `set` type
-(by explicitly including `starlark::linked_hash_set::global()` environment),
-as an extension which is not specified in [the
-official Starlark specification](https://github.com/bazelbuild/starlark/blob/master/spec.md), but note that this
-is just an insertion-order-preserving set, and does not have optimisations for nesting as can be found in the
-starlark Java implementation's [depset](https://docs.bazel.build/versions/master/skylark/lib/depset.html) implementation.
-It uses signed 64-bit integers.
-
-## Usage
-
-### Crate
-
-You can depend on the `starlark` crate, it is documented using [docs.rs](https://docs.rs/crate/starlark).
-Examples are listed under [starlark/examples](starlark/examples). You can run the examples
-using `cargo run --example`, such as
-
-```sh
-echo "str([x * 2 for x in range(10)])" | cargo run --example starlark-simple-cli
-```
-
-### Command line REPL
-
-A command line interpreter is also provided by this project under [starlark-repl](starlark-repl),
-it can interpret files passed at the command line and also start a REPL (Read-Eval-Print Loop).
-The usage of this program is:
-
-```
-Starlark in Rust interpreter
-
-USAGE:
- starlark-rust [FLAGS] [OPTIONS] [file]...
-
-FLAGS:
- -a, --ast Parse and print AST instead of evaluating.
- -b, --build-file Parse the build file format instead of full Starlark. See https://docs.rs/starlark/0.3.0-
- pre/starlark/eval/index.html#build_file
- -h, --help Prints help information
- -r, --repl Run a REPL after files have been parsed.
- -V, --version Prints version information
-
-OPTIONS:
- -c Starlark command to run after files have been parsed.
-
-ARGS:
- ... Files to interpret
-```
-
-## Development
-
-### Build
-
-This project build with [Cargo](https://doc.rust-lang.org/stable/cargo/). Simply
-run `cargo test` to test it, `cargo build --release` to build a release version
-and `cargo run` to run the command-line interpreter.
-
-### Possible improvements and optimizations
-
-* Errors:
- - When an identifier is not found, we can suggest close identifier / keyword.
- - Fix suggestions maybe?
- - Better error spans.
- - Recoverable errors (don't stop at the first error, continue parsing).
-* Evaluation:
- - Static rewrite of the AST before evaluation (e.g. for constant values)
-* Awesome feature:
- - Implement a debugging protocol server side (compatible with the Java one,
- see (bazelbuild/vscode-bazel#6)).
+# This repository has been replaced by https://github.com/facebookexperimental/starlark-rust and is no longer maintained.
\ No newline at end of file
diff --git a/rustfmt.toml b/rustfmt.toml
deleted file mode 100644
index caa5583c..00000000
--- a/rustfmt.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-unstable_features = true
-edition = "2018"
diff --git a/starlark-repl/Cargo.toml b/starlark-repl/Cargo.toml
deleted file mode 100644
index 0f162995..00000000
--- a/starlark-repl/Cargo.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-[package]
-name = "starlark-repl"
-edition = "2018"
-version = "0.3.2-pre"
-authors = [
- "Damien Martin-Guillerez ",
- "Stepan Koltsov ",
-]
-
-description = "A REPL for the implementation in Rust of the Starlark language."
-documentation = "https://docs.rs/crate/starlark-repl"
-homepage = "https://github.com/google/starlark-rust"
-repository = "https://github.com/google/starlark-rust"
-readme = "README.md"
-keywords = ["starlark", "skylark", "bazel", "language", "interpreter"]
-categories = ["development-tools"]
-license = "Apache-2.0"
-
-[badges]
-travis-ci = { repository = "google/starlark-rust", branch = "master" }
-maintenance = { status = "passively-maintained" }
-
-[dependencies]
-codemap = "0.1.1"
-codemap-diagnostic = "0.1.1"
-linefeed = "0.5.3"
-starlark = { path = "../starlark" }
-structopt = "0.3.0"
-
-[dev-dependencies]
-assert_cmd = "0.10.2"
-predicates = "1"
-# 3.0.5 bumps rand to 0.6 which causes problems with other deps.
-tempfile = ">=3, <3.0.5"
-
-[lib]
-bench = false
-
-[[bin]]
-name = "starlark-rust"
-bench = false
-path = "bin/starlark-rust.rs"
diff --git a/starlark-repl/LICENSE b/starlark-repl/LICENSE
deleted file mode 100644
index d6456956..00000000
--- a/starlark-repl/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/starlark-repl/README.md b/starlark-repl/README.md
deleted file mode 100644
index 932f8939..00000000
--- a/starlark-repl/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Starlark in Rust - REPL
-_A REPL for the Starlark language in Rust_
-
-**Disclaimer:** This is not an officially supported Google product. This project is supported
-on a best-effort basis and [welcome contributions](CONTRIBUTING.md).
-
-[Starlark](https://github.com/bazelbuild/starlark), formerly codenamed Skylark, is a non-Turing
-complete language based on Python that was made for the [Bazel build system](https://bazel.build) to
-define compilation plugin.
-
-This REPL uses [starlark](https://crates.io/crates/starlark) crates.
-
-## Usage
-
-A command line interpreter is provided by this project, it can interpret files
-passed at the command line and also start a REPL (Read-Eval-Print Loop).
-The usage of this program is:
-
-```
-Starlark in Rust interpreter
-
-USAGE:
- starlark-rust [FLAGS] [OPTIONS] [file]...
-
-FLAGS:
- -a, --ast Parse and print AST instead of evaluating.
- -b, --build-file Parse the build file format instead of full Starlark. See https://docs.rs/starlark/0.3.0-
- pre/starlark/eval/index.html#build_file
- -h, --help Prints help information
- -r, --repl Run a REPL after files have been parsed.
- -V, --version Prints version information
-
-OPTIONS:
- -c Starlark command to run after files have been parsed.
-
-ARGS:
- ... Files to interpret
-```
diff --git a/starlark-repl/bin/starlark-rust.rs b/starlark-repl/bin/starlark-rust.rs
deleted file mode 100644
index 7346bfad..00000000
--- a/starlark-repl/bin/starlark-rust.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! A command line interpreter for Starlark, provide a REPL.
-
-extern crate structopt;
-
-use starlark::eval::interactive::{eval, eval_file, EvalError};
-use starlark::stdlib::global_environment_for_repl_and_tests;
-use starlark::syntax::dialect::Dialect;
-use starlark::values::Value;
-use starlark_repl::{print_function, repl};
-use std::process::exit;
-use structopt::clap::AppSettings;
-use structopt::StructOpt;
-
-const EXIT_CODE_FAILURE: i32 = 2;
-
-#[derive(Debug, StructOpt)]
-#[structopt(
- name = "starlark-repl",
- about = "Starlark in Rust interpreter",
- global_settings(&[AppSettings::ColoredHelp]),
-)]
-pub struct Opt {
- #[structopt(
- short = "b",
- long,
- help = concat!(
- "Parse the build file format instead of full Starlark. See https://docs.rs/starlark/",
- env!("CARGO_PKG_VERSION"),
- "/starlark/eval/index.html#build_file",
- )
- )]
- build_file: bool,
-
- #[structopt(
- short = "c",
- help = "Starlark command to run after files have been parsed."
- )]
- command: Option,
-
- #[structopt(
- short = "r",
- long,
- conflicts_with = "command",
- help = "Run a REPL after files have been parsed."
- )]
- repl: bool,
-
- #[structopt(name = "FILE", help = "Files to interpret")]
- files: Vec,
-}
-
-fn main() {
- let opt = Opt::from_args();
-
- let command = opt.command;
-
- let (mut global, mut type_values) = global_environment_for_repl_and_tests();
-
- print_function(&mut global, &mut type_values);
- global.freeze();
-
- let dialect = if opt.build_file {
- Dialect::Build
- } else {
- Dialect::Bzl
- };
- let free_args_empty = opt.files.is_empty();
- for i in opt.files.into_iter() {
- maybe_print_or_exit(eval_file(
- &i,
- dialect,
- &mut global.child(&i),
- &type_values,
- global.clone(),
- ));
- }
- if opt.repl || (free_args_empty && command.is_none()) {
- println!("Welcome to Starlark REPL, press Ctrl+D to exit.");
- repl(&mut global, &type_values, dialect);
- }
- if let Some(command) = command {
- maybe_print_or_exit(eval(
- "[command flag]",
- &command,
- dialect,
- &mut global.child("[command flag]"),
- &type_values,
- global.clone(),
- ));
- }
-}
-
-fn maybe_print_or_exit(result: Result, EvalError>) {
- match result {
- Ok(Some(value)) => println!("{}", value.to_repr()),
- Err(err) => {
- err.write_to_stderr();
- exit(EXIT_CODE_FAILURE);
- }
- Ok(None) => {}
- }
-}
diff --git a/starlark-repl/src/lib.rs b/starlark-repl/src/lib.rs
deleted file mode 100644
index bb66a6ed..00000000
--- a/starlark-repl/src/lib.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! a Read-Eval-Print Loop (REPL) for Starlark.
-//!
-//! Starlark, formerly codenamed Skylark, is a non-Turing complete language based on Python that
-//! was made for the [Bazel build system](https://bazel.build) to define compilation plugin.
-//!
-//! See the [starlark](https://docs.rs/crate/starlark) crate documentation for more information
-//! about Starlark.
-//!
-//! # Usage
-//!
-//! One can call the [repl] method to run the repl inside a program or simply run the [starlark-repl]
-//! binary:
-//! ```sh
-//! $ starlark-repl --help
-//! [Starlark in Rust interpretor]
-//!
-//! Usage: starlark-repl [options] [file1..filen]
-//!
-//!
-//! Options:
-//! -b, --build_file Parse the build file format instead of full Starlark.
-//! -h, --help Show the usage of this program.
-//! -r, --repl Run a REPL after files have been parsed.
-//! ```
-use codemap;
-
-#[macro_use]
-extern crate starlark;
-
-use codemap_diagnostic::{ColorConfig, Emitter};
-use linefeed::{Interface, ReadResult};
-use starlark::environment::{Environment, TypeValues};
-use starlark::eval::eval_lexer;
-use starlark::eval::simple::SimpleFileLoader;
-use starlark::syntax::dialect::Dialect;
-use starlark::syntax::lexer::{BufferedLexer, LexerIntoIter, LexerItem};
-use starlark::values::none::NoneType;
-use starlark::values::Value;
-use std::env;
-use std::path::PathBuf;
-use std::sync::{Arc, Mutex};
-
-fn print_eval, T2: LexerIntoIter>(
- map: Arc>,
- filename: &str,
- content: &str,
- lexer: T2,
- dialect: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader_env: Environment,
-) {
- match eval_lexer(
- &map,
- filename,
- content,
- dialect,
- lexer,
- env,
- type_values,
- &SimpleFileLoader::new(&map.clone(), file_loader_env),
- ) {
- Ok(v) => {
- if v.get_type() != "NoneType" {
- println!("{}", v.to_repr())
- }
- }
- Err(p) => Emitter::stderr(ColorConfig::Always, Some(&map.lock().unwrap())).emit(&[p]),
- }
-}
-
-starlark_module! {print_function =>
- /// print: print an object string representation to stderr.
- ///
- /// Examples:
- /// ```python
- /// print("some message") # Will print "some message" to stderr
- /// ```
- print(*args) {
- let mut r = String::new();
- let mut first = true;
- for arg in args {
- if !first {
- r.push_str(" ");
- }
- first = false;
- r.push_str(&arg.to_str());
- }
- eprintln!("{}", r);
- Ok(Value::new(NoneType::None))
- }
-}
-
-/// A REPL (Read-Eval-Print Loop) for Starlark.
-///
-/// This method run a REPL until the user hit Ctrl+D. It can be used for interactive use where the
-/// parent enviroment offer side-effect methods.
-///
-/// # Parameters:
-///
-/// * global_environment: the parent enviroment for the loop.
-/// * dialect: Starlark language dialect.
-/// * ast: print AST instead of evaluating.
-pub fn repl(global_environment: &mut Environment, type_values: &TypeValues, dialect: Dialect) {
- let map = Arc::new(Mutex::new(codemap::CodeMap::new()));
- let reader = Interface::new("Starlark").unwrap();
- let mut env = global_environment.child("repl");
- let mut n = 0;
-
- // Linefeed default history size is unlimited,
- // but since we write history to disk, we better limit it.
- reader.set_history_size(100_000);
-
- let histfile = env::var_os("STARLARK_RUST_HISTFILE").map(PathBuf::from);
-
- if let Some(ref histfile) = histfile {
- if histfile.exists() {
- if let Err(e) = reader.load_history(histfile) {
- eprintln!("Failed to load history from {}: {}", histfile.display(), e);
- }
- }
- }
-
- reader.set_prompt(">>> ").unwrap();
-
- while let Ok(ReadResult::Input(input)) = reader.read_line() {
- if !input.is_empty() {
- reader.set_prompt("... ").unwrap();
- n += 1;
- let input = input + "\n";
- let mut lexer = BufferedLexer::new(&input);
- let mut content = input;
- while lexer.need_more() {
- if let Ok(ReadResult::Input(input)) = reader.read_line() {
- let input = input + "\n";
- content += &input;
- lexer.input(&input);
- } else {
- break;
- }
- }
- let mut hist = content.clone();
- hist.pop();
- reader.add_history(hist);
- print_eval(
- map.clone(),
- &format!("<{}>", n),
- &content,
- lexer,
- dialect,
- &mut env,
- type_values,
- global_environment.clone(),
- )
- }
- reader.set_prompt(">>> ").unwrap();
- }
-
- println!();
-
- if let Some(ref histfile) = histfile {
- if let Err(e) = reader.save_history(histfile) {
- eprintln!("Failed to save history to {}: {}", histfile.display(), e);
- }
- }
-
- println!("Goodbye!");
-}
diff --git a/starlark-repl/tests/integration.rs b/starlark-repl/tests/integration.rs
deleted file mode 100644
index 4d614196..00000000
--- a/starlark-repl/tests/integration.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-use assert_cmd::prelude::*;
-use predicates::str::contains;
-use std::io::Write;
-use std::process::Command;
-
-// Copied from starlark::environment - not currently public because of uncertainty around how to
-// expose it.
-const NOT_FOUND_ERROR_CODE: &str = "CM01";
-
-#[test]
-fn outputs_last_command_value() {
- Command::main_binary()
- .unwrap()
- .arg("-c")
- .arg("5\n1 + 1")
- .assert()
- .success()
- .stdout("2\n");
-}
-
-#[test]
-fn outputs_last_file_values() {
- let f1 = make_file("0");
- let f2 = make_file("");
- let f3 = make_file("None");
- let f4 = make_file("2\n3\n\"Hello\"");
-
- Command::main_binary()
- .unwrap()
- .arg(f1.path())
- .arg(f2.path())
- .arg(f3.path())
- .arg(f4.path())
- .assert()
- .success()
- .stdout("0\n\"Hello\"\n");
-}
-
-#[test]
-fn error_in_command() {
- Command::main_binary()
- .unwrap()
- .arg("-c")
- .arg("x")
- .assert()
- .code(2)
- .stderr(contains(NOT_FOUND_ERROR_CODE));
-}
-
-#[test]
-fn error_in_file() {
- let f = make_file("x");
-
- Command::main_binary()
- .unwrap()
- .arg(f.path())
- .assert()
- .code(2)
- .stderr(contains(NOT_FOUND_ERROR_CODE));
-}
-
-#[test]
-fn files_environments_are_isolated() {
- let f1 = make_file("x = 1");
- let f2 = make_file("x");
-
- Command::main_binary()
- .unwrap()
- .arg(f1.path())
- .arg(f2.path())
- .assert()
- .code(2)
- .stderr(contains(NOT_FOUND_ERROR_CODE));
-}
-
-fn make_file(content: &str) -> tempfile::NamedTempFile {
- let mut file = tempfile::NamedTempFile::new().unwrap();
- writeln!(file, "{}", content).unwrap();
- file
-}
diff --git a/starlark-test/Cargo.toml b/starlark-test/Cargo.toml
deleted file mode 100644
index 82bfdeb3..00000000
--- a/starlark-test/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-name = "starlark-test"
-edition = "2018"
-version = "0.0.0"
-authors = [
- "Damien Martin-Guillerez ",
- "Stepan Koltsov ",
-]
-build = "build.rs"
-publish = false
-
-description = "Tests for starlark crate."
-documentation = "https://docs.rs/crate/starlark"
-homepage = "https://github.com/google/starlark-rust"
-repository = "https://github.com/google/starlark-rust"
-readme = "README.md"
-keywords = ["starlark", "skylark", "bazel", "language", "interpreter"]
-categories = ["development-tools"]
-license = "Apache-2.0"
-
-[dependencies]
-starlark = { path = "../starlark" }
-codemap = "0.1.1"
-codemap-diagnostic = "0.1.1"
-linked-hash-map = "0.5.1"
-
-[lib]
-bench = false
-test = false
-doctest = false
-doc = false
diff --git a/starlark-test/benches/rust-benches/bubble_sort.sky b/starlark-test/benches/rust-benches/bubble_sort.sky
deleted file mode 100644
index f338be44..00000000
--- a/starlark-test/benches/rust-benches/bubble_sort.sky
+++ /dev/null
@@ -1,11 +0,0 @@
-def bubble_sort(array):
- array = list(array)
- for i in range(len(array)):
- # TODO: https://github.com/google/starlark-rust/issues/98
- for j in range((len(array) - i) - 1):
- if array[j] > array[j + 1]:
- array[j], array[j + 1] = array[j + 1], array[j]
- return array
-
-def bench():
- assert_eq([2, 3, 4, 5, 6, 7, 9], bubble_sort([9, 3, 5, 4, 7, 2, 6]))
diff --git a/starlark-test/benches/rust-benches/empty.sky b/starlark-test/benches/rust-benches/empty.sky
deleted file mode 100644
index 20e2b194..00000000
--- a/starlark-test/benches/rust-benches/empty.sky
+++ /dev/null
@@ -1,4 +0,0 @@
-# Benching evaluation of empty function
-
-def bench():
- pass
diff --git a/starlark-test/benches/rust-benches/integer_add.sky b/starlark-test/benches/rust-benches/integer_add.sky
deleted file mode 100644
index a5fc6e37..00000000
--- a/starlark-test/benches/rust-benches/integer_add.sky
+++ /dev/null
@@ -1,23 +0,0 @@
-def bench():
- return (
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16) +
- 0
- )
diff --git a/starlark-test/benches/rust-benches/list.sky b/starlark-test/benches/rust-benches/list.sky
deleted file mode 100644
index 910b0637..00000000
--- a/starlark-test/benches/rust-benches/list.sky
+++ /dev/null
@@ -1,2 +0,0 @@
-def bench():
- return list([1, 2, 3])
diff --git a/starlark-test/benches/rust-benches/named_args.sky b/starlark-test/benches/rust-benches/named_args.sky
deleted file mode 100644
index 616b9ce6..00000000
--- a/starlark-test/benches/rust-benches/named_args.sky
+++ /dev/null
@@ -1,16 +0,0 @@
-def takes_named_args(**kwargs):
- return len(kwargs)
-
-def bench():
- return takes_named_args(
- a0=0,
- a1=1,
- a2=2,
- a3=3,
- a4=4,
- a5=5,
- a6=6,
- a7=7,
- a8=8,
- a9=9,
- )
diff --git a/starlark-test/benches/rust_benches.rs b/starlark-test/benches/rust_benches.rs
deleted file mode 100644
index 49291f9d..00000000
--- a/starlark-test/benches/rust_benches.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-// `#[feature(test)]` only works in nightly
-#![cfg(rustc_nightly)]
-#![feature(test)]
-
-extern crate test;
-use starlark_test::do_bench;
-use test::Bencher;
-
-include!(concat!(env!("OUT_DIR"), "/benches/rust-benches.rs"));
diff --git a/starlark-test/build.rs b/starlark-test/build.rs
deleted file mode 100644
index 475dc618..00000000
--- a/starlark-test/build.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-use std::fs;
-use std::fs::File;
-use std::io::prelude::*;
-use std::path::Path;
-use std::{env, process};
-
-fn main() {
- let nightly = query_rust_version_is_nightly();
-
- test_cases("tests/java-testcases", &TestOrBench::Test);
- test_cases("tests/rust-testcases", &TestOrBench::Test);
- test_cases("tests/go-testcases", &TestOrBench::Test);
- if nightly {
- println!("cargo:rustc-cfg=rustc_nightly");
- // Benches only work in nightly
- test_cases("benches/rust-benches", &TestOrBench::Bench);
- }
-}
-
-fn version_is_nightly(version: &str) -> bool {
- version.contains("nightly")
-}
-
-fn query_rust_version_is_nightly() -> bool {
- let rustc = env::var("RUSTC").expect("RUSTC unset");
-
- let mut child = process::Command::new(rustc)
- .args(&["--version"])
- .stdin(process::Stdio::null())
- .stdout(process::Stdio::piped())
- .spawn()
- .expect("spawn rustc");
-
- let mut rustc_version = String::new();
-
- child
- .stdout
- .as_mut()
- .expect("stdout")
- .read_to_string(&mut rustc_version)
- .expect("read_to_string");
- assert!(child.wait().expect("wait").success());
-
- version_is_nightly(&rustc_version)
-}
-
-enum TestOrBench {
- Test,
- Bench,
-}
-
-/// Load a file and convert it to a vector of string (separated by ---) to be evaluated separately.
-fn read_input(path: &Path) -> Vec<(usize, String)> {
- let mut content = String::new();
- let mut file = File::open(path).unwrap();
- file.read_to_string(&mut content).unwrap();
- let mut v: Vec<(usize, String)> = content
- .split("\n---\n")
- .map(|x| (0, x.to_owned()))
- .collect();
- let mut idx = 0;
- for mut el in &mut v {
- el.0 = idx;
- idx += el.1.chars().filter(|x| *x == '\n').count() + 2 // 2 = separator new lines
- }
- v
-}
-
-fn format_test_content(path: &Path) -> String {
- let test_name = path.file_stem().unwrap().to_str().unwrap();
- let mut r = String::new();
- for (offset, content) in read_input(path).into_iter() {
- let content = std::iter::repeat("\n").take(offset).collect::() + &content;
- r.push_str(&format!(
- r#"
-#[test]
-fn test_{}_{}() {{
- do_conformance_test("{}", {:?})
-}}
-"#,
- test_name,
- offset + 1,
- path.to_str().unwrap(),
- content,
- ));
- }
- r
-}
-
-fn format_test_or_bench_content(path: &Path, test_or_bench: &TestOrBench) -> String {
- let test_name = path.file_stem().unwrap().to_str().unwrap();
- match test_or_bench {
- TestOrBench::Test => format_test_content(path),
- TestOrBench::Bench => format!(
- r#"
-#[bench]
-fn bench_{}(bencher: &mut Bencher) {{
- do_bench(bencher, "{}")
-}}
-"#,
- test_name,
- path.to_str().unwrap(),
- ),
- }
-}
-
-fn test_cases(path: &str, test_or_bench: &TestOrBench) {
- println!("cargo:rerun-if-changed={}", path);
- let outfile_path = Path::new(&env::var("OUT_DIR").unwrap()).join(format!("{}.rs", path));
- fs::create_dir_all(outfile_path.parent().unwrap()).unwrap();
- let mut outfile = File::create(outfile_path).unwrap();
- let cargo_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
- let base = Path::new(&cargo_dir);
- let d = base.join(path);
- let paths = fs::read_dir(d).unwrap();
- for p in paths {
- let path_entry = p.unwrap().path();
- if path_entry.extension().unwrap().to_str().unwrap() != "md" {
- // Exclude markdown files
- let content =
- format_test_or_bench_content(path_entry.strip_prefix(base).unwrap(), test_or_bench);
- outfile.write(content.as_bytes()).unwrap();
- }
- }
-}
diff --git a/starlark-test/src/lib.rs b/starlark-test/src/lib.rs
deleted file mode 100644
index 4ee8dad9..00000000
--- a/starlark-test/src/lib.rs
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Utility to test the tests and benches
-
-#![cfg_attr(rustc_nightly, feature(test))]
-
-#[cfg(rustc_nightly)]
-extern crate test;
-
-use codemap::CodeMap;
-use codemap_diagnostic::ColorConfig;
-use codemap_diagnostic::Diagnostic;
-use codemap_diagnostic::Emitter;
-use codemap_diagnostic::Level;
-use linked_hash_map::LinkedHashMap;
-use starlark::environment::Environment;
-use starlark::environment::TypeValues;
-use starlark::eval::call_stack::CallStack;
-use starlark::eval::eval;
-use starlark::eval::noload;
-use starlark::eval::EvalException;
-use starlark::eval::FileLoader;
-use starlark::stdlib::global_environment_for_repl_and_tests;
-use starlark::syntax::dialect::Dialect;
-use starlark::values::error::ValueError;
-use std::collections::HashMap;
-use std::fs::File;
-use std::io::prelude::*;
-use std::io::{self, Write};
-use std::sync::{Arc, Mutex};
-#[cfg(rustc_nightly)]
-use test::Bencher;
-
-fn assert_diagnostic(
- d: Diagnostic,
- expected: &str,
- path: &str,
- offset: usize,
- map: &Arc>,
-) -> bool {
- let expected = expected.to_lowercase();
- let msg = if d.spans.is_empty() || d.spans[0].label.is_none() {
- d.message.clone()
- } else {
- let label = d.spans[0].label.clone();
- let error_code = d.code.clone().unwrap_or_else(|| "".to_owned());
- format!("[{}] {} ({})", error_code, d.message, label.unwrap())
- };
- if !msg.to_lowercase().contains(&expected) {
- io::stderr()
- .write_all(
- &format!(
- "Expected error '{}' at {}:{}, got {}\n",
- expected, path, offset, msg,
- )
- .into_bytes(),
- )
- .unwrap();
- Emitter::stderr(ColorConfig::Always, Some(&map.lock().unwrap())).emit(&[d]);
- false
- } else {
- true
- }
-}
-
-#[derive(Default)]
-struct ParsedTest {
- error: Option<(usize, String)>,
- files: HashMap,
-}
-
-fn parse_test(content: &str) -> ParsedTest {
- let mut r = ParsedTest::default();
- let mut current_file = "main.sky".to_owned();
- for (i, line) in content.lines().enumerate() {
- let file_prefix = "# file: ";
- if line.starts_with(file_prefix) {
- current_file = line[file_prefix.len()..].to_owned();
- } else {
- r.files
- .entry(current_file.clone())
- .or_default()
- .push_str(&format!("{}\n", line));
-
- if let Some(x) = line.find("###") {
- assert!(r.error.is_none(), "test may contain at most one error");
- r.error = Some((i + 1, line.get(x + 3..).unwrap().trim().to_owned()))
- }
- }
- }
- r
-}
-
-#[derive(Clone)]
-struct HashMapFileLoader {
- parent: Environment,
- files: HashMap,
- map: Arc>,
-}
-
-impl FileLoader for HashMapFileLoader {
- fn load(&self, path: &str, type_values: &TypeValues) -> Result {
- let mut env = self.parent.child(path);
- let content = match self.files.get(path) {
- Some(content) => content,
- None => {
- return Err(EvalException::DiagnosedError(Diagnostic {
- level: Level::Bug,
- message: format!("file not found"),
- code: None,
- spans: Vec::new(),
- }))
- }
- };
- eval(
- &self.map,
- path,
- content,
- Dialect::Bzl,
- &mut env,
- type_values,
- self,
- )?;
- Ok(env)
- }
-}
-
-pub fn do_conformance_test(path: &str, content: &str) {
- let map = Arc::new(Mutex::new(CodeMap::new()));
- let (global, type_values) = global_environment_for_repl_and_tests();
- global.freeze();
- let mut prelude = global.child("PRELUDE");
- noload::eval(
- &map,
- "PRELUDE",
- r#"
-def assert_eq(x, y):
- if x != y:
- fail("%r != %r" % (x, y))
-
-def assert_(cond, msg="assertion failed"):
- if not cond:
- fail(msg)
-"#,
- starlark::syntax::dialect::Dialect::Bzl,
- &mut prelude,
- &type_values,
- )
- .unwrap();
- prelude.freeze();
-
- let test = parse_test(content);
-
- let build = test.files.get("main.sky").expect(&format!(
- "test must contain main.sky file: {:?}",
- test.files.keys().collect::>()
- ));
-
- match eval(
- &map,
- path,
- build,
- starlark::syntax::dialect::Dialect::Bzl,
- &mut prelude.child(path),
- &type_values,
- &HashMapFileLoader {
- parent: prelude.clone(),
- files: test.files.clone(),
- map: map.clone(),
- },
- ) {
- Err(p) => match &test.error {
- Some((offset, err)) => {
- if !assert_diagnostic(p, err, "test", *offset, &map) {
- panic!();
- }
- }
- None => {
- Emitter::stderr(ColorConfig::Always, Some(&map.lock().unwrap())).emit(&[p]);
- panic!();
- }
- },
- _ => {
- if let Some((offset, err)) = test.error {
- io::stderr()
- .write_all(
- &format!(
- "Expected error '{}' at {}:{}, got success",
- err, path, offset
- )
- .into_bytes(),
- )
- .unwrap();
- panic!();
- }
- }
- }
-}
-
-#[cfg(not(rustc_nightly))]
-pub struct Bencher {}
-
-#[cfg(not(rustc_nightly))]
-impl Bencher {
- pub fn iter(&mut self, mut _inner: F)
- where
- F: FnMut() -> T,
- {
- // Bencher included here to typecheck `do_bench` function
- // in stable and also to mute unused imports warnings
- panic!("Bencher available only in nightly");
- }
-}
-
-pub fn do_bench(bencher: &mut Bencher, path: &str) {
- let mut content = String::new();
- let mut file = File::open(path).unwrap();
- file.read_to_string(&mut content).unwrap();
- drop(file);
-
- let map = Arc::new(Mutex::new(CodeMap::new()));
- let (global, type_values) = global_environment_for_repl_and_tests();
- global.freeze();
- let mut prelude = global.child("PRELUDE");
- noload::eval(
- &map,
- "PRELUDE",
- r#"
-def assert_eq(x, y):
- if x != y:
- fail("%r != %r" % (x, y))
-
-def assert_(cond, msg="assertion failed"):
- if not cond:
- fail(msg)
-"#,
- starlark::syntax::dialect::Dialect::Bzl,
- &mut prelude,
- &type_values,
- )
- .unwrap();
- prelude.freeze();
-
- let mut env = prelude.child("run");
- match noload::eval(&map, path, &content, Dialect::Bzl, &mut env, &type_values) {
- Ok(_) => (),
- Err(p) => {
- Emitter::stderr(ColorConfig::Always, Some(&map.lock().unwrap())).emit(&[p]);
- panic!();
- }
- }
-
- env.freeze();
-
- let bench_func = env.get("bench").expect("bench function is not found");
-
- bencher.iter(|| {
- match bench_func.call(
- &mut CallStack::default(),
- &type_values,
- Vec::new(),
- LinkedHashMap::new(),
- None,
- None,
- ) {
- Ok(r) => r,
- Err(ValueError::DiagnosedError(e)) => {
- Emitter::stderr(ColorConfig::Always, Some(&map.lock().unwrap())).emit(&[e]);
- panic!();
- }
- Err(e) => {
- panic!("{:?}", e);
- }
- }
- });
-}
diff --git a/starlark-test/tests/README.md b/starlark-test/tests/README.md
deleted file mode 100644
index 801b6dff..00000000
--- a/starlark-test/tests/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-## Rust Starlark implementation test
-
-* `go-testcases` are taken from
- [Go implementation](https://github.com/google/starlark-go/tree/master/starlark/testdata)
-* `java-testcases` are taken from
- [Java implementation](https://github.com/bazelbuild/bazel/tree/master/src/test/starlark/testdata)
-* `rust-testcases` are written for this project
-
-Certain Java and Go testcases were modified or removed to match this implementation.
diff --git a/starlark-test/tests/go-testcases/assign.sky b/starlark-test/tests/go-testcases/assign.sky
deleted file mode 100644
index e76e8325..00000000
--- a/starlark-test/tests/go-testcases/assign.sky
+++ /dev/null
@@ -1,205 +0,0 @@
-# Tests of Skylark assignment.
-
-# This is a "chunked" file: each "---" effectively starts a new file.
-
-a, b, c = 1, 2, 3
-assert_eq(a, 1)
-assert_eq(b, 2)
-assert_eq(c, 3)
-
----
-(x,) = 1 ### The type 'int' is not iterable
----
-a, b, c = 1, 2 ### Unpacked
----
-a, b = 1, 2, 3 ### Unpacked
----
-a, b = (1,) ### Unpacked
----
-(a,) = [1, 2, 3] ### Unpacked
----
-[a, b, c] = [1, 2, 3]
-assert_eq(a, 1)
-assert_eq(b, 2)
-assert_eq(c, 3)
----
-[a, b, c,] = 1 ### The type 'int' is not iterable
----
-[a, b, c] = 1, 2 ### Unpacked
----
-[a, b] = 1, 2, 3 ### Unpacked
----
-[a, b] = (1,) ### Unpacked
----
-[a, b, c] = (1, 2, 3)
-assert_eq(a, 1)
-assert_eq(b, 2)
-assert_eq(c, 3)
-
-(d, e, f) = [1, 2, 3]
-assert_eq(d, 1)
-assert_eq(e, 2)
-assert_eq(f, 3)
-
-[g, h, (i, j)] = (1, 2, [3, 4])
-assert_eq(g, 1)
-assert_eq(h, 2)
-assert_eq(i, 3)
-assert_eq(j, 4)
-
-(k, l, [m, n]) = [1, 2, (3, 4)]
-assert_eq(k, 1)
-assert_eq(l, 2)
-assert_eq(m, 3)
-assert_eq(n, 4)
-
----
-def assignment():
- a = [1, 2, 3]
- a[1] = 5
- assert_eq(a, [1, 5, 3])
- a[-2] = 2
- assert_eq(a, [1, 2, 3])
- assert_eq("%d %d" % (5, 7), "5 7")
- x={}
- x[1] = 2
- x[1] += 3
- assert_eq(x[1], 5)
-
-assignment()
----
-x = {}
-x[(1, "abc", {})] = 1 ### not hashable
----
-# augmented assignment
-
-def f():
- x = 1
- x += 1
- assert_eq(x, 2)
- x *= 3
- assert_eq(x, 6)
-f()
-
----
-# effects of evaluating LHS occur only once
-
-count = [0] # count[0] is the number of calls to f
-
-def f():
- count[0] += 1
- return count[0]
-
-x = [1, 2, 3]
-x[f()] += 1
-
-assert_eq(x, [1, 3, 3]) # sole call to f returned 1
-assert_eq(count[0], 1) # f was called only once
-
----
-# Order of evaluation.
-
-calls = []
-
-def f(name, result):
- calls.append(name)
- return result
-
-# The right side is evaluated before the left in an ordinary assignment.
-calls.clear()
-f("array", [0])[f("index", 0)] = f("rhs", 0)
-assert_eq(calls, ["rhs", "array", "index"])
-
-calls.clear()
-f("lhs1", [0])[0], f("lhs2", [0])[0] = f("rhs1", 0), f("rhs2", 0)
-assert_eq(calls, ["rhs1", "rhs2", "lhs1", "lhs2"])
-
-# Left side is evaluated first (and only once) in an augmented assignment.
-calls.clear()
-f("array", [0])[f("index", 0)] += f("addend", 1)
-assert_eq(calls, ["array", "index", "addend"])
-
----
-# global referenced before assignment
-
-def f():
- return g ### Variable was not found
-
-f()
-
-g = 1
-
----
-printok = [False]
-
-def use_before_def():
- print(x)
-
-use_before_def() ### Variable was not found
-
----
-x = [1]
-x.extend([2]) # ok
-
-def f():
- x += [4] ### Local variable referenced before assignment
-
-f()
-
----
-
-z += 3 ### Augmented assignment is a binding and not allowed on a global variable
-
----
-# It's ok to define a global that shadows a built-in.
-
-
-assert_eq(type(list), "function")
-list = []
-assert_eq(type(list), "list")
-
----
-# Is that something specific to Go? Is it actually in the java implem too?
-
-# All 'in x' expressions in a comprehension are evaluated
-# in the comprehension's lexical block.
-#
-# By contrast, Python yields [[1, 2], [1, 2]] because it evaluates
-# the first 'in x' in the environment enclosing the comprehension.
-x = [[1, 2]]
-_ = [x for x in x for y in x] # # # "local variable x referenced before assignment"
-
----
-# A comprehension establishes a single new lexical block,
-# not one per 'for' clause.
-x = [1, 2]
-_ = [x for _ in [3] for x in x] # # # "local variable x referenced before assignment"
-
----
-# assign singleton sequence to 1-tuple
-(x,) = (1,)
-assert_eq(x, 1)
-(y,) = [1]
-assert_eq(y, 1)
-
-# assign 1-tuple to variable
-z = (1,)
-assert_eq(type(z), "tuple")
-assert_eq(len(z), 1)
-assert_eq(z[0], 1)
-
----
-# destucturing assigmnent in a for loop.
-def f():
- res = []
- for (x, y), z in [(["a", "b"], 3), (["c", "d"], 4)]:
- res.append((x, y, z))
- return res
-assert_eq(f(), [("a", "b", 3), ("c", "d", 4)])
-
-def g():
- a = {}
- for i, a[i] in [("one", 1), ("two", 2)]:
- pass
- return a
-assert_eq(g(), {"one": 1, "two": 2})
diff --git a/starlark-test/tests/go-testcases/bool.sky b/starlark-test/tests/go-testcases/bool.sky
deleted file mode 100644
index 32cdf807..00000000
--- a/starlark-test/tests/go-testcases/bool.sky
+++ /dev/null
@@ -1,44 +0,0 @@
-# Tests of Skylark 'bool'
-
-# truth
-assert_(True)
-assert_(not False)
-
-# bool conversion
-assert_eq([bool(), bool(1), bool(0), bool("hello"), bool("")],
- [False, True, False, True, False])
-
-# comparison
-assert_(None == None)
-assert_(None != False)
-assert_(None != True)
-assert_eq(1==1, True)
-assert_eq(1==2, False)
-assert_(False == False)
-assert_(True == True)
-
-# ordered comparison
-assert_(False < True)
-assert_(False <= True)
-assert_(False <= False)
-assert_(True > False)
-assert_(True >= False)
-assert_(True >= True)
-
-# conditional expression
-assert_eq(1 if 3 > 2 else 0, 1)
-assert_eq(1 if "foo" else 0, 1)
-assert_eq(1 if "" else 0, 0)
-
-# short-circuit evaluation of 'and' and 'or':
-# 'or' yields the first true operand, or the last if all are false.
-assert_eq(0 or "" or [] or 0, 0)
-assert_eq(0 or "" or [] or 123 or 1//0, 123)
----
-0 or "" or [] or 0 or 1//0 ### division by zero
----
-# 'and' yields the first false operand, or the last if all are true.
-assert_eq(1 and "a" and [1] and 123, 123)
-assert_eq(1 and "a" and [1] and 0 and 1//0, 0)
----
-1 and "a" and [1] and 123 and 1//0 ### division by zero
diff --git a/starlark-test/tests/go-testcases/builtins.sky b/starlark-test/tests/go-testcases/builtins.sky
deleted file mode 100644
index 74a68632..00000000
--- a/starlark-test/tests/go-testcases/builtins.sky
+++ /dev/null
@@ -1,207 +0,0 @@
-# Tests of Skylark built-in functions
-
-# len
-assert_eq(len([1, 2, 3]), 3)
-assert_eq(len((1, 2, 3)), 3)
-assert_eq(len({1: 2}), 1)
----
-len(1) ### len() not supported for type int
----
-
-# and, or
-assert_eq(123 or "foo", 123)
-assert_eq(0 or "foo", "foo")
-assert_eq(123 and "foo", "foo")
-assert_eq(0 and "foo", 0)
-none = None
-_1 = none and none[0] # rhs is not evaluated
-_2 = (not none) or none[0] # rhs is not evaluated
-
-# any, all
-assert_(all([]))
-assert_(all([1, True, "foo"]))
-assert_(not all([1, True, ""]))
-assert_(not any([]))
-assert_(any([0, False, "foo"]))
-assert_(not any([0, False, ""]))
-
-# in
-assert_(3 in [1, 2, 3])
-assert_(4 not in [1, 2, 3])
-assert_(3 in (1, 2, 3))
-assert_(4 not in (1, 2, 3))
----
-3 in "foo" ### Type of parameters mismatch
----
-assert_(123 in {123: ""})
-assert_(456 not in {123:""})
----
-assert_([] not in {123: ""}) ### Not hashable
----
-
-# sorted
-assert_eq(sorted([42, 123, 3]), [3, 42, 123])
-assert_eq(sorted([42, 123, 3], reverse=True), [123, 42, 3])
-assert_eq(sorted(["wiz", "foo", "bar"]), ["bar", "foo", "wiz"])
-assert_eq(sorted(["wiz", "foo", "bar"], reverse=True), ["wiz", "foo", "bar"])
-sorted([1, 2, None, 3]) ### compare not supported for types
----
-sorted([1, "one"]) ### compare not supported for types
----
-# custom key function
-assert_eq(sorted(["two", "three", "four"], key=len),
- ["two", "four", "three"])
-assert_eq(sorted(["two", "three", "four"], key=len, reverse=True),
- ["three", "four", "two"])
-sorted([1, 2, 3], key=None) ### call() not supported for type NoneType
----
-# sort is stable
-pairs = [(4, 0), (3, 1), (4, 2), (2, 3), (3, 4), (1, 5), (2, 6), (3, 7)]
-def first(t): return t[0]
-assert_eq(sorted(pairs, key=first),
- [(1, 5),
- (2, 3), (2, 6),
- (3, 1), (3, 4), (3, 7),
- (4, 0), (4, 2)])
-
-sorted(1) ### The type 'int' is not iterable
-
----
-
-# reversed
-assert_eq(reversed([1, 144, 81, 16]), [16, 81, 144, 1])
-
-# dict
-assert_eq(dict([(1, 2), (3, 4)]), {1: 2, 3: 4})
-assert_eq(dict([(1, 2), (3, 4)], foo="bar"), {1: 2, 3: 4, "foo": "bar"})
-assert_eq(dict({1:2, 3:4}), {1: 2, 3: 4})
-assert_eq(dict({1:2, 3:4}.items()), {1: 2, 3: 4})
-
-# range
-assert_eq("range", type(range(10)))
-assert_eq("range(10)", str(range(0, 10, 1)))
-assert_eq("range(1, 10)", str(range(1, 10)))
-assert_eq(range(0, 5, 10), range(0, 5, 11))
-assert_eq("range(0, 10, -1)", str(range(0, 10, -1)))
----
-{range(10): 10} ### CV04
----
-assert_(bool(range(1, 2)))
-assert_(not(range(2, 1))) # an empty range is false
-assert_eq([x*x for x in range(5)], [0, 1, 4, 9, 16])
-assert_eq(list(range(5)), [0, 1, 2, 3, 4])
-assert_eq(list(range(-5)), [])
-assert_eq(list(range(2, 5)), [2, 3, 4])
-assert_eq(list(range(5, 2)), [])
-assert_eq(list(range(-2, -5)), [])
-assert_eq(list(range(-5, -2)), [-5, -4, -3])
-assert_eq(list(range(2, 10, 3)), [2, 5, 8])
-assert_eq(list(range(10, 2, -3)), [10, 7, 4])
-assert_eq(list(range(-2, -10, -3)), [-2, -5, -8])
-assert_eq(list(range(-10, -2, 3)), [-10, -7, -4])
-assert_eq(list(range(10, 2, -1)), [10, 9, 8, 7, 6, 5, 4, 3])
-assert_eq(list(range(5)[1:]), [1, 2, 3, 4])
-assert_eq(len(range(5)[1:]), 4)
-assert_eq(list(range(5)[:2]), [0, 1])
-assert_eq(list(range(10)[1:]), [1, 2, 3, 4, 5, 6, 7, 8, 9])
-assert_eq(list(range(10)[1:9:2]), [1, 3, 5, 7])
-assert_eq(list(range(10)[1:10:2]), [1, 3, 5, 7, 9])
-assert_eq(list(range(10)[1:11:2]), [1, 3, 5, 7, 9])
-assert_eq(list(range(10)[::-2]), [9, 7, 5, 3, 1])
-assert_eq(list(range(0, 10, 2)[::2]), [0, 4, 8])
-assert_eq(list(range(0, 10, 2)[::-2]), [8, 4, 0])
-# Works fine in Starlark Rust
-# assert.fails(lambda: range(3000000000), "3000000000 out of range") # signed 32-bit values only
-assert_eq(len(range(0x7fffffff)), 0x7fffffff) # O(1)
-# Two ranges compare equal if they denote the same sequence:
-assert_eq(range(0), range(2, 1, 3)) # []
-assert_eq(range(0, 3, 2), range(0, 4, 2)) # [0, 2]
-assert_(range(1, 10) != range(2, 10))
-# Should not be comparable
-# assert.fails(lambda: range(0) < range(0), "range < range not implemented")
-# in
-assert_(1 in range(3))
----
-assert_(True not in range(3)) # The go implementation does not support that but python returns True.
----
-assert_("one" not in range(10))
----
-range(0, 0, 2)[:][0] ### Index out of bound
----
-
-# list
-assert_eq(sorted(list({"a": 1, "b": 2})), ['a', 'b'])
-
-# min, max
-assert_eq(min(5, -2, 1, 7, 3), -2)
-assert_eq(max(5, -2, 1, 7, 3), 7)
-assert_eq(min([5, -2, 1, 7, 3]), -2)
-assert_eq(min("one", "two", "three", "four"), "four")
-assert_eq(max("one", "two", "three", "four"), "two")
----
-min() ### min() expect a non empty iterable
----
-min(1) ### not iterable
----
-min([]) ### empty
----
-def m1(x): return x*x
-def m2(x): return -x
-assert_eq(min(5, -2, 1, 7, 3, key=m1), 1) # min absolute value
-assert_eq(min(5, -2, 1, 7, 3, key=m2), 7) # min negated value
-
-# enumerate
-assert_eq(enumerate([False, True, None], 42), [(42, False), (43, True), (44, None)])
-
-# zip
-assert_eq(zip(), [])
-assert_eq(zip([]), [])
-assert_eq(zip([1, 2, 3]), [(1,), (2,), (3,)])
-z1 = [1]
-assert_eq(zip(z1), [(1,)])
-z1.append(2)
-assert_eq(zip(z1), [(1,), (2,)])
-zip(z1, 1) ### 'int' is not iterable
-z1.append(3)
-
-# dir for builtin_function_or_method
-assert_eq(dir(None), [])
-assert_eq(dir({})[:3], ["clear", "get", "items"]) # etc
-assert_eq(dir(1), [])
-assert_eq(dir([])[:3], ["append", "clear", "extend"]) # etc
-
-# hasattr, getattr, dir
-# hasfields is an application-defined type defined in eval_test.go.
-## We would need to define that type to works, so ignore that test for now
-## TODO: Add hasfields for those test
-# hf = hasfields()
-# assert_eq(dir(hf), [])
-# assert_(not hasattr(hf, "x"))
-# ---
-# getattr(hf, "x") # # # no .x field or method
-# ---
-# assert_eq(getattr(hf, "x", 42), 42)
-# hf.x = 1
-# assert_(hasattr(hf, "x"))
-# assert_eq(getattr(hf, "x"), 1)
-# assert_eq(hf.x, 1)
-# hf.x = 2
-# assert_eq(getattr(hf, "x"), 2)
-# assert_eq(hf.x, 2)
-# built-in types can have attributes (methods) too.
-myset = dict()
-assert_eq(dir(myset), ["union"])
-assert_(hasattr(myset, "union"))
-assert_(not hasattr(myset, "onion"))
-assert_eq(str(getattr(myset, "union")), "")
----
-myset = dict()
-getattr(myset, "onion") ### .onion not supported for type dict
----
-myset = dict()
-assert_eq(getattr(myset, "onion", 42), 42)
-
-# repr
-assert_eq(repr(1), "1")
-assert_eq(repr("x"), '"x"')
-assert_eq(repr(["x", 1]), '["x", 1]')
diff --git a/starlark-test/tests/go-testcases/control.sky b/starlark-test/tests/go-testcases/control.sky
deleted file mode 100644
index 99758ee7..00000000
--- a/starlark-test/tests/go-testcases/control.sky
+++ /dev/null
@@ -1,52 +0,0 @@
-# Tests of Skylark control flow
-
-def controlflow():
- # elif
- x = 0
- if True:
- x=1
- elif False:
- fail("else of true")
- else:
- fail("else of else of true")
- assert_(x)
-
- x = 0
- if False:
- fail("then of false")
- elif True:
- x = 1
- else:
- fail("else of true")
- assert_(x)
-
- x = 0
- if False:
- fail("then of false")
- elif False:
- fail("then of false")
- else:
- x = 1
- assert_(x)
-controlflow()
-
-def loops():
- y = ""
- for x in [1, 2, 3, 4, 5]:
- if x == 2:
- continue
- if x == 4:
- break
- y = y + str(x)
- return y
-assert_eq(loops(), "13")
-
-# return
-g = 123
-def f(x):
- for g in (1, 2, 3):
- if g == x:
- return g
-assert_eq(f(2), 2)
-assert_eq(f(4), None) # falling off end => return None
-assert_eq(g, 123) # unchanged by local use of g in function
diff --git a/starlark-test/tests/go-testcases/dict.sky b/starlark-test/tests/go-testcases/dict.sky
deleted file mode 100644
index ddbbfdec..00000000
--- a/starlark-test/tests/go-testcases/dict.sky
+++ /dev/null
@@ -1,207 +0,0 @@
-# Tests of Skylark 'dict'
-
-# literals
-assert_eq({}, {})
-assert_eq({"a": 1}, {"a": 1})
-assert_eq({"a": 1,}, {"a": 1})
-
-# truth
-assert_({False: False})
-assert_(not {})
-
-# dict + dict (undocumented and deprecated; see b/36360157).
-assert_eq({"a": 1, "b": 2} + {"a": 3, "c": 4}, {"a": 3, "b": 2, "c": 4})
-
-# dict comprehension
-assert_eq({x: x*x for x in range(3)}, {0: 0, 1: 1, 2: 4})
-
-# dict.pop
-x6 = {"a": 1, "b": 2}
-assert_eq(x6.pop("a"), 1)
-assert_eq(str(x6), '{"b": 2}')
-x6.pop("c") ### not found
----
-x6 = {"b": 2}
-assert_eq(x6.pop("c", 3), 3)
-assert_eq(x6.pop("b"), 2)
-assert_eq(len(x6), 0)
-
----
-# dict.popitem
-x7 = {"a": 1, "b": 2}
-assert_eq([x7.popitem(), x7.popitem()], [("a", 1), ("b", 2)])
-assert_eq(len(x7), 0)
-x7.popitem() ### empty dict
----
-
-# dict.keys, dict.values
-x8 = {"a": 1, "b": 2}
-assert_eq(x8.keys(), ["a", "b"])
-assert_eq(x8.values(), [1, 2])
-
-# equality
-assert_eq({"a": 1, "b": 2}, {"a": 1, "b": 2})
-assert_eq({"a": 1, "b": 2,}, {"a": 1, "b": 2})
-assert_eq({"a": 1, "b": 2}, {"b": 2, "a": 1})
-
-# insertion order is preserved
-assert_eq(dict([("a", 0), ("b", 1), ("c", 2), ("b", 3)]).keys(), ["a", "b", "c"])
-assert_eq(dict([("b", 0), ("a", 1), ("b", 2), ("c", 3)]).keys(), ["b", "a", "c"])
-assert_eq(dict([("b", 0), ("a", 1), ("b", 2), ("c", 3)])["b"], 2)
-# ...even after rehashing (which currently occurs after key 'i'):
-small = dict([("a", 0), ("b", 1), ("c", 2)])
-small.update([("d", 4), ("e", 5), ("f", 6), ("g", 7), ("h", 8), ("i", 9), ("j", 10), ("k", 11)])
-assert_eq(small.keys(), ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"])
-
----
-# duplicate keys are not permitted in dictionary expressions (see b/35698444).
-{"aa": 1, "bb": 2, "cc": 3, "bb": 4} # TODO(dmarting): duplicate key: "bb"
----
-
-# index
-x9 = {}
-x9["a"] ### Not found
----
-x9 = {}
-x9["a"] = 1
-assert_eq(x9["a"], 1)
-assert_eq(x9, {"a": 1})
----
-x9 = {}
-x9[[]] = 2 ### Not hashable
----
-
-x9a = {}
-x9a[1, 2] = 3 # unparenthesized tuple is allowed here
-assert_eq(x9a.keys()[0], (1, 2))
-
-# dict.get
-x9 = {"a": 1}
-assert_eq(x9.get("a"), 1)
-assert_eq(x9.get("b"), None)
-assert_eq(x9.get("a", 2), 1)
-assert_eq(x9.get("b", 2), 2)
-
----
-# dict.clear
-x11 = {"a": 1}
-assert_("a" in x10)
-assert_eq(x10["a"], 1)
-x10.clear()
-assert_("a" not in x10)
-x10["a"] ### Not found
----
-
-# dict.setdefault
-x12 = {"a": 1}
-assert_eq(x12.setdefault("a"), 1)
-assert_eq(x12["a"], 1)
-assert_eq(x12.setdefault("b"), None)
-assert_eq(x12["b"], None)
-assert_eq(x12.setdefault("c", 2), 2)
-assert_eq(x12["c"], 2)
-assert_eq(x12.setdefault("c", 3), 2)
-assert_eq(x12["c"], 2)
-
-# dict.update
-x13 = {"a": 1}
-x13.update(a=2, b=3)
-assert_eq(x13, {"a": 2, "b": 3})
-x13.update([("b", 4), ("c", 5)])
-assert_eq(x13, {"a": 2, "b": 4, "c": 5})
-x13.update({"c": 6, "d": 7})
-assert_eq(x13, {"a": 2, "b": 4, "c": 6, "d": 7})
-
-# dict as a sequence
-#
-# for loop
-x14 = {1:2, 3:4}
-def keys(dict):
- keys = []
- for k in dict: keys.append(k)
- return keys
-assert_eq(keys(x14), [1, 3])
-#
-# comprehension
-assert_eq([x for x in x14], [1, 3])
-#
-# varargs
-def varargs(*args): return args
-x15 = {"one": 1}
-assert_eq(varargs(*x15), ["one"])
-
-# kwargs parameter does not alias the **kwargs dict
-def kwargs(**kwargs): return kwargs
-x16 = kwargs(**x15)
-assert_eq(x16, x15)
-x15["two"] = 2 # mutate
-assert_(x16 != x15)
----
-# iterator invalidation
-def iterator1():
- dict = {1:1, 2:1}
- for k in dict:
- dict[2*k] = dict[k]
-iterator1() ### Cannot mutate an iterable while iterating
----
-def iterator2():
- dict = {1:1, 2:1}
- for k in dict:
- dict.pop(k)
-iterator2() ### Cannot mutate an iterable while iterating
----
-def f(d):
- d[3] = 3
-
-def iterator3():
- dict = {1:1, 2:1}
- _ = [f(dict) for x in dict]
-iterator3() ### Cannot mutate an iterable while iterating
----
-# This assignment is not a modification-during-iteration:
-# the sequence x should be completely iterated before
-# the assignment occurs.
-def f():
- x = {1:2, 2:4}
- a, x[0] = x
- # There are two possible outcomes, depending on iteration order:
- if not (a == 1 and x == {0: 2, 1: 2, 2: 4} or
- a == 2 and x == {0: 1, 1: 2, 2: 4}):
- fail("unexpected results: a=%s x=%s" % (a, x))
-f()
-
-# Regression test for a bug in hashtable.delete
-def test_delete():
- d = {}
-
- # delete tail first
- d["one"] = 1
- d["two"] = 2
- assert_eq(str(d), '{"one": 1, "two": 2}')
- d.pop("two")
- assert_eq(str(d), '{"one": 1}')
- d.pop("one")
- assert_eq(str(d), '{}')
-
- # delete head first
- d["one"] = 1
- d["two"] = 2
- assert_eq(str(d), '{"one": 1, "two": 2}')
- d.pop("one")
- assert_eq(str(d), '{"two": 2}')
- d.pop("two")
- assert_eq(str(d), '{}')
-
- # delete middle
- d["one"] = 1
- d["two"] = 2
- d["three"] = 3
- assert_eq(str(d), '{"one": 1, "two": 2, "three": 3}')
- d.pop("two")
- assert_eq(str(d), '{"one": 1, "three": 3}')
- d.pop("three")
- assert_eq(str(d), '{"one": 1}')
- d.pop("one")
- assert_eq(str(d), '{}')
-
-test_delete()
diff --git a/starlark-test/tests/go-testcases/function.sky b/starlark-test/tests/go-testcases/function.sky
deleted file mode 100644
index 0637bde7..00000000
--- a/starlark-test/tests/go-testcases/function.sky
+++ /dev/null
@@ -1,105 +0,0 @@
-# Tests of Skylark 'function'
-
-# TODO(adonovan):
-# - add some introspection functions for looking at function values
-# and test that functions have correct position, free vars, names of locals, etc.
-# - move the hard-coded tests of parameter passing from eval_test.go to here.
-
----
-# recursion detection, simple
-def fib(x):
- if x < 2:
- return x
- return fib(x-2) + fib(x-1)
-fib(10) ### Recursive call
----
-
-# call of function not through its name
-# (regression test for parsing suffixes of primary expressions)
-hf = {"x": [len]}
-assert_eq(hf["x"][0]("abc"), 3)
-def fone(): return 1
-def f():
- return fone
-assert_eq(f()(), 1)
-assert_eq(["abc"][0][0].upper(), "A")
-
-# functions may be recursively defined,
-# so long as they don't dynamically recur.
-calls = []
-def yin(x):
- calls.append("yin")
- if x:
- yang(False)
-
-def yang(x):
- calls.append("yang")
- if x:
- yin(False)
-
-yin(True)
-assert_eq(calls, ["yin", "yang"])
-
-calls.clear()
-yang(True)
-assert_eq(calls, ["yang", "yin"])
-
-
----
-# Default values of function parameters are mutable.
-
-def f(x=[0]):
- return x
-
-assert_eq(f(), [0])
-
-f().append(1)
-assert_eq(f(), [0, 1])
-
----
-# Missing parameters are correctly reported
-# in functions of more than 64 parameters.
-
-def f(a, b, c, d, e, f, g, h,
- i, j, k, l, m, n, o, p,
- q, r, s, t, u, v, w, x,
- y, z, A, B, C, D, E, F,
- G, H, I, J, K, L, M, N,
- O, P, Q, R, S, T, U, V,
- W, X, Y, Z, aa, bb, cc, dd,
- ee, ff, gg, hh, ii, jj, kk, ll,
- mm):
- pass
-
-f(
- 1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64) ### not enough parameters
----
-
-def f(a, b, c, d, e, f, g, h,
- i, j, k, l, m, n, o, p,
- q, r, s, t, u, v, w, x,
- y, z, A, B, C, D, E, F,
- G, H, I, J, K, L, M, N,
- O, P, Q, R, S, T, U, V,
- W, X, Y, Z, aa, bb, cc, dd,
- ee, ff, gg, hh, ii, jj, kk, ll,
- mm):
- pass
-
-f(
- 1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64, 65,
- mm = 100) ### Extraneous parameter
diff --git a/starlark-test/tests/go-testcases/int.sky b/starlark-test/tests/go-testcases/int.sky
deleted file mode 100644
index 60322bb4..00000000
--- a/starlark-test/tests/go-testcases/int.sky
+++ /dev/null
@@ -1,169 +0,0 @@
-# Tests of Skylark 'int'
-
-# basic arithmetic
-assert_eq(0 - 1, -1)
-assert_eq(0 + 1, +1)
-assert_eq(1 + 1, 2)
-assert_eq(5 + 7, 12)
-assert_eq(5 * 7, 35)
-assert_eq(5 - 7, -2)
-
-# truth
-assert_(123)
-assert_(-1)
-assert_(not 0)
-
-# floored division
-# (For real division, see float.sky.)
-assert_eq(100 // 7, 14)
-assert_eq(100 // -7, -15)
-assert_eq(-100 // 7, -15) # NB: different from Go/Java
-assert_eq(-100 // -7, 14) # NB: different from Go/Java
-assert_eq(98 // 7, 14)
-assert_eq(98 // -7, -14)
-assert_eq(-98 // 7, -14)
-assert_eq(-98 // -7, 14)
-
-# remainder
-assert_eq(100 % 7, 2)
-assert_eq(100 % -7, -5) # NB: different from Go/Java
-assert_eq(-100 % 7, 5) # NB: different from Go/Java
-assert_eq(-100 % -7, -2)
-assert_eq(98 % 7, 0)
-assert_eq(98 % -7, 0)
-assert_eq(-98 % 7, 0)
-assert_eq(-98 % -7, 0)
-
-# compound assignment
-def compound():
- x = 1
- x += 1
- assert_eq(x, 2)
- x -= 3
- assert_eq(x, -1)
- x *= 39
- assert_eq(x, -39)
- x //= 4
- assert_eq(x, -10)
- x /= -2
- assert_eq(x, 5)
- x %= 3
- assert_eq(x, 2)
-
-compound()
-
-# int conversion
-# See float.sky for float-to-int conversions.
-# We follow Python 3 here, but I can't see the method in its madness.
-# int from bool/int/float
-assert_eq(int(False), 0)
-assert_eq(int(True), 1)
-assert_eq(int(3), 3)
----
-int(3, base=10) ### non-string with explicit base
----
-int(True, 10) ### non-string with explicit base
----
-# int from string, base implicitly 10
-# The original number here was taking 72bits, Does go version has int that large?
-assert_eq(int("10000000000000000"), 100000000 * 100000000)
-assert_eq(int("-10000000000000000"), -100000000 * 100000000)
-assert_eq(int("123"), 123)
-assert_eq(int("-123"), -123)
-assert_eq(int("0123"), 123) # not octal
-assert_eq(int("-0123"), -123)
-# The followup conversions are considered errors in the go version
-# but are actually ok according to the java implementation. The go
-# version use base = 10 by default whereas the java implementation
-# use base = 0 by default.
-assert_eq(int("0x12"), 0x12)
-assert_eq(int("0o123"), 0o123)
-assert_eq(int("-0x12"), -0x12)
-assert_eq(int("-0o123"), -0o123)
-# int from string, explicit base
-assert_eq(int("11", base=9), 10)
-assert_eq(int("-11", base=9), -10)
-assert_eq(int("10011", base=2), 19)
-assert_eq(int("-10011", base=2), -19)
-assert_eq(int("123", 8), 83)
-assert_eq(int("-123", 8), -83)
-assert_eq(int("0123", 8), 83) # redundant zeros permitted
-assert_eq(int("-0123", 8), -83)
-assert_eq(int("00123", 8), 83)
-assert_eq(int("-00123", 8), -83)
-assert_eq(int("0o123", 8), 83)
-assert_eq(int("-0o123", 8), -83)
-assert_eq(int("123", 7), 66) # 1*7*7 + 2*7 + 3
-assert_eq(int("-123", 7), -66)
-assert_eq(int("12", 16), 18)
-assert_eq(int("-12", 16), -18)
-assert_eq(int("0x12", 16), 18)
-assert_eq(int("-0x12", 16), -18)
-assert_eq(0x10000001 * 0x10000001, 0x100000020000001)
-assert_eq(int("1010", 2), 10)
-assert_eq(int("111111101", 2), 509)
-assert_eq(int("0b0101", 0), 5)
-assert_eq(int("0b00000", 0), 0)
-assert_eq(11111111 * 11111111, 123456787654321)
----
-int("0x123", 8) ### Not a base 8 integer
----
-int("-0x123", 8) ### Not a base 8 integer
----
-int("0o123", 16) ### Not a base 16 integer
----
-int("-0o123", 16) ### Not a base 16 integer
----
-int("0x110", 2) ### Not a base 2 integer
----
-# int from string, auto detect base
-assert_eq(int("123", 0), 123)
-assert_eq(int("+123", 0), +123)
-assert_eq(int("-123", 0), -123)
-assert_eq(int("0x12", 0), 18)
-assert_eq(int("+0x12", 0), +18)
-assert_eq(int("-0x12", 0), -18)
-assert_eq(int("0o123", 0), 83)
-assert_eq(int("+0o123", 0), +83)
-assert_eq(int("-0o123", 0), -83)
-# The go implementation doesn't support the following, why?
-assert_eq(int("0123", 0), 123)
-assert_eq(int("-0123", 0), -123)
-
-# comparisons
-# TODO(adonovan): test: < > == != etc
-assert_(-2 < -1)
-assert_(-1 < 0)
-assert_(0 < 1)
-assert_(1 < 2)
-assert_(2 >= 2)
-assert_(2 > 1)
-assert_(1 >= 1)
-assert_(1 > 0)
-assert_(0 >= 0)
-assert_(0 > -1)
-assert_(-1 >= -1)
-assert_(-1 > -2)
-
-# precision
-maxint64 = 9223372036854775807 # = 2^63
-minint64 = -maxint64 - 1 # = -2^64
-assert_eq(str(maxint64), "9223372036854775807")
-# Overflow
-# assert_eq(str(maxint64+1), "9223372036854775808")
-assert_eq(str(minint64), "-9223372036854775808")
-# Overflow
-# assert_eq(str(minint64-1), "-9223372036854775809")
-# Overflow
-# assert_eq(str(minint64 * minint64), "85070591730234615865843651857942052864")
-
-# string formatting
-assert_eq("%o %x %d" % (0o755, 0xDEADBEEF, 42), "755 deadbeef 42")
-nums = [-95, -1, 0, +1, +95]
-assert_eq(' '.join(["%o" % x for x in nums]), "-137 -1 0 1 137")
-assert_eq(' '.join(["%d" % x for x in nums]), "-95 -1 0 1 95")
-assert_eq(' '.join(["%i" % x for x in nums]), "-95 -1 0 1 95")
-assert_eq(' '.join(["%x" % x for x in nums]), "-5f -1 0 1 5f")
-assert_eq(' '.join(["%X" % x for x in nums]), "-5F -1 0 1 5F")
-assert_eq("%o %x %d" % (123, 123, 123), "173 7b 123")
-assert_eq("%d" % True, "1")
diff --git a/starlark-test/tests/go-testcases/list.sky b/starlark-test/tests/go-testcases/list.sky
deleted file mode 100644
index fac359ad..00000000
--- a/starlark-test/tests/go-testcases/list.sky
+++ /dev/null
@@ -1,253 +0,0 @@
-# Tests of Skylark 'list'
-
-# literals
-assert_eq([], [])
-assert_eq([1], [1])
-assert_eq([1,], [1])
-assert_eq([1, 2], [1, 2])
-assert_([1, 2, 3] != [1, 2, 4])
-
-# truth
-assert_([0])
-assert_(not [])
-
-# indexing, x[i]
----
-abc = list("abc".split_codepoints())
-abc[-4] ### out of bound
----
-abc = list("abc".split_codepoints())
-assert_eq(abc[-3], "a")
-assert_eq(abc[-2], "b")
-assert_eq(abc[-1], "c")
-assert_eq(abc[0], "a")
-assert_eq(abc[1], "b")
-assert_eq(abc[2], "c")
----
-abc = list("abc".split_codepoints())
-abc[3] ### out of bound
----
-# x[i] = ...
-x3 = [0, 1, 2]
-x3[1] = 2
-x3[2] += 3
-assert_eq(x3, [0, 2, 5])
-def f2(): x3[3] = 4
-f2() ### Out of bound
----
-
-# list + list
-assert_eq([1, 2, 3] + [3, 4, 5], [1, 2, 3, 3, 4, 5])
----
-[1, 2] + (3, 4) ### Type of parameters mismatch
----
-(1, 2) + [3, 4] ### Type of parameters mismatch
----
-
-# list * int, int * list
-abc = list("abc".split_codepoints())
-assert_eq(abc * 0, [])
-assert_eq(abc * -1, [])
-assert_eq(abc * 1, abc)
-assert_eq(abc * 3, ["a", "b", "c", "a", "b", "c", "a", "b", "c"])
-assert_eq(0 * abc, [])
-assert_eq(-1 * abc, [])
-assert_eq(1 * abc, abc)
-assert_eq(3 * abc, ["a", "b", "c", "a", "b", "c", "a", "b", "c"])
-
-# list comprehensions
-assert_eq([2 * x for x in [1, 2, 3]], [2, 4, 6])
-assert_eq([2 * x for x in [1, 2, 3] if x > 1], [4, 6])
-assert_eq([(x, y) for x in [1, 2] for y in [3, 4]],
- [(1, 3), (1, 4), (2, 3), (2, 4)])
-assert_eq([(x, y) for x in [1, 2] if x == 2 for y in [3, 4]],[(2, 3), (2, 4)])
-assert_eq([2 * x for x in (1, 2, 3)], [2, 4, 6])
-assert_eq([x for x in "abc".split_codepoints()], ["a", "b", "c"])
-assert_eq([x for x in {"a": 1, "b": 2}], ["a", "b"])
-assert_eq([(y, x) for x, y in {1: 2, 3: 4}.items()], [(2, 1), (4, 3)])
-# corner cases of parsing:
-assert_eq([x for x in range(12) if x%2 == 0 if x%3 == 0], [0, 6])
-
-# list function
-assert_eq(list(), [])
-assert_eq(list("ab".split_codepoints()), ["a", "b"])
-
-# A list comprehension defines a separate lexical block,
-# whether at top-level...
-a = [1, 2]
-b = [a for a in [3, 4]]
-assert_eq(a, [1, 2])
-assert_eq(b, [3, 4])
-# ...or local to a function.
-def listcompblock():
- c = [1, 2]
- d = [c for c in [3, 4]]
- assert_eq(c, [1, 2])
- assert_eq(d, [3, 4])
-listcompblock()
-
-# list.pop
-x4 = [1,2,3,4,5]
-assert_eq(x4.pop(), 5)
-assert_eq(x4, [1,2,3,4])
-assert_eq(x4.pop(1), 2)
-assert_eq(x4, [1,3,4])
-assert_eq(x4.pop(0), 1)
-assert_eq(x4, [3,4])
-
-# TODO(adonovan): test uses of list as sequence
-# (for loop, comprehension, library functions).
-
-# x += y for lists is equivalent to x.extend(y).
-# y may be a sequence.
-# TODO: Test that side-effects of 'x' occur only once.
-def list_extend():
- a = [1, 2, 3]
- b = a
- a = a + [4] # creates a new list
- assert_eq(a, [1, 2, 3, 4])
- assert_eq(b, [1, 2, 3]) # b is unchanged
-
- a = [1, 2, 3]
- b = a
- # += <=> a = a + [4], hence creating a new list. The go implem does it differently...
- a += [4] # create a new list
- assert_eq(a, [1, 2, 3, 4])
- assert_eq(b, [1, 2, 3]) # b is unchanged
-
- a = [1, 2, 3]
- b = a
- a.extend([4]) # updates existing list
- assert_eq(a, [1, 2, 3, 4])
- assert_eq(b, [1, 2, 3, 4]) # alias observes the change
-list_extend()
-
----
-# Unlike list.extend(iterable), list += iterable makes its LHS name local.
-a_list = []
-def f4():
- a_list += [1] ### Local variable referenced before assignment
-f4()
----
-# list +=
-def f5():
- x = []
- x += 1
-f5() ### Type of parameters mismatch
----
-
-# append
-x5 = [1, 2, 3]
-x5.append(4)
-x5.append("abc")
-assert_eq(x5, [1, 2, 3, 4, "abc"])
-
-# extend
-x5a = [1, 2, 3]
-x5a.extend("abc".split_codepoints()) # string
-x5a.extend((True, False)) # tuple
-assert_eq(x5a, [1, 2, 3, "a", "b", "c", True, False])
-
-# list.insert
-def insert_at(index):
- x = list(range(3))
- x.insert(index, 42)
- return x
-assert_eq(insert_at(-99), [42, 0, 1, 2])
-assert_eq(insert_at(-2), [0, 42, 1, 2])
-assert_eq(insert_at(-1), [0, 1, 42, 2])
-assert_eq(insert_at( 0), [42, 0, 1, 2])
-assert_eq(insert_at( 1), [0, 42, 1, 2])
-assert_eq(insert_at( 2), [0, 1, 42, 2])
-assert_eq(insert_at( 3), [0, 1, 2, 42])
-assert_eq(insert_at( 4), [0, 1, 2, 42])
-
-# list.remove
----
-def remove(v):
- x = [3, 1, 4, 1]
- x.remove(v)
- return x
-assert_eq(remove(3), [1, 4, 1])
-assert_eq(remove(1), [3, 4, 1])
-assert_eq(remove(4), [3, 1, 1])
-[3, 1, 4, 1].remove(42) ### Not found
----
-
-# list.index
-bananas = list("bananas".split_codepoints())
-assert_eq(bananas.index('a'), 1) # bAnanas
-bananas.index('d') ### not found
----
-bananas = list("bananas".split_codepoints())
-# start
-assert_eq(bananas.index('a', -1000), 1) # bAnanas
-assert_eq(bananas.index('a', 0), 1) # bAnanas
-assert_eq(bananas.index('a', 1), 1) # bAnanas
-assert_eq(bananas.index('a', 2), 3) # banAnas
-assert_eq(bananas.index('a', 3), 3) # banAnas
-assert_eq(bananas.index('b', 0), 0) # Bananas
-assert_eq(bananas.index('n', -3), 4) # banaNas
-assert_eq(bananas.index('s', -2), 6) # bananaS
-# start, end
-assert_eq(bananas.index('s', -1000, 7), 6) # bananaS
----
-bananas = list("bananas".split_codepoints())
-bananas.index('n', -2) ### not found
----
-bananas = list("bananas".split_codepoints())
-bananas.index('b', 1) ### not found
----
-bananas = list("bananas".split_codepoints())
-bananas.index('s', -1000, 6) ### not found
----
-bananas = list("bananas".split_codepoints())
-bananas.index('d', -1000, 1000) ### not found
----
-
-# slicing, x[i:j:k]
-bananas = list("bananas".split_codepoints())
-assert_eq(bananas[6::-2], list("snnb".split_codepoints()))
-assert_eq(bananas[5::-2], list("aaa".split_codepoints()))
-assert_eq(bananas[4::-2], list("nnb".split_codepoints()))
-assert_eq(bananas[99::-2], list("snnb".split_codepoints()))
-assert_eq(bananas[100::-2], list("snnb".split_codepoints()))
-# TODO(adonovan): many more tests
----
-# iterator invalidation
-def iterator1():
- list = [0, 1, 2]
- for x in list:
- list[x] = 2 * x
- return list
-# Updating elements of a list while iterating is allowed in the go
-# implementation but following the specification
-# (https://github.com/bazelbuild/starlark/blob/815aed90b552fa70adca4dc18d73082fae83b538/design.md#no-mutation-during-iteration)
-# a immutable list element like a number does not match the definition of
-# "deep content" so it is disallowed in our implementation.
-iterator1() ### Cannot mutate an iterable while iterating
----
-def iterator2():
- list = [0, 1, 2]
- for x in list:
- list.remove(x)
-iterator2() ### Cannot mutate an iterable while iterating
----
-def iterator3():
- list = [0, 1, 2]
- for x in list:
- list.append(3)
-iterator3() ### Cannot mutate an iterable while iterating
----
-def iterator4():
- list = [0, 1, 2]
- for x in list:
- list.extend([3, 4])
-iterator4() ### Cannot mutate an iterable while iterating
----
-def fff(x):
- x.append(4)
-def iterator5():
- list = [1, 2, 3]
- _ = [fff(list) for x in list]
-iterator5() ### Cannot mutate an iterable while iterating
diff --git a/starlark-test/tests/go-testcases/misc.sky b/starlark-test/tests/go-testcases/misc.sky
deleted file mode 100644
index 5ef706d1..00000000
--- a/starlark-test/tests/go-testcases/misc.sky
+++ /dev/null
@@ -1,89 +0,0 @@
-# Miscellaneous tests of Skylark evaluation.
-# This is a "chunked" file: each "---" effectively starts a new file.
-
-# TODO(adonovan): move these tests into more appropriate files.
-# TODO(adonovan): test coverage:
-# - stmts: pass; if cond fail; += and failures;
-# for x fail; for x not iterable; for can't assign; for
-# error in loop body
-# - subassign fail
-# - x[i]=x fail in both operands; frozen x; list index not int; boundscheck
-# - x.f = ...
-# - failure in list expr [...]; tuple expr; dict expr (bad key)
-# - cond expr semantics; failures
-# - x[i] failures in both args; dict and iterator key and range checks;
-# unhandled operand types
-# - +: list/list, int/int, string/string, tuple+tuple, dict/dict;
-# - * and ** calls: various errors
-# - call of non-function
-# - slice x[ijk]
-# - comprehension: unhashable dict key;
-# scope of vars (local and toplevel); noniterable for clause
-# - unknown unary op
-# - ordering of values
-# - freeze, transitivity of its effect.
-# - add an application-defined type to the environment so we can test it.
-# - even more:
-#
-# eval
-# pass statement
-# assign to tuple l-value -- illegal
-# assign to list l-value -- illegal
-# assign to field
-# tuple + tuple
-# call with *args, **kwargs
-# slice with step
-# tuple slice
-# interpolate with %c, %%
-
-def lam(): None
-
-# Ordered comparisons require values of the same type.
-None < False ### compare not supported for types NoneType and bool
----
-False < list ### compare not supported for types bool and function
----
-list < {} ### compare not supported for types function and dict
----
-0 < [] ### compare not supported for types int and list
----
-[] < "" ### compare not supported for types list and str
----
-"" < () ### compare not supported for types string and tuple
-
----
-# cyclic data structures
-
-cyclic = [1, 2, 3] # list cycle
-cyclic[1] = cyclic ### Unsupported recursive data structure
----
-cyclic2 = [1, 2, 3]
-cyclic2[1] = cyclic2 ### Unsupported recursive data structure
----
-
-cyclic3 = [1, [2, 3]] # list-list cycle
-cyclic3[1][0] = cyclic3 ### Unsupported recursive data structure
----
-cyclic4 = {"x": 1}
-cyclic4["x"] = cyclic4 ### Unsupported recursive data structure
----
-cyclic5 = [0, {"x": 1}] # list-dict cycle
-cyclic5[1]["x"] = cyclic5 ### Unsupported recursive data structure
----
-cyclic6 = [0, {"x": 1}]
-cyclic6[1]["x"] = cyclic6 ### Unsupported recursive data structure
----
-# was a parse error:
-assert_eq(("ababab"[2:]).replace("b", "c"), "acac")
-assert_eq("ababab"[2:].replace("b", "c"), "acac")
-
-# test parsing of line continuation, at toplevel and in expression.
-three = 1 + \
- 2
-assert_eq(1 + \
- 2, three)
-
----
-# A regression test for error position information.
-
-_ = {}.get(1, default=2) ### Extraneous parameter
diff --git a/starlark-test/tests/go-testcases/string.sky b/starlark-test/tests/go-testcases/string.sky
deleted file mode 100644
index 948512dd..00000000
--- a/starlark-test/tests/go-testcases/string.sky
+++ /dev/null
@@ -1,392 +0,0 @@
-# Tests of Skylark 'string'
-
-# raw string literals:
-assert_eq(r'a\bc', "a\\bc")
-
-# truth
-assert_("abc")
-assert_("\0")
-assert_(not "")
-
-# str + str
-assert_eq("a"+"b"+"c", "abc")
-
-# str * int, int * str
-assert_eq("abc" * 0, "")
-assert_eq("abc" * -1, "")
-assert_eq("abc" * 1, "abc")
-assert_eq("abc" * 5, "abcabcabcabcabc")
-assert_eq(0 * "abc", "")
-assert_eq(-1 * "abc", "")
-assert_eq(1 * "abc", "abc")
-assert_eq(5 * "abc", "abcabcabcabcabc")
-
-# len
-# Note that the go implen return a number of bytes and python3 a number o char...
-assert_eq(len("Hello, 世界!"), 10) # The go implem return 14 (bytes) which is not consistent with python 3.
-assert_eq(len("𐐷"), 1) # U+10437 has a 4-byte UTF-8 encoding (and a 2-code UTF-16 encoding)
-
-# chr & ord
-assert_eq(chr(65), "A") # 1-byte UTF-8 encoding
-assert_eq(chr(1049), "Й") # 2-byte UTF-8 encoding
-assert_eq(chr(0x1F63F), "😿") # 4-byte UTF-8 encoding
----
-chr(-1) ### not a valid UTF-8 codepoint
----
-chr(0x110000) ### not a valid UTF-8 codepoint
----
-assert_eq(ord("A"), 65)
-assert_eq(ord("Й"), 1049)
-assert_eq(ord("😿"), 0x1F63F)
-assert_eq(ord("Й"), 1049)
----
-ord("abc") ### not a one character string
----
-ord("") ### not a one character string
----
-ord("😿"[1:]) ### not a one character string
----
-
-# string.codepoints
-assert_eq(type("abcЙ😿".codepoints()), "list")
-assert_eq(str("abcЙ😿".codepoints()), '[97, 98, 99, 1049, 128575]')
-assert_eq(list("abcЙ😿".codepoints()), [97, 98, 99, 1049, 128575])
-assert_eq(list("".codepoints()), [])
-
-# string.split_codepoints
-assert_eq(type("abcЙ😿".split_codepoints()), "list")
-assert_eq(str("abcЙ😿".split_codepoints()), '["a", "b", "c", "Й", "😿"]')
-assert_eq(list("abcЙ😿".split_codepoints()), ["a", "b", "c", "Й", "😿"])
-assert_eq(list("".split_codepoints()), [])
-
-# string.elems
-assert_eq(type("abcЙ😿".elems()), "list")
-assert_eq(str("abcЙ😿".elems()), '[97, 98, 99, 208, 153, 240, 159, 152, 191]')
-assert_eq(list("abcЙ😿".elems()), [97, 98, 99, 208, 153, 240, 159, 152, 191])
-assert_eq(list("".elems()), [])
-
-# indexing, x[i]
-assert_eq("Hello, 世界!"[0], "H")
-assert_eq("Hello, 世界!"[7], "世")
-assert_eq("Hello, 世界!"[9], "!")
----
-"abc"[-4] ### out of bound
----
-assert_eq("abc"[-3], "a")
-assert_eq("abc"[-2], "b")
-assert_eq("abc"[-1], "c")
-assert_eq("abc"[0], "a")
-assert_eq("abc"[1], "b")
-assert_eq("abc"[2], "c")
----
-"abc"[4] ### out of bound
----
-
-# x[i] = ...
-x2 = "abc"
-def f(): x2[1] = 'B'
-f() ### [] = not supported for types string and int
----
-
-# slicing, x[i:j]
-assert_eq("abc"[:], "abc")
-assert_eq("abc"[-4:], "abc")
-assert_eq("abc"[-3:], "abc")
-assert_eq("abc"[-2:], "bc")
-assert_eq("abc"[-1:], "c")
-assert_eq("abc"[0:], "abc")
-assert_eq("abc"[1:], "bc")
-assert_eq("abc"[2:], "c")
-assert_eq("abc"[3:], "")
-assert_eq("abc"[4:], "")
-assert_eq("abc"[:-4], "")
-assert_eq("abc"[:-3], "")
-assert_eq("abc"[:-2], "a")
-assert_eq("abc"[:-1], "ab")
-assert_eq("abc"[:0], "")
-assert_eq("abc"[:1], "a")
-assert_eq("abc"[:2], "ab")
-assert_eq("abc"[:3], "abc")
-assert_eq("abc"[:4], "abc")
-assert_eq("abc"[1:2], "b")
-assert_eq("abc"[2:1], "")
-# non-unit strides
-assert_eq("abcd"[0:4:1], "abcd")
-assert_eq("abcd"[::2], "ac")
-assert_eq("abcd"[1::2], "bd")
-assert_eq("abcd"[4:0:-1], "dcb")
-assert_eq("banana"[7::-2], "aaa")
-assert_eq("banana"[6::-2], "aaa")
-assert_eq("banana"[5::-2], "aaa")
-assert_eq("banana"[4::-2], "nnb")
-assert_eq("banana"[::-1], "ananab")
-assert_eq("banana"[None:None:-2], "aaa")
----
-"banana"[:"":] ### Type of parameters mismatch
----
-"banana"[:"":True] ### Type of parameters mismatch
----
-
-# in, not in
-assert_("oo" in "food")
-assert_("ox" not in "food")
-assert_("" in "food")
-assert_("" in "")
----
-1 in "" ### Type of parameters mismatch
----
-"" in 1 ### in not supported for types string and int
----
-
-# ==, !=
-assert_eq("hello", "he"+"llo")
-assert_("hello" != "Hello")
-
-# TODO(adonovan): ordered comparisons
-
-# string % tuple formatting
-assert_eq("A %d %x Z" % (123, 456), "A 123 1c8 Z")
-assert_eq("A %(foo)d %(bar)s Z" % {"foo": 123, "bar":"hi"}, "A 123 hi Z")
-assert_eq("%s %r" % ("hi", "hi"), 'hi "hi"')
-assert_eq("%%d %d" % 1, "%d 1")
----
-"%d %d" % 1 ### The type 'int' is not iterable
----
-"%d %d" % (1, 2, 3) ### too many arguments for format string
----
-# %c
-assert_eq("%c" % 65, "A")
-assert_eq("%c" % 0x3b1, "α")
-assert_eq("%c" % "A", "A")
-assert_eq("%c" % "α", "α")
----
-"%c" % "abc" ### requires a single-character string
----
-"%c" % 10000000 ### Invalid codepoint
----
-"%c" % -1 ### Invalid codepoint
----
-# TODO(adonovan): more tests
-
-# str.format
-assert_eq("a{}b".format(123), "a123b")
-assert_eq("a{}b{}c{}d{}".format(1, 2, 3, 4), "a1b2c3d4")
-assert_eq("a{{b".format(), "a{b")
-assert_eq("a}}b".format(), "a}b")
-assert_eq("a{{b}}c".format(), "a{b}c")
-assert_eq("a{x}b{y}c{}".format(1, x=2, y=3), "a2b3c1")
----
-"a{z}b".format(x=1) ### key not found
----
-"{-1}".format(1) ### key not found
----
-"{-0}".format(1) ### key not found
----
-'{0,1} and {1}'.format(1, 2) ### invalid character ','
----
-"a{123}b".format() ### index out of bound
----
-"a{}b{}c".format(1) ### Not enough parameters
----
-assert_eq("a{010}b".format(0,1,2,3,4,5,6,7,8,9,10), "a10b") # index is decimal
----
-"a{}b{1}c".format(1, 2) ### Mixed manual and automatic field numbering
----
-assert_eq("a{!s}c".format("b"), "abc")
-assert_eq("a{!r}c".format("b"), r'a"b"c')
-assert_eq("a{x!r}c".format(x='b'), r'a"b"c')
----
-"{x!}".format(x=1) ### Invalid format string specifier
----
-"{x!:}".format(x=1) ### Invalid format string specifier
----
-'{a.b}'.format(1) ### Invalid character
----
-'{a[0]}'.format(1) ### Invalid character
----
-'{ {} }'.format(1) ### unmatched '{'
----
-'{{}'.format(1) ### standalone '}'
----
-'{}}'.format(1) ### standalone '}'
----
-'}}{'.format(1) ### unmatched '{'
----
-'}{{'.format(1) ### standalone '}'
----
-
-# str.split, str.rsplit
-assert_eq("a.b.c.d".split("."), ["a", "b", "c", "d"])
-assert_eq("a.b.c.d".rsplit("."), ["a", "b", "c", "d"])
-assert_eq("a.b.c.d".split(".", -1), ["a", "b", "c", "d"])
-assert_eq("a.b.c.d".rsplit(".", -1), ["a", "b", "c", "d"])
-assert_eq("a.b.c.d".split(".", 0), ["a.b.c.d"])
-assert_eq("a.b.c.d".rsplit(".", 0), ["a.b.c.d"])
-assert_eq("a.b.c.d".split(".", 1), ["a", "b.c.d"])
-assert_eq("a.b.c.d".rsplit(".", 1), ["a.b.c", "d"])
-assert_eq("a.b.c.d".split(".", 2), ["a", "b", "c.d"])
-assert_eq("a.b.c.d".rsplit(".", 2), ["a.b", "c", "d"])
-
-# {,r}split on white space:
-assert_eq(" a bc\n def \t ghi".split(), ["a", "bc", "def", "ghi"])
-assert_eq(" a bc\n def \t ghi".split(None), ["a", "bc", "def", "ghi"])
-assert_eq(" a bc\n def \t ghi".split(None, 0), ["a bc\n def \t ghi"])
-assert_eq(" a bc\n def \t ghi".rsplit(None, 0), [" a bc\n def \t ghi"])
-assert_eq(" a bc\n def \t ghi".split(None, 1), ["a", "bc\n def \t ghi"])
-assert_eq(" a bc\n def \t ghi".rsplit(None, 1), [" a bc\n def", "ghi"])
-assert_eq(" a bc\n def \t ghi".split(None, 2), ["a", "bc", "def \t ghi"])
-assert_eq(" a bc\n def \t ghi".rsplit(None, 2), [" a bc", "def", "ghi"])
-assert_eq(" a bc\n def \t ghi".split(None, 3), ["a", "bc", "def", "ghi"])
-assert_eq(" a bc\n def \t ghi".rsplit(None, 3), [" a", "bc", "def", "ghi"])
-assert_eq(" a bc\n def \t ghi".split(None, 4), ["a", "bc", "def", "ghi"])
-assert_eq(" a bc\n def \t ghi".rsplit(None, 4), ["a", "bc", "def", "ghi"])
-assert_eq(" a bc\n def \t ghi".rsplit(None, 5), ["a", "bc", "def", "ghi"])
-
-assert_eq(" a bc\n def \t ghi ".split(None, 0), ["a bc\n def \t ghi "])
-assert_eq(" a bc\n def \t ghi ".rsplit(None, 0), [" a bc\n def \t ghi"])
-assert_eq(" a bc\n def \t ghi ".split(None, 1), ["a", "bc\n def \t ghi "])
-assert_eq(" a bc\n def \t ghi ".rsplit(None, 1), [" a bc\n def", "ghi"])
-
-# Observe the algorithmic difference when splitting on spaces versus other delimiters.
-assert_eq('--aa--bb--cc--'.split('-', 0), ['--aa--bb--cc--']) # contrast this
-assert_eq(' aa bb cc '.split(None, 0), ['aa bb cc ']) # with this
-assert_eq('--aa--bb--cc--'.rsplit('-', 0), ['--aa--bb--cc--']) # ditto this
-assert_eq(' aa bb cc '.rsplit(None, 0), [' aa bb cc']) # and this
-#
-assert_eq('--aa--bb--cc--'.split('-', 1), ['', '-aa--bb--cc--'])
-assert_eq('--aa--bb--cc--'.rsplit('-', 1), ['--aa--bb--cc-', ''])
-assert_eq(' aa bb cc '.split(None, 1), ['aa', 'bb cc '])
-assert_eq(' aa bb cc '.rsplit(None, 1), [' aa bb', 'cc'])
-#
-assert_eq('--aa--bb--cc--'.split('-', -1), ['', '', 'aa', '', 'bb', '', 'cc', '', ''])
-assert_eq('--aa--bb--cc--'.rsplit('-', -1), ['', '', 'aa', '', 'bb', '', 'cc', '', ''])
-assert_eq(' aa bb cc '.split(None, -1), ['aa', 'bb', 'cc'])
-assert_eq(' aa bb cc '.rsplit(None, -1), ['aa', 'bb', 'cc'])
-
-assert_eq("localhost:80".rsplit(":", 1)[-1], "80")
-
-# str.splitlines
-assert_eq("\nabc\ndef".splitlines(), ["", "abc", "def"])
-assert_eq("\nabc\ndef\n".splitlines(), ["", "abc", "def"])
-assert_eq("\nabc\ndef".splitlines(True), ["\n", "abc\n", "def"])
-assert_eq("\nabc\ndef\n".splitlines(True), ["\n", "abc\n", "def\n"])
-
-# str.{,l,r}strip
-assert_eq(" \tfoo\n ".strip(), "foo")
-assert_eq(" \tfoo\n ".lstrip(), "foo\n ")
-assert_eq(" \tfoo\n ".rstrip(), " \tfoo")
-# This syntax is undocumented...
-# assert_eq(" \tfoo\n ".strip(""), "foo")
-# assert_eq(" \tfoo\n ".lstrip(""), "foo\n ")
-# assert_eq(" \tfoo\n ".rstrip(""), " \tfoo")
-# assert_eq("blah.h".strip("b.h"), "la")
-# assert_eq("blah.h".lstrip("b.h"), "lah.h")
-# assert_eq("blah.h".rstrip("b.h"), "bla")
-
-# str.count
-assert_eq("banana".count("a"), 3)
-assert_eq("banana".count("a", 2), 2)
-assert_eq("banana".count("a", -4, -2), 1)
-assert_eq("banana".count("a", 1, 4), 2)
-assert_eq("banana".count("a", 0, -100), 0)
-
-# str.{starts,ends}with
-assert_("foo".endswith("oo"))
-assert_(not "foo".endswith("x"))
-assert_("foo".startswith("fo"))
-assert_(not "foo".startswith("x"))
----
-"foo".startswith(1) ### type int while expected string
----
-
-# str.replace
-assert_eq("banana".replace("a", "o", 1), "bonana")
-assert_eq("banana".replace("a", "o"), "bonono")
-# TODO(adonovan): more tests
-
-# str.{,r}find
-assert_eq("foofoo".find("oo"), 1)
-assert_eq("foofoo".find("ox"), -1)
-assert_eq("foofoo".find("oo", 2), 4)
-assert_eq("foofoo".rfind("oo"), 4)
-assert_eq("foofoo".rfind("ox"), -1)
-assert_eq("foofoo".rfind("oo", 1, 4), 1)
-assert_eq("foofoo".find(""), 0)
-assert_eq("foofoo".rfind(""), 6)
-
-# str.{,r}partition
-assert_eq("foo/bar/wiz".partition("/"), ("foo", "/", "bar/wiz"))
-assert_eq("foo/bar/wiz".rpartition("/"), ("foo/bar", "/", "wiz"))
-assert_eq("foo/bar/wiz".partition("."), ("foo/bar/wiz", "", ""))
-assert_eq("foo/bar/wiz".rpartition("."), ("", "", "foo/bar/wiz"))
----
-"foo/bar/wiz".partition("") ### empty separator
----
-"foo/bar/wiz".rpartition("") ### empty separator
----
-
-assert_eq('?'.join(["foo", "a/b/c.go".rpartition("/")[0]]), 'foo?a/b')
-
-# str.is{alpha,...}
-def test_predicates():
- predicates = ["alnum", "alpha", "digit", "lower", "space", "title", "upper"]
- table = {
- "Hello, World!": "title",
- "hello, world!": "lower",
- "base64": "alnum lower",
- "HAL-9000": "upper",
- "Catch-22": "title",
- "": "",
- "\n\t\r": "space",
- "abc": "alnum alpha lower",
- "ABC": "alnum alpha upper",
- "123": "alnum digit",
- }
- for str, want in table.items():
- got = ' '.join([name for name in predicates if getattr(str, "is"+name)()])
- if got != want:
- fail("%r matched [%s], want [%s]" % (str, want, got))
-test_predicates()
-
-# Strings are not iterable.
-# ok
-assert_eq(len("abc"), 3) # len
-assert_("a" in "abc") # str in str
-assert_eq("abc"[1], "b") # indexing
----
-def args(*args): return args
-args(*"abc") ### *args is not iterable
----
-list("abc") ### Not iterable
----
-tuple("abc") ### Not iterable
----
-enumerate("ab") ### Not iterable
----
-sorted("abc") ### Not iterable
----
-[].extend("bc") ### type
----
-",".join("abc") ### Not iterable
----
-dict(["ab"]) ### Non-pair element
----
-# The Java implementation does not correctly reject the following cases:
-# (See Google Issue b/34385336)
-# not ok
-def for_string():
- for x in "abc":
- pass
-for_string() ### Not iterable
----
-[x for x in "abc"] ### Not iterable
----
-all("abc") ### Not iterable
----
-any("abc") ### Not iterable
----
-reversed("abc") ### Not iterable
----
-zip("ab", "cd") ### Not iterable
-
-# TODO(adonovan): tests for: {,r}index join {capitalize,lower,title,upper}
diff --git a/starlark-test/tests/go-testcases/struct.sky b/starlark-test/tests/go-testcases/struct.sky
deleted file mode 100644
index 63501de4..00000000
--- a/starlark-test/tests/go-testcases/struct.sky
+++ /dev/null
@@ -1,20 +0,0 @@
-# Tests of Starlark 'struct' extension.
-# This is not a standard feature and the Go and Starlark APIs may yet change.
-
-assert_(str(struct), "")
-
-# struct is a constructor for "unbranded" structs.
-s = struct(host = "localhost", port = 80)
-assert_(s, s)
-assert_(s, struct(host = "localhost", port = 80))
-assert_(s != struct(host = "localhost", port = 81))
-assert_(type(s), "struct")
-assert_(str(s), 'struct(host = "localhost", port = 80)')
-assert_(s.host, "localhost")
-assert_(s.port, 80)
-s.protocol ### protocol
----
-s = struct(host = "localhost", port = 80)
-assert_(dir(s), ["host", "port"])
-
-# The rest are tests for `gensym` which is not implemented
diff --git a/starlark-test/tests/go-testcases/tuple.sky b/starlark-test/tests/go-testcases/tuple.sky
deleted file mode 100644
index f30011f7..00000000
--- a/starlark-test/tests/go-testcases/tuple.sky
+++ /dev/null
@@ -1,53 +0,0 @@
-# Tests of Skylark 'tuple'
-
-# literal
-assert_eq((), ())
-assert_eq((1), 1)
-assert_eq((1,), (1,))
-assert_((1) != (1,))
-assert_eq((1, 2), (1, 2))
-assert_eq((1, 2, 3, 4, 5), (1, 2, 3, 4, 5))
-assert_((1, 2, 3) != (1, 2, 4))
-
-# truth
-assert_((False,))
-assert_((False, False))
-assert_(not ())
-
-# indexing, x[i]
-assert_eq(("a", "b")[0], "a")
-assert_eq(("a", "b")[1], "b")
-
-# slicing, x[i:j]
-assert_eq("abcd"[0:4:1], "abcd")
-assert_eq("abcd"[::2], "ac")
-assert_eq("abcd"[1::2], "bd")
-assert_eq("abcd"[4:0:-1], "dcb")
-banana = tuple("banana".split_codepoints())
-assert_eq(banana[7::-2], tuple("aaa".split_codepoints()))
-assert_eq(banana[6::-2], tuple("aaa".split_codepoints()))
-assert_eq(banana[5::-2], tuple("aaa".split_codepoints()))
-assert_eq(banana[4::-2], tuple("nnb".split_codepoints()))
-
-# tuple
-assert_eq(tuple(), ())
-assert_eq(tuple("abc".split_codepoints()), ("a", "b", "c"))
-assert_eq(tuple(["a", "b", "c"]), ("a", "b", "c"))
-assert_eq(tuple([1]), (1,))
----
-tuple(1) ### type 'int' is not iterable
----
-
-# tuple * int, int * tuple
-abc = tuple("abc".split_codepoints())
-assert_eq(abc * 0, ())
-assert_eq(abc * -1, ())
-assert_eq(abc * 1, abc)
-assert_eq(abc * 3, ("a", "b", "c", "a", "b", "c", "a", "b", "c"))
-assert_eq(0 * abc, ())
-assert_eq(-1 * abc, ())
-assert_eq(1 * abc, abc)
-assert_eq(3 * abc, ("a", "b", "c", "a", "b", "c", "a", "b", "c"))
-
-# TODO(adonovan): test use of tuple as sequence
-# (for loop, comprehension, library functions).
diff --git a/starlark-test/tests/go_conformance_tests.rs b/starlark-test/tests/go_conformance_tests.rs
deleted file mode 100644
index 42fc8e07..00000000
--- a/starlark-test/tests/go_conformance_tests.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-use starlark_test::do_conformance_test;
-
-include!(concat!(env!("OUT_DIR"), "/tests/go-testcases.rs"));
diff --git a/starlark-test/tests/java-testcases/README.md b/starlark-test/tests/java-testcases/README.md
deleted file mode 100644
index a89deaae..00000000
--- a/starlark-test/tests/java-testcases/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Conformance test cases
-
-Those files are coming from the Bazel repository at https://github.com/bazelbuild/bazel in the
-[`src/test/skylark`](https://github.com/bazelbuild/bazel/tree/9b96c0b37da7dfbb6f590c3da65413d921b83eb5/src/test/skylark)
-directory.
diff --git a/starlark-test/tests/java-testcases/all_any.sky b/starlark-test/tests/java-testcases/all_any.sky
deleted file mode 100644
index 3194b42a..00000000
--- a/starlark-test/tests/java-testcases/all_any.sky
+++ /dev/null
@@ -1,46 +0,0 @@
-# All with empty value
-assert_eq(all(''.split_codepoints()), True)
-assert_eq(all([]), True)
-
-# All with list
-assert_eq(all('test'.split_codepoints()), True)
-assert_eq(all([False]), False)
-assert_eq(all([True, False]), False)
-assert_eq(all([False, False]), False)
-assert_eq(all([False, True]), False)
-assert_eq(all(['', True]), False)
-assert_eq(all([0, True]), False)
-assert_eq(all([[], True]), False)
-assert_eq(all([True, 't', 1]), True)
-
-# All with dict
-assert_eq(all({1 : None}), True)
-assert_eq(all({None : 1}), False)
-
-# Any with empty value
-assert_eq(any(''.split_codepoints()), False)
-assert_eq(any([]), False)
-
-# Any with list
-assert_eq(any('test'.split_codepoints()), True)
-assert_eq(any([False]), False)
-assert_eq(any([0]), False)
-assert_eq(any(['']), False)
-assert_eq(any([[]]), False)
-assert_eq(any([True, False]), True)
-assert_eq(any([False, False]), False)
-assert_eq(any([False, '', 0]), False)
-assert_eq(any([False, '', 42]), True)
-
-# Any with dict
-assert_eq(any({1 : None, '' : None}), True)
-assert_eq(any({None : 1, '' : 2}), False)
-
----
-all(None) ### type 'NoneType' is not iterable
----
-any(None) ### type 'NoneType' is not iterable
----
-any(1) ### type 'int' is not iterable
----
-all(1) ### type 'int' is not iterable
diff --git a/starlark-test/tests/java-testcases/and_or_not.sky b/starlark-test/tests/java-testcases/and_or_not.sky
deleted file mode 100644
index aa4ab784..00000000
--- a/starlark-test/tests/java-testcases/and_or_not.sky
+++ /dev/null
@@ -1,42 +0,0 @@
-assert_eq(8 or 9, 8)
-assert_eq(0 or 9, 9)
-assert_eq(8 and 9, 9)
-assert_eq(0 and 9, 0)
-
-assert_eq(1 and 2 or 3, 2)
-assert_eq(0 and 2 or 3, 3)
-assert_eq(1 and 0 or 3, 3)
-
-assert_eq(1 or 2 and 3, 1)
-assert_eq(0 or 2 and 3, 3)
-assert_eq(0 or 0 and 3, 0)
-assert_eq(1 or 0 and 3, 1)
-
-assert_eq(None and 1, None)
-assert_eq("" or 9, 9)
-assert_eq("abc" or 9, "abc")
-
-# check that fail() is not evaluated
-assert_eq(8 or fail("do not execute"), 8)
-assert_eq(0 and fail("do not execute"), 0)
-
-assert_eq(not 1, False)
-assert_eq(not "", True)
-
-assert_eq(not 0 + 0, True)
-assert_eq(not 2 - 1, False)
-
-assert_eq(not (0 and 0), True)
-assert_eq(not (1 or 0), False)
-
-assert_eq(0 and not 0, 0)
-assert_eq(not 0 and 0, 0)
-
-assert_eq(1 and not 0, True)
-assert_eq(not 0 or 0, True)
-
-assert_eq(not 1 or 0, 0)
-assert_eq(not 1 or 1, 1)
-
-assert_eq(not [], True)
-assert_eq(not {"a": 1}, False)
diff --git a/starlark-test/tests/java-testcases/equality.sky b/starlark-test/tests/java-testcases/equality.sky
deleted file mode 100644
index 89a6009c..00000000
--- a/starlark-test/tests/java-testcases/equality.sky
+++ /dev/null
@@ -1,69 +0,0 @@
-# == operator
-assert_eq(1 == 1, True)
-assert_eq(1 == 2, False)
-assert_eq('hello' == 'hel' + 'lo', True)
-assert_eq('hello' == 'bye', False)
-assert_eq(None == None, True)
-assert_eq([1, 2] == [1, 2], True)
-assert_eq([1, 2] == [2, 1], False)
-assert_eq({'a': 1, 'b': 2} == {'b': 2, 'a': 1}, True)
-assert_eq({'a': 1, 'b': 2} == {'a': 1}, False)
-assert_eq({'a': 1, 'b': 2} == {'a': 1, 'b': 2, 'c': 3}, False)
-assert_eq({'a': 1, 'b': 2} == {'a': 1, 'b': 3}, False)
-
-# != operator
-assert_eq(1 != 1, False)
-assert_eq(1 != 2, True)
-assert_eq('hello' != 'hel' + 'lo', False)
-assert_eq('hello' != 'bye', True)
-assert_eq([1, 2] != [1, 2], False)
-assert_eq([1, 2] != [2, 1], True)
-assert_eq({'a': 1, 'b': 2} != {'b': 2, 'a': 1}, False)
-assert_eq({'a': 1, 'b': 2} != {'a': 1}, True)
-assert_eq({'a': 1, 'b': 2} != {'a': 1, 'b': 2, 'c': 3}, True)
-assert_eq({'a': 1, 'b': 2} != {'a': 1, 'b': 3}, True);
-
-# equality precedence
-assert_eq(1 + 3 == 2 + 2, True)
-assert_eq(not 1 == 2, True)
-assert_eq(not 1 != 2, False)
-assert_eq(2 and 3 == 3 or 1, True)
-assert_eq(2 or 3 == 3 and 1, 2);
-
-# < operator
-assert_eq(1 <= 1, True)
-assert_eq(1 < 1, False)
-assert_eq('a' <= 'b', True)
-assert_eq('c' < 'a', False);
-
-# <= and < operators
-assert_eq(1 <= 1, True)
-assert_eq(1 < 1, False)
-assert_eq('a' <= 'b', True)
-assert_eq('c' < 'a', False);
-
-# >= and > operators
-assert_eq(1 >= 1, True)
-assert_eq(1 > 1, False)
-assert_eq('a' >= 'b', False)
-assert_eq('c' > 'a', True);
-
-# list/tuple comparison
-assert_eq([] < [1], True)
-assert_eq([1] < [1, 1], True)
-assert_eq([1, 1] < [1, 2], True)
-assert_eq([1, 2] < [1, 2, 3], True)
-assert_eq([1, 2, 3] <= [1, 2, 3], True)
-
-assert_eq(['a', 'b'] > ['a'], True)
-assert_eq(['a', 'b'] >= ['a'], True)
-assert_eq(['a', 'b'] < ['a'], False)
-assert_eq(['a', 'b'] <= ['a'], False)
-
-assert_eq(('a', 'b') > ('a', 'b'), False)
-assert_eq(('a', 'b') >= ('a', 'b'), True)
-assert_eq(('a', 'b') < ('a', 'b'), False)
-assert_eq(('a', 'b') <= ('a', 'b'), True)
-
-assert_eq([[1, 1]] > [[1, 1], []], False)
-assert_eq([[1, 1]] < [[1, 1], []], True)
diff --git a/starlark-test/tests/java-testcases/int.sky b/starlark-test/tests/java-testcases/int.sky
deleted file mode 100644
index 25624bbb..00000000
--- a/starlark-test/tests/java-testcases/int.sky
+++ /dev/null
@@ -1,66 +0,0 @@
-# Tests of Skylark 'int'
-
-# basic arithmetic
-assert_eq(0 - 1, -1)
-assert_eq(1 + 1, 2)
-assert_eq(5 + 7, 12)
-assert_eq(5 * 7, 35)
-assert_eq(5 - 7, -2)
-
-# truth
-assert_(123)
-assert_(-1)
-assert_(not 0)
-
-# comparisons
-assert_(5 > 2)
-assert_(2 + 1 == 3)
-assert_(2 + 1 >= 3)
-assert_(not (2 + 1 > 3))
-assert_(2 + 2 <= 5)
-assert_(not (2 + 1 < 3))
-
-# division
-assert_eq(100 // 7, 14)
-assert_eq(100 // -7, -15)
-assert_eq(-100 // 7, -15) # NB: different from Go / Java
-assert_eq(-100 // -7, 14) # NB: different from Go / Java
-assert_eq(98 // 7, 14)
-assert_eq(98 // -7, -14)
-assert_eq(-98 // 7, -14)
-assert_eq(-98 // -7, 14)
-
-# remainder
-assert_eq(100 % 7, 2)
-assert_eq(100 % -7, -5) # NB: different from Go / Java
-assert_eq(-100 % 7, 5) # NB: different from Go / Java
-assert_eq(-100 % -7, -2)
-assert_eq(98 % 7, 0)
-assert_eq(98 % -7, 0)
-assert_eq(-98 % 7, 0)
-assert_eq(-98 % -7, 0)
-
-# precedence
-assert_eq(5 - 7 * 2 + 3, -6)
-assert_eq(4 * 5 // 2 + 5 // 2 * 4, 18)
-
-# compound assignment
-def compound():
- x = 1
- x += 1
- assert_eq(x, 2)
- x -= 3
- assert_eq(x, -1)
- x *= 10
- assert_eq(x, -10)
- x /= -2
- assert_eq(x, 5)
- x %= 3
- assert_eq(x, 2)
-
-compound()
-
----
-1 // 0 ### divide by zero
----
-1 % 0 ### divide by zero
diff --git a/starlark-test/tests/java-testcases/int_constructor.sky b/starlark-test/tests/java-testcases/int_constructor.sky
deleted file mode 100644
index 5e01857b..00000000
--- a/starlark-test/tests/java-testcases/int_constructor.sky
+++ /dev/null
@@ -1,44 +0,0 @@
-assert_eq(int('1'), 1)
-assert_eq(int('-1234'), -1234)
-assert_eq(int(42), 42)
-assert_eq(int(-1), -1)
-assert_eq(int(True), 1)
-assert_eq(int(False), 0)
-assert_eq(int('11', 2), 3)
-assert_eq(int('11', 9), 10)
-assert_eq(int('AF', 16), 175)
-assert_eq(int('11', 36), 37)
-assert_eq(int('az', 36), 395)
-assert_eq(int('11', 10), 11)
-assert_eq(int('11', 0), 11)
-assert_eq(int('0b11', 0), 3)
-assert_eq(int('0B11', 2), 3)
-assert_eq(int('0o11', 0), 9)
-assert_eq(int('0O11', 8), 9)
-assert_eq(int('0XFF', 0), 255)
-assert_eq(int('0xFF', 16), 255)
-
----
-int('1.5') ### invalid digit found in string
----
-int('ab') ### invalid digit found in string
----
-int(None) ### Cannot int() on type NoneType
----
-int('123', 3) ### invalid digit found in string
----
-int('FF', 15) ### invalid digit found in string
----
-int('123', -1) ### int() base must be >= 2 and <= 36
----
-int('123', 1) ### int() base must be >= 2 and <= 36
----
-int('123', 37) ### int() base must be >= 2 and <= 36
----
-int('0xFF', 8) ### invalid digit found in string
----
-int(True, 2) ### int() cannot convert non-string with explicit base
----
-int(1, 2) ### int() cannot convert non-string with explicit base
----
-int(True, 10) ### int() cannot convert non-string with explicit base
diff --git a/starlark-test/tests/java-testcases/list_slices.sky b/starlark-test/tests/java-testcases/list_slices.sky
deleted file mode 100644
index 6e928be5..00000000
--- a/starlark-test/tests/java-testcases/list_slices.sky
+++ /dev/null
@@ -1,62 +0,0 @@
-# Without step
-assert_eq([0, 1, 2, 3][0:-1], [0, 1, 2])
-assert_eq([0, 1, 2, 3, 4, 5][2:4], [2, 3])
-assert_eq([0, 1, 2, 3, 4, 5][-2:-1], [4])
-assert_eq([][1:2], [])
-assert_eq([0, 1, 2, 3][-10:10], [0, 1, 2, 3])
-
-# With step
-assert_eq([1, 2, 3, 4, 5][::1], [1, 2, 3, 4, 5])
-assert_eq([1, 2, 3, 4, 5][1::1], [2, 3, 4, 5])
-assert_eq([1, 2, 3, 4, 5][:2:1], [1, 2])
-assert_eq([1, 2, 3, 4, 5][1:3:1], [2, 3])
-assert_eq([1, 2, 3, 4, 5][-4:-2:1], [2, 3])
-assert_eq([1, 2, 3, 4, 5][-10:10:1], [1, 2, 3, 4, 5])
-assert_eq([1, 2, 3, 4, 5][::42], [1])
-assert_eq([][::1], [])
-assert_eq([][::-1], [])
-assert_eq([1, 2, 3, 4, 5, 6, 7][::3], [1, 4, 7])
-assert_eq([1, 2, 3, 4, 5, 6, 7, 8, 9][1:7:3], [2, 5])
-assert_eq([1, 2, 3][3:1:1], [])
-assert_eq([1, 2, 3][1:3:-1], [])
-
-# Negative step
-assert_eq([1, 2, 3, 4, 5][::-1], [5, 4, 3, 2, 1])
-assert_eq([1, 2, 3, 4, 5][4::-1], [5, 4, 3, 2, 1])
-assert_eq([1, 2, 3, 4, 5][:0:-1], [5, 4, 3, 2])
-assert_eq([1, 2, 3, 4, 5][3:1:-1], [4, 3])
-assert_eq([1, 2, 3, 4, 5][::-2], [5, 3, 1])
-assert_eq([1, 2, 3, 4, 5][::-10], [5])
-
-# None
-assert_eq([1, 2, 3][None:None:None], [1, 2, 3])
-assert_eq([1, 2, 3][None:None], [1, 2, 3])
-assert_eq([1, 2, 3][None:2:None], [1, 2])
-
-# Tuples
-assert_eq(()[1:2], ())
-assert_eq(()[::1], ())
-assert_eq((0, 1, 2, 3)[0:-1], (0, 1, 2))
-assert_eq((0, 1, 2, 3, 4, 5)[2:4], (2, 3))
-assert_eq((0, 1, 2, 3)[-10:10], (0, 1, 2, 3))
-assert_eq((1, 2, 3, 4, 5)[-10:10:1], (1, 2, 3, 4, 5))
-assert_eq((1, 2, 3, 4, 5, 6, 7, 8, 9)[1:7:3], (2, 5))
-assert_eq((1, 2, 3, 4, 5)[::-1], (5, 4, 3, 2, 1))
-assert_eq((1, 2, 3, 4, 5)[3:1:-1], (4, 3))
-assert_eq((1, 2, 3, 4, 5)[::-2], (5, 3, 1))
-assert_eq((1, 2, 3, 4, 5)[::-10], (5,))
-
----
-'123'['a'::] ### Type of parameters mismatch
----
-'123'[:'b':] ### Type of parameters mismatch
----
-(1, 2, 3)[1::0] ### Index 0 is out of bound
----
-[1, 2, 3][::0] ### Index 0 is out of bound
----
-[1, 2, 3][1::0] ### Index 0 is out of bound
----
-[1, 2, 3][:3:0] ### Index 0 is out of bound
----
-[1, 2, 3][1:3:0] ### Index 0 is out of bound
diff --git a/starlark-test/tests/java-testcases/min_max.sky b/starlark-test/tests/java-testcases/min_max.sky
deleted file mode 100644
index 7996c2ff..00000000
--- a/starlark-test/tests/java-testcases/min_max.sky
+++ /dev/null
@@ -1,47 +0,0 @@
-# min / max
-
-assert_eq(min("abcdefxyz".split_codepoints()), "a")
-assert_eq(min("test", "xyz"), "test")
-
-assert_eq(min([4, 5], [1]), [1])
-assert_eq(min([1, 2], [3]), [1, 2])
-assert_eq(min([1, 5], [1, 6], [2, 4], [0, 6]), [0, 6])
-assert_eq(min([-1]), -1)
-assert_eq(min([5, 2, 3]), 2)
-assert_eq(min({1: 2, -1 : 3}), -1)
-assert_eq(min({2: None}), 2)
-assert_eq(min(-1, 2), -1)
-assert_eq(min(5, 2, 3), 2)
-assert_eq(min(1, 1, 1, 1, 1, 1), 1)
-assert_eq(min([1, 1, 1, 1, 1, 1]), 1)
-
-assert_eq(max("abcdefxyz".split_codepoints()), "z")
-assert_eq(max("test", "xyz"), "xyz")
-assert_eq(max("test", "xyz"), "xyz")
-assert_eq(max([1, 2], [5]), [5])
-assert_eq(max([-1]), -1)
-assert_eq(max([5, 2, 3]), 5)
-assert_eq(max({1: 2, -1 : 3}), 1)
-assert_eq(max({2: None}), 2)
-assert_eq(max(-1, 2), 2)
-assert_eq(max(5, 2, 3), 5)
-assert_eq(max(1, 1, 1, 1, 1, 1), 1)
-assert_eq(max([1, 1, 1, 1, 1, 1]), 1)
-
----
-min(1) ### type 'int' is not iterable
----
-min([]) ### Argument is an empty iterable, min() expect a non empty iterable
----
-assert_eq(min(1, "2", True), 1) ### compare not supported for types
----
-assert_eq(min([1, "2", True]), 1) ### compare not supported for types
----
-max(1) ### type 'int' is not iterable
----
-max([]) ### Argument is an empty iterable, max() expect a non empty iterable
----
-assert_eq(max(1, '2', True), '2') ### compare not supported for types
----
-assert_eq(max([1, '2', True]), '2') ### compare not supported for types
----
diff --git a/starlark-test/tests/java-testcases/string_format.sky b/starlark-test/tests/java-testcases/string_format.sky
deleted file mode 100644
index 1bd32b36..00000000
--- a/starlark-test/tests/java-testcases/string_format.sky
+++ /dev/null
@@ -1,93 +0,0 @@
-assert_eq('abc'.format(), "abc")
-
-# named arguments
-assert_eq('x{key}x'.format(key = 2), "x2x")
-assert_eq('x{key}x'.format(key = 'abc'), "xabcx")
-assert_eq('{a}{b}{a}{b}'.format(a = 3, b = True), "3True3True")
-assert_eq('{a}{b}{a}{b}'.format(a = 3, b = True), "3True3True")
-assert_eq('{s1}{s2}'.format(s1 = ['a'], s2 = 'a'), '["a"]a')
-assert_eq('{a}'.format(a = '$'), "$")
-assert_eq('{a}'.format(a = '$a'), "$a")
-assert_eq('{a}$'.format(a = '$a'), "$a$")
-assert_eq('{(}'.format(**{'(': 2}), "2")
-
-# curly brace escaping
-assert_eq('{{}}'.format(), "{}")
-assert_eq('{{}}'.format(42), "{}")
-assert_eq('{{ }}'.format(), "{ }")
-assert_eq('{{ }}'.format(42), "{ }")
-assert_eq('{{{{}}}}'.format(), "{{}}")
-assert_eq('{{{{}}}}'.format(42), "{{}}")
-assert_eq('{{0}}'.format(42), "{0}")
-assert_eq('{{}}'.format(42), "{}")
-assert_eq('{{{}}}'.format(42), "{42}")
-assert_eq('{{ '.format(42), "{ " )
-assert_eq(' }}'.format(42), " }")
-assert_eq('{{ {}'.format(42), "{ 42")
-assert_eq('{} }}'.format(42), "42 }")
-assert_eq('{{0}}'.format(42), "{0}")
-assert_eq('{{{0}}}'.format(42), "{42}")
-assert_eq('{{ 0'.format(42), "{ 0")
-assert_eq('0 }}'.format(42), "0 }")
-assert_eq('{{ {0}'.format(42), "{ 42")
-assert_eq('{0} }}'.format(42), "42 }")
-assert_eq('{{test}}'.format(test = 42), "{test}")
-assert_eq('{{{test}}}'.format(test = 42), "{42}")
-assert_eq('{{ test'.format(test = 42), "{ test")
-assert_eq('test }}'.format(test = 42), "test }")
-assert_eq('{{ {test}'.format(test = 42), "{ 42")
-assert_eq('{test} }}'.format(test = 42), "42 }")
-
-
-# Automatic positionals
-assert_eq('{}, {} {} {} test'.format('hi', 'this', 'is', 'a'), "hi, this is a test")
-assert_eq('skip some {}'.format('arguments', 'obsolete', 'deprecated'), "skip some arguments")
-
-# with numbered positions
-assert_eq('{0}, {1} {2} {3} test'.format('hi', 'this', 'is', 'a'), "hi, this is a test")
-assert_eq('{3}, {2} {1} {0} test'.format('a', 'is', 'this', 'hi'), "hi, this is a test")
-assert_eq('skip some {0}'.format('arguments', 'obsolete', 'deprecated'), "skip some arguments")
-assert_eq('{0} can be reused: {0}'.format('this', 'obsolete'), "this can be reused: this")
-
-# Mixed fields
-assert_eq('{test} and {}'.format(2, test = 1), "1 and 2")
-assert_eq('{test} and {0}'.format(2, test = 1), "1 and 2")
-
----
-'{{}'.format(1) ### Standalone '}'
----
-'{}}'.format(1) ### Standalone '}'
----
-'{0}'.format() ### Index 0 is out of bound
----
-'{0} and {1}'.format('this') ### Index 1 is out of bound
----
-'{0} and {2}'.format('this', 'that') ### Index 2 is out of bound
----
-'{-0} and {-1}'.format('this', 'that') ### Key '-0' was not found
----
-'{0,1} and {1}'.format('this', 'that') ### Invalid character ',' inside replacement field
----
-'{0.1} and {1}'.format('this', 'that') ### Invalid character '.' inside replacement field
----
-'{}'.format() ### Not enough parameters in format string
----
-'{} and {}'.format('this') ### Not enough parameters in format string
----
-'{test} and {}'.format(test = 1, 2) ### Parse error
----
-'{test} and {0}'.format(test = 1, 2) ### Parse error
----
-'{} and {1}'.format(1, 2) ### Cannot mix manual field specification and automatic field numbering in format string
----
-'{1} and {}'.format(1, 2) ### Cannot mix manual field specification and automatic field numbering in format string
----
-'{test.}'.format(test = 1) ### Invalid character '.' inside replacement field
----
-'{test[}'.format(test = 1) ### Invalid character '[' inside replacement field
----
-'{test,}'.format(test = 1) ### Invalid character ',' inside replacement field
----
-'{ {} }'.format(42) ### Unmatched '{'
----
-'{a}{b}'.format(a = 5) ### Key 'b' was not found
diff --git a/starlark-test/tests/java-testcases/string_partition.sky b/starlark-test/tests/java-testcases/string_partition.sky
deleted file mode 100644
index dc2d5be9..00000000
--- a/starlark-test/tests/java-testcases/string_partition.sky
+++ /dev/null
@@ -1,40 +0,0 @@
-assert_eq('lawl'.partition('a'), ('l', 'a', 'wl'))
-assert_eq('lawl'.rpartition('a'), ('l', 'a', 'wl'))
-assert_eq('google'.partition('o'), ('g', 'o', 'ogle'))
-assert_eq('google'.rpartition('o'), ('go', 'o', 'gle'))
-assert_eq('xxx'.partition('x'), ('', 'x', 'xx'))
-assert_eq('xxx'.rpartition('x'), ('xx', 'x', ''))
-assert_eq(''.partition('a'), ('', '', ''))
-assert_eq(''.rpartition('a'), ('', '', ''))
-
-# default separator
-assert_eq('hi this is a test'.partition(), ('hi', ' ', 'this is a test'))
-assert_eq('hi this is a test'.rpartition(), ('hi this is a', ' ', 'test'))
-assert_eq('google'.partition(), ('google', '', ''))
-assert_eq('google'.rpartition(), ('', '', 'google'))
-
-# no match
-assert_eq('google'.partition('x'), ('google', '', ''))
-assert_eq('google'.rpartition('x'), ('', '', 'google'))
-
-# at word boundaries
-assert_eq('goog'.partition('g'), ('', 'g', 'oog'))
-assert_eq('goog'.rpartition('g'), ('goo', 'g', ''))
-assert_eq('plex'.partition('p'), ('', 'p', 'lex'))
-assert_eq('plex'.rpartition('p'), ('', 'p', 'lex'))
-assert_eq('plex'.partition('x'), ('ple', 'x', ''))
-assert_eq('plex'.rpartition('x'), ('ple', 'x', ''))
-
-assert_eq('google'.partition('oog'), ('g', 'oog', 'le'))
-assert_eq('google'.rpartition('oog'), ('g', 'oog', 'le'))
-assert_eq('lolgooglolgooglolgooglol'.partition('goog'), ('lol', 'goog', 'lolgooglolgooglol'))
-assert_eq('lolgooglolgooglolgooglol'.rpartition('goog'), ('lolgooglolgooglol', 'goog', 'lol'))
-
-# full string
-assert_eq('google'.partition('google'), ('', 'google', ''))
-assert_eq('google'.rpartition('google'), ('', 'google', ''))
-
----
-'google'.partition('') ### Empty separator
----
-'google'.rpartition('') ### Empty separator
diff --git a/starlark-test/tests/java-testcases/string_split.sky b/starlark-test/tests/java-testcases/string_split.sky
deleted file mode 100644
index e8c5ba10..00000000
--- a/starlark-test/tests/java-testcases/string_split.sky
+++ /dev/null
@@ -1,45 +0,0 @@
-# split
-assert_eq('h i'.split(' '), ['h', 'i'])
-assert_eq('h i p'.split(' '), ['h', 'i', 'p'])
-assert_eq('a,e,i,o,u'.split(',', 2), ['a', 'e', 'i,o,u'])
-assert_eq(' 1 2 3 '.split(' '), ['', '', '1', '', '2', '', '3', '', ''])
-
-# rsplit
-assert_eq('abcdabef'.rsplit('ab'), ['', 'cd', 'ef'])
-assert_eq('google_or_gogol'.rsplit('go'), ['', 'ogle_or_', '', 'l'])
-
-# rsplit regex
-assert_eq('foo/bar.lisp'.rsplit('.'), ['foo/bar', 'lisp'])
-assert_eq('foo/bar.?lisp'.rsplit('.?'), ['foo/bar', 'lisp'])
-assert_eq('fwe$foo'.rsplit('$'), ['fwe', 'foo'])
-assert_eq('windows'.rsplit('\w'), ['windows'])
-
-# rsplit no match
-assert_eq(''.rsplit('o'), [''])
-assert_eq('google'.rsplit('x'), ['google'])
-
-# rsplit separator
-assert_eq('xxxxxx'.rsplit('x'), ['', '', '', '', '', '', ''])
-assert_eq('xxxxxx'.rsplit('x', 1), ['xxxxx', ''])
-assert_eq('xxxxxx'.rsplit('x', 2), ['xxxx', '', ''])
-assert_eq('xxxxxx'.rsplit('x', 3), ['xxx', '', '', ''])
-assert_eq('xxxxxx'.rsplit('x', 4), ['xx', '', '', '', ''])
-assert_eq('xxxxxx'.rsplit('x', 5), ['x', '', '', '', '', ''])
-assert_eq('xxxxxx'.rsplit('x', 6), ['', '', '', '', '', '', ''])
-assert_eq('xxxxxx'.rsplit('x', 7), ['', '', '', '', '', '', ''])
-
-# split max split
-assert_eq('google'.rsplit('o'), ['g', '', 'gle'])
-assert_eq('google'.rsplit('o'), ['g', '', 'gle'])
-assert_eq('google'.rsplit('o', 1), ['go', 'gle'])
-assert_eq('google'.rsplit('o', 2), ['g', '', 'gle'])
-assert_eq('google'.rsplit('o', 3), ['g', '', 'gle'])
-assert_eq('ogooglo'.rsplit('o'), ['', 'g', '', 'gl', ''])
-assert_eq('ogooglo'.rsplit('o', 1), ['ogoogl', ''])
-assert_eq('ogooglo'.rsplit('o', 2), ['ogo', 'gl', ''])
-assert_eq('ogooglo'.rsplit('o', 3), ['og', '', 'gl', ''])
-assert_eq('ogooglo'.rsplit('o', 4), ['', 'g', '', 'gl', ''])
-assert_eq('ogooglo'.rsplit('o', 5), ['', 'g', '', 'gl', ''])
-assert_eq('google'.rsplit('google'), ['', ''])
-assert_eq('google'.rsplit('google', 1), ['', ''])
-assert_eq('google'.rsplit('google', 2), ['', ''])
diff --git a/starlark-test/tests/java-testcases/string_splitlines.sky b/starlark-test/tests/java-testcases/string_splitlines.sky
deleted file mode 100644
index 8590513f..00000000
--- a/starlark-test/tests/java-testcases/string_splitlines.sky
+++ /dev/null
@@ -1,29 +0,0 @@
-# Empty line
-assert_eq(''.splitlines(), [])
-assert_eq('\n'.splitlines(), [''])
-
-# Starts with line break
-assert_eq('\ntest'.splitlines(), ['', 'test'])
-
-# Ends with line break
-assert_eq('test\n'.splitlines(), ['test'])
-
-# Different line breaks
-assert_eq('this\nis\na\ntest'.splitlines(), ['this', 'is', 'a', 'test'])
-
-# Only line breaks
-assert_eq('\n\n\n'.splitlines(), ['', '', ''])
-assert_eq('\r\r\r'.splitlines(), ['', '', ''])
-assert_eq('\n\r\n\r'.splitlines(), ['', '', ''])
-assert_eq('\r\n\r\n\r\n'.splitlines(), ['', '', ''])
-
-# Escaped sequences
-assert_eq('\n\\n\\\n'.splitlines(), ['', '\\n\\'])
-
-# KeepEnds
-assert_eq(''.splitlines(True), [])
-assert_eq('\n'.splitlines(True), ['\n'])
-assert_eq('this\nis\r\na\rtest'.splitlines(True), ['this\n', 'is\r\n', 'a\r', 'test'])
-assert_eq('\ntest'.splitlines(True), ['\n', 'test'])
-assert_eq('test\n'.splitlines(True), ['test\n'])
-assert_eq('\n\\n\\\n'.splitlines(True), ['\n', '\\n\\\n'])
diff --git a/starlark-test/tests/java-testcases/string_test_characters.sky b/starlark-test/tests/java-testcases/string_test_characters.sky
deleted file mode 100644
index df81d375..00000000
--- a/starlark-test/tests/java-testcases/string_test_characters.sky
+++ /dev/null
@@ -1,54 +0,0 @@
-# isalnum
-assert_eq(''.isalnum(), False)
-assert_eq('a0 33'.isalnum(), False)
-assert_eq('1'.isalnum(), True)
-assert_eq('a033'.isalnum(), True)
-
-# isdigit
-assert_eq(''.isdigit(), False)
-assert_eq(' '.isdigit(), False)
-assert_eq('a'.isdigit(), False)
-assert_eq('0234325.33'.isdigit(), False)
-assert_eq('1'.isdigit(), True)
-assert_eq('033'.isdigit(), True)
-
-# isspace
-assert_eq(''.isspace(), False)
-assert_eq('a'.isspace(), False)
-assert_eq('1'.isspace(), False)
-assert_eq('\ta\n'.isspace(), False)
-assert_eq(' '.isspace(), True)
-assert_eq('\t\n'.isspace(), True)
-
-# islower
-assert_eq(''.islower(), False)
-assert_eq(' '.islower(), False)
-assert_eq('1'.islower(), False)
-assert_eq('Almost'.islower(), False)
-assert_eq('abc'.islower(), True)
-assert_eq(' \nabc'.islower(), True)
-assert_eq('abc def\n'.islower(), True)
-assert_eq('\ta\n'.islower(), True)
-
-# isupper
-assert_eq(''.isupper(), False)
-assert_eq(' '.isupper(), False)
-assert_eq('1'.isupper(), False)
-assert_eq('aLMOST'.isupper(), False)
-assert_eq('ABC'.isupper(), True)
-assert_eq(' \nABC'.isupper(), True)
-assert_eq('ABC DEF\n'.isupper(), True)
-assert_eq('\tA\n'.isupper(), True)
-
-# istitle
-assert_eq(''.istitle(), False)
-assert_eq(' '.istitle(), False)
-assert_eq('134'.istitle(), False)
-assert_eq('almost Correct'.istitle(), False)
-assert_eq('1nope Nope Nope'.istitle(), False)
-assert_eq('NO Way'.istitle(), False)
-assert_eq('T'.istitle(), True)
-assert_eq('Correct'.istitle(), True)
-assert_eq('Very Correct! Yes\nIndeed1X'.istitle(), True)
-assert_eq('1234Ab Ab'.istitle(), True)
-assert_eq('\tA\n'.istitle(), True)
diff --git a/starlark-test/tests/java_conformance_tests.rs b/starlark-test/tests/java_conformance_tests.rs
deleted file mode 100644
index 63af21d1..00000000
--- a/starlark-test/tests/java_conformance_tests.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-use starlark_test::do_conformance_test;
-
-include!(concat!(env!("OUT_DIR"), "/tests/java-testcases.rs"));
diff --git a/starlark-test/tests/rust-testcases/bool.sky b/starlark-test/tests/rust-testcases/bool.sky
deleted file mode 100644
index 7dcc52c3..00000000
--- a/starlark-test/tests/rust-testcases/bool.sky
+++ /dev/null
@@ -1,7 +0,0 @@
-# Boolean tests
-
-True + 9223372036854775807 ### Type of parameters mismatch
----
-[] * True ### Type of parameters mismatch
----
-() * False ### Type of parameters mismatch
diff --git a/starlark-test/tests/rust-testcases/compr.sky b/starlark-test/tests/rust-testcases/compr.sky
deleted file mode 100644
index 608a9943..00000000
--- a/starlark-test/tests/rust-testcases/compr.sky
+++ /dev/null
@@ -1,8 +0,0 @@
-# Test for for comprehensions
-
-# Comprehension in comprehension
-a = [x for x in [y for y in range(3)]]
-assert_eq([0, 1, 2], a)
-
-b = [x for x in [0, 1, 2] if x]
-assert_eq([1, 2], b)
diff --git a/starlark-test/tests/rust-testcases/control.sky b/starlark-test/tests/rust-testcases/control.sky
deleted file mode 100644
index f8d3df39..00000000
--- a/starlark-test/tests/rust-testcases/control.sky
+++ /dev/null
@@ -1,20 +0,0 @@
-# `break` or `continue` cannot be used outside of loop
-# even if code is not executed (static error)
-def zzz():
- return
- break ### break cannot be used outside of loop
----
-def qqq():
- # note this is a parse time error
- [] += [] ### incorrect augmented assignment target
----
-def qqq():
- a = []
- (a,) += [[]] ### incorrect augmented assignment target
----
-def rrr():
- # note this is a parse time error
- [a, 1] = [3, 1] ### incorrect assignment target
----
-def rrr():
- (a, foo()) = [3, 1] ### incorrect assignment target
diff --git a/starlark-test/tests/rust-testcases/dict.sky b/starlark-test/tests/rust-testcases/dict.sky
deleted file mode 100644
index c3b46f34..00000000
--- a/starlark-test/tests/rust-testcases/dict.sky
+++ /dev/null
@@ -1,3 +0,0 @@
-# Dict tests
-
-{[]: 1 for x in [1]} ### Value is not hashable
diff --git a/starlark-test/tests/rust-testcases/freeze.sky b/starlark-test/tests/rust-testcases/freeze.sky
deleted file mode 100644
index 1cfd524d..00000000
--- a/starlark-test/tests/rust-testcases/freeze.sky
+++ /dev/null
@@ -1,36 +0,0 @@
-def two_iterations():
- l = [1]
- for x in l:
- # Second freeze of `l` must not fail
- for y in l:
- pass
-
- # Assert successfully unfrozen after two iterations
- l.append(2)
-
-two_iterations()
-
----
-
-def mutate_after_second_in_first():
- l = [1]
- for x in l:
- for y in l:
- pass
-
- # Test second iteration does not unfreeze
- l.append(2) ### Cannot mutate an iterable while iterating
-
-mutate_after_second_in_first()
-
----
-# test imported objects are frozen
-# file: imported.sky
-
-a = [[]]
-
-# file: main.sky
-
-load("imported.sky", "a")
-
-a[0].append(1) ### Cannot mutate value
diff --git a/starlark-test/tests/rust-testcases/inspect.sky b/starlark-test/tests/rust-testcases/inspect.sky
deleted file mode 100644
index 1a1610f2..00000000
--- a/starlark-test/tests/rust-testcases/inspect.sky
+++ /dev/null
@@ -1,2 +0,0 @@
-a = ""
-assert_("String" in inspect(a).rust_type_name)
diff --git a/starlark-test/tests/rust-testcases/int.sky b/starlark-test/tests/rust-testcases/int.sky
deleted file mode 100644
index 5d7ea1a7..00000000
--- a/starlark-test/tests/rust-testcases/int.sky
+++ /dev/null
@@ -1,28 +0,0 @@
-# Integer tests
-
-9223372036854775807 + 1 ### Integer overflow
----
--9223372036854775807 - 2 ### Integer overflow
----
-9223372036854775807 * 2 ### Integer overflow
----
-int_min = -9223372036854775807 - 1
--int_min ### Integer overflow
----
-int_min = -9223372036854775807 - 1
-int_min // -1 ### Integer overflow
----
-int_min = -9223372036854775807 - 1
-assert_eq(0, int_min % -1)
-assert_eq(0, int_min % int_min)
-assert_eq(9223372036854775806, int_min % 9223372036854775807)
-assert_eq(-1, 9223372036854775807 % int_min)
-
-
-# Issue #98
-assert_eq(4, 7 - 2 - 1)
-
-# Issue 152
-assert_eq(0, int("0", 8))
-assert_eq(0, int("-0", 8))
-assert_eq(0, int("+0", 8))
diff --git a/starlark-test/tests/rust-testcases/josharian_fuzzing.sky b/starlark-test/tests/rust-testcases/josharian_fuzzing.sky
deleted file mode 100644
index 1e1ef1e3..00000000
--- a/starlark-test/tests/rust-testcases/josharian_fuzzing.sky
+++ /dev/null
@@ -1,25 +0,0 @@
-# This file contains the list of example reported by https://github.com/josharian
-# as part of his fuzzing of starlark-rust
-
-# https://github.com/google/starlark-rust/issues/44: whitespace isn't required between some tokens
-assert_eq(6or(), 6)
-# 6burgle still generates a parse error.
-6burgle ### [CP01]
----
-# https://github.com/google/starlark-rust/issues/56: Non whitespace after 0 should be allowed.
-assert_eq(0in[1,2,3], False)
----
-# https://github.com/google/starlark-rust/issues/61: panic on bad range using string.index
-assert_eq('a'.find('', 1, 0), -1)
-assert_eq('a'.rfind('', 1, 0), -1)
-'a'.index('', 1, 0) ### [UF00]
----
-assert_eq('a'.find('', 1, 0), -1)
-assert_eq('a'.rfind('', 1, 0), -1)
-'a'.rindex('', 1, 0) ### [UF00]
----
-# https://github.com/google/starlark-rust/issues/64: alphabetize dir entries
-assert_eq(dir(""), sorted(dir("")))
----
-# https://github.com/google/starlark-rust/issues/66: / is only for floats (which we don't support)
-1 / 1 ### [CV00]
diff --git a/starlark-test/tests/rust-testcases/module.sky b/starlark-test/tests/rust-testcases/module.sky
deleted file mode 100644
index 4cb457b2..00000000
--- a/starlark-test/tests/rust-testcases/module.sky
+++ /dev/null
@@ -1,11 +0,0 @@
-# file: util.bzl
-
-def add_one(x):
- return x + 1
-
-# file: main.sky
-
-load("util.bzl", "add_one")
-
-assert_eq(5, add_one(4))
-
diff --git a/starlark-test/tests/rust-testcases/mutation_during_iteration.sky b/starlark-test/tests/rust-testcases/mutation_during_iteration.sky
deleted file mode 100644
index 0a101a3e..00000000
--- a/starlark-test/tests/rust-testcases/mutation_during_iteration.sky
+++ /dev/null
@@ -1,24 +0,0 @@
-# Test for disallowing mutation during iteration.
-# https://github.com/bazelbuild/starlark/blob/815aed90b552fa70adca4dc18d73082fae83b538/design.md#no-mutation-during-iteration
-a = [1, 2, 3]
-def fun():
- for x in a:
- a.append(1)
-
-fun() ### Cannot mutate an iterable while iterating
----
-def increment_values(dict):
- for k in dict:
- dict[k] += 1
-
-dict = {"one": 1, "two": 2}
-increment_values(dict) ### Cannot mutate an iterable while iterating
----
-# modifying deep content is allowed
-def modify_deep_content():
- list = [[0], [1], [2]]
- for x in list:
- list[x[0]][0] = 2 * x[0]
- return list
-assert_eq(modify_deep_content(), [[0], [2], [4]])
----
diff --git a/starlark-test/tests/rust-testcases/range.sky b/starlark-test/tests/rust-testcases/range.sky
deleted file mode 100644
index 929dd1e0..00000000
--- a/starlark-test/tests/rust-testcases/range.sky
+++ /dev/null
@@ -1,25 +0,0 @@
-# Range tests
-
-# Content matters, not how range is created
-assert_eq(range(1), range(0, -1, -1))
-
-assert_eq(list(range(10)), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
-assert_eq(list(range(3, 10)), [3, 4, 5, 6, 7, 8, 9])
-assert_eq(list(range(3, 10, 2)), [3, 5, 7, 9])
-assert_eq(list(range(10, 3, -2)), [10, 8, 6, 4])
-
-def f():
- # Largest possible range, can create, can't really do much with it
- r = range(-9223372036854775807-1, 9223372036854775807)
- l = []
- for x in r:
- l += [x]
- if len(l) == 3:
- break
- assert_eq([-9223372036854775807-1, -9223372036854775807, -9223372036854775807+1], l)
-f()
-
----
-len(range(-9223372036854775807-1, 9223372036854775807)) ### Integer overflow
----
-assert_eq(9223372036854775807, len(range(-9223372036854775807, 9223372036854775807, 2)))
diff --git a/starlark-test/tests/rust-testcases/regression.sky b/starlark-test/tests/rust-testcases/regression.sky
deleted file mode 100644
index 264a5bb1..00000000
--- a/starlark-test/tests/rust-testcases/regression.sky
+++ /dev/null
@@ -1,6 +0,0 @@
-# Regression for https://github.com/google/starlark-rust/issues/10
-"abc" * True ### Type of parameters mismatch
----
-# Make sure int * string works as well as string * int
-assert_eq(3 * "abc", "abcabcabc")
-assert_eq("abc" * 3, "abcabcabc")
\ No newline at end of file
diff --git a/starlark-test/tests/rust-testcases/string.sky b/starlark-test/tests/rust-testcases/string.sky
deleted file mode 100644
index ae5a2b24..00000000
--- a/starlark-test/tests/rust-testcases/string.sky
+++ /dev/null
@@ -1,19 +0,0 @@
-# String tests
-
-
-# From Starlark spec
-
-# The conversion's operand is the next element of args, which must be a tuple
-# with exactly one component per conversion,
-
-assert_eq("ab1cd2ef", "ab%scd%sef" % [1, 2])
-
-# ... unless the format string contains
-# only a single conversion, in which case args itself is its operand.
-assert_eq("ab[1]cd", "ab%scd" % [1])
-
-
-# Issue #43
-''%(0) ### The type 'int' is not iterable
----
-''%(0,) ### Too many arguments for format string
diff --git a/starlark-test/tests/rust-testcases/struct.sky b/starlark-test/tests/rust-testcases/struct.sky
deleted file mode 100644
index 135b71ed..00000000
--- a/starlark-test/tests/rust-testcases/struct.sky
+++ /dev/null
@@ -1,16 +0,0 @@
-# Struct tests
-
-# Comparison
-assert_(struct() == struct())
-assert_(struct(a=1) == struct(a=1))
-assert_(struct(a=1, b=False) == struct(a=1, b=False))
-
-# Order of fields is not important for comparison
-assert_(struct(a=1, b=2) == struct(b=2, a=1))
-
-# Inequality
-assert_(struct(a=2) != struct())
-assert_(struct() != struct(a=2))
-assert_(struct(a=2) != struct(a=1))
-assert_(struct(a=2) != struct(b=1))
-assert_(struct(a=1, b=2) != struct(a=1, b="2"))
diff --git a/starlark-test/tests/rust_tests.rs b/starlark-test/tests/rust_tests.rs
deleted file mode 100644
index f822a10d..00000000
--- a/starlark-test/tests/rust_tests.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-use starlark_test::do_conformance_test;
-
-include!(concat!(env!("OUT_DIR"), "/tests/rust-testcases.rs"));
diff --git a/starlark/Cargo.toml b/starlark/Cargo.toml
deleted file mode 100644
index 3051591c..00000000
--- a/starlark/Cargo.toml
+++ /dev/null
@@ -1,37 +0,0 @@
-[package]
-name = "starlark"
-edition = "2018"
-version = "0.3.2-pre"
-authors = [
- "Damien Martin-Guillerez ",
- "Stepan Koltsov ",
-]
-build = "build.rs"
-
-description = "An implementation in Rust of the Starlark language."
-documentation = "https://docs.rs/crate/starlark"
-homepage = "https://github.com/google/starlark-rust"
-repository = "https://github.com/google/starlark-rust"
-readme = "README.md"
-keywords = ["starlark", "skylark", "bazel", "language", "interpreter"]
-categories = ["development-tools"]
-license = "Apache-2.0"
-
-[badges]
-travis-ci = { repository = "google/starlark-rust", branch = "master" }
-maintenance = { status = "passively-maintained" }
-
-[build-dependencies]
-lalrpop = "0.19.2"
-
-[dependencies]
-codemap = "0.1.1"
-codemap-diagnostic = "0.1.1"
-lalrpop-util = "0.19.2"
-linked-hash-map = "0.5.1"
-
-[lib]
-bench = false
-
-[features]
-trace = []
diff --git a/starlark/LICENSE b/starlark/LICENSE
deleted file mode 100644
index d6456956..00000000
--- a/starlark/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/starlark/README.md b/starlark/README.md
deleted file mode 100644
index 9c8cc434..00000000
--- a/starlark/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Starlark in Rust
-_An implementation in Rust of the Starlark language_
-
-[Starlark](https://github.com/bazelbuild/starlark), formerly codenamed Skylark, is a non-Turing
-complete language based on Python that was made for the [Bazel build system](https://bazel.build) to
-define compilation plugin.
-
-Starlark has at least 3 implementations: a [Java one for Bazel](
-https://github.com/bazelbuild/bazel/tree/master/src/main/java/com/google/devtools/skylark),
-a [Go one](https://github.com/google/skylark) and this one.
-
-This interpreter was made using the [specification from the go version](
-https://github.com/google/skylark/blob/a0e5de7e63b47e716cca7226662a4c95d47bf873/doc/spec.md)
-and the Python 3 documentation when things were unclear.
-
-This interpreter does not support most of the go extensions (e.g. bitwise
-operator or floating point). It does not include the `set()` type either ([the
-official Starlark specification](https://github.com/bazelbuild/starlark/blob/master/spec.md)
-does not have them either). It uses signed 64-bit integers.
diff --git a/starlark/build.rs b/starlark/build.rs
deleted file mode 100644
index 83cf06ef..00000000
--- a/starlark/build.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-extern crate lalrpop;
-
-fn main() {
- lalrpop();
-}
-
-fn lalrpop() {
- // A test
- println!("cargo:rerun-if-changed=src/syntax/grammar.lalrpop");
- lalrpop::Configuration::new()
- .use_cargo_dir_conventions()
- .always_use_colors()
- .emit_report(true)
- .process_file("src/syntax/grammar.lalrpop")
- .unwrap();
-}
diff --git a/starlark/examples/starlark-simple-cli.rs b/starlark/examples/starlark-simple-cli.rs
deleted file mode 100644
index 574a47fd..00000000
--- a/starlark/examples/starlark-simple-cli.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! An example binary demonstrating how to use the starlark-rust crate.
-//!
-//! This program demonstrates how to set up a `codemap` and `Environment` required for
-//! `eval()`, as well as how to use [values](values) returned by `eval()`. It accepts
-//! a Starlark program on standard input and prints the result if the result is a string.
-
-extern crate codemap;
-extern crate codemap_diagnostic;
-extern crate starlark;
-
-use std::io::{self, Read};
-use std::process::exit;
-use std::sync::{Arc, Mutex};
-
-use codemap_diagnostic::{ColorConfig, Emitter};
-use starlark::eval::simple::eval;
-use starlark::stdlib::global_environment;
-use starlark::syntax::dialect::Dialect;
-
-pub fn simple_evaluation(starlark_input: &String) -> Result {
- // Create a new global environment populated with the stdlib.
- let (global_env, type_values) = global_environment();
- // Extra symbols can be added to the global environment before freezing if desired.
- global_env.freeze();
- // Create our own local copy of the global environment.
- let mut env = global_env.child("simple-cli");
-
- // Create a codemap to record the raw source of all code executed, including code
- // introduced by a Starlark load() call.
- let map = Arc::new(Mutex::new(codemap::CodeMap::new()));
-
- // We don't have a filename since we're not reading from a file, so call it "stdin".
- let result = eval(
- &map,
- "stdin",
- &starlark_input,
- Dialect::Bzl,
- &mut env,
- &type_values,
- global_env.clone(),
- );
-
- match result {
- Ok(res) => match res.get_type() {
- "string" => Ok(res.to_str()),
- _ => Err(format!(
- "Error interpreting '{}': result must be string! (was {})",
- starlark_input,
- res.get_type()
- )),
- },
- Err(diagnostic) => {
- // Get the lock to the codemap and unlock it so we can use it.
- let cloned_map_lock = Arc::clone(&map);
- let unlocked_map = cloned_map_lock.lock().unwrap();
-
- // Emit code diagnostic information to standard error.
- Emitter::stderr(ColorConfig::Always, Some(&unlocked_map)).emit(&[diagnostic]);
- Err(format!("Error interpreting '{}'", starlark_input))
- }
- }
-}
-
-fn main() {
- let mut starlark_input = String::new();
- io::stdin()
- .read_to_string(&mut starlark_input)
- .expect("Error reading from stdin");
- let starlark_input = starlark_input.trim().to_owned();
-
- match simple_evaluation(&starlark_input) {
- Ok(result_string) => println!("{}", result_string),
- Err(error_string) => {
- println!("{}", error_string);
- exit(2);
- }
- }
-}
diff --git a/starlark/src/environment/mod.rs b/starlark/src/environment/mod.rs
deleted file mode 100644
index 3e75c262..00000000
--- a/starlark/src/environment/mod.rs
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! The enviroment, called "Module" in [this spec](
-//! https://github.com/google/skylark/blob/a0e5de7e63b47e716cca7226662a4c95d47bf873/doc/spec.md)
-//! is the list of variable in the current scope. It can be frozen, after which all values from
-//! this environment become immutable.
-
-use crate::values::cell::error::ObjectBorrowMutError;
-use crate::values::cell::ObjectCell;
-use crate::values::error::{RuntimeError, ValueError};
-use crate::values::string::rc::RcString;
-use crate::values::*;
-use std::collections::HashMap;
-use std::rc::Rc;
-
-// TODO: move that code in some common error code list?
-// CM prefix = Critical Module
-const __RESERVED_CM00: &str = "CM00";
-const NOT_FOUND_ERROR_CODE: &str = "CM01";
-const LOCAL_VARIABLE_REFERENCED_BEFORE_ASSIGNMENT: &str = "CM03";
-pub(crate) const LOAD_NOT_SUPPORTED_ERROR_CODE: &str = "CM02";
-const CANNOT_IMPORT_ERROR_CODE: &str = "CE02";
-const BORROW_ERROR_CODE: &str = "CE03";
-
-#[derive(Debug)]
-#[doc(hidden)]
-pub enum EnvironmentError {
- /// Variables was no found.
- VariableNotFound(String),
- LocalVariableReferencedBeforeAssignment(String),
- /// Cannot import private symbol, i.e. underscore prefixed
- CannotImportPrivateSymbol(String),
- BorrowMut(ObjectBorrowMutError),
-}
-
-impl From for EnvironmentError {
- fn from(e: ObjectBorrowMutError) -> EnvironmentError {
- EnvironmentError::BorrowMut(e)
- }
-}
-
-impl Into for EnvironmentError {
- fn into(self) -> RuntimeError {
- RuntimeError {
- code: match self {
- EnvironmentError::VariableNotFound(..) => NOT_FOUND_ERROR_CODE,
- EnvironmentError::CannotImportPrivateSymbol(..) => CANNOT_IMPORT_ERROR_CODE,
- EnvironmentError::LocalVariableReferencedBeforeAssignment(..) => {
- LOCAL_VARIABLE_REFERENCED_BEFORE_ASSIGNMENT
- }
- EnvironmentError::BorrowMut(..) => BORROW_ERROR_CODE,
- },
- label: match self {
- EnvironmentError::VariableNotFound(..) => "Variable was not found".to_owned(),
- EnvironmentError::LocalVariableReferencedBeforeAssignment(..) => {
- "Local variable referenced before assignment".to_owned()
- }
- EnvironmentError::CannotImportPrivateSymbol(ref s) => {
- format!("Symbol '{}' is private", s)
- }
- EnvironmentError::BorrowMut(ref e) => format!("{}", e),
- },
- message: match self {
- EnvironmentError::VariableNotFound(s) => format!("Variable '{}' not found", s),
- EnvironmentError::LocalVariableReferencedBeforeAssignment(ref s) => {
- format!("Local variable '{}' referenced before assignment", s)
- }
- EnvironmentError::CannotImportPrivateSymbol(s) => {
- format!("Cannot import private symbol '{}'", s)
- }
- EnvironmentError::BorrowMut(ref e) => {
- format!("Cannot borrow environment mutably: {}", e)
- }
- },
- }
- }
-}
-
-impl From for ValueError {
- fn from(e: EnvironmentError) -> Self {
- ValueError::Runtime(e.into())
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct Environment {
- env: Rc>,
-}
-
-#[derive(Debug)]
-struct EnvironmentContent {
- /// A name for this environment, used mainly for debugging.
- name_: RcString,
- /// Super environment that represent a higher scope than the current one
- parent: Option,
- /// List of variable bindings
- ///
- /// These bindings include methods for native types, e.g. `string.isalnum`.
- variables: HashMap,
- /// When `true`, set `{foo, bar}` literals are allowed.
- set_literals: bool,
-}
-
-impl Environment {
- /// Create a new environment
- pub fn new(name: &str) -> Environment {
- Environment {
- env: Rc::new(ObjectCell::new_mutable(EnvironmentContent {
- name_: name.into(),
- parent: None,
- variables: HashMap::new(),
- set_literals: false,
- })),
- }
- }
-
- /// Create a new child environment for this environment
- pub fn child(&self, name: &str) -> Environment {
- self.freeze();
- Environment {
- env: Rc::new(ObjectCell::new_mutable(EnvironmentContent {
- name_: name.into(),
- parent: Some(self.clone()),
- variables: HashMap::new(),
- set_literals: self.env.borrow().set_literals,
- })),
- }
- }
-
- /// Create a new child environment
- /// Freeze the environment, all its value will become immutable after that
- pub fn freeze(&self) -> &Self {
- if !self.env.get_header_copy().is_mutable_frozen() {
- self.env.borrow_mut().freeze();
- self.env.freeze();
- }
- self
- }
-
- /// Return the name of this module
- pub fn name(&self) -> RcString {
- self.env.borrow().name_.clone()
- }
-
- /// Set the value of a variable in that environment.
- pub fn set(&self, name: &str, value: Value) -> Result<(), EnvironmentError> {
- self.env.try_borrow_mut()?.set(name, value)
- }
-
- /// Get the value of the variable `name`
- pub fn get(&self, name: &str) -> Result {
- self.env.borrow().get(name)
- }
-
- pub fn import_symbol(
- &self,
- env: &Environment,
- symbol: &str,
- new_name: &str,
- ) -> Result<(), EnvironmentError> {
- let first = symbol.chars().next();
- match first {
- Some('_') | None => Err(EnvironmentError::CannotImportPrivateSymbol(
- symbol.to_owned(),
- )),
- _ => self.set(new_name, env.get(symbol)?),
- }
- }
-
- /// Return the parent environment (or `None` if there is no parent).
- pub fn get_parent(&self) -> Option {
- self.env.borrow().get_parent()
- }
-
- /// Set the function which will be used to instantiate set literals encountered when evaluating
- /// in this `Environment`. Set literals are {}s with one or more elements between, separated by
- /// commas, e.g. `{1, 2, "three"}`.
- ///
- /// If this function is not called on the `Environment`, its parent's set constructor will be
- /// used when set literals are encountered. If neither this `Environment`, nor any of its
- /// transitive parents, have a set constructor defined, attempts to evaluate set literals will
- /// raise and error.
- ///
- /// The `Value` returned by this function is expected to be a one-dimensional collection
- /// containing no duplicates.
- pub fn enable_set_literals(&self) {
- self.env.borrow_mut().set_literals = true;
- }
-
- /// Is it OK to have set literals?
- pub(crate) fn set_literals_emabled(&self) -> bool {
- self.env.borrow().set_literals
- }
-}
-
-impl EnvironmentContent {
- /// Create a new child environment
- /// Freeze the environment, all its value will become immutable after that
- pub fn freeze(&mut self) {
- for v in self.variables.values_mut() {
- v.freeze();
- }
- }
-
- /// Set the value of a variable in that environment.
- pub fn set(&mut self, name: &str, value: Value) -> Result<(), EnvironmentError> {
- self.variables.insert(name.to_string(), value);
- Ok(())
- }
-
- /// Get the value of the variable `name`
- pub fn get(&self, name: &str) -> Result {
- if self.variables.contains_key(name) {
- Ok(self.variables[name].clone())
- } else {
- match self.parent {
- Some(ref p) => p.get(name),
- None => Err(EnvironmentError::VariableNotFound(name.to_owned())),
- }
- }
- }
-
- /// Return the parent environment (or `None` if there is no parent).
- pub fn get_parent(&self) -> Option {
- self.parent.clone()
- }
-}
-
-/// Environment passed to `call` calls.
-///
-/// Function implementations are only allowed to access
-/// type values from "type values" from the caller context,
-/// so this struct is passed instead of full `Environment`.
-#[derive(Clone, Default, Debug)]
-pub struct TypeValues {
- /// List of static values of an object per type
- type_objs: HashMap>,
-}
-
-impl TypeValues {
- /// Get a type value if it exists (e.g. list.index).
- pub fn get_type_value(&self, obj: &Value, id: &str) -> Option {
- self.type_objs
- .get(obj.get_type())
- .and_then(|o| o.get(id))
- .cloned()
- }
-
- /// List the attribute of a type
- pub fn list_type_value(&self, obj: &Value) -> Vec {
- self.type_objs
- .get(obj.get_type())
- .into_iter()
- .flat_map(|o| o.keys().cloned())
- .collect()
- }
-
- /// Get the object of type `obj_type`, and create it if none exists
- pub fn add_type_value(&mut self, obj: &str, attr: &str, value: Value) {
- if let Some(ref mut v) = self.type_objs.get_mut(obj) {
- v.insert(attr.into(), value);
- } else {
- let mut dict = HashMap::new();
- dict.insert(attr.into(), value);
- self.type_objs.insert(obj.into(), dict);
- }
- }
-}
diff --git a/starlark/src/eval/call_stack.rs b/starlark/src/eval/call_stack.rs
deleted file mode 100644
index 6da56b44..00000000
--- a/starlark/src/eval/call_stack.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-//! Starlark call stack.
-
-use crate::values::error::ValueError;
-use crate::values::{FunctionId, Value};
-use codemap::{CodeMap, Pos};
-use std::cell::Cell;
-use std::fmt;
-use std::sync::{Arc, Mutex};
-
-#[derive(Clone)]
-struct Frame(Value, Arc>, Pos);
-
-impl fmt::Debug for Frame {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_tuple("Frame").field(&self.0).finish()
- }
-}
-
-/// Starlark call stack. Used internally, opague for the public API.
-// TODO: unimplement `Clone`, `Default`, users do not need to be able to create stacks
-#[derive(Clone, Debug, Default)]
-pub struct CallStack {
- stack: Vec ,
-}
-
-impl CallStack {
- /// Push an element to the stack
- pub(crate) fn push(&mut self, function: Value, code_map: Arc>, pos: Pos) {
- self.stack.push(Frame(function, code_map, pos));
- }
-
- /// Pop an element from the stack, panic if stack is already empty.
- pub(crate) fn pop(&mut self) {
- self.stack.pop().unwrap();
- }
-
- /// Test if call stack contains a function with given id.
- pub(crate) fn contains(&self, function_id: FunctionId) -> bool {
- self.stack
- .iter()
- .any(|&Frame(ref f, _, _)| f.function_id() == function_id)
- }
-
- /// Print call stack as multiline string
- /// with each line beginning with newline.
- pub(crate) fn print_with_newline_before<'a>(&'a self) -> impl fmt::Display + 'a {
- DisplayWithNewlineBefore { call_stack: self }
- }
-}
-
-struct DisplayWithNewlineBefore<'a> {
- call_stack: &'a CallStack,
-}
-
-impl<'a> fmt::Display for DisplayWithNewlineBefore<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- for Frame(function, code_map, pos) in self.call_stack.stack.iter().rev() {
- let loc = { code_map.lock().unwrap().look_up_pos(*pos) };
- write!(
- f,
- "\n call to {} at {}:{}",
- function.to_str(),
- loc.file.name(),
- loc.position.line + 1, // line 1 is 0, so add 1 for human readable.
- )?;
- }
- Ok(())
- }
-}
-
-// Maximum recursion level for comparison
-// TODO(dmarting): those are rather short, maybe make it configurable?
-#[cfg(debug_assertions)]
-const MAX_RECURSION: u32 = 200;
-
-#[cfg(not(debug_assertions))]
-const MAX_RECURSION: u32 = 3000;
-
-// A thread-local counter is used to detect too deep recursion.
-//
-// Thread-local is chosen instead of explicit function "recursion" parameter
-// for two reasons:
-// * It's possible to propagate stack depth across external functions like
-// `Display::to_string` where passing a stack depth parameter is hard
-// * We need to guarantee that stack depth is not lost in complex invocation
-// chains like function calls compare which calls native function which calls
-// starlark function which calls to_str. We could change all evaluation stack
-// signatures to accept some "context" parameters, but passing it as thread-local
-// is easier.
-thread_local!(static STACK_DEPTH: Cell = Cell::new(0));
-
-/// Stored previous stack depth before calling `try_inc`.
-///
-/// Stores that previous stack depths back to thread-local on drop.
-#[must_use]
-pub struct StackGuard {
- prev_depth: u32,
-}
-
-impl Drop for StackGuard {
- fn drop(&mut self) {
- STACK_DEPTH.with(|c| c.set(self.prev_depth));
- }
-}
-
-/// Increment stack depth.
-fn inc() -> StackGuard {
- let prev_depth = STACK_DEPTH.with(|c| {
- let prev = c.get();
- c.set(prev + 1);
- prev
- });
- StackGuard { prev_depth }
-}
-
-/// Check stack depth does not exceed configured max stack depth.
-fn check() -> Result<(), ValueError> {
- if STACK_DEPTH.with(Cell::get) >= MAX_RECURSION {
- return Err(ValueError::TooManyRecursionLevel);
- }
- Ok(())
-}
-
-/// Try increment stack depth.
-///
-/// Return opaque `StackGuard` object which resets stack to previous value
-/// on `drop`.
-///
-/// If stack depth exceeds configured limit, return error.
-pub fn try_inc() -> Result {
- check()?;
- Ok(inc())
-}
diff --git a/starlark/src/eval/compiler.rs b/starlark/src/eval/compiler.rs
deleted file mode 100644
index 96a096a5..00000000
--- a/starlark/src/eval/compiler.rs
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Utilities for translation of AST into interpreter-friendly data structures
-
-use crate::eval::expr::AssignTargetExprCompiled;
-use crate::eval::expr::AstClauseCompiled;
-use crate::eval::expr::AstGlobalOrSlot;
-use crate::eval::expr::ClauseCompiled;
-use crate::eval::expr::ExprCompiled;
-use crate::eval::expr::ExprLocal;
-use crate::eval::expr::GlobalOrSlot;
-use crate::eval::globals::Globals;
-use crate::eval::locals::LocalsBuilder;
-use crate::eval::locals::LocalsQuery;
-use crate::syntax::ast::AstClause;
-use crate::syntax::ast::AstExpr;
-use crate::syntax::ast::AstString;
-use crate::syntax::ast::Clause;
-use crate::syntax::ast::Expr;
-use codemap::Span;
-use codemap::Spanned;
-use codemap_diagnostic::Diagnostic;
-
-/// Encapsulate differences between compilation of module scope vs
-/// function or comprehension scope
-pub(crate) trait LocalOrGlobalCompiler {
- /// Resolve identifier to either local slot or global name
- fn ident(&mut self, ident: AstString) -> GlobalOrSlot;
-
- fn ast_ident(&mut self, ident: AstString) -> AstGlobalOrSlot {
- Spanned {
- span: ident.span,
- node: self.ident(ident),
- }
- }
-
- /// Compile list comprehension
- fn list_comprenesion(
- &mut self,
- span: Span,
- expr: AstExpr,
- clauses: Vec,
- ) -> Result;
- /// Compile set comprehension
- fn set_comprenesion(
- &mut self,
- span: Span,
- expr: AstExpr,
- clauses: Vec,
- ) -> Result;
- /// Compile dict comprehension
- fn dict_comprenesion(
- &mut self,
- span: Span,
- key: AstExpr,
- value: AstExpr,
- clauses: Vec,
- ) -> Result;
-}
-
-pub(crate) struct LocalCompiler<'a> {
- locals_query: &'a mut LocalsQuery<'a>,
-}
-
-impl<'a> LocalCompiler<'a> {
- pub fn new(locals_query: &'a mut LocalsQuery<'a>) -> LocalCompiler<'a> {
- LocalCompiler { locals_query }
- }
-}
-
-impl<'a> LocalCompiler<'a> {
- fn compile_clauses(&mut self, clauses: Vec, expr: E) -> Result
- where
- E: FnOnce(Vec, &mut LocalCompiler) -> Result,
- {
- let mut transformed_clauses = Vec::new();
- let mut scope_count = 0;
- for clause in clauses {
- transformed_clauses.push(Spanned {
- span: clause.span,
- node: match clause.node {
- Clause::If(expr) => ClauseCompiled::If(ExprCompiled::compile(expr, self)?),
- Clause::For(target, expr) => {
- let expr = ExprCompiled::compile(expr, self)?;
- self.locals_query.push_next_scope();
- scope_count += 1;
- let target = AssignTargetExprCompiled::compile(target, self)?;
- ClauseCompiled::For(target, expr)
- }
- },
- });
- }
- let r = expr(transformed_clauses, self)?;
- for _ in 0..scope_count {
- self.locals_query.pop_scope();
- }
- Ok(r)
- }
-}
-
-impl<'a> LocalOrGlobalCompiler for LocalCompiler<'a> {
- fn ident(&mut self, ident: AstString) -> GlobalOrSlot {
- let (slot, local) = self.locals_query.slot(&ident.node);
- GlobalOrSlot {
- name: ident.node,
- local,
- slot,
- }
- }
-
- fn list_comprenesion(
- &mut self,
- _span: Span,
- expr: AstExpr,
- clauses: Vec,
- ) -> Result {
- self.compile_clauses(clauses, |clauses, compiler| {
- let expr = ExprCompiled::compile(expr, compiler)?;
- Ok(ExprCompiled::ListComprehension(expr, clauses))
- })
- }
-
- fn set_comprenesion(
- &mut self,
- _span: Span,
- expr: AstExpr,
- clauses: Vec,
- ) -> Result {
- self.compile_clauses(clauses, |clauses, compiler| {
- let expr = ExprCompiled::compile(expr, compiler)?;
- Ok(ExprCompiled::SetComprehension(expr, clauses))
- })
- }
-
- fn dict_comprenesion(
- &mut self,
- _span: Span,
- key: AstExpr,
- value: AstExpr,
- clauses: Vec,
- ) -> Result {
- self.compile_clauses(clauses, |clauses, compiler| {
- let key = ExprCompiled::compile(key, compiler)?;
- let value = ExprCompiled::compile(value, compiler)?;
- Ok(ExprCompiled::DictComprehension((key, value), clauses))
- })
- }
-}
-
-pub(crate) struct GlobalCompiler<'a> {
- globals: &'a mut Globals,
-}
-
-impl<'a> GlobalCompiler<'a> {
- pub fn new(globals: &'a mut Globals) -> GlobalCompiler<'a> {
- GlobalCompiler { globals }
- }
-
- fn compile_comprehension_in_global_scope(
- &mut self,
- expr: AstExpr,
- ) -> Result {
- let mut locals_builder = LocalsBuilder::default();
-
- Expr::collect_locals(&expr, &mut locals_builder);
-
- let locals = locals_builder.build();
- // Note we are using private global index for comprehensions
- let mut globals = Globals::default();
-
- let mut locals_query = LocalsQuery::new(&locals, &mut globals);
-
- let expr = ExprCompiled::compile_local(expr, &mut locals_query)?;
-
- Ok(ExprCompiled::Local(ExprLocal {
- expr,
- locals,
- globals,
- }))
- }
-}
-
-impl<'a> LocalOrGlobalCompiler for GlobalCompiler<'a> {
- fn ident(&mut self, ident: AstString) -> GlobalOrSlot {
- GlobalOrSlot {
- slot: self.globals.register_global(&ident.node),
- name: ident.node,
- local: false,
- }
- }
- fn list_comprenesion(
- &mut self,
- span: Span,
- expr: AstExpr,
- clauses: Vec,
- ) -> Result {
- self.compile_comprehension_in_global_scope(Box::new(Spanned {
- span,
- node: Expr::ListComprehension(expr, clauses),
- }))
- }
-
- fn set_comprenesion(
- &mut self,
- span: Span,
- expr: AstExpr,
- clauses: Vec,
- ) -> Result {
- self.compile_comprehension_in_global_scope(Box::new(Spanned {
- span,
- node: Expr::SetComprehension(expr, clauses),
- }))
- }
-
- fn dict_comprenesion(
- &mut self,
- span: Span,
- key: AstExpr,
- value: AstExpr,
- clauses: Vec,
- ) -> Result {
- self.compile_comprehension_in_global_scope(Box::new(Spanned {
- span,
- node: Expr::DictComprehension((key, value), clauses),
- }))
- }
-}
diff --git a/starlark/src/eval/compr.rs b/starlark/src/eval/compr.rs
deleted file mode 100644
index d0d97d29..00000000
--- a/starlark/src/eval/compr.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! List/dict/set comprenension evaluation.
-
-use crate::eval::eval_expr;
-use crate::eval::expr::AstClauseCompiled;
-use crate::eval::expr::ClauseCompiled;
-use crate::eval::set_expr;
-use crate::eval::t;
-use crate::eval::EvalException;
-use crate::values::context::EvaluationContext;
-use crate::values::context::EvaluationContextEnvironment;
-
-pub(crate) fn eval_one_dimensional_comprehension<
- E: EvaluationContextEnvironment,
- F: FnMut(&mut EvaluationContext) -> Result<(), EvalException>,
->(
- expr: &mut F,
- clauses: &[AstClauseCompiled],
- context: &mut EvaluationContext,
-) -> Result<(), EvalException> {
- if let Some((first, tl)) = clauses.split_first() {
- match &first.node {
- ClauseCompiled::If(ref cond) => {
- if !eval_expr(cond, context)?.to_bool() {
- return Ok(());
- }
- eval_one_dimensional_comprehension(expr, tl, context)
- }
- ClauseCompiled::For(ref var, ref iter) => {
- let iterable = eval_expr(iter, context)?;
- for item in &t(iterable.iter(), iter)? {
- set_expr(var, context, item)?;
-
- eval_one_dimensional_comprehension(expr, tl, context)?;
- }
-
- Ok(())
- }
- }
- } else {
- expr(context)
- }
-}
diff --git a/starlark/src/eval/def.rs b/starlark/src/eval/def.rs
deleted file mode 100644
index 12ac3353..00000000
--- a/starlark/src/eval/def.rs
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Implementation of `def`.
-
-use crate::environment::{Environment, TypeValues};
-use crate::eval::call_stack::CallStack;
-use crate::eval::compiler::LocalCompiler;
-use crate::eval::eval_block;
-use crate::eval::expr::AstExprCompiled;
-use crate::eval::expr::ExprCompiled;
-use crate::eval::globals::Globals;
-use crate::eval::locals::Locals;
-use crate::eval::locals::LocalsBuilder;
-use crate::eval::locals::LocalsQuery;
-use crate::eval::stmt::BlockCompiled;
-use crate::eval::EvalException;
-use crate::eval::EvaluationContext;
-use crate::eval::EvaluationContextEnvironment;
-use crate::eval::IndexedGlobals;
-use crate::eval::IndexedLocals;
-use crate::stdlib::structs::StarlarkStruct;
-use crate::syntax::ast::AssignTargetExpr;
-use crate::syntax::ast::AstParameter;
-use crate::syntax::ast::AstStatement;
-use crate::syntax::ast::AstString;
-use crate::syntax::ast::AugmentedAssignTargetExpr;
-use crate::syntax::ast::Expr;
-use crate::syntax::ast::Parameter;
-use crate::syntax::ast::Statement;
-use crate::values::context::EvaluationContextEnvironmentLocal;
-use crate::values::error::ValueError;
-use crate::values::function;
-use crate::values::function::FunctionParameter;
-use crate::values::function::FunctionSignature;
-use crate::values::function::FunctionType;
-use crate::values::function::StrOrRepr;
-use crate::values::inspect::Inspectable;
-use crate::values::none::NoneType;
-use crate::values::string::rc::RcString;
-use crate::values::Immutable;
-use crate::values::TypedValue;
-use crate::values::Value;
-use crate::values::ValueOther;
-use crate::values::ValueResult;
-use codemap::CodeMap;
-use codemap::Spanned;
-use codemap_diagnostic::Diagnostic;
-use linked_hash_map::LinkedHashMap;
-use std::convert::TryInto;
-use std::fmt;
-use std::iter;
-use std::sync::{Arc, Mutex};
-
-#[derive(Debug, Clone)]
-pub(crate) enum ParameterCompiled {
- Normal(AstString),
- WithDefaultValue(AstString, AstExprCompiled),
- Args(AstString),
- KWArgs(AstString),
-}
-pub(crate) type AstParameterCompiled = Spanned;
-
-impl ParameterCompiled {
- fn compile(
- param: AstParameter,
- globals: &mut Globals,
- ) -> Result {
- Ok(Spanned {
- span: param.span,
- node: match param.node {
- Parameter::Normal(n) => ParameterCompiled::Normal(n),
- Parameter::WithDefaultValue(n, d) => ParameterCompiled::WithDefaultValue(
- n,
- ExprCompiled::compile_global(d, globals)?,
- ),
- Parameter::Args(args) => ParameterCompiled::Args(args),
- Parameter::KWArgs(args) => ParameterCompiled::KWArgs(args),
- },
- })
- }
-}
-
-/// `def` AST with post-processing suitable for faster excecution
-#[doc(hidden)]
-#[derive(Debug, Clone)]
-pub struct DefCompiled {
- pub(crate) name: AstString,
- pub(crate) slot: usize,
- pub(crate) params: Vec,
- pub(crate) suite: BlockCompiled,
- locals: Locals,
- globals: Globals,
-}
-
-impl DefCompiled {
- pub fn new(
- name: AstString,
- slot: usize,
- params: Vec,
- suite: AstStatement,
- ) -> Result {
- let mut locals_builder = LocalsBuilder::default();
- let mut globals = Globals::default();
-
- for p in ¶ms {
- locals_builder.register_local(p.name());
- }
-
- let params = params
- .into_iter()
- .map(|p| ParameterCompiled::compile(p, &mut globals))
- .collect::>()?;
-
- DefCompiled::collect_locals(&suite, &mut locals_builder);
-
- let locals = locals_builder.build();
-
- let mut locals_query = LocalsQuery::new(&locals, &mut globals);
-
- let mut local_compiler = LocalCompiler::new(&mut locals_query);
-
- let suite = BlockCompiled::compile_local(suite, &mut local_compiler)?;
-
- Ok(DefCompiled {
- name,
- slot,
- params,
- suite,
- locals,
- globals,
- })
- }
-
- fn collect_locals(stmt: &AstStatement, locals_builder: &mut LocalsBuilder) {
- match stmt.node {
- Statement::Assign(ref dest, ref source) => {
- AssignTargetExpr::collect_locals_from_assign_expr(dest, locals_builder);
- Expr::collect_locals(source, locals_builder);
- }
- Statement::AugmentedAssign(ref dest, _op, ref source) => {
- AugmentedAssignTargetExpr::collect_locals_from_assign_expr(dest, locals_builder);
- Expr::collect_locals(source, locals_builder);
- }
- Statement::For(ref dest, ref iter, ref body) => {
- AssignTargetExpr::collect_locals_from_assign_expr(dest, locals_builder);
- Expr::collect_locals(iter, locals_builder);
- DefCompiled::collect_locals(body, locals_builder);
- }
- Statement::Statements(ref stmts) => {
- for stmt in stmts {
- DefCompiled::collect_locals(stmt, locals_builder);
- }
- }
- Statement::If(ref cond, ref then_block) => {
- Expr::collect_locals(cond, locals_builder);
- DefCompiled::collect_locals(then_block, locals_builder);
- }
- Statement::IfElse(ref cond, ref then_block, ref else_block) => {
- Expr::collect_locals(cond, locals_builder);
- DefCompiled::collect_locals(then_block, locals_builder);
- DefCompiled::collect_locals(else_block, locals_builder);
- }
- Statement::Return(ref expr) => {
- if let Some(expr) = expr {
- Expr::collect_locals(expr, locals_builder);
- }
- }
- Statement::Expression(ref expr) => {
- Expr::collect_locals(expr, locals_builder);
- }
- Statement::Break | Statement::Continue | Statement::Pass => {}
- Statement::Load(..) | Statement::Def(..) => unreachable!(),
- }
- }
-}
-
-impl Inspectable for DefCompiled {
- fn inspect(&self) -> Value {
- let mut fields = LinkedHashMap::::new();
- fields.insert("name".into(), self.name.node.clone().into());
- fields.insert("locals".into(), self.locals.inspect());
- fields.insert("suite".into(), self.suite.inspect());
- Value::new(StarlarkStruct::new(fields))
- }
-}
-
-/// Starlark function internal representation and implementation of [`TypedValue`].
-pub(crate) struct Def {
- signature: FunctionSignature,
- function_type: FunctionType,
- captured_env: Environment,
- map: Arc>,
- stmt: DefCompiled,
-}
-
-impl Def {
- pub fn new(
- module: RcString,
- signature: FunctionSignature,
- stmt: DefCompiled,
- map: Arc>,
- env: Environment,
- ) -> ValueOther {
- // This can be implemented by delegating to `Function::new`,
- // but having a separate type allows slight more efficient implementation
- // and optimizations in the future.
- ValueOther::new(Def {
- function_type: FunctionType::Def(stmt.name.node.clone(), module),
- signature,
- stmt,
- captured_env: env,
- map,
- })
- }
-}
-
-impl TypedValue for Def {
- type Holder = Immutable;
-
- const TYPE: &'static str = "function";
-
- fn values_for_descendant_check_and_freeze<'a>(
- &'a self,
- ) -> Box + 'a> {
- Box::new(iter::empty())
- }
-
- fn to_str_impl(&self, buf: &mut String) -> fmt::Result {
- function::str_impl(buf, &self.function_type, &self.signature, StrOrRepr::Str)
- }
-
- fn to_repr_impl(&self, buf: &mut String) -> fmt::Result {
- function::str_impl(buf, &self.function_type, &self.signature, StrOrRepr::Repr)
- }
-
- fn call(
- &self,
- call_stack: &mut CallStack,
- type_values: &TypeValues,
- positional: Vec,
- named: LinkedHashMap,
- args: Option,
- kwargs: Option,
- ) -> ValueResult {
- // argument binding
- let mut ctx = EvaluationContext {
- call_stack,
- env: EvaluationContextEnvironmentLocal {
- globals: IndexedGlobals::new(&self.stmt.globals, self.captured_env.clone()),
- locals: IndexedLocals::new(&self.stmt.locals),
- },
- type_values,
- map: self.map.clone(),
- };
-
- let mut parser = function::ParameterParser::new(
- &self.signature,
- &self.function_type,
- positional,
- named,
- args,
- kwargs,
- )?;
-
- for (i, (s, positional_only)) in self.signature.iter().enumerate() {
- let (name, v) = match s {
- FunctionParameter::Normal(ref name) => {
- (name, parser.next_normal(name, positional_only)?)
- }
- FunctionParameter::WithDefaultValue(ref name, ref default_value) => (
- name,
- parser.next_with_default_value(name, positional_only, default_value),
- ),
- FunctionParameter::ArgsArray(ref name) => (name, parser.next_args_array().into()),
- FunctionParameter::KWArgsDict(ref name) => {
- (name, parser.next_kwargs_dict().try_into().unwrap())
- }
- FunctionParameter::Optional(..) => {
- unreachable!("optional parameters only exist in native functions")
- }
- };
-
- // tricky part: we know that we assign locals for function parameters
- // sequentially starting from 0
- if cfg!(debug_assertions) {
- assert_eq!(
- i,
- ctx.env
- .locals
- .local_defs
- .top_level_name_to_slot(name)
- .unwrap()
- );
- }
- ctx.env.set_local(i, name, v);
- }
-
- parser.check_no_more_args()?;
-
- match eval_block(&self.stmt.suite, &mut ctx) {
- Err(EvalException::Return(_s, ret)) => Ok(ret),
- Err(x) => Err(ValueError::DiagnosedError(x.into())),
- Ok(..) => Ok(Value::new(NoneType::None)),
- }
- }
-
- fn inspect_custom(&self) -> Value {
- let mut fields = LinkedHashMap::::new();
- fields.insert("captured_env".into(), self.captured_env.name().into());
- fields.insert("stmt".into(), self.stmt.inspect());
- Value::new(StarlarkStruct::new(fields))
- }
-}
diff --git a/starlark/src/eval/expr.rs b/starlark/src/eval/expr.rs
deleted file mode 100644
index 9c05a61d..00000000
--- a/starlark/src/eval/expr.rs
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Interpreter-ready expr
-
-use crate::eval::compiler::GlobalCompiler;
-use crate::eval::compiler::LocalCompiler;
-use crate::eval::compiler::LocalOrGlobalCompiler;
-use crate::eval::globals::Globals;
-use crate::eval::locals::Locals;
-use crate::eval::locals::LocalsQuery;
-use crate::stdlib::structs::StarlarkStruct;
-use crate::syntax::ast::AssignTargetExpr;
-use crate::syntax::ast::AstAssignTargetExpr;
-use crate::syntax::ast::AstAugmentedAssignTargetExpr;
-use crate::syntax::ast::AstExpr;
-use crate::syntax::ast::AstString;
-use crate::syntax::ast::AugmentedAssignTargetExpr;
-use crate::syntax::ast::BinOp;
-use crate::syntax::ast::Expr;
-use crate::syntax::ast::UnOp;
-use crate::values::frozen::FrozenValue;
-use crate::values::inspect::Inspectable;
-use crate::values::string::rc::RcString;
-use crate::values::Value;
-use codemap::Spanned;
-use codemap_diagnostic::Diagnostic;
-use linked_hash_map::LinkedHashMap;
-
-/// After syntax check each variable is resolved to either global or slot
-#[derive(Debug, Clone)]
-pub(crate) struct GlobalOrSlot {
- pub name: RcString,
- pub local: bool,
- pub slot: usize,
-}
-pub(crate) type AstGlobalOrSlot = Spanned;
-
-#[derive(Debug, Clone)]
-pub(crate) enum AssignTargetExprCompiled {
- Name(AstGlobalOrSlot),
- Dot(AstExprCompiled, AstString),
- ArrayIndirection(AstExprCompiled, AstExprCompiled),
- Subtargets(Vec),
-}
-pub(crate) type AstAssignTargetExprCompiled = Spanned;
-
-#[derive(Debug, Clone)]
-pub(crate) enum AugmentedAssignTargetExprCompiled {
- // there's no augmented assignment for globals
- Slot(usize, AstString),
- Dot(AstExprCompiled, AstString),
- ArrayIndirection(AstExprCompiled, AstExprCompiled),
-}
-pub(crate) type AstAugmentedAssignTargetExprCompiled = Spanned;
-
-#[doc(hidden)]
-#[derive(Debug, Clone)]
-pub(crate) enum ClauseCompiled {
- For(AstAssignTargetExprCompiled, AstExprCompiled),
- If(AstExprCompiled),
-}
-pub(crate) type AstClauseCompiled = Spanned;
-
-/// Expression wrapper which creates own local context.
-/// Used to evaluate comprehensions
-#[derive(Debug, Clone)]
-pub(crate) struct ExprLocal {
- pub expr: AstExprCompiled,
- pub locals: Locals,
- pub globals: Globals,
-}
-
-impl Inspectable for ExprLocal {
- fn inspect(&self) -> Value {
- let mut fields = LinkedHashMap::::new();
- fields.insert("expr".into(), self.expr.inspect());
- fields.insert("locals".into(), self.locals.inspect());
- fields.insert("globals".into(), self.globals.inspect());
- Value::new(StarlarkStruct::new(fields))
- }
-}
-
-/// Interperter-ready version of [`Expr`](crate::syntax::ast::Expr)
-#[derive(Debug, Clone)]
-pub(crate) enum ExprCompiled {
- Tuple(Vec),
- Dot(AstExprCompiled, AstString),
- Call(
- AstExprCompiled,
- Vec,
- Vec<(AstString, AstExprCompiled)>,
- Option,
- Option,
- ),
- ArrayIndirection(AstExprCompiled, AstExprCompiled),
- Slice(
- AstExprCompiled,
- Option,
- Option,
- Option,
- ),
- Name(AstGlobalOrSlot),
- Value(FrozenValue),
- Not(AstExprCompiled),
- And(AstExprCompiled, AstExprCompiled),
- Or(AstExprCompiled, AstExprCompiled),
- BinOp(BinOp, AstExprCompiled, AstExprCompiled),
- UnOp(UnOp, AstExprCompiled),
- If(AstExprCompiled, AstExprCompiled, AstExprCompiled), // Order: condition, v1, v2 <=> v1 if condition else v2
- List(Vec),
- Set(Vec),
- Dict(Vec<(AstExprCompiled, AstExprCompiled)>),
- ListComprehension(AstExprCompiled, Vec),
- SetComprehension(AstExprCompiled, Vec),
- DictComprehension((AstExprCompiled, AstExprCompiled), Vec),
- /// Creates a local scope for evaluation of subexpression in global scope.
- /// Used for evaluate comprehensions in global scope.
- Local(ExprLocal),
-}
-
-#[doc(hidden)]
-pub(crate) type AstExprCompiled = Box>;
-
-impl GlobalOrSlot {
- pub fn inspect(&self) -> Value {
- let GlobalOrSlot { name, local, slot } = self;
- Value::from((name.clone(), if *local { "local" } else { "global" }, *slot))
- }
-}
-
-impl ExprCompiled {
- pub(crate) fn compile(
- expr: AstExpr,
- compiler: &mut C,
- ) -> Result {
- Ok(Box::new(Spanned {
- span: expr.span,
- node: match expr.node {
- Expr::Tuple(args) => ExprCompiled::Tuple(
- args.into_iter()
- .map(|a| Self::compile(a, compiler))
- .collect::>()?,
- ),
- Expr::List(args) => ExprCompiled::List(
- args.into_iter()
- .map(|a| Self::compile(a, compiler))
- .collect::>()?,
- ),
- Expr::Set(args) => ExprCompiled::Set(
- args.into_iter()
- .map(|a| Self::compile(a, compiler))
- .collect::>()?,
- ),
- Expr::Dict(args) => ExprCompiled::Dict(
- args.into_iter()
- .map(|(k, v)| {
- Ok((Self::compile(k, compiler)?, Self::compile(v, compiler)?))
- })
- .collect::>()?,
- ),
- Expr::Identifier(ident) => ExprCompiled::Name(Spanned {
- span: ident.span,
- node: compiler.ident(ident),
- }),
- Expr::Dot(object, field) => {
- ExprCompiled::Dot(Self::compile(object, compiler)?, field)
- }
- Expr::ArrayIndirection(array, index) => ExprCompiled::ArrayIndirection(
- Self::compile(array, compiler)?,
- Self::compile(index, compiler)?,
- ),
- Expr::Call(f, args, kwargs, star, star_star) => ExprCompiled::Call(
- Self::compile(f, compiler)?,
- args.into_iter()
- .map(|a| Self::compile(a, compiler))
- .collect::>()?,
- kwargs
- .into_iter()
- .map(|(k, v)| Ok((k, Self::compile(v, compiler)?)))
- .collect::>()?,
- star.map(|e| Self::compile(e, compiler)).transpose()?,
- star_star.map(|e| Self::compile(e, compiler)).transpose()?,
- ),
- Expr::Slice(array, a, b, c) => ExprCompiled::Slice(
- Self::compile(array, compiler)?,
- a.map(|e| Self::compile(e, compiler)).transpose()?,
- b.map(|e| Self::compile(e, compiler)).transpose()?,
- c.map(|e| Self::compile(e, compiler)).transpose()?,
- ),
- Expr::IntLiteral(i) => ExprCompiled::Value(FrozenValue::from(i.node)),
- Expr::StringLiteral(s) => {
- ExprCompiled::Value(FrozenValue::new(s.node.into()).unwrap())
- }
- Expr::Not(e) => ExprCompiled::Not(Self::compile(e, compiler)?),
- Expr::And(lhs, rhs) => {
- ExprCompiled::And(Self::compile(lhs, compiler)?, Self::compile(rhs, compiler)?)
- }
- Expr::Or(lhs, rhs) => {
- ExprCompiled::Or(Self::compile(lhs, compiler)?, Self::compile(rhs, compiler)?)
- }
- Expr::BinOp(op, lhs, rhs) => ExprCompiled::BinOp(
- op,
- Self::compile(lhs, compiler)?,
- Self::compile(rhs, compiler)?,
- ),
- Expr::UnOp(op, e) => ExprCompiled::UnOp(op, Self::compile(e, compiler)?),
- Expr::If(cond, then_expr, else_expr) => ExprCompiled::If(
- Self::compile(cond, compiler)?,
- Self::compile(then_expr, compiler)?,
- Self::compile(else_expr, compiler)?,
- ),
- Expr::ListComprehension(expr, clauses) => {
- compiler.list_comprenesion(expr.span, expr, clauses)?
- }
- Expr::SetComprehension(expr, clauses) => {
- compiler.set_comprenesion(expr.span, expr, clauses)?
- }
- Expr::DictComprehension((key, value), clauses) => {
- compiler.dict_comprenesion(expr.span, key, value, clauses)?
- }
- },
- }))
- }
-
- pub(crate) fn compile_local<'a>(
- expr: AstExpr,
- locals_query: &'a mut LocalsQuery<'a>,
- ) -> Result {
- Self::compile(expr, &mut LocalCompiler::new(locals_query))
- }
-
- pub(crate) fn compile_global(
- expr: AstExpr,
- globals: &mut Globals,
- ) -> Result {
- Self::compile(expr, &mut GlobalCompiler::new(globals))
- }
-}
-
-impl Inspectable for ExprCompiled {
- fn inspect(&self) -> Value {
- let (name, param): (&str, Value) = match &self {
- ExprCompiled::Dot(object, field) => ("dot", (object.inspect(), field.inspect()).into()),
- ExprCompiled::ArrayIndirection(array, index) => (
- "array_indirection",
- (array.inspect(), index.inspect()).into(),
- ),
- ExprCompiled::Call(expr, args, kwargs, star, star_star) => {
- ("call", (expr, args, kwargs, star, star_star).inspect())
- }
- ExprCompiled::Slice(array, a, b, c) => ("slice", (array, a, b, c).inspect()),
- ExprCompiled::Name(n) => ("name", n.node.inspect()),
- ExprCompiled::Value(v) => ("value", Value::from(v.clone())),
- ExprCompiled::Not(e) => ("not", e.inspect()),
- ExprCompiled::And(l, r) => ("and", (l, r).inspect()),
- ExprCompiled::Or(l, r) => ("or", (l, r).inspect()),
- ExprCompiled::BinOp(op, l, r) => ("bin_op", (format!("{:?}", op), l, r).inspect()),
- ExprCompiled::UnOp(op, e) => ("un_op", (format!("{:?}", op), e).inspect()),
- ExprCompiled::If(cond, then_expr, else_expr) => {
- ("if", (cond, then_expr, else_expr).inspect())
- }
- ExprCompiled::List(e) => ("list", e.inspect()),
- ExprCompiled::Tuple(e) => ("tuple", e.inspect()),
- ExprCompiled::Set(e) => ("set", e.inspect()),
- ExprCompiled::Dict(d) => ("dict", d.inspect()),
- ExprCompiled::ListComprehension(expr, clauses) => {
- ("list_comprehension", (expr, clauses).inspect())
- }
- ExprCompiled::DictComprehension(expr, clauses) => {
- ("dict_comprehension", (expr, clauses).inspect())
- }
- ExprCompiled::SetComprehension(expr, clauses) => {
- ("set_comprehension", (expr, clauses).inspect())
- }
- ExprCompiled::Local(e) => ("local", e.inspect()),
- };
- Value::from((Value::from(name), param))
- }
-}
-
-impl AssignTargetExprCompiled {
- pub(crate) fn compile(
- expr: AstAssignTargetExpr,
- compiler: &mut C,
- ) -> Result {
- Ok(Spanned {
- span: expr.span,
- node: match expr.node {
- AssignTargetExpr::Identifier(a) => {
- AssignTargetExprCompiled::Name(compiler.ast_ident(a))
- }
- AssignTargetExpr::ArrayIndirection(array, index) => {
- AssignTargetExprCompiled::ArrayIndirection(
- ExprCompiled::compile(array, compiler)?,
- ExprCompiled::compile(index, compiler)?,
- )
- }
- AssignTargetExpr::Dot(object, field) => {
- AssignTargetExprCompiled::Dot(ExprCompiled::compile(object, compiler)?, field)
- }
- AssignTargetExpr::Subtargets(subtargets) => AssignTargetExprCompiled::Subtargets(
- subtargets
- .into_iter()
- .map(|t| AssignTargetExprCompiled::compile(t, compiler))
- .collect::>()?,
- ),
- },
- })
- }
-}
-
-impl AugmentedAssignTargetExprCompiled {
- pub(crate) fn compile_impl(
- expr: AstAugmentedAssignTargetExpr,
- compiler: &mut C,
- ) -> Result {
- Ok(Spanned {
- span: expr.span,
- node: match expr.node {
- AugmentedAssignTargetExpr::Identifier(a) => {
- let span = a.span;
- let GlobalOrSlot { slot, local, name } = compiler.ident(a);
- assert!(local, "global must be filtered out at parse level");
- AugmentedAssignTargetExprCompiled::Slot(slot, Spanned { span, node: name })
- }
- AugmentedAssignTargetExpr::ArrayIndirection(array, index) => {
- AugmentedAssignTargetExprCompiled::ArrayIndirection(
- ExprCompiled::compile(array, compiler)?,
- ExprCompiled::compile(index, compiler)?,
- )
- }
- AugmentedAssignTargetExpr::Dot(object, field) => {
- AugmentedAssignTargetExprCompiled::Dot(
- ExprCompiled::compile(object, compiler)?,
- field,
- )
- }
- },
- })
- }
-}
-
-impl Inspectable for AssignTargetExprCompiled {
- fn inspect(&self) -> Value {
- let (name, param): (&str, Value) = match self {
- AssignTargetExprCompiled::Dot(object, field) => ("dot", (object, field).inspect()),
- AssignTargetExprCompiled::ArrayIndirection(array, index) => {
- ("array_indirection", (array, index).inspect())
- }
- AssignTargetExprCompiled::Name(name) => ("name", name.node.inspect()),
- AssignTargetExprCompiled::Subtargets(st) => ("subtargets", st.inspect()),
- };
- Value::from((name, param))
- }
-}
-
-impl Inspectable for AugmentedAssignTargetExprCompiled {
- fn inspect(&self) -> Value {
- let (name, param): (&str, Value) = match self {
- AugmentedAssignTargetExprCompiled::Slot(slot, name) => ("slot", (slot, name).inspect()),
- AugmentedAssignTargetExprCompiled::ArrayIndirection(array, index) => {
- ("array_indirection", (array, index).inspect())
- }
- AugmentedAssignTargetExprCompiled::Dot(object, field) => {
- ("dot", (object, field).inspect())
- }
- };
- Value::from((name, param))
- }
-}
-
-impl Inspectable for ClauseCompiled {
- fn inspect(&self) -> Value {
- let (name, param): (&str, Value) = match self {
- ClauseCompiled::If(cond) => ("if", cond.inspect()),
- ClauseCompiled::For(var, over) => ("for", (var, over).inspect()),
- };
- Value::from((name, param))
- }
-}
diff --git a/starlark/src/eval/globals.rs b/starlark/src/eval/globals.rs
deleted file mode 100644
index e37d06d3..00000000
--- a/starlark/src/eval/globals.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Utilities to work with scope global variables.
-
-use crate::stdlib::structs::StarlarkStruct;
-use crate::values::inspect::Inspectable;
-use crate::values::string::rc::RcString;
-use crate::values::Value;
-use linked_hash_map::LinkedHashMap;
-use std::collections::HashMap;
-
-#[derive(Default, Debug, Clone)]
-pub(crate) struct Globals {
- name_to_index: HashMap,
-}
-
-impl Globals {
- pub fn register_global(&mut self, name: &str) -> usize {
- let global_count = self.name_to_index.len();
- *self
- .name_to_index
- .entry(name.to_owned())
- .or_insert(global_count)
- }
-
- /// Return the number of global variable slots
- pub fn len(&self) -> usize {
- self.name_to_index.len()
- }
-}
-
-impl Inspectable for Globals {
- fn inspect(&self) -> Value {
- let mut fields = LinkedHashMap::::new();
- fields.insert("name_to_index".into(), self.name_to_index.inspect());
- Value::new(StarlarkStruct::new(fields))
- }
-}
diff --git a/starlark/src/eval/interactive.rs b/starlark/src/eval/interactive.rs
deleted file mode 100644
index 3834de83..00000000
--- a/starlark/src/eval/interactive.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Defines very basic versions of the evaluation functions that are suitable for interactive use:
-//! they output diagnostic to stderr and the result value to stdout.
-use crate::environment::{Environment, TypeValues};
-use crate::syntax::dialect::Dialect;
-use crate::values::Value;
-use codemap::CodeMap;
-use codemap_diagnostic::{ColorConfig, Diagnostic, Emitter};
-use std::sync::{Arc, Mutex};
-
-pub struct EvalError {
- codemap: Arc>,
- diagnostic: Diagnostic,
-}
-
-impl EvalError {
- pub fn write_to_stderr(self) {
- Emitter::stderr(ColorConfig::Auto, Some(&self.codemap.lock().unwrap()))
- .emit(&[self.diagnostic])
- }
-}
-
-/// Evaluate a string content, mutate the environment accordingly, and return the value of the last
-/// statement, or a printable error.
-///
-/// # Arguments
-///
-/// __This version uses the [`SimpleFileLoader`](crate::eval::simple::SimpleFileLoader)
-/// implementation for the file loader__
-///
-/// * path: the name of the file being evaluated, for diagnostics
-/// * content: the content to evaluate
-/// * dialect: starlark language dialect
-/// * env: the environment to mutate during the evaluation
-pub fn eval(
- path: &str,
- content: &str,
- dialect: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader_env: Environment,
-) -> Result, EvalError> {
- let map = Arc::new(Mutex::new(CodeMap::new()));
- transform_result(
- super::simple::eval(
- &map,
- path,
- content,
- dialect,
- env,
- type_values,
- file_loader_env,
- ),
- map,
- )
-}
-
-/// Evaluate a file, mutate the environment accordingly, and return the value of the last
-/// statement, or a printable error.
-///
-/// __This version uses the [`SimpleFileLoader`](crate::eval::simple::SimpleFileLoader)
-/// implementation for the file loader__
-///
-/// # Arguments
-///
-/// * path: the file to parse and evaluate
-/// * dialect: Starlark language dialect
-/// * env: the environment to mutate during the evaluation
-pub fn eval_file(
- path: &str,
- dialect: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader_env: Environment,
-) -> Result , EvalError> {
- let map = Arc::new(Mutex::new(CodeMap::new()));
- transform_result(
- super::simple::eval_file(&map, path, dialect, env, type_values, file_loader_env),
- map,
- )
-}
-
-fn transform_result(
- result: Result,
- codemap: Arc>,
-) -> Result, EvalError> {
- match result {
- Ok(ref v) if v.get_type() == "NoneType" => Ok(None),
- Ok(v) => Ok(Some(v)),
- Err(diagnostic) => Err(EvalError {
- codemap,
- diagnostic,
- }),
- }
-}
diff --git a/starlark/src/eval/locals.rs b/starlark/src/eval/locals.rs
deleted file mode 100644
index fc3bce71..00000000
--- a/starlark/src/eval/locals.rs
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Utilities to work with scope local variables.
-
-use crate::eval::globals::Globals;
-use crate::stdlib::structs::StarlarkStruct;
-use crate::values::dict::Dictionary;
-use crate::values::inspect::Inspectable;
-use crate::values::string::rc::RcString;
-use crate::values::Value;
-use linked_hash_map::LinkedHashMap;
-use std::collections::hash_map;
-use std::collections::HashMap;
-
-#[derive(Default, Debug, Clone)]
-struct Scope {
- /// Name to slot mapping in current scope
- name_to_slot: HashMap,
- nested_scopes: Vec,
-}
-
-/// Mapping of local variables and scopes to local variable slots
-#[derive(Default, Debug, Clone)]
-#[doc(hidden)]
-pub struct Locals {
- locals: Scope,
- local_count: usize,
-}
-
-/// Utility to assign slots to local variables
-#[derive(Default)]
-pub(crate) struct LocalsBuilder {
- locals: Locals,
- current_scope_path: Vec,
-}
-
-/// Utility to query slots assigned to local variables
-pub(crate) struct LocalsQuery<'a> {
- locals: &'a Locals,
- globals: &'a mut Globals,
- current_scope_path: Vec,
- next: usize,
-}
-
-impl Scope {
- /// Find local variable index in given scope
- fn local_index(&self, name: &str, scope_path: &[usize]) -> Option {
- let deepest_index = if let Some((first, rem)) = scope_path.split_first() {
- self.nested_scopes[*first].local_index(name, rem)
- } else {
- None
- };
- match deepest_index {
- Some(index) => Some(index),
- None => self.name_to_slot.get(name).cloned(),
- }
- }
-
- fn scope_by_path<'a>(&'a self, path: &[usize]) -> &'a Scope {
- match path.split_first() {
- Some((&first, rem)) => self.nested_scopes[first].scope_by_path(rem),
- None => self,
- }
- }
-}
-
-impl Inspectable for Scope {
- fn inspect(&self) -> Value {
- let mut fields = LinkedHashMap::::new();
-
- let mut name_to_slot = Dictionary::new_typed();
- for (n, s) in &self.name_to_slot {
- name_to_slot.insert(n.as_str().into(), (*s).into()).unwrap();
- }
- fields.insert("name_to_slot".into(), Value::new(name_to_slot));
-
- fields.insert("nested_scopes".into(), self.nested_scopes.inspect());
-
- Value::new(StarlarkStruct::new(fields))
- }
-}
-
-impl Locals {
- /// Return the number of local variable slots
- pub fn len(&self) -> usize {
- self.local_count
- }
-
- pub fn top_level_name_to_slot(&self, name: &str) -> Option {
- self.locals.local_index(name, &[])
- }
-}
-
-impl Inspectable for Locals {
- fn inspect(&self) -> Value {
- let mut fields = LinkedHashMap::::new();
- fields.insert("count".into(), (self.local_count as i64).into());
- fields.insert("locals".into(), self.locals.inspect());
- Value::new(StarlarkStruct::new(fields))
- }
-}
-
-impl LocalsBuilder {
- fn current_locals(&mut self) -> &mut Scope {
- let mut locals = &mut self.locals.locals;
- for &index in &self.current_scope_path {
- locals = &mut locals.nested_scopes[index];
- }
- locals
- }
-
- /// Create a new nested scope
- pub fn push_scope(&mut self) {
- let locals = self.current_locals();
- locals.nested_scopes.push(Scope::default());
- let n = locals.nested_scopes.len() - 1;
- self.current_scope_path.push(n);
- }
-
- /// Go to one scope down
- pub fn pop_scope(&mut self) {
- self.current_scope_path.pop().unwrap();
- }
-
- /// Register a variable in current scope
- pub fn register_local(&mut self, name: RcString) {
- let local_count = self.locals.local_count;
- if let hash_map::Entry::Vacant(e) = self.current_locals().name_to_slot.entry(name) {
- e.insert(local_count);
- }
- self.locals.local_count += 1;
- }
-
- /// Finish the building
- pub fn build(self) -> Locals {
- // sanity check
- assert!(self.current_scope_path.is_empty());
-
- self.locals
- }
-}
-
-impl<'a> LocalsQuery<'a> {
- pub fn new(locals: &'a Locals, globals: &'a mut Globals) -> LocalsQuery<'a> {
- LocalsQuery {
- locals,
- globals,
- current_scope_path: Vec::new(),
- next: 0,
- }
- }
-
- /// Return a slot for a variable visible in current scope.
- /// Local could be registered in current scope or in parent scopes,
- /// but not in nested scopes.
- pub fn slot(&mut self, name: &str) -> (usize, bool) {
- match self
- .locals
- .locals
- .local_index(name, &self.current_scope_path)
- {
- Some(slot) => (slot, true),
- None => (self.globals.register_global(name), false),
- }
- }
-
- /// Go to the next nested scope
- pub fn push_next_scope(&mut self) {
- self.current_scope_path.push(self.next);
- self.next = 0;
- }
-
- /// Pop a scope
- pub fn pop_scope(&mut self) {
- // We must not leave the current scope if
- // nested scopes were not traversed
- assert_eq!(
- self.next,
- self.locals
- .locals
- .scope_by_path(&self.current_scope_path)
- .nested_scopes
- .len()
- );
-
- self.next = self.current_scope_path.pop().unwrap() + 1;
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn one_level() {
- let mut builder = LocalsBuilder::default();
- builder.register_local("a".into());
- builder.register_local("b".into());
- builder.register_local("a".into());
- let locals = builder.build();
- let mut globals = Globals::default();
- let mut query = LocalsQuery::new(&locals, &mut globals);
- assert_eq!((0, true), query.slot("a"));
- assert_eq!((1, true), query.slot("b"));
- assert_eq!((0, false), query.slot("c"));
- }
-
- #[test]
- fn override_on_second_level() {
- let mut builder = LocalsBuilder::default();
- builder.register_local("a".into());
- builder.push_scope();
- builder.register_local("a".into());
- builder.pop_scope();
- let locals = builder.build();
- let mut globals = Globals::default();
- let mut query = LocalsQuery::new(&locals, &mut globals);
- assert_eq!((0, true), query.slot("a"));
- query.push_next_scope();
- assert_eq!((1, true), query.slot("a"));
- query.pop_scope();
- assert_eq!((0, true), query.slot("a"));
- }
-
- #[test]
- fn overrride_twice_on_second_level() {
- // Here we have three distinct `a` variables:
- // in the top scope, and in two nested scopes
- let mut builder = LocalsBuilder::default();
- builder.register_local("a".into());
- builder.push_scope();
- builder.register_local("a".into());
- builder.pop_scope();
- builder.push_scope();
- builder.register_local("a".into());
- builder.pop_scope();
- let locals = builder.build();
- let mut globals = Globals::default();
- let mut query = LocalsQuery::new(&locals, &mut globals);
- assert_eq!((0, true), query.slot("a"));
- query.push_next_scope();
- assert_eq!((1, true), query.slot("a"));
- query.pop_scope();
- assert_eq!((0, true), query.slot("a"));
- query.push_next_scope();
- assert_eq!((2, true), query.slot("a"));
- query.pop_scope();
- assert_eq!((0, true), query.slot("a"));
- }
-}
diff --git a/starlark/src/eval/mod.rs b/starlark/src/eval/mod.rs
deleted file mode 100644
index 081ddec1..00000000
--- a/starlark/src/eval/mod.rs
+++ /dev/null
@@ -1,891 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Evaluation environment, provide converters from Ast* element to value.
-//!
-//! # Starlark and BUILD dialect
-//!
-//! All evaluation function can evaluate the full Starlark language (i.e. Bazel's
-//! .bzl files) or the BUILD file dialect (i.e. used to interpret Bazel's BUILD file).
-//! The BUILD dialect does not allow `def` statements.
-use crate::environment::Environment;
-use crate::environment::TypeValues;
-use crate::eval::call_stack::CallStack;
-use crate::eval::compr::eval_one_dimensional_comprehension;
-use crate::eval::def::Def;
-use crate::eval::def::ParameterCompiled;
-use crate::eval::expr::AssignTargetExprCompiled;
-use crate::eval::expr::AstAssignTargetExprCompiled;
-use crate::eval::expr::AstAugmentedAssignTargetExprCompiled;
-use crate::eval::expr::AstExprCompiled;
-use crate::eval::expr::AugmentedAssignTargetExprCompiled;
-use crate::eval::expr::ExprCompiled;
-use crate::eval::expr::ExprLocal;
-use crate::eval::module::Module;
-use crate::eval::stmt::AstStatementCompiled;
-use crate::eval::stmt::BlockCompiled;
-use crate::eval::stmt::StatementCompiled;
-use crate::linked_hash_set::value::Set;
-use crate::syntax::ast::BinOp;
-use crate::syntax::ast::UnOp;
-use crate::syntax::ast::*;
-use crate::syntax::dialect::Dialect;
-use crate::syntax::errors::SyntaxError;
-use crate::syntax::lexer::{LexerIntoIter, LexerItem};
-use crate::syntax::parser::{parse, parse_file, parse_lexer};
-use crate::values::context::EvaluationContext;
-use crate::values::context::EvaluationContextEnvironment;
-use crate::values::context::EvaluationContextEnvironmentLocal;
-use crate::values::context::EvaluationContextEnvironmentModule;
-use crate::values::context::IndexedGlobals;
-use crate::values::context::IndexedLocals;
-use crate::values::dict::Dictionary;
-use crate::values::error::UnsupportedOperation;
-use crate::values::error::ValueError;
-use crate::values::function::FunctionParameter;
-use crate::values::function::FunctionSignature;
-use crate::values::function::WrappedMethod;
-use crate::values::none::NoneType;
-use crate::values::string::rc::RcString;
-use crate::values::*;
-use codemap::{CodeMap, Span, Spanned};
-use codemap_diagnostic::{Diagnostic, Level, SpanLabel, SpanStyle};
-use linked_hash_map::LinkedHashMap;
-use std::cmp::Ordering;
-use std::sync::{Arc, Mutex};
-
-fn eval_vector(
- v: &[AstExprCompiled],
- ctx: &mut EvaluationContext,
-) -> Result, EvalException> {
- v.into_iter().map(|s| eval_expr(s, ctx)).collect()
-}
-
-// TODO: move that code in some common error code list?
-// CE prefix = Critical Evaluation
-#[doc(hidden)]
-pub const BREAK_ERROR_CODE: &str = "CE00";
-#[doc(hidden)]
-pub const CONTINUE_ERROR_CODE: &str = "CE01";
-#[doc(hidden)]
-pub const RETURN_ERROR_CODE: &str = "CE02";
-#[doc(hidden)]
-pub const INCORRECT_LEFT_VALUE_ERROR_CODE: &str = "CE03";
-#[doc(hidden)]
-pub const INCORRECT_UNPACK_ERROR_CODE: &str = "CE04";
-#[doc(hidden)]
-pub const RECURSION_ERROR_CODE: &str = "CE05";
-
-#[doc(hidden)]
-#[derive(Debug, Clone)]
-pub enum EvalException {
- // Flow control statement reached
- Break(Span),
- Continue(Span),
- Return(Span, Value),
- // Error bubbling up as diagnostics
- DiagnosedError(Diagnostic),
- // Expression used as left value cannot be assigned
- IncorrectLeftValue(Span),
- // Incorrect number of value to unpack (expected, got)
- IncorrectNumberOfValueToUnpack(Span, i64, i64),
- // Recursion
- Recursion(Span, String, CallStack),
-}
-
-impl From for EvalException {
- fn from(diagnostic: Diagnostic) -> Self {
- EvalException::DiagnosedError(diagnostic)
- }
-}
-
-type EvalResult = Result;
-
-/// An object with [`Span`]
-trait AsSpan {
- fn as_span(&self) -> Span;
-}
-
-impl AsSpan for Span {
- fn as_span(&self) -> Span {
- *self
- }
-}
-
-impl AsSpan for Spanned {
- fn as_span(&self) -> Span {
- self.span
- }
-}
-
-impl AsSpan for Box> {
- fn as_span(&self) -> Span {
- self.span
- }
-}
-
-/// Convert syntax error to spanned evaluation exception
-fn t(r: Result, spanned: &S) -> Result {
- match r {
- Ok(v) => Ok(v),
- Err(e) => Err(EvalException::DiagnosedError(
- e.to_diagnostic(spanned.as_span()),
- )),
- }
-}
-
-impl Into for EvalException {
- fn into(self) -> Diagnostic {
- match self {
- EvalException::DiagnosedError(e) => e,
- EvalException::Break(s) => Diagnostic {
- level: Level::Error,
- message: "Break statement used outside of a loop".to_owned(),
- code: Some(BREAK_ERROR_CODE.to_owned()),
- spans: vec![SpanLabel {
- span: s,
- style: SpanStyle::Primary,
- label: None,
- }],
- },
- EvalException::Continue(s) => Diagnostic {
- level: Level::Error,
- message: "Continue statement used outside of a loop".to_owned(),
- code: Some(CONTINUE_ERROR_CODE.to_owned()),
- spans: vec![SpanLabel {
- span: s,
- style: SpanStyle::Primary,
- label: None,
- }],
- },
- EvalException::Return(s, ..) => Diagnostic {
- level: Level::Error,
- message: "Return statement used outside of a function call".to_owned(),
- code: Some(RETURN_ERROR_CODE.to_owned()),
- spans: vec![SpanLabel {
- span: s,
- style: SpanStyle::Primary,
- label: None,
- }],
- },
- EvalException::IncorrectLeftValue(s) => Diagnostic {
- level: Level::Error,
- message: "Incorrect expression as left value".to_owned(),
- code: Some(INCORRECT_LEFT_VALUE_ERROR_CODE.to_owned()),
- spans: vec![SpanLabel {
- span: s,
- style: SpanStyle::Primary,
- label: None,
- }],
- },
- EvalException::IncorrectNumberOfValueToUnpack(s, expected, got) => Diagnostic {
- level: Level::Error,
- message: format!("Unpacked {} values but expected {}", got, expected),
- code: Some(INCORRECT_UNPACK_ERROR_CODE.to_owned()),
- spans: vec![SpanLabel {
- span: s,
- style: SpanStyle::Primary,
- label: None,
- }],
- },
- EvalException::Recursion(s, f, stack) => Diagnostic {
- level: Level::Error,
- message: format!(
- "Function {} recursed, call stack:{}",
- f,
- stack.print_with_newline_before()
- ),
- code: Some(RECURSION_ERROR_CODE.to_owned()),
- spans: vec![SpanLabel {
- span: s,
- style: SpanStyle::Primary,
- label: Some("Recursive call".to_owned()),
- }],
- },
- }
- }
-}
-
-/// A trait for loading file using the load statement path.
-pub trait FileLoader {
- /// Open the file given by the load statement `path`.
- fn load(&self, path: &str, type_values: &TypeValues) -> Result;
-}
-
-fn eval_un_op(op: UnOp, v: Value) -> Result {
- match op {
- UnOp::Plus => v.plus(),
- UnOp::Minus => v.minus(),
- }
-}
-
-fn eval_bin_op(op: BinOp, l: Value, r: Value) -> Result {
- match op {
- BinOp::EqualsTo => l.equals(&r).map(Value::new),
- BinOp::Different => l.equals(&r).map(|b| Value::new(!b)),
- BinOp::LowerThan => l.compare(&r).map(|c| Value::new(c == Ordering::Less)),
- BinOp::GreaterThan => l.compare(&r).map(|c| Value::new(c == Ordering::Greater)),
- BinOp::LowerOrEqual => l.compare(&r).map(|c| Value::new(c != Ordering::Greater)),
- BinOp::GreaterOrEqual => l.compare(&r).map(|c| Value::new(c != Ordering::Less)),
- BinOp::In => r.contains(&l).map(Value::new),
- BinOp::NotIn => r.contains(&l).map(|r| Value::new(!r)),
- BinOp::Substraction => l.sub(r),
- BinOp::Addition => l.add(r),
- BinOp::Multiplication => l.mul(r),
- BinOp::Percent => l.percent(r),
- BinOp::Division => {
- // No types currently support / so always error.
- return Err(ValueError::OperationNotSupported {
- op: UnsupportedOperation::Div,
- left: l.get_type().to_string(),
- right: Some(r.get_type().to_string()),
- });
- }
- BinOp::FloorDivision => l.floor_div(r),
- BinOp::Pipe => l.pipe(r),
- }
-}
-
-fn eval_bin_op_expr(
- expr: &AstExprCompiled,
- op: BinOp,
- l: &AstExprCompiled,
- r: &AstExprCompiled,
- context: &mut EvaluationContext,
-) -> EvalResult {
- let l = eval_expr(l, context)?;
- let r = eval_expr(r, context)?;
-
- t(eval_bin_op(op, l, r), expr)
-}
-
-fn eval_slice(
- this: &AstExprCompiled,
- a: &AstExprCompiled,
- start: &Option,
- stop: &Option,
- stride: &Option,
- context: &mut EvaluationContext,
-) -> EvalResult {
- let a = eval_expr(a, context)?;
- let start = match start {
- Some(ref e) => Some(eval_expr(e, context)?),
- None => None,
- };
- let stop = match stop {
- Some(ref e) => Some(eval_expr(e, context)?),
- None => None,
- };
- let stride = match stride {
- Some(ref e) => Some(eval_expr(e, context)?),
- None => None,
- };
- t(a.slice(start, stop, stride), this)
-}
-
-fn eval_call(
- this: &AstExprCompiled,
- e: &AstExprCompiled,
- pos: &[AstExprCompiled],
- named: &[(AstString, AstExprCompiled)],
- args: &Option,
- kwargs: &Option,
- context: &mut EvaluationContext,
-) -> EvalResult {
- let npos = eval_vector(pos, context)?;
- let mut nnamed = LinkedHashMap::new();
- for &(ref k, ref v) in named.iter() {
- nnamed.insert(k.node.clone(), eval_expr(v, context)?);
- }
- let nargs = if let Some(ref x) = args {
- Some(eval_expr(x, context)?)
- } else {
- None
- };
- let nkwargs = if let Some(ref x) = kwargs {
- Some(eval_expr(x, context)?)
- } else {
- None
- };
- let f = eval_expr(e, context)?;
- if context.call_stack.contains(f.function_id()) {
- let mut new_stack = context.call_stack.clone();
- new_stack.push(f.clone(), context.map.clone(), this.span.low());
- Err(EvalException::Recursion(this.span, f.to_repr(), new_stack))
- } else {
- context
- .call_stack
- .push(f.clone(), context.map.clone(), this.span.low());
- let r = t(
- eval_expr(e, context)?.call(
- context.call_stack,
- context.type_values,
- npos,
- nnamed,
- nargs,
- nkwargs,
- ),
- this,
- );
- context.call_stack.pop();
- r
- }
-}
-
-fn eval_dot(
- this: &AstExprCompiled,
- e: &AstExprCompiled,
- s: &AstString,
- context: &mut EvaluationContext,
-) -> EvalResult {
- let left = eval_expr(e, context)?;
- if let Some(v) = context.type_values.get_type_value(&left, &s.node) {
- if v.get_type() == "function" {
- // Insert self so the method see the object it is acting on
- Ok(WrappedMethod::new(left, v))
- } else {
- Ok(v)
- }
- } else {
- t(left.get_attr(&s.node), this)
- }
-}
-
-enum TransformedExpr {
- Dot(Value, RcString, Span),
- ArrayIndirection(Value, Value, Span),
- Slot(usize, AstString),
-}
-
-fn set_transformed(
- transformed: &TransformedExpr,
- context: &mut EvaluationContext,
- new_value: Value,
-) -> EvalResult {
- let ok = Ok(Value::new(NoneType::None));
- match transformed {
- TransformedExpr::Dot(ref e, ref s, ref span) => {
- t(e.clone().set_attr(&s, new_value), span)?;
- ok
- }
- TransformedExpr::ArrayIndirection(ref e, ref idx, ref span) => {
- t(e.clone().set_at(idx.clone(), new_value), span)?;
- ok
- }
- TransformedExpr::Slot(slot, ident) => {
- context.env.set_local(*slot, &ident.node, new_value);
- ok
- }
- }
-}
-
-fn eval_transformed(
- transformed: &TransformedExpr,
- context: &mut EvaluationContext,
-) -> EvalResult {
- match transformed {
- TransformedExpr::Dot(ref left, ref s, ref span) => {
- if let Some(v) = context.type_values.get_type_value(left, &s) {
- if v.get_type() == "function" {
- // Insert self so the method see the object it is acting on
- Ok(WrappedMethod::new(left.clone(), v))
- } else {
- Ok(v)
- }
- } else {
- t(left.get_attr(&s), span)
- }
- }
- TransformedExpr::ArrayIndirection(ref e, ref idx, ref span) => t(e.at(idx.clone()), span),
- TransformedExpr::Slot(slot, ident) => t(context.env.get_local(*slot, &ident.node), ident),
- }
-}
-
-// An intermediate transformation that tries to evaluate parameters of function / indices.
-// It is used to cache result of LHS in augmented assignment.
-// This transformation by default should be a deep copy (clone).
-fn transform(
- expr: &AstAugmentedAssignTargetExprCompiled,
- context: &mut EvaluationContext,
-) -> Result {
- match &expr.node {
- AugmentedAssignTargetExprCompiled::Dot(ref e, ref s) => Ok(TransformedExpr::Dot(
- eval_expr(e, context)?,
- s.node.clone(),
- expr.span,
- )),
- AugmentedAssignTargetExprCompiled::ArrayIndirection(ref e, ref idx) => {
- Ok(TransformedExpr::ArrayIndirection(
- eval_expr(e, context)?,
- eval_expr(idx, context)?,
- expr.span,
- ))
- }
- AugmentedAssignTargetExprCompiled::Slot(index, ref ident) => {
- Ok(TransformedExpr::Slot(*index, ident.clone()))
- }
- }
-}
-
-// Evaluate the AST in global context, create local context, and continue evaluating in local
-fn eval_expr_local(
- local: &ExprLocal,
- context: &mut EvaluationContext,
-) -> EvalResult {
- let mut ctx = EvaluationContext {
- call_stack: context.call_stack,
- env: EvaluationContextEnvironmentLocal {
- // Note assertion that we where in module context
- globals: IndexedGlobals::new(&local.globals, context.env.env().clone()),
- locals: IndexedLocals::new(&local.locals),
- },
- type_values: context.type_values,
- map: context.map.clone(),
- };
- eval_expr(&local.expr, &mut ctx)
-}
-
-// Evaluate the AST element, i.e. mutate the environment and return an evaluation result
-fn eval_expr(
- expr: &AstExprCompiled,
- context: &mut EvaluationContext,
-) -> EvalResult {
- match expr.node {
- ExprCompiled::Tuple(ref v) => {
- let r = eval_vector(v, context)?;
- Ok(Value::new(tuple::Tuple::new(r)))
- }
- ExprCompiled::Dot(ref e, ref s) => eval_dot(expr, e, s, context),
- ExprCompiled::Call(ref e, ref pos, ref named, ref args, ref kwargs) => {
- eval_call(expr, e, pos, named, args, kwargs, context)
- }
- ExprCompiled::ArrayIndirection(ref e, ref idx) => {
- let idx = eval_expr(idx, context)?;
- t(eval_expr(e, context)?.at(idx), expr)
- }
- ExprCompiled::Slice(ref a, ref start, ref stop, ref stride) => {
- eval_slice(expr, a, start, stop, stride, context)
- }
- ExprCompiled::Name(ref name) => t(context.env.get(&name.node), name),
- ExprCompiled::Value(ref v) => Ok(v.clone().into()),
- ExprCompiled::Not(ref s) => Ok(Value::new(!eval_expr(s, context)?.to_bool())),
- ExprCompiled::UnOp(op, ref s) => {
- let v = eval_expr(s, context)?;
- t(eval_un_op(op, v), expr)
- }
- ExprCompiled::Or(ref l, ref r) => {
- let l = eval_expr(l, context)?;
- Ok(if l.to_bool() {
- l
- } else {
- eval_expr(r, context)?
- })
- }
- ExprCompiled::And(ref l, ref r) => {
- let l = eval_expr(l, context)?;
- Ok(if !l.to_bool() {
- l
- } else {
- eval_expr(r, context)?
- })
- }
- ExprCompiled::BinOp(op, ref l, ref r) => eval_bin_op_expr(expr, op, l, r, context),
- ExprCompiled::If(ref cond, ref v1, ref v2) => {
- if eval_expr(cond, context)?.to_bool() {
- eval_expr(v1, context)
- } else {
- eval_expr(v2, context)
- }
- }
- ExprCompiled::List(ref v) => {
- let r = eval_vector(v, context)?;
- Ok(Value::from(r))
- }
- ExprCompiled::Dict(ref v) => {
- let r = dict::Dictionary::new();
- for s in v.iter() {
- t(
- r.borrow_mut()
- .set_at(eval_expr(&s.0, context)?, eval_expr(&s.1, context)?),
- expr,
- )?
- }
- Ok(r.into())
- }
- ExprCompiled::Set(ref v) => {
- if !context.env.env().set_literals_emabled() {
- return t(Err(ValueError::TypeNotSupported("set".to_string())), expr);
- }
- let mut values = Vec::with_capacity(v.len());
- for s in v {
- values.push(eval_expr(s, context)?);
- }
- t(Set::from(values), expr)
- }
- ExprCompiled::ListComprehension(ref expr, ref clauses) => {
- let mut list = Vec::new();
- eval_one_dimensional_comprehension(
- &mut |context| {
- list.push(eval_expr(expr, context)?);
- Ok(())
- },
- clauses,
- context,
- )?;
- Ok(Value::from(list))
- }
- ExprCompiled::SetComprehension(ref expr, ref clauses) => {
- if !context.env.env().set_literals_emabled() {
- return t(Err(ValueError::TypeNotSupported("set".to_string())), expr);
- }
-
- let mut values = Vec::new();
- eval_one_dimensional_comprehension(
- &mut |context| {
- values.push(eval_expr(expr, context)?);
- Ok(())
- },
- clauses,
- context,
- )?;
-
- t(Set::from(values), expr)
- }
- ExprCompiled::DictComprehension((ref k, ref v), ref clauses) => {
- let mut dict = Dictionary::new_typed();
- eval_one_dimensional_comprehension(
- &mut |context| {
- t(
- dict.insert(eval_expr(k, context)?, eval_expr(v, context)?),
- &expr.span,
- )
- },
- clauses,
- context,
- )?;
- Ok(Value::new(dict))
- }
- ExprCompiled::Local(ref local) => eval_expr_local(&local, context),
- }
-}
-
-// Perform an assignment on the LHS represented by this AST element
-fn set_expr(
- expr: &AstAssignTargetExprCompiled,
- context: &mut EvaluationContext,
- new_value: Value,
-) -> EvalResult {
- let ok = Ok(Value::new(NoneType::None));
- match expr.node {
- AssignTargetExprCompiled::Subtargets(ref v) => {
- // TODO: the span here should probably include the rvalue
- let new_values: Vec = t(new_value.iter(), expr)?.iter().collect();
- let l = v.len();
- if new_values.len() != l {
- Err(EvalException::IncorrectNumberOfValueToUnpack(
- expr.span,
- l as i64,
- new_values.len() as i64,
- ))
- } else {
- let mut it1 = v.iter();
- let mut it2 = new_values.into_iter();
- for _ in 0..l {
- set_expr(it1.next().unwrap(), context, it2.next().unwrap())?;
- }
- ok
- }
- }
- AssignTargetExprCompiled::Dot(ref e, ref s) => {
- t(eval_expr(e, context)?.set_attr(&(s.node), new_value), expr)?;
- ok
- }
- AssignTargetExprCompiled::Name(ref name) => {
- t(context.env.set(&name.node, new_value), expr)?;
- ok
- }
- AssignTargetExprCompiled::ArrayIndirection(ref e, ref idx) => {
- t(
- eval_expr(e, context)?.set_at(eval_expr(idx, context)?, new_value),
- expr,
- )?;
- ok
- }
- }
-}
-
-fn eval_assign_modify(
- stmt: &AstStatementCompiled,
- lhs: &AstAugmentedAssignTargetExprCompiled,
- rhs: &AstExprCompiled,
- context: &mut EvaluationContext,
- op: AugmentedAssignOp,
-) -> EvalResult
-where
-{
- let op = match op {
- AugmentedAssignOp::Increment => Value::add,
- AugmentedAssignOp::Decrement => Value::sub,
- AugmentedAssignOp::Multiplier => Value::mul,
- AugmentedAssignOp::Divider => Value::div,
- AugmentedAssignOp::FloorDivider => Value::floor_div,
- AugmentedAssignOp::Percent => Value::percent,
- };
-
- let lhs = transform(lhs, context)?;
- let l = eval_transformed(&lhs, context)?;
- let r = eval_expr(rhs, context)?;
- set_transformed(&lhs, context, t(op(&l, r), stmt)?)
-}
-
-fn eval_stmt(
- stmt: &AstStatementCompiled,
- context: &mut EvaluationContext,
-) -> EvalResult {
- match stmt.node {
- StatementCompiled::Break => Err(EvalException::Break(stmt.span)),
- StatementCompiled::Continue => Err(EvalException::Continue(stmt.span)),
- StatementCompiled::Return(ref e) => {
- Err(EvalException::Return(stmt.span, eval_expr(e, context)?))
- }
- StatementCompiled::Expression(ref e) => eval_expr(e, context),
- StatementCompiled::Assign(ref lhs, ref rhs) => {
- let rhs = eval_expr(rhs, context)?;
- set_expr(lhs, context, rhs)
- }
- StatementCompiled::AugmentedAssign(ref lhs, op, ref rhs) => {
- eval_assign_modify(stmt, lhs, rhs, context, op)
- }
- StatementCompiled::IfElse(ref cond, ref st1, ref st2) => {
- if eval_expr(cond, context)?.to_bool() {
- eval_block(st1, context)
- } else {
- eval_block(st2, context)
- }
- }
- StatementCompiled::For(ref e1, ref e2, ref st) => {
- let iterable = eval_expr(e2, context)?;
- let mut result = Ok(Value::new(NoneType::None));
- for v in &t(iterable.iter(), &e2.span)? {
- set_expr(e1, context, v)?;
- match eval_block(st, context) {
- Err(EvalException::Break(..)) => break,
- Err(EvalException::Continue(..)) => (),
- Err(x) => {
- result = Err(x);
- break;
- }
- _ => (),
- }
- }
- result
- }
- StatementCompiled::Def(ref stmt) => {
- let mut p = Vec::new();
- for x in &stmt.params {
- p.push(match x.node {
- ParameterCompiled::Normal(ref n) => FunctionParameter::Normal(n.node.clone()),
- ParameterCompiled::WithDefaultValue(ref n, ref v) => {
- FunctionParameter::WithDefaultValue(n.node.clone(), eval_expr(v, context)?)
- }
- ParameterCompiled::Args(ref n) => FunctionParameter::ArgsArray(n.node.clone()),
- ParameterCompiled::KWArgs(ref n) => {
- FunctionParameter::KWArgsDict(n.node.clone())
- }
- })
- }
- let f = Def::new(
- context.env.assert_module_env().env.name(),
- FunctionSignature::new(p, 0),
- stmt.clone(),
- context.map.clone(),
- context.env.assert_module_env().env.clone(),
- );
- t(
- context
- .env
- .set_global(stmt.slot, &stmt.name.node, f.clone().into()),
- &stmt.name,
- )?;
- Ok(f.into())
- }
- StatementCompiled::Load(ref name, ref v) => {
- let loadenv = context
- .env
- .assert_module_env()
- .loader
- .load(name, context.type_values)?;
- loadenv.freeze();
- for &(ref new_name, ref orig_name) in v.iter() {
- t(
- context.env.assert_module_env().env.import_symbol(
- &loadenv,
- &orig_name.node,
- &new_name.node,
- ),
- &new_name.span.merge(orig_name.span),
- )?
- }
- Ok(Value::new(NoneType::None))
- }
- }
-}
-
-fn eval_block(
- block: &BlockCompiled,
- context: &mut EvaluationContext,
-) -> EvalResult {
- let mut r = Value::new(NoneType::None);
- for stmt in &block.0 {
- r = eval_stmt(stmt, context)?;
- }
- Ok(r)
-}
-
-fn eval_module(
- module: &Module,
- env: &mut Environment,
- type_values: &TypeValues,
- map: Arc>,
- loader: &dyn FileLoader,
-) -> EvalResult {
- let mut call_stack = CallStack::default();
- let mut context = EvaluationContext {
- env: EvaluationContextEnvironmentModule {
- env: env.clone(),
- globals: IndexedGlobals::new(&module.globals, env.clone()),
- loader,
- },
- type_values,
- call_stack: &mut call_stack,
- map,
- };
- eval_block(&module.block, &mut context)
-}
-
-/// Evaluate a content provided by a custom Lexer, mutate the environment accordingly and return
-/// the evaluated value.
-///
-/// # Arguments
-///
-/// * map: the codemap object used for diagnostics
-/// * filename: the name of the file being evaluated, for diagnostics
-/// * content: the content to evaluate, for diagnostics
-/// * dialect: starlark syntax dialect
-/// * lexer: the custom lexer to use
-/// * env: the environment to mutate during the evaluation
-/// * file_loader: the [`FileLoader`] to react to `load()` statements.
-pub fn eval_lexer, T2: LexerIntoIter>(
- map: &Arc>,
- filename: &str,
- content: &str,
- dialect: Dialect,
- lexer: T2,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader: &dyn FileLoader,
-) -> Result {
- match eval_module(
- &parse_lexer(map, filename, content, dialect, lexer)?,
- env,
- type_values,
- map.clone(),
- file_loader,
- ) {
- Ok(v) => Ok(v),
- Err(p) => Err(p.into()),
- }
-}
-
-/// Evaluate a string content, mutate the environment accordingly and return the evaluated value.
-///
-/// # Arguments
-///
-/// * map: the codemap object used for diagnostics
-/// * path: the name of the file being evaluated, for diagnostics
-/// * content: the content to evaluate
-/// * build: set to true if you want to evaluate a BUILD file or false to evaluate a .bzl file.
-/// More information about the difference can be found in [this module's
-/// documentation](index.html#build_file).
-/// * env: the environment to mutate during the evaluation
-/// * file_loader: the [`FileLoader`] to react to `load()` statements.
-pub fn eval(
- map: &Arc>,
- path: &str,
- content: &str,
- build: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader: &dyn FileLoader,
-) -> Result {
- match eval_module(
- &parse(map, path, content, build)?,
- env,
- type_values,
- map.clone(),
- file_loader,
- ) {
- Ok(v) => Ok(v),
- Err(p) => Err(p.into()),
- }
-}
-
-/// Evaluate a file, mutate the environment accordingly and return the evaluated value.
-///
-/// # Arguments
-///
-/// * map: the codemap object used for diagnostics
-/// * path: the file to parse and evaluate
-/// * build: set to true if you want to evaluate a BUILD file or false to evaluate a .bzl file.
-/// More information about the difference can be found in [this module's
-/// documentation](index.html#build_file).
-/// * env: the environment to mutate during the evaluation
-/// * file_loader: the [`FileLoader`] to react to `load()` statements.
-pub fn eval_file(
- map: &Arc>,
- path: &str,
- build: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader: &dyn FileLoader,
-) -> Result {
- match eval_module(
- &parse_file(map, path, build)?,
- env,
- type_values,
- map.clone(),
- file_loader,
- ) {
- Ok(v) => Ok(v),
- Err(p) => Err(p.into()),
- }
-}
-
-pub mod interactive;
-pub mod noload;
-pub mod simple;
-
-pub mod call_stack;
-
-#[cfg(test)]
-mod tests;
-
-pub(crate) mod compiler;
-pub(crate) mod compr;
-pub(crate) mod def;
-pub(crate) mod expr;
-pub(crate) mod globals;
-pub(crate) mod locals;
-pub mod module;
-pub mod stmt;
diff --git a/starlark/src/eval/module.rs b/starlark/src/eval/module.rs
deleted file mode 100644
index 873d1984..00000000
--- a/starlark/src/eval/module.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Starlark module (`.bzl` or `BUILD` file parsed and post-processed)
-
-use crate::eval::globals::Globals;
-use crate::eval::stmt::BlockCompiled;
-use crate::syntax::ast::AstStatement;
-use crate::syntax::ast::Statement;
-use crate::syntax::dialect::Dialect;
-use codemap_diagnostic::Diagnostic;
-
-/// Starlark module (`.bzl` or `BUILD` file parsed and post-processed)
-#[derive(Debug, Clone)]
-pub struct Module {
- /// Index of global variables used in this scope
- /// (but not in child scopes).
- pub(crate) globals: Globals,
- /// Code
- pub(crate) block: BlockCompiled,
-}
-
-impl Module {
- pub(crate) fn compile(stmt: AstStatement, _dialect: Dialect) -> Result {
- let mut globals = Globals::default();
- Statement::validate_break_continue(&stmt)?;
- Statement::validate_augmented_assignment_in_module(&stmt)?;
- let block = BlockCompiled::compile_global(stmt, &mut globals)?;
- Ok(Module { globals, block })
- }
-}
diff --git a/starlark/src/eval/noload.rs b/starlark/src/eval/noload.rs
deleted file mode 100644
index dea1e7a9..00000000
--- a/starlark/src/eval/noload.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Define simpler version of the evaluation function,
-//! which does not support `load(...)` statement.
-
-use crate::environment::{Environment, TypeValues, LOAD_NOT_SUPPORTED_ERROR_CODE};
-use crate::eval::{EvalException, FileLoader};
-use crate::syntax::dialect::Dialect;
-use crate::values::Value;
-use codemap::CodeMap;
-use codemap_diagnostic::{Diagnostic, Level};
-use std::sync::{Arc, Mutex};
-
-/// File loader which returns error unconditionally.
-pub struct NoLoadFileLoader;
-
-impl FileLoader for NoLoadFileLoader {
- fn load(&self, _path: &str, _: &TypeValues) -> Result {
- Err(EvalException::DiagnosedError(Diagnostic {
- level: Level::Error,
- message: "ErrorFileLoader does not support loading".to_owned(),
- code: Some(LOAD_NOT_SUPPORTED_ERROR_CODE.to_owned()),
- spans: Vec::new(),
- }))
- }
-}
-
-/// Evaluate a string content, mutate the environment accordingly and return the evaluated value.
-///
-/// # Arguments
-///
-/// __This version uses the [`NoLoadFileLoader`] implementation for
-/// the file loader__
-///
-/// * map: the codemap object used for diagnostics
-/// * path: the name of the file being evaluated, for diagnostics
-/// * content: the content to evaluate
-/// * dialect: Starlark language dialect
-/// * env: the environment to mutate during the evaluation
-/// * global: the environment used to resolve type values
-pub fn eval(
- map: &Arc>,
- path: &str,
- content: &str,
- dialect: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
-) -> Result {
- super::eval(
- map,
- path,
- content,
- dialect,
- env,
- type_values,
- &NoLoadFileLoader,
- )
-}
diff --git a/starlark/src/eval/simple.rs b/starlark/src/eval/simple.rs
deleted file mode 100644
index 291724d1..00000000
--- a/starlark/src/eval/simple.rs
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Define simpler version of the evaluation function
-use super::Dialect;
-use super::{EvalException, FileLoader};
-use crate::environment::{Environment, TypeValues};
-use crate::values::*;
-use codemap::CodeMap;
-use codemap_diagnostic::Diagnostic;
-use std::collections::HashMap;
-use std::sync::{Arc, Mutex};
-
-/// A simple FileLoader that load file from disk and cache the result in a hashmap.
-#[derive(Clone)]
-pub struct SimpleFileLoader {
- map: Arc>>,
- parent_env: Environment,
- codemap: Arc>,
-}
-
-impl SimpleFileLoader {
- pub fn new(map: &Arc>, parent_env: Environment) -> SimpleFileLoader {
- SimpleFileLoader {
- map: Arc::new(Mutex::new(HashMap::new())),
- parent_env,
- codemap: map.clone(),
- }
- }
-}
-
-impl FileLoader for SimpleFileLoader {
- fn load(&self, path: &str, type_values: &TypeValues) -> Result {
- {
- let lock = self.map.lock().unwrap();
- if lock.contains_key(path) {
- return Ok(lock.get(path).unwrap().clone());
- }
- } // Release the lock
- let mut env = self.parent_env.child(path);
- if let Err(d) = super::eval_file(
- &self.codemap,
- path,
- Dialect::Bzl,
- &mut env,
- type_values,
- self,
- ) {
- return Err(EvalException::DiagnosedError(d));
- }
- env.freeze();
- self.map
- .lock()
- .unwrap()
- .insert(path.to_owned(), env.clone());
- Ok(env)
- }
-}
-
-/// Evaluate a string content, mutate the environment accordingly and return the evaluated value.
-///
-/// # Arguments
-///
-/// __This version uses the [`SimpleFileLoader`] implementation for
-/// the file loader__
-///
-/// * map: the codemap object used for diagnostics
-/// * path: the name of the file being evaluated, for diagnostics
-/// * content: the content to evaluate
-/// * dialect: Starlark language dialect
-/// * env: the environment to mutate during the evaluation
-pub fn eval(
- map: &Arc>,
- path: &str,
- content: &str,
- dialect: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader_env: Environment,
-) -> Result {
- super::eval(
- map,
- path,
- content,
- dialect,
- env,
- type_values,
- &SimpleFileLoader::new(map, file_loader_env),
- )
-}
-
-/// Evaluate a file, mutate the environment accordingly and return the evaluated value.
-///
-/// __This version uses the [`SimpleFileLoader`] implementation for
-/// the file loader__
-///
-/// # Arguments
-///
-/// * map: the codemap object used for diagnostics
-/// * path: the file to parse and evaluate
-/// * build: set to true if you want to evaluate a BUILD file or false to evaluate a .bzl file
-/// * env: the environment to mutate during the evaluation
-pub fn eval_file(
- map: &Arc>,
- path: &str,
- build: Dialect,
- env: &mut Environment,
- type_values: &TypeValues,
- file_loader_env: Environment,
-) -> Result {
- super::eval_file(
- map,
- path,
- build,
- env,
- type_values,
- &SimpleFileLoader::new(map, file_loader_env),
- )
-}
diff --git a/starlark/src/eval/stmt.rs b/starlark/src/eval/stmt.rs
deleted file mode 100644
index 0f1f7016..00000000
--- a/starlark/src/eval/stmt.rs
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Interpreter-ready statement
-
-use crate::eval::compiler::GlobalCompiler;
-use crate::eval::compiler::LocalCompiler;
-use crate::eval::def::DefCompiled;
-use crate::eval::expr::AssignTargetExprCompiled;
-use crate::eval::expr::AstAssignTargetExprCompiled;
-use crate::eval::expr::AstAugmentedAssignTargetExprCompiled;
-use crate::eval::expr::AstExprCompiled;
-use crate::eval::expr::AugmentedAssignTargetExprCompiled;
-use crate::eval::expr::ExprCompiled;
-use crate::eval::globals::Globals;
-use crate::syntax::ast::AstStatement;
-use crate::syntax::ast::AstString;
-use crate::syntax::ast::AugmentedAssignOp;
-use crate::syntax::ast::Statement;
-use crate::values::frozen::FrozenValue;
-use crate::values::inspect::Inspectable;
-use crate::values::none::NoneType;
-use crate::values::Value;
-use codemap::Spanned;
-use codemap_diagnostic::Diagnostic;
-
-#[doc(hidden)]
-pub(crate) type AstStatementCompiled = Spanned;
-
-/// Interperter-ready version of [`Statement`](crate::syntax::ast::Statement)
-#[derive(Debug, Clone)]
-pub(crate) enum StatementCompiled {
- Break,
- Continue,
- Return(AstExprCompiled),
- Expression(AstExprCompiled),
- Assign(AstAssignTargetExprCompiled, AstExprCompiled),
- AugmentedAssign(
- AstAugmentedAssignTargetExprCompiled,
- AugmentedAssignOp,
- AstExprCompiled,
- ),
- IfElse(AstExprCompiled, BlockCompiled, BlockCompiled),
- For(AstAssignTargetExprCompiled, AstExprCompiled, BlockCompiled),
- Def(DefCompiled),
- Load(AstString, Vec<(AstString, AstString)>),
-}
-
-#[derive(Debug, Clone)]
-pub(crate) struct BlockCompiled(pub(crate) Vec);
-
-impl BlockCompiled {
- fn compile_local_stmts(
- stmts: Vec,
- compiler: &mut LocalCompiler,
- ) -> Result {
- let mut r = Vec::new();
- for stmt in stmts {
- r.extend(Self::compile_local(stmt, compiler)?.0);
- }
- Ok(BlockCompiled(r))
- }
-
- pub(crate) fn compile_local(
- stmt: AstStatement,
- compiler: &mut LocalCompiler,
- ) -> Result {
- Ok(BlockCompiled(vec![Spanned {
- span: stmt.span,
- node: match stmt.node {
- Statement::Def(..) => unreachable!(),
- Statement::For(var, over, body) => {
- let over = ExprCompiled::compile(over, compiler)?;
- StatementCompiled::For(
- AssignTargetExprCompiled::compile(var, compiler)?,
- over,
- BlockCompiled::compile_local(body, compiler)?,
- )
- }
- Statement::Return(Some(expr)) => {
- StatementCompiled::Return(ExprCompiled::compile(expr, compiler)?)
- }
- Statement::Return(None) => StatementCompiled::Return(Box::new(Spanned {
- span: stmt.span,
- node: ExprCompiled::Value(FrozenValue::from(NoneType::None)),
- })),
- Statement::If(cond, then_block) => StatementCompiled::IfElse(
- ExprCompiled::compile(cond, compiler)?,
- BlockCompiled::compile_local(then_block, compiler)?,
- BlockCompiled(Vec::new()),
- ),
- Statement::IfElse(cond, then_block, else_block) => StatementCompiled::IfElse(
- ExprCompiled::compile(cond, compiler)?,
- BlockCompiled::compile_local(then_block, compiler)?,
- BlockCompiled::compile_local(else_block, compiler)?,
- ),
- Statement::Statements(stmts) => {
- return BlockCompiled::compile_local_stmts(stmts, compiler)
- }
- Statement::Expression(e) => {
- StatementCompiled::Expression(ExprCompiled::compile(e, compiler)?)
- }
- Statement::Assign(left, right) => StatementCompiled::Assign(
- AssignTargetExprCompiled::compile(left, compiler)?,
- ExprCompiled::compile(right, compiler)?,
- ),
- Statement::AugmentedAssign(left, op, right) => StatementCompiled::AugmentedAssign(
- AugmentedAssignTargetExprCompiled::compile_impl(left, compiler)?,
- op,
- ExprCompiled::compile(right, compiler)?,
- ),
- Statement::Load(module, args) => StatementCompiled::Load(module, args),
- Statement::Pass => return Ok(BlockCompiled(Vec::new())),
- Statement::Break => StatementCompiled::Break,
- Statement::Continue => StatementCompiled::Continue,
- },
- }]))
- }
-
- fn compile_global_stmts(
- stmts: Vec,
- globals: &mut Globals,
- ) -> Result {
- let mut r = Vec::new();
- for stmt in stmts {
- r.extend(Self::compile_global(stmt, globals)?.0);
- }
- Ok(BlockCompiled(r))
- }
-
- pub(crate) fn compile_global(
- stmt: AstStatement,
- globals: &mut Globals,
- ) -> Result {
- Ok(BlockCompiled(vec![Spanned {
- span: stmt.span,
- node: match stmt.node {
- Statement::Def(name, params, suite) => {
- let slot = globals.register_global(&name.node);
- StatementCompiled::Def(DefCompiled::new(name, slot, params, suite)?)
- }
- Statement::For(var, over, body) => StatementCompiled::For(
- AssignTargetExprCompiled::compile(var, &mut GlobalCompiler::new(globals))?,
- ExprCompiled::compile_global(over, globals)?,
- BlockCompiled::compile_global(body, globals)?,
- ),
- Statement::If(cond, then_block) => StatementCompiled::IfElse(
- ExprCompiled::compile_global(cond, globals)?,
- BlockCompiled::compile_global(then_block, globals)?,
- BlockCompiled(Vec::new()),
- ),
- Statement::IfElse(cond, then_block, else_block) => StatementCompiled::IfElse(
- ExprCompiled::compile_global(cond, globals)?,
- BlockCompiled::compile_global(then_block, globals)?,
- BlockCompiled::compile_global(else_block, globals)?,
- ),
- Statement::Statements(stmts) => {
- return BlockCompiled::compile_global_stmts(stmts, globals)
- }
- Statement::Expression(expr) => {
- StatementCompiled::Expression(ExprCompiled::compile_global(expr, globals)?)
- }
- Statement::Return(Some(expr)) => {
- StatementCompiled::Return(ExprCompiled::compile_global(expr, globals)?)
- }
- Statement::Return(None) => StatementCompiled::Return(Box::new(Spanned {
- span: stmt.span,
- node: ExprCompiled::Value(FrozenValue::from(NoneType::None)),
- })),
- Statement::Assign(target, source) => StatementCompiled::Assign(
- AssignTargetExprCompiled::compile(target, &mut GlobalCompiler::new(globals))?,
- ExprCompiled::compile_global(source, globals)?,
- ),
- Statement::AugmentedAssign(target, op, source) => {
- StatementCompiled::AugmentedAssign(
- AugmentedAssignTargetExprCompiled::compile_impl(
- target,
- &mut GlobalCompiler::new(globals),
- )?,
- op,
- ExprCompiled::compile_global(source, globals)?,
- )
- }
- Statement::Load(path, map) => StatementCompiled::Load(path, map),
- Statement::Pass => return Ok(BlockCompiled(Vec::new())),
- Statement::Break => StatementCompiled::Break,
- Statement::Continue => StatementCompiled::Continue,
- },
- }]))
- }
-}
-
-impl Inspectable for BlockCompiled {
- fn inspect(&self) -> Value {
- self.0.inspect()
- }
-}
-
-impl Inspectable for StatementCompiled {
- fn inspect(&self) -> Value {
- let (name, param): (&str, Value) = match self {
- StatementCompiled::Break => ("break", Value::from(NoneType::None)),
- StatementCompiled::Continue => ("continue", Value::from(NoneType::None)),
- StatementCompiled::Return(e) => ("return", e.inspect()),
- StatementCompiled::Expression(e) => ("expression", e.inspect()),
- StatementCompiled::Assign(t, e) => ("assign", (t, e).inspect()),
- StatementCompiled::AugmentedAssign(t, op, e) => {
- ("augmented_assign", (t, format!("{:?}", op), e).inspect())
- }
- StatementCompiled::IfElse(cond, then_block, else_block) => {
- ("if_else", (cond, then_block, else_block).inspect())
- }
- StatementCompiled::For(var, over, block) => ("for", (var, over, block).inspect()),
- StatementCompiled::Def(def) => ("def", def.name.inspect()),
- StatementCompiled::Load(what, bindings) => ("load", (what, bindings).inspect()),
- };
- Value::from((Value::from(name), param))
- }
-}
diff --git a/starlark/src/eval/tests.rs b/starlark/src/eval/tests.rs
deleted file mode 100644
index 5c33d392..00000000
--- a/starlark/src/eval/tests.rs
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-use crate::environment::Environment;
-use crate::environment::TypeValues;
-use crate::eval::eval;
-use crate::eval::EvalException;
-use crate::eval::FileLoader;
-use crate::eval::{noload, RECURSION_ERROR_CODE};
-use crate::syntax::dialect::Dialect;
-use crate::testutil::starlark_no_diagnostic;
-use crate::values::Value;
-use codemap::CodeMap;
-use std::sync::{Arc, Mutex};
-
-#[test]
-fn arithmetic_test() {
- starlark_ok!("(1 + 2 == 3)");
- starlark_ok!("(1 * 2 == 2)");
- starlark_ok!("(-1 * 2 == -2)");
- starlark_ok!("(5 // 2 == 2)");
- starlark_ok!("(5 % 2 == 1)");
-}
-
-#[test]
-fn alias_test() {
- starlark_ok!(
- r#"
-a = [1, 2, 3]
-b = a
-a[2] = 0
-a == [1, 2, 0] and b == [1, 2, 0]
-"#
- )
-}
-
-#[test]
-fn recursive_list() {
- starlark_fail!(
- r#"
-cyclic = [1, 2, 3]
-cyclic[1] = cyclic
-"#
- )
-}
-
-#[test]
-fn funcall_test() {
- const F: &str = "
-def f1():
- return 1
-
-def f2(a): return a
-
-def f3(a, b, c):
- return a + b + c
-
-def f4(a, *args):
- r = a
- for i in args:
- r += i
- return r
-
-def f5(a, **kwargs): return kwargs
-
-def rec1(): rec1()
-
-def rec2(): rec3()
-def rec3(): rec4()
-def rec4(): rec5()
-def rec5(): rec6()
-def rec6(): rec2()
-";
- starlark_ok!(F, "(f1() == 1)");
- starlark_ok!(F, "(f2(2) == 2)");
- starlark_ok!(F, "(f3(1, 2, 3) == 6)");
- starlark_ok!(F, "(f4(1, 2, 3) == 6)");
- starlark_ok!(F, "(f5(2) == {})");
- starlark_ok!(F, "(f5(a=2) == {})");
- starlark_ok!(F, "(f5(1, b=2) == {'b': 2})");
- starlark_fail!(F, "rec1()", RECURSION_ERROR_CODE);
- starlark_fail!(F, "rec2()", RECURSION_ERROR_CODE);
- // multiple argument with the same name should not be allowed
- starlark_fail!("def f(a, a=2): pass");
- // Invalid order of parameter
- starlark_fail!("def f(a, *args, b): pass");
- starlark_fail!("def f(a, *args, b=1): pass");
- starlark_fail!("def f(a, b=1, *args, c=1): pass");
- starlark_fail!("def f(a, **kwargs, b=1): pass");
- starlark_fail!("def f(a, b=1, **kwargs, c=1): pass");
- starlark_fail!("def f(a, **kwargs, *args): pass");
-}
-
-#[test]
-fn sets_disabled() {
- let (mut env, type_values) = crate::stdlib::global_environment();
- let err = starlark_no_diagnostic(&mut env, "s = {1, 2, 3}", &type_values).unwrap_err();
- assert_eq!(
- err.message,
- "Type `set` is not supported. Perhaps you need to enable some crate feature?".to_string()
- );
- assert_eq!(err.level, codemap_diagnostic::Level::Error);
- assert_eq!(
- err.code,
- Some(crate::values::error::NOT_SUPPORTED_ERROR_CODE.to_string())
- );
-}
-
-#[test]
-fn sets() {
- fn env_with_set() -> (Environment, TypeValues) {
- let (mut env, mut type_values) = crate::stdlib::global_environment();
- crate::linked_hash_set::global(&mut env, &mut type_values);
- (env, type_values)
- }
-
- fn starlark_ok_with_global_env(snippet: &str) {
- let (mut env, type_values) = env_with_set();
- assert!(starlark_no_diagnostic(&mut env, snippet, &type_values,).unwrap());
- }
-
- starlark_ok_with_global_env(
- "s1 = {1, 2, 3, 1} ; s2 = set([1, 2, 3]) ; len(s1) == 3 and s1 == s2",
- );
- starlark_ok_with_global_env("list(set([1, 2, 3, 1])) == [1, 2, 3]");
- starlark_ok_with_global_env("list(set()) == []");
- starlark_ok_with_global_env("not set()");
-
- let (parent_env, type_values) = env_with_set();
- assert!(starlark_no_diagnostic(
- &mut parent_env.child("child"),
- "len({1, 2}) == 2",
- &type_values,
- )
- .unwrap());
-}
-
-#[test]
-fn test_context_captured() {
- #[derive(Clone)]
- struct TestContextCapturedFileLoader {}
-
- impl FileLoader for TestContextCapturedFileLoader {
- fn load(&self, path: &str, type_values: &TypeValues) -> Result {
- assert_eq!("f.bzl", path);
- let mut env = Environment::new("new");
- // Check that `x` is captured with the function
- let f_bzl = r#"
-x = 17
-def f(): return x
-"#;
- noload::eval(
- &Arc::new(Mutex::new(CodeMap::new())),
- path,
- f_bzl,
- Dialect::Bzl,
- &mut env,
- type_values,
- )
- .unwrap();
- env.freeze();
- Ok(env)
- }
- }
-
- let mut env = Environment::new("z");
- // Import `f` but do not import `x`
- let program = "load('f.bzl', 'f')\nf()";
- assert_eq!(
- Value::new(17),
- eval(
- &Arc::new(Mutex::new(CodeMap::new())),
- "outer.build",
- program,
- Dialect::Build,
- &mut env,
- &TypeValues::default(),
- &TestContextCapturedFileLoader {}
- )
- .unwrap()
- );
-}
-
-#[test]
-fn test_type_values_are_imported_from_caller() {
- use crate::starlark_fun;
- use crate::starlark_module;
- use crate::starlark_parse_param_type;
- use crate::starlark_signature;
- use crate::starlark_signature_extraction;
- use crate::starlark_signatures;
-
- starlark_module! { string_truncate =>
- string.truncate(this: String, len: usize) {
- // This works properly only for ASCII, but that enough for a test
- this.truncate(len);
- Ok(Value::new(this))
- }
- }
-
- struct MyFileLoader {}
-
- impl FileLoader for MyFileLoader {
- fn load(&self, path: &str, type_values: &TypeValues) -> Result {
- assert_eq!("utils.bzl", path);
-
- let mut env = Environment::new("utils.bzl");
- noload::eval(
- &Arc::new(Mutex::new(CodeMap::new())),
- "utils.bzl",
- "def truncate_strings(strings, len): return [s.truncate(len) for s in strings]",
- Dialect::Bzl,
- &mut env,
- type_values,
- )?;
- Ok(env)
- }
- }
-
- let mut env = Environment::new("my.bzl");
-
- let mut type_values = TypeValues::default();
- string_truncate(&mut Environment::new("ignore"), &mut type_values);
-
- // Note `string.truncate` is not available in either `utils.bzl` or `my.bzl`,
- // but this code works.
- let result = eval(
- &Arc::new(Mutex::new(CodeMap::new())),
- "my.bzl",
- "load('utils.bzl', 'truncate_strings'); truncate_strings(['abc', 'de'], 2)",
- Dialect::Bzl,
- &mut env,
- &type_values,
- &MyFileLoader {},
- )
- .unwrap();
-
- assert_eq!("[\"ab\", \"de\"]", result.to_str());
-}
diff --git a/starlark/src/lib.rs b/starlark/src/lib.rs
deleted file mode 100644
index fdbbe929..00000000
--- a/starlark/src/lib.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2018 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! A Starlark interpreter library in rust.
-//!
-//! Starlark, formerly codenamed Skylark, is a non-Turing complete language based on Python that
-//! was made for the [Bazel build system](https://bazel.build) to define compilation plugin.
-//!
-//! Starlark has at least 3 implementations: a [Java one for Bazel](
-//! https://github.com/bazelbuild/bazel/tree/master/src/main/java/com/google/devtools/skylark),
-//! a [go one](https://github.com/google/skylark) and this one.
-//!
-//! This interpreter was made using the [specification from the go version](
-//! https://github.com/google/skylark/blob/a0e5de7e63b47e716cca7226662a4c95d47bf873/doc/spec.md)
-//! and the Python 3 documentation when things were unclear.
-//!
-//! This interpreter does not support most of the go extensions (e.g. bitwise operator or
-//! floating point). It does not include the `set()` type either (the Java implementation use a
-//! custom type, `depset`, instead). It uses signed 64-bit integer.
-//!
-//! # Usage
-//!
-//! The library can be used to define a dialect of Starlark (e.g. for a build system).
-//!
-//! The methods in the [eval](eval) modules can be used to evaluate Starlark code:
-//! * General purpose [eval](eval::eval) and [eval_file](eval::eval_file) function evaluate
-//! Starlark code and return the result of the last statement. Those are generic purpose
-//! function to be used when rewiring load statements.
-//! * A file loader that simply load relative path to the program is provided by the
-//! [eval::simple] module. This module also contains version of [eval](eval::simple::eval) and
-//! [eval_file](eval::simple::eval_file) that use this file loader.
-//! * Interactive versions of those function are provided in the [eval::interactive] module.
-//! Those function are printing the result / diagnostic to the stdout / stderr instead of
-//! returning an output.
-//!
-//! # Defining a Starlark dialect
-//!
-//! To specify a new Starlark dialect, the global [Environment](environment::Environment) can be
-//! edited, adding functions or constants. The [starlark_module!](starlark_module) macro let you
-//! define new function with limited boilerplate.
-//!
-//! Those added function or macros can however return their own type, all of them should implement
-//! the [TypedValue](values::TypedValue) trait. See the documentation of the [values](values)
-//! module.
-//!
-//! # Content of the default global environment
-//!
-//! The default global environment is returned by the
-//! [stdlib::global_environment] function and add the `True`,
-//! `False` and `None` constants, as well as the functions in the [stdlib] module.
-//!
-//! # Provided types
-//!
-//! The [values](values) module provide the following types:
-//!
-//! * integer (signed 64bit), bool, and NoneType,
-//! * [string](values::string),
-//! * [dictionary](values::dict),
-//! * [list](values::list),
-//! * [tuple](values::tuple), and
-//! * [function](values::function).
-
-#![deny(broken_intra_doc_links)]
-
-#[cfg(test)]
-#[macro_use]
-pub(crate) mod testutil;
-
-pub mod environment;
-#[doc(hidden)]
-pub mod syntax;
-#[macro_use]
-pub mod values;
-#[macro_use]
-pub mod eval;
-#[macro_use]
-pub mod stdlib;
-pub mod linked_hash_set;
diff --git a/starlark/src/linked_hash_set/mod.rs b/starlark/src/linked_hash_set/mod.rs
deleted file mode 100644
index bbc81894..00000000
--- a/starlark/src/linked_hash_set/mod.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-use crate::environment::{Environment, TypeValues};
-
-pub(crate) mod set_impl;
-mod stdlib;
-pub(crate) mod value;
-
-/// Include `set` constructor and set functions in environment.
-pub fn global(env: &mut Environment, type_values: &mut TypeValues) {
- self::stdlib::global(env, type_values);
- env.enable_set_literals();
-}
diff --git a/starlark/src/linked_hash_set/set_impl.rs b/starlark/src/linked_hash_set/set_impl.rs
deleted file mode 100644
index 13f91677..00000000
--- a/starlark/src/linked_hash_set/set_impl.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Simple implementation of `LinkedHashSet`.
-
-use linked_hash_map::{Entry, LinkedHashMap};
-use std::hash::Hash;
-
-/// `LinkedHashSet` is a tiny wrapper around `LinkedHashMap`.
-///
-/// Using `LinkedHashMap` directly to avoid adding extra dependency.
-#[derive(PartialEq, Eq, Debug, Clone)]
-pub(crate) struct LinkedHashSet {
- map: LinkedHashMap,
-}
-
-impl Default for LinkedHashSet {
- fn default() -> Self {
- LinkedHashSet::new()
- }
-}
-
-impl LinkedHashSet {
- pub fn new() -> Self {
- LinkedHashSet {
- map: LinkedHashMap::new(),
- }
- }
-
- pub fn _with_capacity(capacity: usize) -> Self {
- LinkedHashSet {
- map: LinkedHashMap::with_capacity(capacity),
- }
- }
-
- pub fn len(&self) -> usize {
- self.map.len()
- }
-
- pub fn is_empty(&self) -> bool {
- self.map.is_empty()
- }
-
- pub fn clear(&mut self) {
- self.map.clear()
- }
-
- pub fn iter(&self) -> impl Iterator- {
- self.map.keys()
- }
-
- pub fn contains(&self, value: &K) -> bool {
- self.map.get(value).is_some()
- }
-
- pub fn insert(&mut self, value: K) {
- self.map.insert(value, ());
- }
-
- pub fn insert_if_absent(&mut self, value: K) {
- if let Entry::Vacant(e) = self.map.entry(value) {
- e.insert(());
- }
- }
-
- pub fn remove(&mut self, value: &K) -> bool {
- self.map.remove(value).is_some()
- }
-
- /// Items in both sets
- pub fn intersection<'a>(&'a self, other: &'a LinkedHashSet
) -> impl Iterator- {
- let (a, b) = if self.len() <= other.len() {
- (self, other)
- } else {
- (other, self)
- };
- a.iter().filter(move |k| b.contains(k))
- }
-
- /// Items which are in `self`, but not in `other`.
- pub fn difference<'a>(&'a self, other: &'a LinkedHashSet
) -> impl Iterator- {
- self.iter().filter(move |k| !other.contains(k))
- }
-
- /// Items which are in `self` or in `other` but not in `both`
- pub fn symmetric_difference<'a>(
- &'a self,
- other: &'a LinkedHashSet
,
- ) -> impl Iterator- {
- self.difference(other).chain(other.difference(self))
- }
-
- pub fn is_subset(&self, other: &LinkedHashSet
) -> bool {
- self.len() <= other.len() && self.iter().all(|k| other.contains(k))
- }
-
- pub fn pop_front(&mut self) -> Option {
- self.map.pop_front().map(|(k, ())| k)
- }
-
- pub fn pop_back(&mut self) -> Option {
- self.map.pop_back().map(|(k, ())| k)
- }
-}
-
-impl<'a, K: Hash + Eq> IntoIterator for &'a LinkedHashSet {
- type Item = &'a K;
- type IntoIter = linked_hash_map::Keys<'a, K, ()>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.map.keys()
- }
-}
diff --git a/starlark/src/linked_hash_set/stdlib.rs b/starlark/src/linked_hash_set/stdlib.rs
deleted file mode 100644
index d63e12a3..00000000
--- a/starlark/src/linked_hash_set/stdlib.rs
+++ /dev/null
@@ -1,607 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Methods for the `set` type.
-
-use crate::values::error::*;
-use crate::values::none::NoneType;
-use crate::values::*;
-
-use crate::linked_hash_set::value::Set;
-
-// Errors -- UF = User Failure -- Failure that should be expected by the user (e.g. from a fail()).
-pub const SET_REMOVE_ELEMENT_NOT_FOUND_ERROR_CODE: &str = "UF30";
-
-macro_rules! ok {
- ($e:expr) => {
- return Ok(Value::from($e));
- };
-}
-
-starlark_module! {global =>
- /// set: construct a set.
- ///
- /// `set(x)` returns a new set containing the elements of the
- /// iterable sequence x.
- ///
- /// With no argument, `set()` returns a new empty set.
- set(?a, /) {
- let mut s = Set::default();
- if let Some(a) = a {
- for x in &a.iter()? {
- s.insert_if_absent(x)?;
- }
- }
- ok!(s)
- }
-
- /// set.add: append an element to a set.
- ///
- /// `S.add(x)` adds `x` to the set S, and returns `None`.
- ///
- /// `add` fails if the set is frozen or has active iterators.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set()
- /// # (
- /// x.add(1) == None
- /// # and
- /// x.add(2) == None
- /// # and
- /// x.add(3) == None
- /// # and
- /// x.add(1) == None
- /// # and
- /// x == set([1, 2, 3])
- /// # )"#).unwrap());
- /// ```
- set.add(this, el, /) {
- let mut this = this.downcast_mut::()?.unwrap();
- this.insert_if_absent(el)?;
- Ok(Value::new(NoneType::None))
- }
-
- /// set.clear: clear a set
- ///
- /// `S.clear()` removes all the elements of the set S and returns `None`.
- ///
- /// It fails if the set is frozen or if there are active iterators.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3])
- /// # (
- /// x.clear() == None
- /// # and
- /// x == set()
- /// # )"#).unwrap());
- /// ```
- set.clear(this) {
- let mut this = this.downcast_mut::()?.unwrap();
- this.clear();
- Ok(Value::new(NoneType::None))
- }
-
- /// set.copy: return a set containing all of the elements of this set, in the same order.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3])
- /// y = x.copy()
- /// x.add(4)
- /// y.add(5)
- /// # (
- /// x == set([1, 2, 3, 4])
- /// # and
- /// y == set([1, 2, 3, 5])
- /// # )"#).unwrap());
- /// ```
- set.copy(this) {
- let this = this.downcast_ref::().unwrap();
- ok!(this.copy())
- }
-
- /// set.difference: return a set containing all of the elements of this set, without any
- /// elements present in any of the passed sets.
- ///
- /// `S.difference(x, y)` returns `S - x - y`.
- ///
- /// `difference` fails if its argument(s) are not iterable.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// y = [1]
- /// z = set([2, 3])
- /// (
- /// x.difference(y, z) == set([4])
- /// # and
- /// x.difference() == x
- /// # and
- /// x == set([1, 2, 3, 4])
- /// # and
- /// y == [1]
- /// # and
- /// z == set([2, 3])
- /// # )"#).unwrap());
- /// ```
- set.difference(this, *others) {
- let mut ret = Set::default();
- for el in &this.iter()? {
- let mut is_in_any_other = false;
- for other in &others {
- if other.contains(&el)? {
- is_in_any_other = true;
- break;
- }
- }
- if !is_in_any_other {
- ret.insert_if_absent(el)?;
- }
- }
- ok!(ret)
- }
-
- /// set.difference_update: remove all elements of another iterable from this set.
- ///
- /// `S.difference_update(x)` removes all values in x from S.
- ///
- /// `difference_update` fails if its argument is not iterable.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// x.difference_update(set([1]))
- /// x.difference_update([2, 3])
- /// x == set([4])
- /// # "#).unwrap());
- /// ```
- set.difference_update(this, other, /) {
- let mut this = this.downcast_mut::()?.unwrap();
- let previous_length = this.len() as usize;
- let mut values = Vec::with_capacity(previous_length);
- for el in this.get_content() {
- if !other.contains(el.get_value())? {
- values.push(el.clone());
- }
- }
- this.clear();
- for value in values.into_iter() {
- this.insert(value.into())?;
- }
- Ok(Value::new(NoneType::None))
- }
-
- /// set.discard: remove a value from a set if it is present.
- ///
- /// `S.discard(x)` removes the the value `x` from the set S if it is present, and returns `None`.
- ///
- /// `discard` fails if the set is frozen, or has active iterators.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3])
- /// # (
- /// x.discard(2) == None
- /// # and
- /// x.discard(4) == None
- /// # and
- /// x == set([1, 3])
- /// # )"#).unwrap());
- /// ```
- set.discard(this, needle, /) {
- let mut this = this.downcast_mut::()?.unwrap();
- this.remove(&needle)?;
- Ok(Value::new(NoneType::None))
- }
-
- /// set.intersection: return a set containing all of the elements of this set which are also
- /// present in all of the passed iterables.
- ///
- /// `intersection` fails if its argument(s) are not iterable.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// y = [1, 2]
- /// z = set([2, 3])
- /// (
- /// x.intersection(y, z) == set([2])
- /// # and
- /// x.intersection() == x
- /// # and
- /// x.intersection().clear() == None
- /// # and
- /// x == set([1, 2, 3, 4])
- /// # and
- /// y == [1, 2]
- /// # and
- /// z == set([2, 3])
- /// # )"#).unwrap());
- /// ```
- set.intersection(this, *others) {
- let mut ret = Set::default();
- for el in &this.iter()? {
- let mut is_in_every_other = true;
- for other in &others {
- if !other.contains(&el)? {
- is_in_every_other = false;
- break;
- }
- }
- if is_in_every_other {
- ret.insert_if_absent(el)?;
- }
- }
- ok!(ret)
- }
-
- /// set.intersection_update: remove all elements from this set which are not in the other
- /// iterable.
- ///
- /// `S.intersection_update(x)` removes all values not in x from S.
- ///
- /// `intersection_update` fails if its argument is not iterable.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// x.intersection_update(set([1, 2]))
- /// x.intersection_update([2, 3])
- /// x == set([2])
- /// # "#).unwrap());
- /// ```
- set.intersection_update(this, other, /) {
- let mut this = this.downcast_mut::()?.unwrap();
- let previous_length = this.len();
- let mut values = Vec::with_capacity(previous_length);
- for el in this.get_content() {
- if other.contains(el.get_value())? {
- values.push(el.clone());
- }
- }
- this.clear();
- for value in values.into_iter() {
- this.insert(value.into())?;
- }
- Ok(Value::new(NoneType::None))
- }
-
- /// set.isdisjoint: return whether a set has no intersection with another set.
- ///
- /// `isdisjoint` fails if its argument is not a set.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// (
- /// x.isdisjoint(set()) == True
- /// # and
- /// x.isdisjoint(set([5])) == True
- /// # and
- /// x.isdisjoint(set([1])) == False
- /// # and
- /// x.isdisjoint(set([1, 5])) == False
- /// # )"#).unwrap());
- /// ```
- set.isdisjoint(this, other, /) {
- ok!(Set::compare(&this, &other, &|s1, s2| Ok(s1.intersection(s2).next().is_none()))?)
- }
-
- /// set.issubset: return whether another set contains this set.
- ///
- /// `issubset` fails if its argument is not a set.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// (
- /// x.issubset(set()) == False
- /// # and
- /// x.issubset(set([1, 2, 3])) == False
- /// # and
- /// x.issubset(set([4, 3, 2, 1])) == True
- /// # and
- /// x.issubset(set([1, 2, 3, 4, 5])) == True
- /// # )"#).unwrap());
- /// ```
- set.issubset(this, other, /) {
- ok!(Set::compare(&this, &other, &|this, other| Ok(this.is_subset(other)))?)
- }
-
- /// set.issubset: return whether this set contains another set.
- ///
- /// `issuperset` fails if its argument is not a set.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// (
- /// x.issuperset(set()) == True
- /// # and
- /// x.issuperset(set([1, 2, 3])) == True
- /// # and
- /// x.issuperset(set([4, 3, 2, 1])) == True
- /// # and
- /// x.issuperset(set([1, 2, 3, 4, 5])) == False
- /// # )"#).unwrap());
- /// ```
- set.issuperset(this, other, /) {
- ok!(Set::compare(&this, &other, &|this, other| Ok(other.is_subset(this)))?)
- }
-
- /// set.pop: removes and returns the last element of a set.
- ///
- /// `S.pop([index])` removes and returns the last element of the set S, or,
- /// if the optional index is provided, at that index.
- ///
- /// `pop` fails if the index is negative or not less than the length of
- /// the set, of if the set is frozen or has active iterators.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// # (
- /// x.pop(1) == 2
- /// # and
- /// x.pop() == 4
- /// # and
- /// x.pop(0) == 1
- /// # and
- /// x == set([3])
- /// # )"#).unwrap());
- /// ```
- set.pop(this, index = NoneType::None, /) {
- let mut this = this.downcast_mut::()?.unwrap();
- let length = this.len() as i64;
- let index = if index.get_type() == "NoneType" {
- length - 1
- } else {
- index.to_int()?
- };
- if index < 0 || index >= length {
- return Err(ValueError::IndexOutOfBound(index));
- }
- let index = index as usize;
- let ret = if index == (length - 1) as usize {
- this.pop_back()
- } else if index == 0 {
- this.pop_front()
- } else {
- let ret = this.get_content().iter().nth(index).cloned();
- let values: Vec<_> = this.get_content().iter().take(index).chain(this.get_content().iter().skip(index + 1)).cloned().collect();
- this.clear();
- for value in values {
- this.insert(value.into())?;
- }
- ret.map(Into::into)
- };
- Ok(ret.unwrap())
- }
-
- /// set.remove: remove a value from a set
- ///
- /// `S.remove(x)` removes the the value `x` from the set S, and returns `None`.
- ///
- /// `remove` fails if the set does not contain `x`, is frozen, or has active iterators.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3])
- /// # (
- /// x.remove(2) == None
- /// # and
- /// x == set([1, 3])
- /// # )"#).unwrap());
- /// ```
- ///
- /// A subsequent call to `x.remove(2)` would yield an error because the element won't be
- /// found.
- set.remove(this, needle, /) {
- let mut this = this.downcast_mut::()?.unwrap();
- let did_remove = this.remove(&needle)?;
- if did_remove {
- Ok(Value::new(NoneType::None))
- } else {
- starlark_err!(
- SET_REMOVE_ELEMENT_NOT_FOUND_ERROR_CODE,
- format!("Element '{}' not found in '{}'", needle, this.to_str()),
- "not found".to_owned()
- )
- }
- }
-
- /// set.symmetric_difference: return a set containing the elements present in exactly one of
- /// this and another set.
- ///
- /// `symmetric_difference` fails if its argument is not a set.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3, 4])
- /// y = set([0, 1, 2])
- /// z = set([5])
- /// (
- /// x.symmetric_difference(y) == set([3, 4, 0])
- /// # and
- /// y.symmetric_difference(x) == set([0, 3, 4])
- /// # and
- /// x.symmetric_difference(z) == set([1, 2, 3, 4, 5])
- /// # )"#).unwrap());
- /// ```
- set.symmetric_difference(this, other, /) {
- Set::compare(&this, &other, &|s1, s2| {
- Ok(Set::from(s1.symmetric_difference(s2).cloned().collect()).unwrap())
- })
- }
-
- /// set.symmetric_difference_update: update this set to contain the symmetric difference of
- /// this and another set.
- ///
- /// `symmetric_difference_update` fails if its argument is not a set.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x1 = set([1, 2, 3, 4])
- /// x2 = set([1, 2, 3, 4])
- /// y = set([0, 1, 2])
- /// z = set([5])
- /// (
- /// x1.symmetric_difference_update(y) == None
- /// # and
- /// x1 == set([3, 4, 0])
- /// # and
- /// y == set([0, 1, 2])
- /// # and
- /// y.symmetric_difference_update(x2) == None
- /// # and
- /// y == set([0, 3, 4])
- /// # and
- /// x2 == set([1, 2, 3, 4])
- /// # and
- /// x2.symmetric_difference_update(z) == None
- /// # and
- /// x2 == set([1, 2, 3, 4, 5])
- /// # and
- /// z == set([5])
- /// # )"#).unwrap());
- /// ```
- set.symmetric_difference_update(this, other, /) {
- let symmetric_difference = Set::compare(&this, &other, &|s1, s2| {
- Ok(Set::from(s1.symmetric_difference(s2).cloned().collect()).unwrap())
- })?;
- let mut this = this.downcast_mut::()?.unwrap();
- this.clear();
- for item in &symmetric_difference.iter()? {
- this.insert(item)?;
- }
- Ok(Value::new(NoneType::None))
- }
-
- /// set.union: return a set containing all of the elements of this set, then all of the extra
- /// elements of the other iterables.
- ///
- /// `S.union(x, y)` returns a set of the union of `S` and `x` and `y`
- /// (which must be iterables)'s elements.
- ///
- /// `union` fails if its arguments are not iterable.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set([1, 2, 3])
- /// y = set([2, 4, 5])
- /// z = [5, 6]
- /// (
- /// x.union(y, z) == set([1, 2, 3, 4, 5, 6])
- /// # and
- /// x == set([1, 2, 3])
- /// # and
- /// y == set([2, 4, 5])
- /// # and
- /// z == [5, 6]
- /// # )"#).unwrap());
- /// ```
- set.union(this, *others) {
- let mut ret = Set::default();
- for el in &this.iter()? {
- ret.insert_if_absent(el)?;
- }
- for other in others {
- for el in &other.iter()? {
- ret.insert_if_absent(el)?;
- }
- }
- ok!(ret)
- }
-
- /// set.update: update a set to also contain another iterable's content.
- ///
- /// `S.update(x)` adds the elements of `x`, which must be iterable, to
- /// the set S, and returns `None`.
- ///
- /// `update` fails if `x` is not iterable, or if the set S is frozen or has active iterators.
- ///
- /// Examples:
- ///
- /// ```
- /// # use starlark::stdlib::starlark_default;
- /// # assert!(starlark_default(r#"
- /// x = set()
- /// # (
- /// x.update([1, 2, 3], set(["foo"])) == None
- /// # and
- /// x.update(["bar"]) == None
- /// # and
- /// x == set([1, 2, 3, "foo", "bar"])
- /// # )"#).unwrap());
- /// ```
- set.update(this, *others) {
- let mut this = this.downcast_mut::()?.unwrap();
- for other in others {
- for el in &other.iter()? {
- this.insert_if_absent(el)?;
- }
- }
- Ok(Value::new(NoneType::None))
- }
-}
diff --git a/starlark/src/linked_hash_set/value.rs b/starlark/src/linked_hash_set/value.rs
deleted file mode 100644
index 15c0216c..00000000
--- a/starlark/src/linked_hash_set/value.rs
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2019 The Starlark in Rust Authors
-//
-// 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
-//
-// https://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.
-
-//! Define the set type of Starlark
-use crate::linked_hash_set::set_impl::LinkedHashSet;
-use crate::values::error::ValueError;
-use crate::values::hashed_value::HashedValue;
-use crate::values::iter::TypedIterable;
-use crate::values::slice_indices::convert_slice_indices;
-use crate::values::*;
-use std::fmt;
-use std::fmt::Write as _;
-use std::num::Wrapping;
-
-#[derive(Default, Clone)]
-pub(crate) struct Set {
- content: LinkedHashSet,
-}
-
-impl Set {
- pub fn _new() -> ValueOther {
- ValueOther::default()
- }
-
- pub fn from>(values: Vec) -> Result {
- let mut result = Self::default();
- for v in values.into_iter() {
- result.content.insert_if_absent(HashedValue::new(v.into())?);
- }
- Ok(Value::new(result))
- }
-
- pub fn insert_if_absent(&mut self, v: Value) -> Result<(), ValueError> {
- let v = v.clone_for_container(self)?;
- self.content.insert_if_absent(HashedValue::new(v.clone())?);
- Ok(())
- }
-
- pub fn compare(
- v1: &Value,
- v2: &Value,
- f: &dyn Fn(
- &LinkedHashSet,
- &LinkedHashSet,
- ) -> Result