Skip to content
Snippets Groups Projects
Commit 94e47a00 authored by Michael Aaron Murphy's avatar Michael Aaron Murphy
Browse files

Merge branch 'use-enums' into 'master'

Use enums

See merge request !1014
parents 0d3202e7 7e50cf58
No related branches found
No related tags found
1 merge request!1014Use enums
......@@ -8,13 +8,11 @@ use std::error::Error;
/// Executes the givent commmand.
pub fn exec(shell: &mut Shell, args: &[small::String]) -> Result<(), small::String> {
const CLEAR_ENV: u8 = 1;
let mut flags = 0u8;
let mut clear_env = false;
let mut idx = 0;
for arg in args.iter() {
match &**arg {
"-c" => flags |= CLEAR_ENV,
"-c" => clear_env = true,
_ if check_help(args, MAN_EXEC) => {
return Ok(());
}
......@@ -27,7 +25,7 @@ pub fn exec(shell: &mut Shell, args: &[small::String]) -> Result<(), small::Stri
Some(argument) => {
let args = if args.len() > idx + 1 { &args[idx + 1..] } else { &[] };
shell.prep_for_exit();
Err(execve(argument, args, (flags & CLEAR_ENV) == 1).description().into())
Err(execve(argument, args, clear_env).description().into())
}
None => Err("no command provided".into()),
}
......
......@@ -7,7 +7,7 @@ use crate::{
builtins::BuiltinMap,
lexers::{assignment_lexer, ArgumentSplitter},
shell::{
flow_control::{Case, ElseIf, ExportAction, LocalAction, Statement},
flow_control::{Case, ElseIf, ExportAction, IfMode, LocalAction, Statement},
status::FAILURE,
},
};
......@@ -83,7 +83,7 @@ pub fn parse<'a>(code: &str, builtins: &BuiltinMap<'a>) -> Statement<'a> {
success: Vec::new(),
else_if: Vec::new(),
failure: Vec::new(),
mode: 0,
mode: IfMode::Success,
},
"else" => Statement::Else,
_ if cmd.starts_with("else") => {
......@@ -279,7 +279,7 @@ mod tests {
success: vec![],
else_if: vec![],
failure: vec![],
mode: 0,
mode: IfMode::Success,
};
assert_eq!(correct_parse, parsed_if);
......
......@@ -183,7 +183,7 @@ impl<'b> Shell<'b> {
}
}
// This should logically be a method over iterator, but Value is only accessible in the main repo
// This should logically be a method over operator, but Value is only accessible in the main repo
// TODO: too much allocations occur over here. We need to expand variables before they get
// parsed
fn apply<'b>(op: Operator, lhs: &Value<'b>, rhs: Value<'b>) -> Result<Value<'b>, OpError> {
......
......@@ -62,6 +62,13 @@ pub enum ExportAction {
Assign(String, Operator, String),
}
#[derive(Debug, PartialEq, Clone, Copy, Hash)]
pub enum IfMode {
Success,
ElseIf,
Else,
}
// TODO: Enable statements and expressions to contain &str values.
#[derive(Debug, PartialEq, Clone)]
pub enum Statement<'a> {
......@@ -73,7 +80,7 @@ pub enum Statement<'a> {
success: Block<'a>,
else_if: Vec<ElseIf<'a>>,
failure: Block<'a>,
mode: u8, // {0 = success, 1 = else_if, 2 = failure}
mode: IfMode,
},
ElseIf(ElseIf<'a>),
Function {
......@@ -206,44 +213,42 @@ pub fn insert_statement<'a>(
}
}
Statement::And(_) | Statement::Or(_) if !block.is_empty() => {
let mut pushed = true;
match block.last_mut().unwrap() {
let pushed = match block.last_mut().unwrap() {
Statement::If {
ref mut expression,
ref mode,
ref success,
ref mut else_if,
..
} => match *mode {
0 if success.is_empty() => {
} => match mode {
IfMode::Success if success.is_empty() => {
// Insert into If expression if there's no previous statement.
expression.push(statement.clone());
true
}
1 => {
IfMode::ElseIf => {
// Try to insert into last ElseIf expression if there's no previous
// statement.
if let Some(eif) = else_if.last_mut() {
if eif.success.is_empty() {
eif.expression.push(statement.clone());
} else {
pushed = false;
}
let eif = else_if.last_mut().expect("Missmatch in 'If' mode!");
if eif.success.is_empty() {
eif.expression.push(statement.clone());
true
} else {
// should not be reached...
unreachable!("Missmatch in 'If' mode!")
false
}
}
_ => pushed = false,
_ => false,
},
Statement::While { ref mut expression, ref statements } => {
if statements.is_empty() {
expression.push(statement.clone());
true
} else {
pushed = false;
false
}
}
_ => pushed = false,
}
_ => false,
};
if !pushed {
insert_into_block(block, statement)?;
}
......@@ -306,25 +311,24 @@ fn insert_into_block<'a>(
ref mut success, ref mut else_if, ref mut failure, ref mut mode, ..
} => match statement {
Statement::ElseIf(eif) => {
if *mode > 1 {
if *mode == IfMode::Else {
return Err("ion: error: ElseIf { .. } found after Else");
} else {
*mode = 1;
*mode = IfMode::ElseIf;
else_if.push(eif);
}
}
Statement::Else => {
if *mode == 2 {
if *mode == IfMode::Else {
return Err("ion: error: Else block already exists");
} else {
*mode = 2;
*mode = IfMode::Else;
}
}
_ => match *mode {
0 => success.push(statement),
1 => else_if.last_mut().unwrap().success.push(statement),
2 => failure.push(statement),
_ => unreachable!(),
_ => match mode {
IfMode::Success => success.push(statement),
IfMode::ElseIf => else_if.last_mut().unwrap().success.push(statement),
IfMode::Else => failure.push(statement),
},
},
_ => unreachable!("Not block-like statement pushed to stack!"),
......@@ -430,7 +434,7 @@ mod tests {
success: Vec::new(),
else_if: Vec::new(),
failure: Vec::new(),
mode: 0,
mode: IfMode::Success,
}
}
fn new_case() -> Statement<'static> {
......
......@@ -29,9 +29,9 @@ impl ForegroundSignals {
pub fn was_processed(&self) -> Option<BackgroundResult> {
let reply = self.reply.load(Ordering::SeqCst) as u8;
self.reply.store(0, Ordering::SeqCst);
if reply & ERRORED != 0 {
if reply == ERRORED {
Some(BackgroundResult::Errored)
} else if reply & REPLIED != 0 {
} else if reply == REPLIED {
Some(BackgroundResult::Status(self.status.load(Ordering::SeqCst) as u8))
} else {
None
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment