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)?); 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) => { Expr::Matrix(rows) => {
let mut analysed_rows = Vec::new(); 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::Comprehension(left, right, vars) => Expr::Comprehension(left, right, vars),
Expr::Equation(left, right, identifier) => Expr::Equation(left, right, identifier), 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. /// A tree structure of a statement.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -27,6 +27,7 @@ pub enum Expr {
Indexer(Box<Expr>, Vec<Expr>), Indexer(Box<Expr>, Vec<Expr>),
Comprehension(Box<Expr>, Vec<Expr>, Vec<RangedVar>), Comprehension(Box<Expr>, Vec<Expr>, Vec<RangedVar>),
Equation(Box<Expr>, Box<Expr>, Identifier), Equation(Box<Expr>, Box<Expr>, Identifier),
Preevaluated(KalkValue),
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]

View File

@ -166,6 +166,7 @@ pub(crate) fn eval_expr(
context, left, conditions, vars, context, left, conditions, vars,
)?)), )?)),
Expr::Equation(left, right, identifier) => eval_equation(context, left, right, identifier), 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( let var_decl = Stmt::VarDecl(
argument_identifier, argument_identifier,
Box::new(crate::ast::build_literal_ast(&eval_expr( Box::new(Expr::Preevaluated(eval_expr(
context, context,
&expressions[i], &expressions[i],
None, None,

View File

@ -94,6 +94,7 @@ fn invert(
Err(KalkError::UnableToInvert(String::from("Comprehension"))) Err(KalkError::UnableToInvert(String::from("Comprehension")))
} }
Expr::Equation(_, _, _) => Err(KalkError::UnableToInvert(String::from("Equation"))), 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::Indexer(_, _) => false,
Expr::Comprehension(_, _, _) => false, Expr::Comprehension(_, _, _) => false,
Expr::Equation(_, _, _) => 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> { fn parse_vector(context: &mut Context) -> Result<Expr, KalkError> {
let kind = advance(context).kind; let kind = advance(context).kind;
if match_token(context, TokenKind::ClosedBracket) {
advance(context);
return Ok(Expr::Vector(vec![]));
}
if kind == TokenKind::OpenBracket { if kind == TokenKind::OpenBracket {
skip_newlines(context); skip_newlines(context);
@ -617,7 +622,7 @@ fn parse_vector(context: &mut Context) -> Result<Expr, KalkError> {
if rows.len() == 1 { if rows.len() == 1 {
let mut values = rows.pop().unwrap(); 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()))) Ok(Expr::Group(Box::new(values.pop().unwrap())))
} else { } else {
Ok(Expr::Vector(values)) Ok(Expr::Vector(values))

View File

@ -90,6 +90,7 @@ lazy_static! {
}; };
pub static ref BINARY_FUNCS: HashMap<&'static str, (BinaryFuncInfo, &'static str)> = { pub static ref BINARY_FUNCS: HashMap<&'static str, (BinaryFuncInfo, &'static str)> = {
let mut m = HashMap::new(); let mut m = HashMap::new();
m.insert("append", (BinaryFuncInfo(append, Other), ""));
m.insert("bitand", (BinaryFuncInfo(bitand, Other), "")); m.insert("bitand", (BinaryFuncInfo(bitand, Other), ""));
m.insert("bitor", (BinaryFuncInfo(bitor, Other), "")); m.insert("bitor", (BinaryFuncInfo(bitor, Other), ""));
m.insert("bitxor", (BinaryFuncInfo(bitxor, 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⎜ ⎟ // ⎜ ⎜a⎜ ⎟
// lcm(a, b) = ⎜ ───────── ⎟ × ⎜b⎜ // lcm(a, b) = ⎜ ───────── ⎟ × ⎜b⎜