diff --git a/Cargo.lock b/Cargo.lock index 202f5bf..1844377 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,7 +102,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "fplc" -version = "0.9.496" +version = "0.9.497" dependencies = [ "chrono", "chrono-tz", diff --git a/Cargo.toml b/Cargo.toml index 760a101..4914fa3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "fplc" -version = "0.9.496" +version = "0.9.497" edition = "2021" description = "A pseudolang interpreter written in Rust" diff --git a/Pseudolang.md b/Pseudolang.md index 87e9212..ea5a981 100644 --- a/Pseudolang.md +++ b/Pseudolang.md @@ -255,6 +255,10 @@ Evaluates to the number of elements in aList (1 through length). Returns a new list that is a sorted version of `aList` (must be an array of integers). The sorting is done in ascending order. +`RANGE(start (optional), end)` + +Creates a new list containing integers from start (1 by default) to end inclusive. + `aList + bList` The `+` operator can be used to concatenate two lists. This creates a new list containing all the elements of `aList` followed by all the elements of `bList`. diff --git a/installer/pseudolang.nsi b/installer/pseudolang.nsi index e1304c8..87d9274 100644 --- a/installer/pseudolang.nsi +++ b/installer/pseudolang.nsi @@ -4,7 +4,7 @@ !define MUI_ICON "Pseudolang-Logo.ico" -Name "PseudoLang Installer v0.9.496" +Name "PseudoLang Installer v0.9.497" InstallDir "$PROGRAMFILES\PseudoLang\" OutFile "../release/installer/pseudolang-setup-x64.exe" BrandingText "(c) 2024 PseudoLang Software Foundation" @@ -33,7 +33,7 @@ Section "" WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$INSTDIR;$R0" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pseudolang" "DisplayName" "Pseudolang" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pseudolang" "DisplayVersion" "0.9.496" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pseudolang" "DisplayVersion" "0.9.497" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pseudolang" "Publisher" "Pseudolang Software Foundation" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pseudolang" "DisplayIcon" "$INSTDIR\Pseudolang-Logo.ico" diff --git a/readme.md b/readme.md index 87cc1b4..82ad09c 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@

Build and Test Pseudolang - Version + Version Nightly Releases

diff --git a/src/interpreter.rs b/src/interpreter.rs index d8223d7..15ab1a4 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -832,6 +832,39 @@ fn evaluate_node( _ => Err("FIND requires two string arguments".to_string()), } } + "RANGE" => match args.len() { + 1 => { + let end = evaluate_node(&args[0], Rc::clone(&env), debug)?; + if let Value::Integer(end_val) = end { + if end_val < 1 { + return Err("RANGE end value must be greater than 0".to_string()); + } + let list: Vec = + (1..=end_val).map(|i| Value::Integer(i)).collect(); + Ok(Value::List(list)) + } else { + Err("RANGE requires integer arguments".to_string()) + } + } + 2 => { + let start = evaluate_node(&args[0], Rc::clone(&env), debug)?; + let end = evaluate_node(&args[1], Rc::clone(&env), debug)?; + if let (Value::Integer(start_val), Value::Integer(end_val)) = (start, end) { + if end_val < start_val { + return Err( + "RANGE end value must be greater than or equal to start value" + .to_string(), + ); + } + let list: Vec = + (start_val..=end_val).map(|i| Value::Integer(i)).collect(); + Ok(Value::List(list)) + } else { + Err("RANGE requires integer arguments".to_string()) + } + } + _ => Err("RANGE requires one or two arguments".to_string()), + }, _ => { let procedure = env .borrow() diff --git a/src/tests/mod.rs b/src/tests/mod.rs index c3e918e..7e1be5d 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1387,6 +1387,66 @@ DISPLAY(arr)"#, ); } + #[test] + fn test_calc_functions() { + assert_output( + r#" + PROCEDURE DERIVATIVE(coefficients, exponents) + { + result_coeffs <- [] + result_exps <- [] + i <- 1 + + REPEAT LENGTH(coefficients) TIMES + { + IF (exponents[i] NOT= 0) + { + new_coeff <- coefficients[i] * exponents[i] + new_exp <- exponents[i] - 1 + APPEND(result_coeffs, new_coeff) + APPEND(result_exps, new_exp) + } + i <- i + 1 + } + RETURN([result_coeffs, result_exps]) + } + + PROCEDURE ANTIDERIVATIVE(coefficients, exponents) + { + result_coeffs <- [] + result_exps <- [] + i <- 1 + + REPEAT LENGTH(coefficients) TIMES + { + new_exp <- exponents[i] + 1 + new_coeff <- coefficients[i] / new_exp + APPEND(result_coeffs, new_coeff) + APPEND(result_exps, new_exp) + i <- i + 1 + } + APPEND(result_coeffs, 0) + APPEND(result_exps, 0) + RETURN([result_coeffs, result_exps]) + } + + coeffs <- [3, 2, 1] + exps <- [2, 1, 0] + + deriv <- DERIVATIVE(coeffs, exps) + DISPLAY("Derivative coefficients: " + TOSTRING(deriv[1])) + DISPLAY("Derivative exponents: " + TOSTRING(deriv[2])) + + coeffs2 <- deriv[1] + exps2 <- deriv[2] + + antideriv <- ANTIDERIVATIVE(coeffs2, exps2) + DISPLAY("Antiderivative coefficients: " + TOSTRING(antideriv[1])) + DISPLAY("Antiderivative exponents: " + TOSTRING(antideriv[2])) + "#, "Derivative coefficients: [6, 2]\nDerivative exponents: [1, 0]\nAntiderivative coefficients: [3, 2, 0]\nAntiderivative exponents: [2, 1, 0]", + ); + } + #[test] fn test_heap_sort() { assert_output( @@ -2164,4 +2224,28 @@ DISPLAY(arr)"#, "true\n5", ); } + + #[test] + fn test_range() { + assert_output("DISPLAY(RANGE(5))", "[1, 2, 3, 4, 5]"); + assert_output("DISPLAY(RANGE(2, 5))", "[2, 3, 4, 5]"); + assert_output("DISPLAY(RANGE(1))", "[1]"); + assert_output("DISPLAY(RANGE(1, 1))", "[1]"); + + assert_output( + r#" + list <- RANGE(3) + DISPLAY(list[2]) + "#, + "2", + ); + + assert_output( + r#" + list <- RANGE(2, 4) + DISPLAY(list[2]) + "#, + "3", + ); + } }