diff --git a/README.md b/README.md index 5316b41..1b647b9 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ Limp has two major constructions. The first is the "atom", which is a singular u | `*` | Multiplies all rands given. Requires at least two rands (int/float). | `/` | Divides the first rand from the remaining rands. Requires at least two rands (int/float). | `and` | Ands all rands given. Requires at least two rands (boolean). +| `or` | Ors all rands given. Requires at least two rands (boolean). +| `xor` | Xors all rands given. Requires at least two rands (boolean). | `print` | Prints (on new lines) each rand. Requires at least one rand (int/float/boolean). | `exit` | Exits the program with a 0 status. With an optional rand, exits with that status (int/float). diff --git a/src/evaluator.rs b/src/evaluator.rs index e9215f7..9e77c17 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -249,7 +249,7 @@ fn eval_invocation(invocation: Pair) -> LimpValue { match rand { Boolean(b) => { if !*b { - return Boolean(false) + return Boolean(false); } } // TODO: implement bindings @@ -259,6 +259,47 @@ fn eval_invocation(invocation: Pair) -> LimpValue { return Boolean(true); }, + "or" => { + if rands.len() < 2 { + panic!("Rator `or` expects at least 2 rands!"); + } + + for rand in rands { + match rand { + Boolean(b) => { + if *b { + return Boolean(true); + } + } + // TODO: implement bindings + _ => { panic!("Bad type of {:?} for or!", rand)} + } + } + + return Boolean(false); + }, + "xor" => { + if rands.len() < 2 { + panic!("Rator `or` expects at least 2 rands!"); + } + + // Wikipedia: "[xor] may be considered to be an n-ary operator which is true if and only if an odd number of arguments are true" + let mut trues = 0; + + for rand in rands { + match rand { + Boolean(b) => { + if *b { + trues += 1; + } + } + // TODO: implement bindings + _ => { panic!("Bad type of {:?} for or!", rand)} + } + } + + return Boolean(if trues % 2 == 0 { false } else { true }); + }, "print" => { if rands.len() < 1 { panic!("Rator `print` expects at least 1 rand!"); diff --git a/src/limp.pest b/src/limp.pest index 6582f7a..af8397e 100644 --- a/src/limp.pest +++ b/src/limp.pest @@ -9,6 +9,6 @@ invocation = { "(" ~ expr_list ~ ")" } int = @{ ("+" | "-")? ~ ASCII_DIGIT+ } float = @{ ("+" | "-")? ~ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT+ } boolean = { "true" | "false" } -name = { "+" | "-" | "*" | "/" | "and" | "print" | "exit" } +name = { "+" | "-" | "*" | "/" | "and" | "or" | "xor" | "print" | "exit" } WHITESPACE = _{ " " | "\t" | "\n" | "\r" | "\r\n" }