Skip to content

Commit

Permalink
feat: evaluator (#2816)
Browse files Browse the repository at this point in the history
  • Loading branch information
aljazerzen authored Jun 13, 2023
1 parent de01bb0 commit 5425a67
Show file tree
Hide file tree
Showing 8 changed files with 1,037 additions and 78 deletions.
64 changes: 52 additions & 12 deletions prql-compiler/prqlc/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use ariadne::Source;
use clap::{CommandFactory, Parser, Subcommand, ValueHint};
use clio::Output;
use itertools::Itertools;
use prql_compiler::ast::pl::StmtKind;
use std::io::Write;
use std::ops::Range;
use std::path::PathBuf;
Expand Down Expand Up @@ -75,11 +76,8 @@ enum Command {
input: clio_extended::Input,
},

/// Parse, resolve & combine source with comments annotating relation type
Annotate(IoArgs),

/// Parse & resolve, but don't lower into RQ
Debug(IoArgs),
#[command(subcommand)]
Debug(DebugCommand),

/// Parse, resolve & lower into RQ
Resolve {
Expand Down Expand Up @@ -133,6 +131,22 @@ enum Command {
},
}

/// Commands for meant for debugging, prone to change
#[derive(Subcommand, Debug, Clone)]
pub enum DebugCommand {
/// Parse & resolve, but don't lower into RQ
Semantics(IoArgs),

/// Parse & evaluate expression down to a value
///
/// Cannot contain references to tables or any other outside sources.
/// Meant as a playground for testing out language design decisions.
Eval(IoArgs),

/// Parse, resolve & combine source with comments annotating relation type
Annotate(IoArgs),
}

#[derive(clap::Args, Default, Debug, Clone)]
pub struct IoArgs {
#[arg(value_parser, default_value = "-", value_hint(ValueHint::AnyPath))]
Expand Down Expand Up @@ -233,7 +247,7 @@ impl Command {
Format::Yaml => serde_yaml::to_string(&ast)?.into_bytes(),
}
}
Command::Debug(_) => {
Command::Debug(DebugCommand::Semantics(_)) => {
semantic::load_std_lib(sources);
let stmts = prql_to_pl_tree(sources)?;

Expand All @@ -250,7 +264,7 @@ impl Command {
out.extend(format!("\n{context:#?}\n").into_bytes());
out
}
Command::Annotate(_) => {
Command::Debug(DebugCommand::Annotate(_)) => {
let (_, source) = sources.sources.clone().into_iter().exactly_one().or_else(
|_| bail!(
"Currently `annotate` only works with a single source, but found multiple sources: {:?}",
Expand Down Expand Up @@ -280,6 +294,29 @@ impl Command {
// combine with source
combine_prql_and_frames(&source, frames).as_bytes().to_vec()
}
Command::Debug(DebugCommand::Eval(_)) => {
let stmts = prql_to_pl_tree(sources)?;

let mut res = String::new();

for (path, stmts) in stmts.sources {
res += &format!("# {}\n\n", path.to_str().unwrap());

for stmt in stmts {
if let StmtKind::VarDef(def) = stmt.kind {
res += &format!("## {}\n", stmt.name);

let val = semantic::eval(*def.value)
.map_err(downcast)
.map_err(|e| e.composed(sources))?;
res += &val.to_string();
res += "\n\n";
}
}
}

res.into_bytes()
}
Command::Resolve { format, .. } => {
semantic::load_std_lib(sources);

Expand Down Expand Up @@ -352,8 +389,9 @@ impl Command {
| SQLCompile { io_args, .. }
| SQLPreprocess(io_args)
| SQLAnchor { io_args, .. }
| Debug(io_args)
| Annotate(io_args) => io_args,
| Debug(DebugCommand::Semantics(io_args))
| Debug(DebugCommand::Annotate(io_args))
| Debug(DebugCommand::Eval(io_args)) => io_args,
_ => unreachable!(),
};
let input = &mut io_args.input;
Expand Down Expand Up @@ -382,8 +420,10 @@ impl Command {
| Resolve { io_args, .. }
| SQLCompile { io_args, .. }
| SQLAnchor { io_args, .. }
| SQLPreprocess(io_args) => io_args.output.to_owned(),
Debug(io) | Annotate(io) => io.output.to_owned(),
| SQLPreprocess(io_args)
| Debug(DebugCommand::Semantics(io_args))
| Debug(DebugCommand::Annotate(io_args))
| Debug(DebugCommand::Eval(io_args)) => io_args.output.to_owned(),
_ => unreachable!(),
};
output.write_all(data)
Expand Down Expand Up @@ -602,7 +642,7 @@ mod tests {
#[test]
fn layouts() {
let output = Command::execute(
&Command::Annotate(IoArgs::default()),
&Command::Debug(DebugCommand::Annotate(IoArgs::default())),
&mut r#"
from initial_table
select {f = first_name, l = last_name, gender}
Expand Down
52 changes: 34 additions & 18 deletions prql-compiler/prqlc/tests/snapshots/test__shell_completion-2.snap

Large diffs are not rendered by default.

61 changes: 53 additions & 8 deletions prql-compiler/prqlc/tests/snapshots/test__shell_completion-3.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ source: prql-compiler/prqlc/tests/test.rs
info:
program: prqlc
args:
- "--color=never"
- shell-completion
- powershell
env:
CLICOLOR_FORCE: ""
---
success: true
exit_code: 0
Expand Down Expand Up @@ -39,8 +42,7 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('parse', 'parse', [CompletionResultType]::ParameterValue, 'Parse into PL AST')
[CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Parse & generate PRQL code back')
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Commands for meant for debugging, prone to change')
[CompletionResult]::new('resolve', 'resolve', [CompletionResultType]::ParameterValue, 'Parse, resolve & lower into RQ')
[CompletionResult]::new('sql:preprocess', 'sql:preprocess', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess SRQ')
[CompletionResult]::new('sql:anchor', 'sql:anchor', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess & anchor SRQ')
Expand All @@ -64,18 +66,53 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
break
}
'prqlc;annotate' {
'prqlc;debug' {
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('semantics', 'semantics', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
[CompletionResult]::new('eval', 'eval', [CompletionResultType]::ParameterValue, 'Parse & evaluate expression down to a value')
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'prqlc;debug' {
'prqlc;debug;semantics' {
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
break
}
'prqlc;debug;eval' {
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
}
'prqlc;debug;annotate' {
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
break
}
'prqlc;debug;help' {
[CompletionResult]::new('semantics', 'semantics', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
[CompletionResult]::new('eval', 'eval', [CompletionResultType]::ParameterValue, 'Parse & evaluate expression down to a value')
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'prqlc;debug;help;semantics' {
break
}
'prqlc;debug;help;eval' {
break
}
'prqlc;debug;help;annotate' {
break
}
'prqlc;debug;help;help' {
break
}
'prqlc;resolve' {
[CompletionResult]::new('--format', 'format', [CompletionResultType]::ParameterName, 'format')
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Controls when to use color')
Expand Down Expand Up @@ -128,8 +165,7 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
'prqlc;help' {
[CompletionResult]::new('parse', 'parse', [CompletionResultType]::ParameterValue, 'Parse into PL AST')
[CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Parse & generate PRQL code back')
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
[CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'Commands for meant for debugging, prone to change')
[CompletionResult]::new('resolve', 'resolve', [CompletionResultType]::ParameterValue, 'Parse, resolve & lower into RQ')
[CompletionResult]::new('sql:preprocess', 'sql:preprocess', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess SRQ')
[CompletionResult]::new('sql:anchor', 'sql:anchor', [CompletionResultType]::ParameterValue, 'Parse, resolve, lower into RQ & preprocess & anchor SRQ')
Expand All @@ -146,10 +182,19 @@ Register-ArgumentCompleter -Native -CommandName 'prqlc' -ScriptBlock {
'prqlc;help;fmt' {
break
}
'prqlc;help;annotate' {
'prqlc;help;debug' {
[CompletionResult]::new('semantics', 'semantics', [CompletionResultType]::ParameterValue, 'Parse & resolve, but don''t lower into RQ')
[CompletionResult]::new('eval', 'eval', [CompletionResultType]::ParameterValue, 'Parse & evaluate expression down to a value')
[CompletionResult]::new('annotate', 'annotate', [CompletionResultType]::ParameterValue, 'Parse, resolve & combine source with comments annotating relation type')
break
}
'prqlc;help;debug' {
'prqlc;help;debug;semantics' {
break
}
'prqlc;help;debug;eval' {
break
}
'prqlc;help;debug;annotate' {
break
}
'prqlc;help;resolve' {
Expand Down
Loading

0 comments on commit 5425a67

Please sign in to comment.