basic implementation of return command
This commit is contained in:
		
							parent
							
								
									ed62e75e89
								
							
						
					
					
						commit
						5c4d340162
					
				| 
						 | 
					@ -28,6 +28,8 @@ pub fn compile_if_cond(
 | 
				
			||||||
    global_state: &MutCompilerState,
 | 
					    global_state: &MutCompilerState,
 | 
				
			||||||
    function_state: &FunctionCompilerState,
 | 
					    function_state: &FunctionCompilerState,
 | 
				
			||||||
) -> Vec<CompiledCommand> {
 | 
					) -> Vec<CompiledCommand> {
 | 
				
			||||||
 | 
					    // TODO: special handling for return command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if options.pack_format < 20 {
 | 
					    if options.pack_format < 20 {
 | 
				
			||||||
        compile_pre_20_format(
 | 
					        compile_pre_20_format(
 | 
				
			||||||
            cond,
 | 
					            cond,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,9 @@ pub enum Command {
 | 
				
			||||||
    Group(Vec<Command>),
 | 
					    Group(Vec<Command>),
 | 
				
			||||||
    /// Comment to be added to the function
 | 
					    /// Comment to be added to the function
 | 
				
			||||||
    Comment(String),
 | 
					    Comment(String),
 | 
				
			||||||
 | 
					    /// Return value
 | 
				
			||||||
 | 
					    Return(ReturnCommand),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Command that is a concatenation of two commands
 | 
					    /// Command that is a concatenation of two commands
 | 
				
			||||||
    Concat(Box<Command>, Box<Command>),
 | 
					    Concat(Box<Command>, Box<Command>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -65,6 +68,23 @@ impl Command {
 | 
				
			||||||
            Self::Comment(comment) => {
 | 
					            Self::Comment(comment) => {
 | 
				
			||||||
                vec![CompiledCommand::new("#".to_string() + comment).with_forbid_prefix(true)]
 | 
					                vec![CompiledCommand::new("#".to_string() + comment).with_forbid_prefix(true)]
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            Self::Return(return_cmd) => match return_cmd {
 | 
				
			||||||
 | 
					                ReturnCommand::Value(value) => {
 | 
				
			||||||
 | 
					                    vec![CompiledCommand::new(format!("return {}", value.compile()))]
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ReturnCommand::Command(cmd) => {
 | 
				
			||||||
 | 
					                    let compiled_cmd = Self::Group(vec![*cmd.clone()]).compile(
 | 
				
			||||||
 | 
					                        options,
 | 
				
			||||||
 | 
					                        global_state,
 | 
				
			||||||
 | 
					                        function_state,
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                    let compiled_cmd = compiled_cmd
 | 
				
			||||||
 | 
					                        .into_iter()
 | 
				
			||||||
 | 
					                        .next()
 | 
				
			||||||
 | 
					                        .expect("group will always return exactly one command");
 | 
				
			||||||
 | 
					                    vec![compiled_cmd.apply_prefix("return run ")]
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            Self::Concat(a, b) => {
 | 
					            Self::Concat(a, b) => {
 | 
				
			||||||
                let a = a.compile(options, global_state, function_state);
 | 
					                let a = a.compile(options, global_state, function_state);
 | 
				
			||||||
                let b = b.compile(options, global_state, function_state);
 | 
					                let b = b.compile(options, global_state, function_state);
 | 
				
			||||||
| 
						 | 
					@ -97,7 +117,7 @@ impl Command {
 | 
				
			||||||
            Self::Raw(cmd) => cmd.split('\n').count(),
 | 
					            Self::Raw(cmd) => cmd.split('\n').count(),
 | 
				
			||||||
            Self::UsesMacro(cmd) => cmd.line_count(),
 | 
					            Self::UsesMacro(cmd) => cmd.line_count(),
 | 
				
			||||||
            Self::Execute(ex) => ex.get_count(options),
 | 
					            Self::Execute(ex) => ex.get_count(options),
 | 
				
			||||||
            Self::Group(_) => 1,
 | 
					            Self::Group(_) | Self::Return(_) => 1,
 | 
				
			||||||
            Self::Concat(a, b) => a.get_count(options) + b.get_count(options) - 1,
 | 
					            Self::Concat(a, b) => a.get_count(options) + b.get_count(options) - 1,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -110,6 +130,12 @@ impl Command {
 | 
				
			||||||
            Self::Raw(cmd) => validate_raw_cmd(cmd, pack_formats),
 | 
					            Self::Raw(cmd) => validate_raw_cmd(cmd, pack_formats),
 | 
				
			||||||
            Self::UsesMacro(cmd) => validate_raw_cmd(&cmd.compile(), pack_formats),
 | 
					            Self::UsesMacro(cmd) => validate_raw_cmd(&cmd.compile(), pack_formats),
 | 
				
			||||||
            Self::Execute(ex) => ex.validate(pack_formats),
 | 
					            Self::Execute(ex) => ex.validate(pack_formats),
 | 
				
			||||||
 | 
					            Self::Return(ret) => match ret {
 | 
				
			||||||
 | 
					                ReturnCommand::Value(_) => pack_formats.start() >= &14,
 | 
				
			||||||
 | 
					                ReturnCommand::Command(cmd) => {
 | 
				
			||||||
 | 
					                    pack_formats.start() >= &16 && cmd.validate(pack_formats)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            Self::Concat(a, b) => a.validate(pack_formats) && b.validate(pack_formats),
 | 
					            Self::Concat(a, b) => a.validate(pack_formats) && b.validate(pack_formats),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        if pack_formats.start() < &16 {
 | 
					        if pack_formats.start() < &16 {
 | 
				
			||||||
| 
						 | 
					@ -127,6 +153,10 @@ impl Command {
 | 
				
			||||||
            Self::UsesMacro(s) | Self::Debug(s) => s.contains_macro(),
 | 
					            Self::UsesMacro(s) | Self::Debug(s) => s.contains_macro(),
 | 
				
			||||||
            Self::Group(commands) => group_contains_macro(commands),
 | 
					            Self::Group(commands) => group_contains_macro(commands),
 | 
				
			||||||
            Self::Execute(ex) => ex.contains_macro(),
 | 
					            Self::Execute(ex) => ex.contains_macro(),
 | 
				
			||||||
 | 
					            Self::Return(ret) => match ret {
 | 
				
			||||||
 | 
					                ReturnCommand::Value(value) => value.contains_macro(),
 | 
				
			||||||
 | 
					                ReturnCommand::Command(cmd) => cmd.contains_macro(),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            Self::Concat(a, b) => a.contains_macro() || b.contains_macro(),
 | 
					            Self::Concat(a, b) => a.contains_macro() || b.contains_macro(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -139,6 +169,10 @@ impl Command {
 | 
				
			||||||
            Self::UsesMacro(s) | Self::Debug(s) => s.get_macros(),
 | 
					            Self::UsesMacro(s) | Self::Debug(s) => s.get_macros(),
 | 
				
			||||||
            Self::Group(commands) => group_get_macros(commands),
 | 
					            Self::Group(commands) => group_get_macros(commands),
 | 
				
			||||||
            Self::Execute(ex) => ex.get_macros(),
 | 
					            Self::Execute(ex) => ex.get_macros(),
 | 
				
			||||||
 | 
					            Self::Return(ret) => match ret {
 | 
				
			||||||
 | 
					                ReturnCommand::Value(value) => value.get_macros(),
 | 
				
			||||||
 | 
					                ReturnCommand::Command(cmd) => cmd.get_macros(),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            Self::Concat(a, b) => {
 | 
					            Self::Concat(a, b) => {
 | 
				
			||||||
                let mut macros = a.get_macros();
 | 
					                let mut macros = a.get_macros();
 | 
				
			||||||
                macros.extend(b.get_macros());
 | 
					                macros.extend(b.get_macros());
 | 
				
			||||||
| 
						 | 
					@ -154,6 +188,10 @@ impl Command {
 | 
				
			||||||
            Self::Comment(_) => true,
 | 
					            Self::Comment(_) => true,
 | 
				
			||||||
            Self::Raw(_) | Self::Debug(_) | Self::Execute(_) | Self::UsesMacro(_) => false,
 | 
					            Self::Raw(_) | Self::Debug(_) | Self::Execute(_) | Self::UsesMacro(_) => false,
 | 
				
			||||||
            Self::Group(commands) => commands.len() == 1 && commands[0].forbid_prefix(),
 | 
					            Self::Group(commands) => commands.len() == 1 && commands[0].forbid_prefix(),
 | 
				
			||||||
 | 
					            Self::Return(ret) => match ret {
 | 
				
			||||||
 | 
					                ReturnCommand::Value(_) => false,
 | 
				
			||||||
 | 
					                ReturnCommand::Command(cmd) => cmd.forbid_prefix(),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            Self::Concat(a, _) => a.forbid_prefix(),
 | 
					            Self::Concat(a, _) => a.forbid_prefix(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -175,6 +213,16 @@ impl From<&mut Function> for Command {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Represents a command that returns a value.
 | 
				
			||||||
 | 
					#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 | 
				
			||||||
 | 
					pub enum ReturnCommand {
 | 
				
			||||||
 | 
					    /// Returns the value
 | 
				
			||||||
 | 
					    Value(MacroString),
 | 
				
			||||||
 | 
					    /// Returns the result of the command
 | 
				
			||||||
 | 
					    Command(Box<Command>),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn compile_debug(message: &MacroString, option: &CompileOptions) -> Vec<CompiledCommand> {
 | 
					fn compile_debug(message: &MacroString, option: &CompileOptions) -> Vec<CompiledCommand> {
 | 
				
			||||||
    if option.debug {
 | 
					    if option.debug {
 | 
				
			||||||
        vec![CompiledCommand::new(format!(
 | 
					        vec![CompiledCommand::new(format!(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ mod command;
 | 
				
			||||||
mod function;
 | 
					mod function;
 | 
				
			||||||
mod namespace;
 | 
					mod namespace;
 | 
				
			||||||
pub mod tag;
 | 
					pub mod tag;
 | 
				
			||||||
pub use command::{Command, Condition, Execute};
 | 
					pub use command::{Command, Condition, Execute, ReturnCommand};
 | 
				
			||||||
pub use function::Function;
 | 
					pub use function::Function;
 | 
				
			||||||
pub use namespace::Namespace;
 | 
					pub use namespace::Namespace;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue