Skip to content

Commit daceac5

Browse files
authored
feat(jsruntime): closures (#236)
* refactor(jsruntime): refactoring * docs(jsruntime): update the link * style(jsparser): format comments * docs(jsruntime): documentation * refactor(jsruntime): remove unnecessary operations * refactor(jsruntime): remove unused field * refactor(jsruntime): FunctionId * feat(jstb): add the `parse` subcommand * refactor(jsruntime): move `references` from `Analyzer` to `FunctionContext` * style(jsruntime): format * refactor(jsruntime): refactoring * refactor(jsruntime): compute locations of variables at compile time * feat(jsruntime): closures * fix(jsruntime): the argument order was wrong * fix(jsruntime): capture arguments * style(jsruntime): format * fix(jsruntime): add missing case clauses * test(jsruntime): add test cases * feat(jsruntime): implement std::fmt::Debug for Capture * refactor(jsruntime): refactoring * refactor(jsruntime): rename * fix(jsruntime): workaround for #234 the test scripts should be replaced with original ones after #234 is fixed. * feat(jstb): add options * docs(jsruntime): add implementation notes * refactor(jsruntime): remove `Locator::offset` * chore(jsruntime): add TODO marks * feat(jsruntime): always create a closure for a function even if the function has no free variable. * refactor(jsruntime): Remove ValueKind::Function * refactor(jsruntime): rename * refactor(jsruntime): refactoring * refactor(jsruntime): remove argc and argv from FunctionScope * refactor(jsruntime): refactoring * refactor(jsruntime): rename * chore(jsruntime): add TODO * refactor(jsruntime): rename * fix(jsruntime): eliminate warnings in the release build * chore(tools): update the example * refactor(jsruntime): reuse the Variable type as the Value type * refactor(jsruntime): remove FunctionScope * refactor(jsruntime): add num_formal_parameters and num_locals
1 parent e635836 commit daceac5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2039
-766
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ update-devcontainer:
127127

128128
.PHONY: doc
129129
doc:
130-
cargo doc --workspace --all-features
130+
cargo doc --workspace --all-features --document-private-items
131131

132132
.PHONY: format
133133
format: format-rust format-cxx format-js

bins/jstb/src/main.rs

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@ struct CommandLine {
1616
/// A testbed for the jsruntime module.
1717
#[derive(clap::Subcommand)]
1818
enum Command {
19-
/// Compile a JavaScript program and print the compiled module.
19+
/// Parses a JavaScript program and print the result.
20+
Parse(Parse),
21+
22+
/// Compiles a JavaScript program and print the compiled module.
2023
///
21-
/// lli cannot interpret the module directly. Because it includes unresolved symbols for the
24+
/// `lli` cannot interpret the module directly. Because it includes unresolved symbols for the
2225
/// runtime function calls. At this point, there is no command-line option to output anything
2326
/// containing the runtime functions which can link to the module.
2427
Compile(Compile),
@@ -28,8 +31,16 @@ enum Command {
2831
}
2932

3033
#[derive(clap::Args)]
31-
struct Run {
32-
/// The source file of the JavaScript program to run.
34+
struct Parse {
35+
/// Prints the functions.
36+
#[arg(long)]
37+
print_functions: bool,
38+
39+
/// Prints the scope tree.
40+
#[arg(long)]
41+
print_scope_tree: bool,
42+
43+
/// The source file of the JavaScript program to parse.
3344
///
3445
/// Reads the source text from STDIN if this argument is not specified.
3546
#[arg()]
@@ -42,6 +53,19 @@ struct Compile {
4253
#[arg(long)]
4354
no_optimize: bool,
4455

56+
/// The source file of the JavaScript program to compile.
57+
///
58+
/// Reads the source text from STDIN if this argument is not specified.
59+
#[arg()]
60+
source: Option<PathBuf>,
61+
}
62+
63+
#[derive(clap::Args)]
64+
struct Run {
65+
/// Disable optimization.
66+
#[arg(long)]
67+
no_optimize: bool,
68+
4569
/// The source file of the JavaScript program to run.
4670
///
4771
/// Reads the source text from STDIN if this argument is not specified.
@@ -55,23 +79,31 @@ fn main() -> Result<()> {
5579
let cl = CommandLine::parse();
5680
let mut runtime = Runtime::new().with_host_function("print", print);
5781
match cl.command {
82+
Command::Parse(args) => {
83+
let source = read_source(args.source.as_ref())?;
84+
let program = runtime.parse_script(&source)?;
85+
if args.print_functions {
86+
println!("### functions");
87+
program.print_functions("");
88+
}
89+
if args.print_scope_tree {
90+
println!("### scope tree");
91+
program.print_scope_tree("");
92+
}
93+
Ok(())
94+
}
5895
Command::Compile(args) => {
5996
let source = read_source(args.source.as_ref())?;
60-
let module = match runtime.compile_script(&source, !args.no_optimize) {
61-
Some(module) => module,
62-
None => anyhow::bail!("Failed to parse"),
63-
};
97+
let program = runtime.parse_script(&source)?;
98+
let module = runtime.compile(&program, !args.no_optimize)?;
6499
module.print(false); // to STDOUT
65100
Ok(())
66101
}
67102
Command::Run(args) => {
68103
let source = read_source(args.source.as_ref())?;
69-
// Always perform optimization.
70-
let module = match runtime.compile_script(&source, true) {
71-
Some(module) => module,
72-
None => anyhow::bail!("Failed to parse"),
73-
};
74-
match runtime.eval(module) {
104+
let program = runtime.parse_script(&source)?;
105+
let module = runtime.compile(&program, !args.no_optimize)?;
106+
match runtime.evaluate(module) {
75107
Ok(_) => Ok(()),
76108
Err(v) => anyhow::bail!("Uncaught {v:?}"),
77109
}

0 commit comments

Comments
 (0)