Add 'append' function and parse [x] as a vector rather than a group

This commit is contained in:
PaddiM8 2024-04-20 23:44:09 +02:00
parent 1ff6813951
commit c94c6da65a
6 changed files with 30 additions and 4 deletions

View File

@ -234,7 +234,11 @@ fn analyse_expr(context: &mut Context, expr: Expr) -> Result<Expr, KalkError> {
analysed_values.push(analyse_expr(context, value)?);
}
Expr::Vector(analysed_values)
if analysed_values.len() == 1 && matches!(analysed_values[0], Expr::Comprehension(_, _, _)) {
analysed_values.pop().unwrap()
} else {
Expr::Vector(analysed_values)
}
}
Expr::Matrix(rows) => {
let mut analysed_rows = Vec::new();
@ -259,6 +263,7 @@ fn analyse_expr(context: &mut Context, expr: Expr) -> Result<Expr, KalkError> {
}
Expr::Comprehension(left, right, vars) => Expr::Comprehension(left, right, vars),
Expr::Equation(left, right, identifier) => Expr::Equation(left, right, identifier),
Expr::Preevaluated(_) => expr,
})
}

View File

@ -1,4 +1,4 @@
use crate::{kalk_value::KalkFloat, lexer::TokenKind};
use crate::{kalk_value::{KalkFloat, KalkValue}, lexer::TokenKind};
/// A tree structure of a statement.
#[derive(Debug, Clone, PartialEq)]
@ -27,6 +27,7 @@ pub enum Expr {
Indexer(Box<Expr>, Vec<Expr>),
Comprehension(Box<Expr>, Vec<Expr>, Vec<RangedVar>),
Equation(Box<Expr>, Box<Expr>, Identifier),
Preevaluated(KalkValue),
}
#[derive(Debug, Clone, PartialEq)]

View File

@ -166,6 +166,7 @@ pub(crate) fn eval_expr(
context, left, conditions, vars,
)?)),
Expr::Equation(left, right, identifier) => eval_equation(context, left, right, identifier),
Expr::Preevaluated(value) => Ok(value.clone()),
}
}
@ -548,7 +549,7 @@ pub(crate) fn eval_fn_call_expr(
};
let var_decl = Stmt::VarDecl(
argument_identifier,
Box::new(crate::ast::build_literal_ast(&eval_expr(
Box::new(Expr::Preevaluated(eval_expr(
context,
&expressions[i],
None,

View File

@ -94,6 +94,7 @@ fn invert(
Err(KalkError::UnableToInvert(String::from("Comprehension")))
}
Expr::Equation(_, _, _) => Err(KalkError::UnableToInvert(String::from("Equation"))),
Expr::Preevaluated(_) => Err(KalkError::UnableToInvert(String::from("Equation"))),
}
}
@ -402,6 +403,7 @@ pub fn contains_var(symbol_table: &SymbolTable, expr: &Expr, var_name: &str) ->
Expr::Indexer(_, _) => false,
Expr::Comprehension(_, _, _) => false,
Expr::Equation(_, _, _) => false,
Expr::Preevaluated(_) => false,
}
}

View File

@ -564,6 +564,11 @@ fn parse_group_fn(context: &mut Context) -> Result<Expr, KalkError> {
fn parse_vector(context: &mut Context) -> Result<Expr, KalkError> {
let kind = advance(context).kind;
if match_token(context, TokenKind::ClosedBracket) {
advance(context);
return Ok(Expr::Vector(vec![]));
}
if kind == TokenKind::OpenBracket {
skip_newlines(context);
@ -617,7 +622,7 @@ fn parse_vector(context: &mut Context) -> Result<Expr, KalkError> {
if rows.len() == 1 {
let mut values = rows.pop().unwrap();
if values.len() == 1 {
if values.len() == 1 && kind == TokenKind::OpenParenthesis {
Ok(Expr::Group(Box::new(values.pop().unwrap())))
} else {
Ok(Expr::Vector(values))

View File

@ -90,6 +90,7 @@ lazy_static! {
};
pub static ref BINARY_FUNCS: HashMap<&'static str, (BinaryFuncInfo, &'static str)> = {
let mut m = HashMap::new();
m.insert("append", (BinaryFuncInfo(append, Other), ""));
m.insert("bitand", (BinaryFuncInfo(bitand, Other), ""));
m.insert("bitor", (BinaryFuncInfo(bitor, Other), ""));
m.insert("bitxor", (BinaryFuncInfo(bitxor, Other), ""));
@ -700,6 +701,17 @@ pub mod funcs {
))
}
pub fn append(x: KalkValue, y: KalkValue) -> Result<KalkValue, KalkError> {
if let KalkValue::Vector(items) = x {
let mut new_items = items.clone();
new_items.push(y);
Ok(KalkValue::Vector(new_items))
} else {
Err(KalkError::Expected(String::from("Vector")))
}
}
// ⎛ ⎞
// ⎜ ⎜a⎜ ⎟
// lcm(a, b) = ⎜ ───────── ⎟ × ⎜b⎜