Skip to content

Commit

Permalink
Update runtime structure and clean up redundant code
Browse files Browse the repository at this point in the history
Refactored the runtime structure within the execution module to include references to a dictionary and employ VerifiedCommand as opposed to ExecutableCommand_. In parallel, removed or commented out extraneous code spanning multiple modules. Modified Verifier to effectively handle commands using a Dictionary. Incorporated methods for registering and retrieving commands within the Dictionary.
  • Loading branch information
Barsik-sus committed Mar 8, 2024
1 parent 4362bea commit 973ff54
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 166 deletions.
182 changes: 88 additions & 94 deletions module/move/wca/src/ca/aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ pub( crate ) mod private
use crate::*;
use ca::
{
Parser, Verifier, ExecutorConverter,
Parser, Verifier,// ExecutorConverter,
Executor,
ProgramParser,
Command,
grammar::command::private::CommandFormer,
Routine,
help::{ HelpGeneratorFn, HelpVariants, dot_command },
// Routine,
// help::{ HelpGeneratorFn, HelpVariants, dot_command },
};

use std::collections::{ HashMap, HashSet };
// use std::collections::{ HashMap, HashSet };
use std::fmt;
use wtools::thiserror;
use wtools::error::
Expand Down Expand Up @@ -60,7 +60,7 @@ pub( crate ) mod private
// xxx : qqq : qqq2 : for Bohdan : one level is obviously redundant
// Program< Namespace< ExecutableCommand_ > > -> Program< ExecutableCommand_ >
// aaa : done. The concept of `Namespace` has been removed
struct CommandsAggregatorCallback( Box< dyn Fn( &str, &Program< ExecutableCommand_ > ) > );
struct CommandsAggregatorCallback( Box< dyn Fn( &str, &Program< VerifiedCommand > ) > );

impl fmt::Debug for CommandsAggregatorCallback
{
Expand Down Expand Up @@ -109,24 +109,28 @@ pub( crate ) mod private
#[ perform( fn build() -> CommandsAggregator ) ]
pub struct CommandsAggregator
{
#[ setter( false ) ]
#[ default( Dictionary::default() ) ]
dictionary : Dictionary,

#[ default( Parser::former().form() ) ]
parser : Parser,

#[ setter( false ) ]
#[ default( Executor::former().form() ) ]
executor : Executor,

help_generator : HelpGeneratorFn,
#[ default( HashSet::from([ HelpVariants::All ]) ) ]
help_variants : HashSet< HelpVariants >,
// help_generator : HelpGeneratorFn,
// #[ default( HashSet::from([ HelpVariants::All ]) ) ]
// help_variants : HashSet< HelpVariants >,
// qqq : for Bohdan : should not have fields help_generator and help_variants
// help_generator generateds VerifiedCommand(s) and stop to exist

#[ default( Verifier::former().form() ) ]
verifier : Verifier,
// #[ default( Verifier::former().form() ) ]
// verifier : Verifier,

#[ default( ExecutorConverter::former().form() ) ]
executor_converter : ExecutorConverter,
// #[ default( ExecutorConverter::former().form() ) ]
// executor_converter : ExecutorConverter,

callback_fn : Option< CommandsAggregatorCallback >,
}
Expand All @@ -142,22 +146,12 @@ pub( crate ) mod private
let on_end = | command : Command, super_former : Option< Self > | -> Self
{
let mut super_former = super_former.unwrap();
if let Some( ref mut commands ) = super_former.container.verifier
{
commands.commands.entry( command.phrase.clone() ).or_default().push( command.clone() );
}
else
{
super_former.container.verifier = Some( Verifier::former().command( command.clone() ).form() );
}
if let Some( ref mut commands ) = super_former.container.executor_converter
{
commands.routines.insert( command.phrase, command.routine );
}
else
{
super_former.container.executor_converter = Some( ExecutorConverter::former().routine( command.phrase, command.routine ).form() );
}
let mut dictionary = super_former.container.dictionary.unwrap_or_default();

dictionary.register( command );

super_former.container.dictionary = Some( dictionary );

super_former
};
let former = CommandFormer::begin( Some( self ), on_end );
Expand All @@ -167,56 +161,56 @@ pub( crate ) mod private

impl CommandsAggregatorFormer
{
/// Setter for grammar
///
/// Gets list of available commands
pub fn grammar< V >( mut self, commands : V ) -> Self
where
V : Into< Vec< Command > >
{
let verifier = Verifier::former()
.commands( commands )
.form();
self.container.verifier = Some( verifier );
self
}
// /// Setter for grammar
// ///
// /// Gets list of available commands
// pub fn grammar< V >( mut self, commands : V ) -> Self
// where
// V : Into< Vec< Command > >
// {
// let verifier = Verifier::former()
// .commands( commands )
// .form();
// self.container.verifier = Some( verifier );
// self
// }

/// Setter for executor
///
/// Gets dictionary of routines( command name -> callback )
pub fn executor< H >( mut self, routines : H ) -> Self
where
H : Into< HashMap< String, Routine > >
{
let executor = ExecutorConverter::former()
.routines( routines )
.form();
// /// Setter for executor
// ///
// /// Gets dictionary of routines( command name -> callback )
// pub fn executor< H >( mut self, routines : H ) -> Self
// where
// H : Into< HashMap< String, Routine > >
// {
// let executor = ExecutorConverter::former()
// .routines( routines )
// .form();
//
// self.container.executor_converter = Some( executor );
// self
// }

self.container.executor_converter = Some( executor );
self
}

/// Setter for help content generator
///
/// ```
/// use wca::CommandsAggregator;
///
/// # fn main() -> Result< (), Box< dyn std::error::Error > > {
/// let ca = CommandsAggregator::former()
/// // ...
/// .help( | grammar, command | format!( "Replaced help content" ) )
/// .perform();
///
/// ca.perform( ".help" )?;
/// # Ok( () ) }
/// ```
pub fn help< HelpFunction >( mut self, func : HelpFunction ) -> Self
where
HelpFunction : Fn( &Verifier, Option< &Command > ) -> String + 'static
{
self.container.help_generator = Some( HelpGeneratorFn::new( func ) );
self
}
// /// Setter for help content generator
// ///
// /// ```
// /// use wca::CommandsAggregator;
// ///
// /// # fn main() -> Result< (), Box< dyn std::error::Error > > {
// /// let ca = CommandsAggregator::former()
// /// // ...
// /// .help( | grammar, command | format!( "Replaced help content" ) )
// /// .perform();
// ///
// /// ca.perform( ".help" )?;
// /// # Ok( () ) }
// /// ```
// pub fn help< HelpFunction >( mut self, func : HelpFunction ) -> Self
// where
// HelpFunction : Fn( &Verifier, Option< &Command > ) -> String + 'static
// {
// self.container.help_generator = Some( HelpGeneratorFn::new( func ) );
// self
// }
// qqq : it is good access method, but formed structure should not have help_generator anymore

/// Set callback function that will be executed after validation state
Expand All @@ -236,7 +230,7 @@ pub( crate ) mod private
/// ```
pub fn callback< Callback >( mut self, callback : Callback ) -> Self
where
Callback : Fn( &str, &Program< ExecutableCommand_ > ) + 'static,
Callback : Fn( &str, &Program< VerifiedCommand > ) + 'static,
{
self.container.callback_fn = Some( CommandsAggregatorCallback( Box::new( callback ) ) );
self
Expand All @@ -250,19 +244,19 @@ pub( crate ) mod private
{
let mut ca = self;

if ca.help_variants.contains( &HelpVariants::All )
{
HelpVariants::All.generate( &ca.help_generator, &mut ca.verifier, &mut ca.executor_converter );
}
else
{
for help in &ca.help_variants
{
help.generate( &ca.help_generator, &mut ca.verifier, &mut ca.executor_converter );
}
}

dot_command( &mut ca.verifier, &mut ca.executor_converter );
// if ca.help_variants.contains( &HelpVariants::All )
// {
// HelpVariants::All.generate( &ca.help_generator, &mut ca.dictionary );
// }
// else
// {
// for help in &ca.help_variants
// {
// help.generate( &ca.help_generator, &mut ca.dictionary );
// }
// }
//
// dot_command( &mut ca.dictionary );

ca
}
Expand All @@ -277,15 +271,15 @@ pub( crate ) mod private
let Input( ref program ) = program.into_input();

let raw_program = self.parser.program( program ).map_err( | e | Error::Validation( ValidationError::Parser { input : program.to_string(), error : e } ) )?;
let grammar_program = self.verifier.to_program( raw_program ).map_err( | e | Error::Validation( ValidationError::Verifier( e ) ) )?;
let exec_program = self.executor_converter.to_program( grammar_program ).map_err( | e | Error::Validation( ValidationError::ExecutorConverter( e ) ) )?;
let grammar_program = Verifier::to_program( &self.dictionary, raw_program ).map_err( | e | Error::Validation( ValidationError::Verifier( e ) ) )?;
// let exec_program = self.executor_converter.to_program( grammar_program ).map_err( | e | Error::Validation( ValidationError::ExecutorConverter( e ) ) )?;

if let Some( callback ) = &self.callback_fn
{
callback.0( program, &exec_program )
callback.0( program, &grammar_program )
}

self.executor.program( exec_program ).map_err( | e | Error::Execution( e ) )
self.executor.program( &self.dictionary, grammar_program ).map_err( | e | Error::Execution( e ) )
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions module/move/wca/src/ca/executor/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ pub( crate ) mod private
/// Executes a program
///
/// Setup runtimes for each namespace into program and run it with specified execution type
pub fn program( &self, program : Program< ExecutableCommand_ > ) -> Result< () >
pub fn program( &self, dictionary : &Dictionary, program : Program< VerifiedCommand > ) -> Result< () >
{
let context = self.context.clone();
let runtime = Runtime
{
dictionary,
context,
pos : 0,
namespace : program.commands,
Expand All @@ -66,15 +67,16 @@ pub( crate ) mod private
/// Executes a command
///
/// Call command callback with context if it is necessary.
pub fn command( &self, command : ExecutableCommand_ ) -> Result< () >
pub fn command( &self, dictionary : &Dictionary, command : VerifiedCommand ) -> Result< () >
{
_exec_command( command, self.context.clone() )
let routine = dictionary.command( &command.phrase ).unwrap().routine.clone();
_exec_command( command, routine, self.context.clone() )
}

// qqq : for Bohdan : probably redundant
// aaa : removed `parallel_execution_loop`

fn sequential_execution_loop( mut runtime : Runtime ) -> Result< () >
fn sequential_execution_loop( mut runtime : Runtime< '_ > ) -> Result< () >
{
while !runtime.is_finished()
{
Expand Down
8 changes: 4 additions & 4 deletions module/move/wca/src/ca/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ crate::mod_interface!
layer executor;
/// Represents the state of the program's runtime
layer runtime;
/// Converts from `VerifiedCommand` to `ExecutableCommand_`
layer converter;
// /// Converts from `VerifiedCommand` to `ExecutableCommand_`
// layer converter;
/// Container for contexts values
layer context;
/// `ExecutableCommand_` representation
layer command;
// /// `ExecutableCommand_` representation
// layer command;
/// Command callback representation
layer routine;

Expand Down
14 changes: 8 additions & 6 deletions module/move/wca/src/ca/executor/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,21 @@ pub( crate ) mod private
/// assert!( runtime.is_finished() );
/// ```
#[ derive( Debug, Clone ) ]
pub struct Runtime
pub struct Runtime< 'a >
{
pub dictionary : &'a Dictionary,
/// context for current runtime
pub context : Context,
/// current execution position
pub pos : usize,
/// namespace which must be executed
pub namespace : Vec< ExecutableCommand_ >, // qqq : for Bohdan : use VerifiedCommand
pub namespace : Vec< VerifiedCommand >, // qqq : for Bohdan : use VerifiedCommand
}
// qqq : for Bohdan : why both Runtime and RuntimeState exist? probably one should removed
// qqq : for Bohdan : why both Runtime and Context exist? What about incapsulating Context into Runtime maybe
// qqq : for Bohdan : why both Runtime and Executor exist? rid off of Executor. Incapsulating Executor into Runtime.

impl Runtime
impl Runtime< '_ >
{
/// returns true if execution position at the end
pub fn is_finished( &self ) -> bool
Expand All @@ -76,17 +77,18 @@ pub( crate ) mod private
.ok_or_else( || err!( "No command here. Current execution pos was `{}`", self.pos ) )
.and_then( | cmd |
{
_exec_command( cmd.clone(), self.context.clone() )
let routine = self.dictionary.command( &cmd.phrase ).unwrap().routine.clone();
_exec_command( cmd.clone(), routine, self.context.clone() )
})
}
}

// qqq : for Bohdan : _exec_command probably should be method of Runtime.
// qqq : for Bohdan : Accept reference instead of copy.
/// executes a command
pub fn _exec_command( command : ExecutableCommand_, ctx : Context ) -> Result< () >
pub fn _exec_command( command : VerifiedCommand, routine : Routine, ctx : Context ) -> Result< () >
{
match command.routine
match routine
{
Routine::WithoutContext( routine ) => routine( ( Args( command.subjects ), Props( command.properties ) )),
Routine::WithContext( routine ) => routine( ( Args( command.subjects ), Props( command.properties ) ), ctx ),
Expand Down
Loading

0 comments on commit 973ff54

Please sign in to comment.