Skip to content

Commit 5425a67

Browse files
authored
feat: evaluator (#2816)
1 parent de01bb0 commit 5425a67

File tree

8 files changed

+1037
-78
lines changed

8 files changed

+1037
-78
lines changed

prql-compiler/prqlc/src/cli.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use ariadne::Source;
55
use clap::{CommandFactory, Parser, Subcommand, ValueHint};
66
use clio::Output;
77
use itertools::Itertools;
8+
use prql_compiler::ast::pl::StmtKind;
89
use std::io::Write;
910
use std::ops::Range;
1011
use std::path::PathBuf;
@@ -75,11 +76,8 @@ enum Command {
7576
input: clio_extended::Input,
7677
},
7778

78-
/// Parse, resolve & combine source with comments annotating relation type
79-
Annotate(IoArgs),
80-
81-
/// Parse & resolve, but don't lower into RQ
82-
Debug(IoArgs),
79+
#[command(subcommand)]
80+
Debug(DebugCommand),
8381

8482
/// Parse, resolve & lower into RQ
8583
Resolve {
@@ -133,6 +131,22 @@ enum Command {
133131
},
134132
}
135133

134+
/// Commands for meant for debugging, prone to change
135+
#[derive(Subcommand, Debug, Clone)]
136+
pub enum DebugCommand {
137+
/// Parse & resolve, but don't lower into RQ
138+
Semantics(IoArgs),
139+
140+
/// Parse & evaluate expression down to a value
141+
///
142+
/// Cannot contain references to tables or any other outside sources.
143+
/// Meant as a playground for testing out language design decisions.
144+
Eval(IoArgs),
145+
146+
/// Parse, resolve & combine source with comments annotating relation type
147+
Annotate(IoArgs),
148+
}
149+
136150
#[derive(clap::Args, Default, Debug, Clone)]
137151
pub struct IoArgs {
138152
#[arg(value_parser, default_value = "-", value_hint(ValueHint::AnyPath))]
@@ -233,7 +247,7 @@ impl Command {
233247
Format::Yaml => serde_yaml::to_string(&ast)?.into_bytes(),
234248
}
235249
}
236-
Command::Debug(_) => {
250+
Command::Debug(DebugCommand::Semantics(_)) => {
237251
semantic::load_std_lib(sources);
238252
let stmts = prql_to_pl_tree(sources)?;
239253

@@ -250,7 +264,7 @@ impl Command {
250264
out.extend(format!("\n{context:#?}\n").into_bytes());
251265
out
252266
}
253-
Command::Annotate(_) => {
267+
Command::Debug(DebugCommand::Annotate(_)) => {
254268
let (_, source) = sources.sources.clone().into_iter().exactly_one().or_else(
255269
|_| bail!(
256270
"Currently `annotate` only works with a single source, but found multiple sources: {:?}",
@@ -280,6 +294,29 @@ impl Command {
280294
// combine with source
281295
combine_prql_and_frames(&source, frames).as_bytes().to_vec()
282296
}
297+
Command::Debug(DebugCommand::Eval(_)) => {
298+
let stmts = prql_to_pl_tree(sources)?;
299+
300+
let mut res = String::new();
301+
302+
for (path, stmts) in stmts.sources {
303+
res += &format!("# {}\n\n", path.to_str().unwrap());
304+
305+
for stmt in stmts {
306+
if let StmtKind::VarDef(def) = stmt.kind {
307+
res += &format!("## {}\n", stmt.name);
308+
309+
let val = semantic::eval(*def.value)
310+
.map_err(downcast)
311+
.map_err(|e| e.composed(sources))?;
312+
res += &val.to_string();
313+
res += "\n\n";
314+
}
315+
}
316+
}
317+
318+
res.into_bytes()
319+
}
283320
Command::Resolve { format, .. } => {
284321
semantic::load_std_lib(sources);
285322

@@ -352,8 +389,9 @@ impl Command {
352389
| SQLCompile { io_args, .. }
353390
| SQLPreprocess(io_args)
354391
| SQLAnchor { io_args, .. }
355-
| Debug(io_args)
356-
| Annotate(io_args) => io_args,
392+
| Debug(DebugCommand::Semantics(io_args))
393+
| Debug(DebugCommand::Annotate(io_args))
394+
| Debug(DebugCommand::Eval(io_args)) => io_args,
357395
_ => unreachable!(),
358396
};
359397
let input = &mut io_args.input;
@@ -382,8 +420,10 @@ impl Command {
382420
| Resolve { io_args, .. }
383421
| SQLCompile { io_args, .. }
384422
| SQLAnchor { io_args, .. }
385-
| SQLPreprocess(io_args) => io_args.output.to_owned(),
386-
Debug(io) | Annotate(io) => io.output.to_owned(),
423+
| SQLPreprocess(io_args)
424+
| Debug(DebugCommand::Semantics(io_args))
425+
| Debug(DebugCommand::Annotate(io_args))
426+
| Debug(DebugCommand::Eval(io_args)) => io_args.output.to_owned(),
387427
_ => unreachable!(),
388428
};
389429
output.write_all(data)
@@ -602,7 +642,7 @@ mod tests {
602642
#[test]
603643
fn layouts() {
604644
let output = Command::execute(
605-
&Command::Annotate(IoArgs::default()),
645+
&Command::Debug(DebugCommand::Annotate(IoArgs::default())),
606646
&mut r#"
607647
from initial_table
608648
select {f = first_name, l = last_name, gender}

prql-compiler/prqlc/tests/snapshots/test__shell_completion-2.snap

Lines changed: 34 additions & 18 deletions
Large diffs are not rendered by default.

prql-compiler/prqlc/tests/snapshots/test__shell_completion-3.snap

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ source: prql-compiler/prqlc/tests/test.rs
33
info:
44
program: prqlc
55
args:
6+
- "--color=never"
67
- shell-completion
78
- powershell
9+
env:
10+
CLICOLOR_FORCE: ""
811
---
912
success: true
1013
exit_code: 0
@@ -39,8 +42,7 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
3942
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version')
4043
[CompletionResult]::new('parse', 'parse', [CompletionResultType]::ParameterValue, 'Parse into PL AST')
4144
[CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Parse & generate PRQL code back')
42-
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
43-
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
45+
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Commands for meant for debugging, prone to change')
4446
[CompletionResult]::new('resolve', 'resolve', [CompletionResultType]::ParameterValue, 'Parse, resolve & lower into RQ')
4547
[CompletionResult]::new('sql:preprocess', 'sql:preprocess', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess SRQ')
4648
[CompletionResult]::new('sql:anchor', 'sql:anchor', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess & anchor SRQ')
@@ -64,18 +66,53 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
6466
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
6567
break
6668
}
67-
'prqlc;annotate' {
69+
'prqlc;debug' {
6870
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
6971
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
7072
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
73+
[CompletionResult]::new('semantics', 'semantics', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
74+
[CompletionResult]::new('eval', 'eval', [CompletionResultType]::ParameterValue, 'Parse & evaluate expression down to a value')
75+
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
76+
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
7177
break
7278
}
73-
'prqlc;debug' {
79+
'prqlc;debug;semantics' {
80+
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
81+
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
82+
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
83+
break
84+
}
85+
'prqlc;debug;eval' {
86+
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
87+
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
88+
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
89+
break
90+
}
91+
'prqlc;debug;annotate' {
7492
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
7593
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
7694
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
7795
break
7896
}
97+
'prqlc;debug;help' {
98+
[CompletionResult]::new('semantics', 'semantics', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
99+
[CompletionResult]::new('eval', 'eval', [CompletionResultType]::ParameterValue, 'Parse & evaluate expression down to a value')
100+
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
101+
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
102+
break
103+
}
104+
'prqlc;debug;help;semantics' {
105+
break
106+
}
107+
'prqlc;debug;help;eval' {
108+
break
109+
}
110+
'prqlc;debug;help;annotate' {
111+
break
112+
}
113+
'prqlc;debug;help;help' {
114+
break
115+
}
79116
'prqlc;resolve' {
80117
[CompletionResult]::new('--format', 'format', [CompletionResultType]::ParameterName, 'format')
81118
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
@@ -128,8 +165,7 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
128165
'prqlc;help' {
129166
[CompletionResult]::new('parse', 'parse', [CompletionResultType]::ParameterValue, 'Parse into PL AST')
130167
[CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Parse & generate PRQL code back')
131-
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
132-
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
168+
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Commands for meant for debugging, prone to change')
133169
[CompletionResult]::new('resolve', 'resolve', [CompletionResultType]::ParameterValue, 'Parse, resolve & lower into RQ')
134170
[CompletionResult]::new('sql:preprocess', 'sql:preprocess', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess SRQ')
135171
[CompletionResult]::new('sql:anchor', 'sql:anchor', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess & anchor SRQ')
@@ -146,10 +182,19 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
146182
'prqlc;help;fmt' {
147183
break
148184
}
149-
'prqlc;help;annotate' {
185+
'prqlc;help;debug' {
186+
[CompletionResult]::new('semantics', 'semantics', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
187+
[CompletionResult]::new('eval', 'eval', [CompletionResultType]::ParameterValue, 'Parse & evaluate expression down to a value')
188+
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
150189
break
151190
}
152-
'prqlc;help;debug' {
191+
'prqlc;help;debug;semantics' {
192+
break
193+
}
194+
'prqlc;help;debug;eval' {
195+
break
196+
}
197+
'prqlc;help;debug;annotate' {
153198
break
154199
}
155200
'prqlc;help;resolve' {

0 commit comments

Comments
 (0)