Added logical and/or operators

This commit is contained in:
PaddiM8 2022-01-14 17:46:07 +01:00
parent abd22c4d88
commit f5eff6d28f
6 changed files with 62 additions and 37 deletions

View File

@ -106,7 +106,7 @@ impl Highlighter for LineHighlighter {
let reg = Regex::new(
r"(?x)
(?P<op>([+\-/*%^!×÷⋅]|if|otherwise|load|exit|clear|help)) |
(?P<op>([+\-/*%^!×÷⋅∧∨]|if|otherwise|\sand|\sor|load|exit|clear|help)) |
(?P<radix>0[box][a-zA-Z0-9]+) |
(?P<identifier>[^!-@\s_|^\[\]\{\}¹²³]+(_\d+)?)",
)
@ -158,6 +158,8 @@ lazy_static! {
m.insert("!=", "");
m.insert(">=", "");
m.insert("<=", "");
m.insert(" and", "");
m.insert(" or", " ");
m.insert("*", "×");
m.insert("/", "÷");
m.insert("asin", "sin⁻¹()");

View File

@ -169,6 +169,8 @@ fn eval_binary_expr(
TokenKind::LessThan => left.less_than(context, right),
TokenKind::GreaterOrEquals => left.greater_or_equals(context, right),
TokenKind::LessOrEquals => left.less_or_equals(context, right),
TokenKind::And => left.and(&right),
TokenKind::Or => left.or(&right),
_ => KalkValue::from(1),
};

View File

@ -676,6 +676,24 @@ impl KalkValue {
}
}
pub(crate) fn and(self, rhs: &KalkValue) -> KalkValue {
match (self, rhs) {
(KalkValue::Boolean(boolean), KalkValue::Boolean(boolean_rhs)) => {
KalkValue::Boolean(boolean && *boolean_rhs)
}
_ => KalkValue::nan(),
}
}
pub(crate) fn or(self, rhs: &KalkValue) -> KalkValue {
match (self, rhs) {
(KalkValue::Boolean(boolean), KalkValue::Boolean(boolean_rhs)) => {
KalkValue::Boolean(boolean || *boolean_rhs)
}
_ => KalkValue::nan(),
}
}
pub(crate) fn add_without_unit(self, rhs: &KalkValue) -> KalkValue {
match (self.clone(), rhs) {
(

View File

@ -23,6 +23,8 @@ pub enum TokenKind {
NotEquals,
GreaterOrEquals,
LessOrEquals,
And,
Or,
UnitKeyword,
ToKeyword,
@ -144,6 +146,8 @@ impl<'a> Lexer<'a> {
'=' => build(TokenKind::Equals, "", span),
'>' => build(TokenKind::GreaterThan, "", span),
'<' => build(TokenKind::LessThan, "", span),
'∧' => build(TokenKind::And, "", span),
'' => build(TokenKind::Or, "", span),
',' => build(TokenKind::Comma, "", span),
';' => build(TokenKind::Semicolon, "", span),
'\n' => build(TokenKind::Newline, "", span),
@ -316,6 +320,8 @@ impl<'a> Lexer<'a> {
}
let kind = match value.as_ref() {
"and" => TokenKind::And,
"or" => TokenKind::Or,
"unit" => TokenKind::UnitKeyword,
"to" => TokenKind::ToKeyword,
"if" => TokenKind::IfKeyword,
@ -382,7 +388,9 @@ fn is_valid_identifier(c: Option<&char>) -> bool {
match c {
'+' | '-' | '/' | '*' | '%' | '^' | '!' | '(' | ')' | '=' | '.' | ',' | ';' | '|'
| '⌊' | '⌋' | '⌈' | '⌉' | '[' | ']' | '{' | '}' | 'π' | '√' | 'τ' | 'ϕ' | 'Γ' | '<'
| '>' | '≠' | '≥' | '≤' | '×' | '÷' | '⋅' | '⟦' | '⟧' | '\n' => false,
| '>' | '≠' | '≥' | '≤' | '×' | '÷' | '⋅' | '⟦' | '⟧' | '∧' | '' | '\n' => {
false
}
_ => !c.is_digit(10) || is_superscript(c) || is_subscript(c),
}
} else {

View File

@ -342,43 +342,36 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
}
fn parse_expr(context: &mut Context) -> Result<Expr, CalcError> {
Ok(parse_equality(context)?)
Ok(parse_or(context)?)
}
fn parse_or(context: &mut Context) -> Result<Expr, CalcError> {
let left = parse_and(context)?;
if match_token(context, TokenKind::Or) {
let op = advance(context).kind;
let right = Box::new(parse_or(context)?);
return Ok(Expr::Binary(Box::new(left), op, right));
}
Ok(left)
}
fn parse_and(context: &mut Context) -> Result<Expr, CalcError> {
let left = parse_equality(context)?;
if match_token(context, TokenKind::And) {
let op = advance(context).kind;
let right = Box::new(parse_and(context)?);
return Ok(Expr::Binary(Box::new(left), op, right));
}
Ok(left)
}
fn parse_equality(context: &mut Context) -> Result<Expr, CalcError> {
let mut left = parse_to(context)?;
// Equation
/*if match_token(context, TokenKind::Equals) && context.contains_equation_equal_sign {
advance(context);
let right = parse_to(context)?;
let var_name = if let Some(var_name) = &context.equation_variable {
var_name
} else {
return Err(CalcError::UnableToSolveEquation);
};
let inverted =
if inverter::contains_var(&mut context.symbol_table.get_mut(), &left, var_name) {
left.invert_to_target(&mut context.symbol_table.get_mut(), right, var_name)?
} else {
right.invert_to_target(&mut context.symbol_table.get_mut(), left, var_name)?
};
// If the inverted expression still contains the variable,
// the equation solving failed.
if inverter::contains_var(&mut context.symbol_table.get_mut(), &inverted, var_name) {
return Err(CalcError::UnableToSolveEquation);
}
context.symbol_table.get_mut().insert(Stmt::VarDecl(
Identifier::from_full_name(var_name),
Box::new(inverted.clone()),
));
return Ok(inverted);
}*/
// Equality check
while match_token(context, TokenKind::Equals)
|| match_token(context, TokenKind::NotEquals)

View File

@ -306,7 +306,7 @@
let result = input;
let offset = 0;
result = result.replace(
/(?<brackets>\[\[)|(?<radix>0[box][a-zA-Z0-9]+)|(?<comparison>(!=|[<>]=?))|(?<html>[<>&]|(\n\s*\}?|\s+))|(?<op>([+\-/*%^!≈×÷⋅]|if|otherwise)|(?<identifier>[^!-@\s_|^⌊⌋⌈⌉≈\[\]\{\}⟦⟧≠≥≤⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎]+(_\d+)?)\(?)/g,
/(?<brackets>\[\[)|(?<radix>0[box][a-zA-Z0-9]+)|(?<comparison>(!=|[<>]=?))|(?<html>[<>&]|(\n\s*\}?|\s+))|(?<op>([+\-/*%^!≈×÷⋅∧∨]|if|otherwise|and|or)|(?<identifier>[^!-@\s_|^⌊⌋⌈⌉≈\[\]\{\}⟦⟧≠≥≤⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎]+(_\d+)?)\(?)/g,
(
substring,
brackets,
@ -380,8 +380,10 @@
}
if (op && highlightType != HighlightType.Output) {
if (substring == "*") return "⋅";
if (substring == "/") return "÷";
if (substring == "*") substring = "⋅";
if (substring == "/") substring = "÷";
if (substring == "and") substring = "∧";
if (substring == "or") substring = "";
}
if (identifier) {