Skip to content

Commit 8f67892

Browse files
adonovancopybara-github
authored andcommitted
bazel syntax: add examples of interpreter API
RELNOTES: N/A PiperOrigin-RevId: 329940788
1 parent 2bb3b73 commit 8f67892

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

src/test/java/com/google/devtools/build/lib/syntax/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ java_test(
4848
# CpuProfilerTest.java doesn't run under OSS Bazel
4949
"EvalUtilsTest.java",
5050
"EvaluationTest.java",
51+
"Examples.java",
5152
"FunctionTest.java",
5253
"MethodLibraryTest.java",
5354
"MutabilityTest.java",
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright 2020 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package com.google.devtools.build.lib.syntax;
15+
16+
import com.google.common.collect.ImmutableMap;
17+
import com.google.common.collect.ImmutableSet;
18+
import java.io.IOException;
19+
import net.starlark.java.annot.Param;
20+
import net.starlark.java.annot.StarlarkGlobalLibrary;
21+
import net.starlark.java.annot.StarlarkMethod;
22+
23+
/**
24+
* Examples of typical API usage of the Starlark interpreter.<br>
25+
* This is not a test, but it is checked by the compiler.
26+
*/
27+
final class Examples {
28+
29+
/**
30+
* This example reads, parses, compiles, and executes a Starlark file. It returns the module,
31+
* which holds the values of global variables.
32+
*/
33+
Module execFile(String filename)
34+
throws IOException, SyntaxError.Exception, EvalException, InterruptedException {
35+
// Read input from the named file.
36+
ParserInput input = ParserInput.readFile(filename);
37+
38+
// Create the module that will be populated by executing the file.
39+
// It holds the global variables, initially empty.
40+
// Its predeclared environment defines only the standard builtins:
41+
// None, True, len, and so on.
42+
Module module = Module.create();
43+
44+
// Resolve, compile, and execute the file.
45+
//
46+
// The Mutability will be associated with all the values created by this thread.
47+
// The try-with-resources statement ensures that all values become frozen
48+
// after execution.
49+
try (Mutability mu = Mutability.create(input.getFile())) {
50+
StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
51+
Starlark.execFile(input, FileOptions.DEFAULT, module, thread);
52+
}
53+
54+
return module;
55+
}
56+
57+
/**
58+
* This example evaluates a Starlark expression in the specified environment and returns its
59+
* value.
60+
*/
61+
Object evalExpr(String expr, ImmutableMap<String, Object> env)
62+
throws SyntaxError.Exception, EvalException, InterruptedException {
63+
// The apparent file name (for error messages) will be "<expr>".
64+
ParserInput input = ParserInput.fromString(expr, "<expr>");
65+
66+
// Create the module in which the expression is evaluated.
67+
// It may define additional predeclared environment bindings.
68+
Module module = Module.withPredeclared(StarlarkSemantics.DEFAULT, env);
69+
70+
// Resolve, compile, and execute the expression.
71+
try (Mutability mu = Mutability.create(input.getFile())) {
72+
StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
73+
return Starlark.eval(input, FileOptions.DEFAULT, module, thread);
74+
}
75+
}
76+
77+
/**
78+
* This advanced example reads, parses, and compiles a Starlark file to a Program, then later
79+
* executes it.
80+
*/
81+
Module compileThenExecute()
82+
throws IOException, SyntaxError.Exception, EvalException, InterruptedException {
83+
// Read and parse the named file.
84+
ParserInput input = ParserInput.readFile("my/file.star");
85+
StarlarkFile file = StarlarkFile.parse(input);
86+
87+
// Compile the program, with additional predeclared environment bindings.
88+
Program prog = Program.compileFile(file, () -> ImmutableSet.of("zero", "square"));
89+
90+
// . . .
91+
92+
// TODO(adonovan): when supported, show how the compiled program can be
93+
// saved and reloaded, to avoid repeating the cost of parsing and
94+
// compilation.
95+
96+
// Execute the compiled program to populate a module.
97+
// The module's predeclared environment must match the
98+
// names provided during compilation.
99+
Module module = Module.withPredeclared(StarlarkSemantics.DEFAULT, makeEnvironment());
100+
try (Mutability mu = Mutability.create(prog.getFilename())) {
101+
StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
102+
Starlark.execFileProgram(prog, module, thread);
103+
}
104+
return module;
105+
}
106+
107+
/** This function shows how to construct a callable Starlark value from a Java method. */
108+
ImmutableMap<String, Object> makeEnvironment() {
109+
ImmutableMap.Builder<String, Object> env = ImmutableMap.builder();
110+
env.put("zero", 0);
111+
Starlark.addMethods(env, new MyFunctions(), StarlarkSemantics.DEFAULT); // adds 'square'
112+
return env.build();
113+
}
114+
115+
/** The methods of this class are accessible from Starlark. */
116+
@StarlarkGlobalLibrary
117+
static final class MyFunctions {
118+
@StarlarkMethod(
119+
name = "square",
120+
parameters = {@Param(name = "x", type = int.class)},
121+
doc = "Returns the square of its integer argument.")
122+
public int square(int x) {
123+
return x * x;
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)