Skip to content

Commit

Permalink
or/xor
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-unc committed Mar 21, 2021
1 parent f3b763f commit 8acbee9
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
43 changes: 42 additions & 1 deletion src/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ fn eval_invocation(invocation: Pair<Rule>) -> LimpValue {
match rand {
Boolean(b) => {
if !*b {
return Boolean(false)
return Boolean(false);
}
}
// TODO: implement bindings
Expand All @@ -259,6 +259,47 @@ fn eval_invocation(invocation: Pair<Rule>) -> 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!");
Expand Down
2 changes: 1 addition & 1 deletion src/limp.pest
Original file line number Diff line number Diff line change
Expand Up @@ -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" }

0 comments on commit 8acbee9

Please sign in to comment.