Skip to content

Commit

Permalink
Enhancement: Runtime - [Breaking Change] New Env struct enabling comm…
Browse files Browse the repository at this point in the history
…ands to redirect out/err to provided streams #440
  • Loading branch information
sagiegurari committed Aug 31, 2024
1 parent 85332f5 commit 8acbcd7
Show file tree
Hide file tree
Showing 109 changed files with 663 additions and 111 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## CHANGELOG

### v0.10.0

* Enhancement: Runtime - \[Breaking Change\] New Env struct enabling commands to redirect out/err to provided streams #440

### v0.9.3 (2024-01-19)

* Fix: if/else condition with a command that accepts empty values #390
Expand Down
8 changes: 5 additions & 3 deletions docs/_includes/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ The run_with_context signature is as follows:
/// * `instructions` - The entire list of instructions which make up the currently running script
/// * `commands` - The currently known commands
/// * `line` - The current instruction line number (global line number after including all scripts into one global script)
/// * `env` - The current runtime env with access to out/err writers, etc...
fn run_with_context(
&self,
arguments: Vec<String>,
Expand All @@ -466,6 +467,7 @@ fn run_with_context(
instructions: &Vec<Instruction>,
commands: &mut Commands,
line: usize,
env: &mut Env,
) -> CommandResult;
```
Expand All @@ -479,7 +481,7 @@ The duckscript cli basically embeds duckscript so you can look at it as a refere
```rust
let mut context = Context::new();
duckscriptsdk::load(&mut context.commands)?;
runner::run_script_file(file, context)?;
runner::run_script_file(file, context, None)?;
```
That's it!<br>
Expand All @@ -502,10 +504,10 @@ The following public functions are available:
```rust
/// Executes the provided script with the given context
pub fn run_script(text: &str, context: Context) -> Result<Context, ScriptError>;
pub fn run_script(text: &str, context: Context, env: Option<Env>) -> Result<Context, ScriptError>;
/// Executes the provided script file with the given context
pub fn run_script_file(file: &str, context: Context) -> Result<Context, ScriptError>;
pub fn run_script_file(file: &str, context: Context, env: Option<Env>) -> Result<Context, ScriptError>;
```
<a name="editor-support"></a>
Expand Down
43 changes: 32 additions & 11 deletions duckscript/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod runner_test;
use crate::expansion::{self, ExpandedValue};
use crate::parser;
use crate::types::command::{CommandResult, Commands, GoToValue};
use crate::types::env::Env;
use crate::types::error::ScriptError;
use crate::types::instruction::{
Instruction, InstructionMetaInfo, InstructionType, ScriptInstruction,
Expand All @@ -26,17 +27,21 @@ enum EndReason {
}

/// Executes the provided script with the given context
pub fn run_script(text: &str, context: Context) -> Result<Context, ScriptError> {
pub fn run_script(text: &str, context: Context, env: Option<Env>) -> Result<Context, ScriptError> {
match parser::parse_text(text) {
Ok(instructions) => run(instructions, context),
Ok(instructions) => run(instructions, context, env),
Err(error) => Err(error),
}
}

/// Executes the provided script file with the given context
pub fn run_script_file(file: &str, context: Context) -> Result<Context, ScriptError> {
pub fn run_script_file(
file: &str,
context: Context,
env: Option<Env>,
) -> Result<Context, ScriptError> {
match parser::parse_file(file) {
Ok(instructions) => run(instructions, context),
Ok(instructions) => run(instructions, context, env),
Err(error) => Err(error),
}
}
Expand All @@ -58,7 +63,7 @@ pub fn repl(mut context: Context) -> Result<Context, ScriptError> {

// add new instructions
instructions.append(&mut new_instructions);
let runtime = create_runtime(instructions.clone(), context);
let runtime = create_runtime(instructions.clone(), context, None);

let (updated_context, end_reason) = run_instructions(runtime, start, true)?;

Expand All @@ -83,17 +88,21 @@ pub fn repl(mut context: Context) -> Result<Context, ScriptError> {
}
}

fn run(instructions: Vec<Instruction>, context: Context) -> Result<Context, ScriptError> {
let runtime = create_runtime(instructions, context);
fn run(
instructions: Vec<Instruction>,
context: Context,
env: Option<Env>,
) -> Result<Context, ScriptError> {
let runtime = create_runtime(instructions, context, env);

match run_instructions(runtime, 0, false) {
Ok((context, _)) => Ok(context),
Err(error) => Err(error),
}
}

fn create_runtime(instructions: Vec<Instruction>, context: Context) -> Runtime {
let mut runtime = Runtime::new(context);
fn create_runtime(instructions: Vec<Instruction>, context: Context, env: Option<Env>) -> Runtime {
let mut runtime = Runtime::new(context, env);

let mut line = 0;
for instruction in &instructions {
Expand Down Expand Up @@ -141,6 +150,7 @@ fn run_instructions(
instructions,
instruction,
line,
&mut runtime.env,
);

match command_result {
Expand Down Expand Up @@ -185,6 +195,7 @@ fn run_instructions(
instructions,
error,
meta_info.clone(),
&mut runtime.env,
) {
return Err(ScriptError::Runtime(error, Some(meta_info.clone())));
};
Expand Down Expand Up @@ -249,6 +260,7 @@ fn run_on_error_instruction(
instructions: &Vec<Instruction>,
error: String,
meta_info: InstructionMetaInfo,
env: &mut Env,
) -> Result<(), String> {
if commands.exists("on_error") {
let mut script_instruction = ScriptInstruction::new();
Expand All @@ -263,8 +275,15 @@ fn run_on_error_instruction(
instruction_type: InstructionType::Script(script_instruction),
};

let (command_result, output_variable) =
run_instruction(commands, variables, state, instructions, instruction, 0);
let (command_result, output_variable) = run_instruction(
commands,
variables,
state,
instructions,
instruction,
0,
env,
);

match command_result {
CommandResult::Exit(output) => {
Expand All @@ -288,6 +307,7 @@ pub fn run_instruction(
instructions: &Vec<Instruction>,
instruction: Instruction,
line: usize,
env: &mut Env,
) -> (CommandResult, Option<String>) {
let mut output_variable = None;
let command_result = match instruction.instruction_type {
Expand All @@ -314,6 +334,7 @@ pub fn run_instruction(
instructions,
commands,
line,
env,
)
} else {
command_instance.run(command_arguments)
Expand Down
Loading

0 comments on commit 8acbcd7

Please sign in to comment.