From b2d295a04d90d45acd3d9eea6f1f446abeb0c9f7 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Wed, 4 Oct 2023 01:59:57 +0300 Subject: [PATCH 01/81] fix #61: identifiers beginning with numbers --- lexer/lexer.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lexer/lexer.go b/lexer/lexer.go index e1db11f..73d4094 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -1,3 +1,5 @@ +// This will convert the sequence of characters into a sequence of tokens + package lexer import ( @@ -13,7 +15,7 @@ type Lexer struct { } func New(input string) *Lexer { - l := &Lexer{input: []rune(input)} + l := &Lexer{input: []rune(input), line: 1} l.readChar() return l } @@ -176,6 +178,11 @@ func (l *Lexer) NextToken() token.Token { tok.Type = token.LookupIdent(tok.Literal) tok.Line = l.line return tok + } else if isDigit(l.ch) && isLetter(l.peekChar()) { + tok.Literal = l.readIdentifier() + tok.Type = token.LookupIdent(tok.Literal) + tok.Line = l.line + return tok } else if isDigit(l.ch) { tok = l.readDecimal() return tok From a18cce4d830fd62e38f104eb35d0f82c8d9db2e0 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Wed, 4 Oct 2023 02:04:01 +0300 Subject: [PATCH 02/81] fix tests --- evaluator/evaluator_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index 0e72748..c4a8a97 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -206,27 +206,27 @@ func TestErrorHandling(t *testing.T) { }{ { "5 + kweli", - "Mstari 0: Aina Hazilingani: NAMBA + BOOLEAN", + "Mstari 1: Aina Hazilingani: NAMBA + BOOLEAN", }, { "5 + kweli; 5;", - "Mstari 0: Aina Hazilingani: NAMBA + BOOLEAN", + "Mstari 1: Aina Hazilingani: NAMBA + BOOLEAN", }, { "-kweli", - "Mstari 0: Operesheni Haielweki: -BOOLEAN", + "Mstari 1: Operesheni Haielweki: -BOOLEAN", }, { "kweli + sikweli", - "Mstari 0: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 1: Operesheni Haielweki: BOOLEAN + BOOLEAN", }, { "5; kweli + sikweli; 5", - "Mstari 0: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 1: Operesheni Haielweki: BOOLEAN + BOOLEAN", }, { "kama (10 > 1) { kweli + sikweli;}", - "Mstari 0: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 1: Operesheni Haielweki: BOOLEAN + BOOLEAN", }, { ` @@ -238,19 +238,19 @@ kama (10 > 1) { rudisha 1; } `, - "Mstari 3: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 4: Operesheni Haielweki: BOOLEAN + BOOLEAN", }, { "bangi", - "Mstari 0: Neno Halifahamiki: bangi", + "Mstari 1: Neno Halifahamiki: bangi", }, { `"Habari" - "Habari"`, - "Mstari 0: Operesheni Haielweki: NENO - NENO", + "Mstari 1: Operesheni Haielweki: NENO - NENO", }, { `{"jina": "Avi"}[unda(x) {x}];`, - "Mstari 0: Samahani, UNDO (FUNCTION) haitumiki kama key", + "Mstari 1: Samahani, UNDO (FUNCTION) haitumiki kama key", }, } From ede224c9cc3d69e11f96e88cb3f73299c53f9341 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Wed, 11 Oct 2023 13:48:02 +0300 Subject: [PATCH 03/81] fix: check for null when inspecting array --- object/array.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/object/array.go b/object/array.go index d8b7233..970a488 100644 --- a/object/array.go +++ b/object/array.go @@ -15,8 +15,12 @@ func (ao *Array) Inspect() string { var out bytes.Buffer elements := []string{} - for _, e := range ao.Elements { - elements = append(elements, e.Inspect()) + if len(ao.Elements) != 0 { + for _, e := range ao.Elements { + if e.Inspect() != "" { + elements = append(elements, e.Inspect()) + } + } } out.WriteString("[") From b2fedea213208d1677d839b37998288f2ee60939 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Wed, 11 Oct 2023 18:14:30 +0300 Subject: [PATCH 04/81] add hisabati package written in pure nuru by Victor --- third_party/math/README.md | 121 +++++++ third_party/math/hisabati.nr | 615 +++++++++++++++++++++++++++++++++++ 2 files changed, 736 insertions(+) create mode 100644 third_party/math/README.md create mode 100644 third_party/math/hisabati.nr diff --git a/third_party/math/README.md b/third_party/math/README.md new file mode 100644 index 0000000..b006d78 --- /dev/null +++ b/third_party/math/README.md @@ -0,0 +1,121 @@ +# Math Package + +A math pacakage written in pure Nuru by [VictorKariuki](https://github.com/VictorKariuki) + + +## Explanation + +A detailed list of all methods and description and example: + +### abs(namba) + +Description: Calculates the absolute value of a number. +Example: Hisabati.abs(-42) returns 42. + +### acos(x) +Description: Calculates the arccosine (inverse cosine) of a number in radians. +Example: Hisabati.acos(0.5) returns the arccosine of 0.5. + +### acosh(x) +Description: Calculates the inverse hyperbolic cosine of a number. +Example: Hisabati.acosh(2) returns the inverse hyperbolic cosine of 2. + +### arcsin(x) +Description: Calculates the arcsine (inverse sine) of a number using a Taylor series. +Example: Hisabati.arcsin(0.5) returns the arcsine of 0.5. + +### arsinh(x) +Description: Calculates the inverse hyperbolic sine of a number. +Example: Hisabati.arsinh(1) returns the inverse hyperbolic sine of 1. + +### atan(x) +Description: Calculates the arctangent (inverse tangent) of a number in radians using a Taylor series. +Example: Hisabati.atan(1) returns the arctangent of 1. + +### atan2(y, x) +Description: Calculates the angle in radians between the positive x-axis and the point (x, y). +Example: Hisabati.atan2(1, 1) returns the angle for the point (1, 1). + +### atanh(x) +Description: Calculates the inverse hyperbolic tangent of a number. +Example: Hisabati.atanh(0.5) returns the inverse hyperbolic tangent of 0.5. + +### cbrt(x) +Description: Calculates the cube root of a number. +Example: Hisabati.cbrt(8) returns the cube root of 8. + +### ceil(x) +Description: Rounds up to the smallest integer greater than or equal to a given number. +Example: Hisabati.ceil(4.2) returns 5. + +### cos(x, terms) +Description: Calculates the cosine of a number in radians using a Taylor series. +Example: Hisabati.cos(1) returns the cosine of 1. + +### cosh(x) +Description: Calculates the hyperbolic cosine of a number. +Example: Hisabati.cosh(2) returns the hyperbolic cosine of 2. + +### exp(x, precision) +Description: Calculates the value of the mathematical constant e raised to the power of x using a Taylor series. +Example: Hisabati.exp(2) returns e^2. + +### expm1(x) +Description: Calculates the value of e^x - 1 using a Taylor series. +Example: Hisabati.expm1(1) returns e - 1. + +### floor(x) +Description: Rounds down to the largest integer less than or equal to a given number. +Example: Hisabati.floor(4.9) returns 4. + +### hypot(values) +Description: Calculates the Euclidean norm (square root of the sum of squares) of a list of values. +Example: Hisabati.hypot([3, 4]) returns 5, which is the hypotenuse of a right triangle. + +### log(x) +Description: Calculates the natural logarithm of a number using a Taylor series. +Example: Hisabati.log(2) returns the natural logarithm of 2. + +### log10(x) +Description: Calculates the base 10 logarithm of a number using the natural logarithm. +Example: Hisabati.log10(100) returns 2. + +### log1p(x) +Description: Calculates the natural logarithm of 1 + x using a Taylor series. +Example: Hisabati.log1p(0.5) returns the natural logarithm of 1.5. + +### log2(x) +Description: Calculates the base 2 logarithm of a number. +Example: Hisabati.log2(8) returns 3. + +### max(numbers) +Description: Returns the largest number from a list of numbers. +Example: Hisabati.max([3, 7, 2, 9]) returns 9. + +### min(numbers) +Description: Returns the smallest number from a list of numbers. +Example: Hisabati.min([3, 7, 2, 9]) returns 2. + +### round(x, method) +Description: Rounds a number to the nearest integer using different rounding methods. +Example: Hisabati.round(3.6, "rpi") rounds to the nearest integer (4) using "round half up." + +### sign(x) +Description: Returns the sign of a number: 1 for positive, -1 for negative, and 0 for zero. +Example: Hisabati.sign(-7) returns -1. + +### sin(x, terms) +Description: Calculates the sine of a number in radians using a Taylor series. +Example: Hisabati.sin(0.5) returns the sine of 0.5. + +### sinh(x) +Description: Calculates the hyperbolic sine of a number. +Example: Hisabati.sinh(1) returns the hyperbolic sine of 1. + +### sqrt(x) +Description: Calculates the square root of a number using the Newton-Raphson method. +Example: Hisabati.sqrt(16) returns 4. + +### sine(x) +Description: Calculates the sine of a number in radians using a Taylor series. +Example: Hisabati.sine(1.5) returns the sine of 1.5 \ No newline at end of file diff --git a/third_party/math/hisabati.nr b/third_party/math/hisabati.nr new file mode 100644 index 0000000..bdbd67e --- /dev/null +++ b/third_party/math/hisabati.nr @@ -0,0 +1,615 @@ +pakeji hisabati{ + andaa = unda() { // the andaa function is mandatory even kama its empty + // π (Pi): The ratio of the circumference of a circle to its diameter. + @.PI = 3.141592653589793; + + // e (Euler's Number): The base of the natural logarithm and used in various mathematical contexts. + @.e = 2.718281828459045; + + // φ (Phi, Golden Ratio): A mathematical fanyaant with applications in nature, art, and architecture. + @.phi = 1.618033988749895; + + // Natural logarithm of 10. + @.ln10 = 2.302585092994046; + + // Natural logarithm of 2. + @.ln2 = 0.6931471805599453; + + // Base 10 logarithm of Euler's number (e). + @.log10e = 0.4342944819032518; + + // Base 2 logarithm of Euler's number (e). + @.log2e = 1.4426950408889634; + + // √1/2 (equivalent to 1 / sqrt(2)). + @.sqrt1_2 = 0.7071067811865476; + + // √2 (Square Root of 2): Used in geometry and mathematical proofs. + @.sqrt2 = 1.414213562373095; + + // √3 (Square Root of 3): Used in geometry, trigonometry, and mathematics. + @.sqrt3 = 1.732050807568877; + + // √5 (Square Root of 5): Used in various mathematical contexts. + @.sqrt5 = 2.236067977499790; + + //@.EPSILON = 2.220446049250313e-16; + + } + + + // Methods + + abs = unda(namba){ + kama(namba < 0){ + rudisha - 1 * namba; + } + + rudisha namba; + } + + acos = unda(x) { + kama(x < -1 || x > 1) { + rudisha 0; + } + + // Define the precision for the approximation. + fanya precision = 1e-10; + + // Initial guess for the angle in radians (between 0 and π). + fanya angle = @.PI / 4; + + wakati(true) { + fanya cosAngle = @.cos(angle); + fanya error = @.abs(cosAngle - x); + + kama(error < precision) { + rudisha angle; + } + + // Update the angle using the Newton-Raphson method. + angle -= (cosAngle - x) / (-@.sin(angle)); + } + } + + acosh = unda(x) { + kama(x < 1) { + rudisha 0; + } + + rudisha @.log(x + @.sqrt(x * x - 1)); + } + + // method to calculate arcsin using Taylor series + arcsin = unda(x) { + kama(x < -1 || x > 1) { + rudisha 0; + } + + fanya maxIterations = 50; // Maximum number of iterations + fanya result = 0; + + fanya n = 0; + wakati(n < maxIterations) { + fanya numerator = @.pow(-1, n) * @.pow(x, 2 * n + 1); + fanya denominator = @.factorial(2 * n + 1); // You'll need to implement a factorial function + + result += numerator / denominator; + n++; + } + + rudisha result; + } + + arsinh = unda(x) { + // Calculate arsinh using the formula: arsinh(x) = ln(x + sqrt(x^2 + 1)) + kama(x >= 0) { + rudisha @.log(x + @.sqrt(x * x + 1)); + } sivyo { + // For negative values, arsinh(x) = -arsinh(-x) + rudisha - @.log(-x + @.sqrt(x * x + 1)); + } + } + + atan = unda(x) { + kama(x == 0) { + rudisha 0; + } // arctan(0) is 0 + kama(x == Infinity) { + rudisha @.PI / 2; + } + kama(x == -Infinity) { + rudisha - @.PI / 2; + } // arctan(-Infinity) is -π/2 + + // Use the Taylor series expansion for arctan(x) + // arctan(x) = x - (x^3) / 3 + (x^5) / 5 - (x^7) / 7 + ... + fanya n = 3; + fanya result = 0; + fanya term = x * x; + fanya sign = -1; + + wakati(true) { + fanya currentTerm = sign * (term / n); + + kama(currentTerm == 0) { + vunja + } + + result += currentTerm; + n += 2; + sign = -sign; + term *= x * x; + } + + rudisha result; + } + + atan2 = unda(y, x) { + kama(x > 0) { + rudisha @.atan(y / x); + } au kama(x < 0 && y >= 0) { + rudisha @.atan(y / x) + @.PI; + } au kama(x < 0 && y < 0) { + rudisha @.atan(y / x) - @.PI; + } au kama(x == 0 && y > 0) { + rudisha @.PI / 2; + } au kama(x == 0 && y < 0) { + rudisha - @.PI / 2; + } au kama(x == 0 && y == 0) { + rudisha NaN; // Undefined + } + } + + atanh = unda(x) { + kama(x < -1 || x > 1) { + rudisha 0; + } + rudisha 0.5 * @.log((1 + x) / (1 - x)); + } + + // Cube Root + cbrt = unda(x) { + kama(x >= 0) { + rudisha @.root(x, 3); + } sivyo { + rudisha - @.root(-x, 3); + } + } + + // Helper method to calculate the nth root using the Newton-Raphson method + root = unda(x, n) { + fanya guess = x / 2; // Initial guess + fanya tolerance = 1e-10; // Tolerance for convergence + + wakati(true) { + fanya nextGuess = ((n - 1) * guess + x / @.pow(guess, n - 1)) / n; + kama(@.abs(nextGuess - guess) < tolerance) { + rudisha nextGuess; + } + guess = nextGuess; + } + } + + // Rounds up to the smallest integer greater than or equal to a given number + ceil = unda(x) { + kama(x >= 0) { + kama(x % 1 == 0) { + rudisha x; // x is already an integer + } + rudisha floor(x) + 1; + } sivyo { + rudisha - floor(abs(x)); + } + } + + cos = unda(x, terms = 10) { + // Initialize the result + fanya n = 0; + fanya result = 0; + + wakati(n < terms) { + // Calculate the numerator and denominator for the nth term + fanya numerator = 0; + kama(n % 2 == 0) { + numerator = x ** (2 * n + 1); + } sivyo { + numerator = -x ** (2 * n + 1); + } + fanya denominator = factorial(2 * n); + + // Add the nth term to the result + result += numerator / denominator; + + n++; + } + + rudisha result; + } + + cosh = unda(x) { + fanya eToX = @.exp(x); + fanya eToMinusX = @.exp(-x); + rudisha(eToX + eToMinusX) / 2; + } + + exp = unda(x, precision = 15) { + fanya result = 1; + fanya term = 1; + fanya i = 1; + + wakati(i <= precision) { + term *= x / i; + result += term; + i++; + } + + + rudisha result; + } + + expm1 = unda(x) { + fanya epsilon = 1e-15; // A small value to improve accuracy + fanya result = 0; + fanya term = x; + fanya n = 1; + + wakati(@.abs(term) > epsilon) { + result += term; + n++; + term *= x / n; + } + + rudisha result; + } + + floor = unda(x) { + kama(x >= 0) { + rudisha x - (x % 1); + } sivyo { + rudisha x - (1 + x % 1); + } + } + + hypot = unda(values) { + // Calculate the sum of squares of the values + fanya exp = unda(acc, value){ + rudisha acc + value ** 2; + } + + fanya sumOfSquares = @.reduce(values, exp, 0); + + // Calculate the square root of the sum of squares + fanya result = @.sqrt(sumOfSquares); + + rudisha result; + } + + log = unda(x) { + kama(x <= 0) { + rudisha 0; + } + + fanya approx = 0; + fanya n = 50; + fanya i = 1; + + wakati(i <= n) { + approx += (1 / i) * @.pow((x - 1) / (x + 1), 2 * i - 1); + i++; + } + + + rudisha 2 * approx; + } + + // method to calculate the base 10 logarithm + log10 = unda(x) { + kama(x <= 0) { + rudisha 0; + } + + // Calculate natural logarithm and divide by the natural logarithm of 10 + rudisha this.log(x) / this.log(10); + } + + log1p = unda(x) { + kama(x < -1) { + rudisha 0; + } + + kama(x == -1) { + rudisha(-Infinity); + } + + kama(x == Infinity) { + rudisha Infinity; + } + + kama(x == 0) { + rudisha 0; + } + + // Use the formula: ln(1 + x) = x - (x^2)/2 + (x^3)/3 - (x^4)/4 + ... + fanya result = 0; + fanya term = x; + fanya i = 2; + + wakati(@.abs(term) > @.EPSILON) { + result += term; + term *= -x / i; + i++; + } + + rudisha result; + } + + log2 = unda(x) { + kama(x <= 0) { + rudisha 0; + } + + fanya result = 0; + fanya currentValue = x; + + wakati(currentValue > 1) { + currentValue /= 2; + result++; + } + + rudisha result; + } + + max = unda(numbers) { + // Initialize a variable to store the largest number + fanya largest = -Infinity; + + // Iterate through the numbers and update 'largest' kama a larger number is found + kwa num ktk numbers { + kama(num > largest) { + largest = num; + } + } + + // rudisha the largest number (or -Infinity kama there are no parameters) + rudisha largest; + } + + min = unda(numbers) { + kama(numbers.length == 0) { + rudisha Infinity; + } + + fanya minVal = numbers[0]; + + fanya i = 1; + wakati(i < numbers.length) { + kama(numbers[i] < minVal) { + minVal = numbers[i]; + } + i++; + } + + rudisha minVal; + } + + round = unda(x, method = "ri") { + kama(method == "rpi") { + rudisha floor(x + 0.5); + } au kama(method == "rni") { + rudisha ceiling(x - 0.5); + } au kama(method == "ri") { + kama(x >= 0){ + rudisha floor(x + 0.5); + }sivyo{ + rudisha ceiling(x - 0.5); + } + } sivyo { + rudisha NaN; // Invalid method + } + } + + sign = unda(x) { + kama(x == 0 || x == -0) { + rudisha x; + } au kama(x > 0) { + rudisha 1; + } sivyo { + rudisha - 1; + } + } + + sin = unda(x, terms = 10) { + // Initialize the result + fanya n = 0; + fanya result = 0; + + wakati(n < terms) { + // Calculate the numerator and denominator for the nth term + fanya numerator = 0; + kama(n % 2 == 0) { + numerator = x ** (2 * n + 1); + } sivyo { + numerator = -x ** (2 * n + 1); + } + + fanya denominator = @.factorial(2 * n + 1); + + // Add the nth term to the result + result += numerator / denominator; + + n++; + } + + rudisha result; + } + + sinh = unda(x) { + // sinh(x) = (e^x - e^(-x)) / 2 + fanya eToX = @.exp(x); + fanya eToMinusX = @.exp(-x); + rudisha(eToX - eToMinusX) / 2; + } + + sqrt = unda(x) { + kama(x < 0) { + rudisha 0; + } + + // Initial guess for the square root (you can choose a better initial guess) + fanya guess = x / 2; + fanya tolerance = 1e-7; // Tolerance for approximation + + wakati(true) { + fanya nextGuess = 0.5 * (guess + x / guess); + + // Check kama the guess is close enough to the actual square root + kama(@.abs(nextGuess - guess) < tolerance) { + rudisha nextGuess; + } + + guess = nextGuess; + } + } + + sine = unda(x) { + fanya tolerance = @.e-15; // Tolerance for convergence + fanya result = x; + fanya term = x; + fanya n = 1; + + wakati(@.abs(term) > tolerance) { + term *= (-x * x) / ((2 * n + 1) * (2 * n)); + result += term; + n++; + } + + rudisha result; + } + + // Calculate the tangent of a number in radians + tangent = unda(x) { + fanya sineX = @.sine(x); + fanya cosineX = @.sqrt(1 - sineX * sineX); + + kama(cosineX == 0) { + rudisha 0; + } + + rudisha sineX / cosineX; + } + + tanh = unda(x) { + kama(x == Infinity) { + rudisha 1; + } au kama(x == -Infinity) { + rudisha - 1; + } sivyo { + fanya expX = @.exp(x); + fanya expNegX = @.exp(-x); + rudisha(expX - expNegX) / (expX + expNegX); + } + } + + // utility methods + // Function to check kama a number is negative zero + isNegativeZero = unda(num) { + rudisha num == 0 && 1 / num == -Infinity; + } + // Helper function to calculate the factorial of a number + factorial = unda(n) { + kama(n == 0){ + rudisha 1; + }; + fanya result = 1; + fanya i = 1; + + wakati(i <= n) { + result *= i; + i++; + } + + rudisha result; + + } + + // Helper function to calculate pow using Taylor series + pow = unda(base, exponent) { + fanya result = 1; + fanya i = 0; + wakati(i < exponent) { + result *= base; + i++; + } + rudisha result; + } + + // Helper function to check kama a number is negative + isNegative = unda(num) { + rudisha num < 0; + } + + isInteger = unda(num) { + rudisha num == @.floor(num); + } + + // method to get the integer part of a number + getIntegerPart = unda(num) { + // Handle negative numbers separately + kama(@.isNegative(num)) { + // For negative numbers, we subtract the absolute value of the fractional part from 1 + rudisha - (@.ceil(-num) - 1); + } sivyo { + // For positive numbers, we simply truncate the fractional part + rudisha @.floor(num); + } + } + + // create a list of numbers + list = unda(first, last, interval){ + fanya list = [first]; + fanya i = first + interval; + wakati(i < last){ + list.sukuma(i); + i += interval; + } + rudisha list; + } + + // Maths functions + // square a number + square = unda(n, i, j){ + fanya kati = (i + j) / 2; + fanya mul = kati * kati; + fanya abs_diff = abs(mul - n); + + kama(mul == n || abs_diff < 0.00001){ + rudisha kati; + }au kama(mul < n){ + rudisha square(n, kati, j); + }au{ + rudisha square(n, i, kati); + } + } + + // find the square root of a number + sqrt = unda(namba){ + kwa i ktk list(0, namba, 1) { + kama((i * i) == namba){ + rudisha i; + }au kama((i * i) > namba){ + rudisha square(namba, i - 1, i); + } + } + } + + reduce = unda(iterator, callback, initialValue) { + fanya accumulator = initialValue; + + kwa thamani ktk iterator { + accumulator = callback(accumulator, thamani); + } + + rudisha accumulator; + } +} From fba74b2be4b1774d1c6254eeb50583d74ba23b61 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Wed, 11 Oct 2023 18:21:46 +0300 Subject: [PATCH 05/81] fix formatting --- third_party/math/README.md | 114 ++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/third_party/math/README.md b/third_party/math/README.md index b006d78..5e084e6 100644 --- a/third_party/math/README.md +++ b/third_party/math/README.md @@ -5,117 +5,117 @@ A math pacakage written in pure Nuru by [VictorKariuki](https://github.com/Victo ## Explanation -A detailed list of all methods and description and example: +A detailed list of all methods and - Description and - Example: ### abs(namba) -Description: Calculates the absolute value of a number. -Example: Hisabati.abs(-42) returns 42. +- Description: Calculates the absolute value of a number. +- Example: Hisabati.abs(-42) returns 42. ### acos(x) -Description: Calculates the arccosine (inverse cosine) of a number in radians. -Example: Hisabati.acos(0.5) returns the arccosine of 0.5. +- Description: Calculates the arccosine (inverse cosine) of a number in radians. +- Example: Hisabati.acos(0.5) returns the arccosine of 0.5. ### acosh(x) -Description: Calculates the inverse hyperbolic cosine of a number. -Example: Hisabati.acosh(2) returns the inverse hyperbolic cosine of 2. +- Description: Calculates the inverse hyperbolic cosine of a number. +- Example: Hisabati.acosh(2) returns the inverse hyperbolic cosine of 2. ### arcsin(x) -Description: Calculates the arcsine (inverse sine) of a number using a Taylor series. -Example: Hisabati.arcsin(0.5) returns the arcsine of 0.5. +- Description: Calculates the arcsine (inverse sine) of a number using a Taylor series. +- Example: Hisabati.arcsin(0.5) returns the arcsine of 0.5. ### arsinh(x) -Description: Calculates the inverse hyperbolic sine of a number. -Example: Hisabati.arsinh(1) returns the inverse hyperbolic sine of 1. +- Description: Calculates the inverse hyperbolic sine of a number. +- Example: Hisabati.arsinh(1) returns the inverse hyperbolic sine of 1. ### atan(x) -Description: Calculates the arctangent (inverse tangent) of a number in radians using a Taylor series. -Example: Hisabati.atan(1) returns the arctangent of 1. +- Description: Calculates the arctangent (inverse tangent) of a number in radians using a Taylor series. +- Example: Hisabati.atan(1) returns the arctangent of 1. ### atan2(y, x) -Description: Calculates the angle in radians between the positive x-axis and the point (x, y). -Example: Hisabati.atan2(1, 1) returns the angle for the point (1, 1). +- Description: Calculates the angle in radians between the positive x-axis and the point (x, y). +- Example: Hisabati.atan2(1, 1) returns the angle for the point (1, 1). ### atanh(x) -Description: Calculates the inverse hyperbolic tangent of a number. -Example: Hisabati.atanh(0.5) returns the inverse hyperbolic tangent of 0.5. +- Description: Calculates the inverse hyperbolic tangent of a number. +- Example: Hisabati.atanh(0.5) returns the inverse hyperbolic tangent of 0.5. ### cbrt(x) -Description: Calculates the cube root of a number. -Example: Hisabati.cbrt(8) returns the cube root of 8. +- Description: Calculates the cube root of a number. +- Example: Hisabati.cbrt(8) returns the cube root of 8. ### ceil(x) -Description: Rounds up to the smallest integer greater than or equal to a given number. -Example: Hisabati.ceil(4.2) returns 5. +- Description: Rounds up to the smallest integer greater than or equal to a given number. +- Example: Hisabati.ceil(4.2) returns 5. ### cos(x, terms) -Description: Calculates the cosine of a number in radians using a Taylor series. -Example: Hisabati.cos(1) returns the cosine of 1. +- Description: Calculates the cosine of a number in radians using a Taylor series. +- Example: Hisabati.cos(1) returns the cosine of 1. ### cosh(x) -Description: Calculates the hyperbolic cosine of a number. -Example: Hisabati.cosh(2) returns the hyperbolic cosine of 2. +- Description: Calculates the hyperbolic cosine of a number. +- Example: Hisabati.cosh(2) returns the hyperbolic cosine of 2. ### exp(x, precision) -Description: Calculates the value of the mathematical constant e raised to the power of x using a Taylor series. -Example: Hisabati.exp(2) returns e^2. +- Description: Calculates the value of the mathematical constant e raised to the power of x using a Taylor series. +- Example: Hisabati.exp(2) returns e^2. ### expm1(x) -Description: Calculates the value of e^x - 1 using a Taylor series. -Example: Hisabati.expm1(1) returns e - 1. +- Description: Calculates the value of e^x - 1 using a Taylor series. +- Example: Hisabati.expm1(1) returns e - 1. ### floor(x) -Description: Rounds down to the largest integer less than or equal to a given number. -Example: Hisabati.floor(4.9) returns 4. +- Description: Rounds down to the largest integer less than or equal to a given number. +- Example: Hisabati.floor(4.9) returns 4. ### hypot(values) -Description: Calculates the Euclidean norm (square root of the sum of squares) of a list of values. -Example: Hisabati.hypot([3, 4]) returns 5, which is the hypotenuse of a right triangle. +- Description: Calculates the Euclidean norm (square root of the sum of squares) of a list of values. +- Example: Hisabati.hypot([3, 4]) returns 5, which is the hypotenuse of a right triangle. ### log(x) -Description: Calculates the natural logarithm of a number using a Taylor series. -Example: Hisabati.log(2) returns the natural logarithm of 2. +- Description: Calculates the natural logarithm of a number using a Taylor series. +- Example: Hisabati.log(2) returns the natural logarithm of 2. ### log10(x) -Description: Calculates the base 10 logarithm of a number using the natural logarithm. -Example: Hisabati.log10(100) returns 2. +- Description: Calculates the base 10 logarithm of a number using the natural logarithm. +- Example: Hisabati.log10(100) returns 2. ### log1p(x) -Description: Calculates the natural logarithm of 1 + x using a Taylor series. -Example: Hisabati.log1p(0.5) returns the natural logarithm of 1.5. +- Description: Calculates the natural logarithm of 1 + x using a Taylor series. +- Example: Hisabati.log1p(0.5) returns the natural logarithm of 1.5. ### log2(x) -Description: Calculates the base 2 logarithm of a number. -Example: Hisabati.log2(8) returns 3. +- Description: Calculates the base 2 logarithm of a number. +- Example: Hisabati.log2(8) returns 3. ### max(numbers) -Description: Returns the largest number from a list of numbers. -Example: Hisabati.max([3, 7, 2, 9]) returns 9. +- Description: Returns the largest number from a list of numbers. +- Example: Hisabati.max([3, 7, 2, 9]) returns 9. ### min(numbers) -Description: Returns the smallest number from a list of numbers. -Example: Hisabati.min([3, 7, 2, 9]) returns 2. +- Description: Returns the smallest number from a list of numbers. +- Example: Hisabati.min([3, 7, 2, 9]) returns 2. ### round(x, method) -Description: Rounds a number to the nearest integer using different rounding methods. -Example: Hisabati.round(3.6, "rpi") rounds to the nearest integer (4) using "round half up." +- Description: Rounds a number to the nearest integer using different rounding methods. +- Example: Hisabati.round(3.6, "rpi") rounds to the nearest integer (4) using "round half up." ### sign(x) -Description: Returns the sign of a number: 1 for positive, -1 for negative, and 0 for zero. -Example: Hisabati.sign(-7) returns -1. +- Description: Returns the sign of a number: 1 for positive, -1 for negative, and 0 for zero. +- Example: Hisabati.sign(-7) returns -1. ### sin(x, terms) -Description: Calculates the sine of a number in radians using a Taylor series. -Example: Hisabati.sin(0.5) returns the sine of 0.5. +- Description: Calculates the sine of a number in radians using a Taylor series. +- Example: Hisabati.sin(0.5) returns the sine of 0.5. ### sinh(x) -Description: Calculates the hyperbolic sine of a number. -Example: Hisabati.sinh(1) returns the hyperbolic sine of 1. +- Description: Calculates the hyperbolic sine of a number. +- Example: Hisabati.sinh(1) returns the hyperbolic sine of 1. ### sqrt(x) -Description: Calculates the square root of a number using the Newton-Raphson method. -Example: Hisabati.sqrt(16) returns 4. +- Description: Calculates the square root of a number using the Newton-Raphson method. +- Example: Hisabati.sqrt(16) returns 4. ### sine(x) -Description: Calculates the sine of a number in radians using a Taylor series. -Example: Hisabati.sine(1.5) returns the sine of 1.5 \ No newline at end of file +- Description: Calculates the sine of a number in radians using a Taylor series. +- Example: Hisabati.sine(1.5) returns the sine of 1.5 \ No newline at end of file From cce9f1ed7af27ecf2302e9cbf7541709a45192a9 Mon Sep 17 00:00:00 2001 From: "Karim M. Nyumba" <96383368+karimnyumba@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:01:14 +0300 Subject: [PATCH 06/81] Typo fixing --- evaluator/builtins.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evaluator/builtins.go b/evaluator/builtins.go index 806689d..0cc4dfd 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -74,7 +74,7 @@ var builtins = map[string]*object.Builtin{ "aina": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { - return newError("Samahani, tunahitaji Hoja 1, wewe umeweka %d", len(args)) + return newError("Samahani, tunahitaji hoja 1, wewe umeweka %d", len(args)) } return &object.String{Value: string(args[0].Type())} From 844c6b3e1d36d0c59bf799bc78bd5c82cddabbea Mon Sep 17 00:00:00 2001 From: "Karim M. Nyumba" <96383368+karimnyumba@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:09:20 +0300 Subject: [PATCH 07/81] Translation fix --- evaluator/property.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evaluator/property.go b/evaluator/property.go index b68199f..fad7bf3 100644 --- a/evaluator/property.go +++ b/evaluator/property.go @@ -58,6 +58,7 @@ func evalPropertyAssignment(name *ast.PropertyExpression, val object.Object, env obj.Env.Set(prop, val) return NULL default: - return newError("Imeshindikana ku assign kwenye package %s", left.Type()) + return newError("Imeshindikana kuweka kwenye pakiti %s", left.Type()) + // Alternative: return newError("Imeshindikana kukabidhi kwenye kifurushi %s", left.Type()) } } From 51dbee7d1aa941a166402a5ac5477fa4c16d1d2c Mon Sep 17 00:00:00 2001 From: "Karim M. Nyumba" <96383368+karimnyumba@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:10:34 +0300 Subject: [PATCH 08/81] typo fix --- evaluator/prefix.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evaluator/prefix.go b/evaluator/prefix.go index 4bb9f56..5efb52d 100644 --- a/evaluator/prefix.go +++ b/evaluator/prefix.go @@ -12,7 +12,7 @@ func evalMinusPrefixOperatorExpression(right object.Object, line int) object.Obj return &object.Float{Value: -obj.Value} default: - return newError("Mstari %d: Operesheni Haielweki: -%s", line, right.Type()) + return newError("Mstari %d: Operesheni haieleweki: -%s", line, right.Type()) } } func evalPlusPrefixOperatorExpression(right object.Object, line int) object.Object { @@ -25,7 +25,7 @@ func evalPlusPrefixOperatorExpression(right object.Object, line int) object.Obje return &object.Float{Value: obj.Value} default: - return newError("Mstari %d: Operesheni Haielweki: +%s", line, right.Type()) + return newError("Mstari %d: Operesheni haieleweki: +%s", line, right.Type()) } } From efc6ff157e8ba90cc1e88635285949e9ffb52724 Mon Sep 17 00:00:00 2001 From: "Karim M. Nyumba" <96383368+karimnyumba@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:14:31 +0300 Subject: [PATCH 09/81] translation --- evaluator/index.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evaluator/index.go b/evaluator/index.go index 07945f0..e5a182f 100644 --- a/evaluator/index.go +++ b/evaluator/index.go @@ -32,7 +32,7 @@ func evalDictIndexExpression(dict, index object.Object, line int) object.Object key, ok := index.(object.Hashable) if !ok { - return newError("Mstari %d: Samahani, %s haitumiki kama key", line, index.Type()) + return newError("Mstari %d: Samahani, %s haitumiki kama ufunguo", line, index.Type()) } pair, ok := dictObject.Pairs[key.HashKey()] From 56ecd1f4ce3086900aa32fdbdbcc7f8d5fb5e5b7 Mon Sep 17 00:00:00 2001 From: "Karim M. Nyumba" <96383368+karimnyumba@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:21:09 +0300 Subject: [PATCH 10/81] translation --- evaluator/evaluator.go | 8 ++++---- evaluator/import.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go index 70f2db9..758f4dd 100644 --- a/evaluator/evaluator.go +++ b/evaluator/evaluator.go @@ -180,7 +180,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object { } array.Elements[idx.Value] = value } else { - return newError("Hauwezi kufanya opereshen hii na %#v", index) + return newError("Hauwezi kufanya operesheni hii na %#v", index) } } else if hash, ok := obj.(*object.Dict); ok { key := Eval(ie.Index, env) @@ -191,13 +191,13 @@ func Eval(node ast.Node, env *object.Environment) object.Object { hashed := hashKey.HashKey() hash.Pairs[hashed] = object.DictPair{Key: key, Value: value} } else { - return newError("Hauwezi kufanya opereshen hii na %T", key) + return newError("Hauwezi kufanya operesheni hii na %T", key) } } else { - return newError("%T haifanyi operation hii", obj) + return newError("%T haifanyi operesheni hii", obj) } } else { - return newError("Tumia neno kama variable, sio %T", left) + return newError("Tumia neno kama kibadala, sio %T", left) } } diff --git a/evaluator/import.go b/evaluator/import.go index 0375a3c..130f20c 100644 --- a/evaluator/import.go +++ b/evaluator/import.go @@ -31,7 +31,7 @@ func evalImportFile(name string, ident *ast.Identifier, env *object.Environment) addSearchPath("") filename := findFile(name) if filename == "" { - return newError("Module %s haipo", name) + return newError("Moduli %s haipo", name) } var scope *object.Environment scope, err := evaluateFile(filename, env) @@ -70,7 +70,7 @@ func evaluateFile(file string, env *object.Environment) (*object.Environment, ob p := parser.New(l) program := p.ParseProgram() if len(p.Errors()) != 0 { - return nil, &object.Error{Message: fmt.Sprintf("Pakeji %s ina errors zifuatozo:\n%s", file, strings.Join(p.Errors(), "\n"))} + return nil, &object.Error{Message: fmt.Sprintf("Pakeji %s ina makosa yafuatayo:\n%s", file, strings.Join(p.Errors(), "\n"))} } scope := object.NewEnvironment() From 26e997974931dd719acb6c20b28f7ba445b2af9e Mon Sep 17 00:00:00 2001 From: "Karim M. Nyumba" <96383368+karimnyumba@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:29:05 +0300 Subject: [PATCH 11/81] fix --- evaluator/property.go | 1 - 1 file changed, 1 deletion(-) diff --git a/evaluator/property.go b/evaluator/property.go index fad7bf3..13ea8be 100644 --- a/evaluator/property.go +++ b/evaluator/property.go @@ -59,6 +59,5 @@ func evalPropertyAssignment(name *ast.PropertyExpression, val object.Object, env return NULL default: return newError("Imeshindikana kuweka kwenye pakiti %s", left.Type()) - // Alternative: return newError("Imeshindikana kukabidhi kwenye kifurushi %s", left.Type()) } } From 38c907a12c43fa823df018db00234967703752f8 Mon Sep 17 00:00:00 2001 From: "Karim M. Nyumba" <96383368+karimnyumba@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:44:11 +0300 Subject: [PATCH 12/81] test fix --- evaluator/evaluator_test.go | 12 ++++++------ evaluator/prefix.go | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index c4a8a97..2142a22 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -214,19 +214,19 @@ func TestErrorHandling(t *testing.T) { }, { "-kweli", - "Mstari 1: Operesheni Haielweki: -BOOLEAN", + "Mstari 1: Operesheni Haieleweki: -BOOLEAN", }, { "kweli + sikweli", - "Mstari 1: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 1: Operesheni Haieleweki: BOOLEAN + BOOLEAN", }, { "5; kweli + sikweli; 5", - "Mstari 1: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 1: Operesheni Haieleweki: BOOLEAN + BOOLEAN", }, { "kama (10 > 1) { kweli + sikweli;}", - "Mstari 1: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 1: Operesheni Haieleweki: BOOLEAN + BOOLEAN", }, { ` @@ -238,7 +238,7 @@ kama (10 > 1) { rudisha 1; } `, - "Mstari 4: Operesheni Haielweki: BOOLEAN + BOOLEAN", + "Mstari 4: Operesheni Haieleweki: BOOLEAN + BOOLEAN", }, { "bangi", @@ -246,7 +246,7 @@ kama (10 > 1) { }, { `"Habari" - "Habari"`, - "Mstari 1: Operesheni Haielweki: NENO - NENO", + "Mstari 1: Operesheni Haieleweki: NENO - NENO", }, { `{"jina": "Avi"}[unda(x) {x}];`, diff --git a/evaluator/prefix.go b/evaluator/prefix.go index 5efb52d..3038006 100644 --- a/evaluator/prefix.go +++ b/evaluator/prefix.go @@ -12,7 +12,7 @@ func evalMinusPrefixOperatorExpression(right object.Object, line int) object.Obj return &object.Float{Value: -obj.Value} default: - return newError("Mstari %d: Operesheni haieleweki: -%s", line, right.Type()) + return newError("Mstari %d: Operesheni Haieleweki: -%s", line, right.Type()) } } func evalPlusPrefixOperatorExpression(right object.Object, line int) object.Object { @@ -25,7 +25,7 @@ func evalPlusPrefixOperatorExpression(right object.Object, line int) object.Obje return &object.Float{Value: obj.Value} default: - return newError("Mstari %d: Operesheni haieleweki: +%s", line, right.Type()) + return newError("Mstari %d: Operesheni Haieleweki: +%s", line, right.Type()) } } @@ -38,6 +38,6 @@ func evalPrefixExpression(operator string, right object.Object, line int) object case "+": return evalPlusPrefixOperatorExpression(right, line) default: - return newError("Mstari %d: Operesheni haieleweki: %s%s", line, operator, right.Type()) + return newError("Mstari %d: Operesheni Haieleweki: %s%s", line, operator, right.Type()) } } From 9066ba614cdabc86f802019d7f7349db0c30e872 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 21:51:12 +0300 Subject: [PATCH 13/81] fix tests --- evaluator/evaluator_test.go | 2 +- evaluator/infix.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index 2142a22..ad9e925 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -250,7 +250,7 @@ kama (10 > 1) { }, { `{"jina": "Avi"}[unda(x) {x}];`, - "Mstari 1: Samahani, UNDO (FUNCTION) haitumiki kama key", + "Mstari 1: Samahani, UNDO (FUNCTION) haitumiki kama ufunguo", }, } diff --git a/evaluator/infix.go b/evaluator/infix.go index 33fa484..e17645a 100644 --- a/evaluator/infix.go +++ b/evaluator/infix.go @@ -90,7 +90,7 @@ func evalInfixExpression(operator string, left, right object.Object, line int) o line, left.Type(), operator, right.Type()) default: - return newError("Mstari %d: Operesheni Haielweki: %s %s %s", + return newError("Mstari %d: Operesheni Haieleweki: %s %s %s", line, left.Type(), operator, right.Type()) } } @@ -132,7 +132,7 @@ func evalFloatIntegerInfixExpression(operator string, left, right object.Object, case "!=": return nativeBoolToBooleanObject(leftVal != rightVal) default: - return newError("Mstari %d: Operesheni Haielweki: %s %s %s", + return newError("Mstari %d: Operesheni Haieleweki: %s %s %s", line, left.Type(), operator, right.Type()) } @@ -156,7 +156,7 @@ func evalStringInfixExpression(operator string, left, right object.Object, line case "!=": return nativeBoolToBooleanObject(leftVal != rightVal) default: - return newError("Mstari %d: Operesheni Haielweki: %s %s %s", line, left.Type(), operator, right.Type()) + return newError("Mstari %d: Operesheni Haieleweki: %s %s %s", line, left.Type(), operator, right.Type()) } } @@ -170,7 +170,7 @@ func evalBooleanInfixExpression(operator string, left, right object.Object, line case "||": return nativeBoolToBooleanObject(leftVal || rightVal) default: - return newError("Mstari %d: Operesheni Haielweki: %s %s %s", line, left.Type(), operator, right.Type()) + return newError("Mstari %d: Operesheni Haieleweki: %s %s %s", line, left.Type(), operator, right.Type()) } } @@ -202,7 +202,7 @@ func evalFloatInfixExpression(operator string, left, right object.Object, line i case "!=": return nativeBoolToBooleanObject(leftVal != rightVal) default: - return newError("Mstari %d: Operesheni Haielweki: %s %s %s", + return newError("Mstari %d: Operesheni Haieleweki: %s %s %s", line, left.Type(), operator, right.Type()) } } @@ -242,7 +242,7 @@ func evalIntegerInfixExpression(operator string, left, right object.Object, line case "!=": return nativeBoolToBooleanObject(leftVal != rightVal) default: - return newError("Mstari %d: Operesheni Haielweki: %s %s %s", + return newError("Mstari %d: Operesheni Haieleweki: %s %s %s", line, left.Type(), operator, right.Type()) } } From 9b438d52de51d5eddc5c22d48c9ee3beed32391e Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 22:10:35 +0300 Subject: [PATCH 14/81] test releasing --- .github/workflows/tests.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fa3aa02..14d7469 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,12 +10,23 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v3 with: go-version: 1.18 + id: go - name: Test run: go mod tidy && make test + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@master + with: + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }} From 96ad29422d18f68553166ab78e5bd713c209e390 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 22:18:56 +0300 Subject: [PATCH 15/81] add comment to tokens --- token/token.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/token/token.go b/token/token.go index fff5b1d..0608580 100644 --- a/token/token.go +++ b/token/token.go @@ -1,3 +1,5 @@ +// This is where we define our tokens + package token type TokenType string From a45eb2a317de9b6a398ca1a5e7718ebc0d4a1b12 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 22:27:23 +0300 Subject: [PATCH 16/81] fix ci will this work? --- .github/workflows/tests.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 14d7469..b749c10 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,17 +16,18 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.21 id: go - name: Test run: go mod tidy && make test - name: Run GoReleaser - uses: goreleaser/goreleaser-action@master + uses: goreleaser/goreleaser-action@v5 with: + distribution: goreleaser version: latest - args: release --rm-dist + args: release --clean env: GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }} From c2c991f1c0962a45fdf31d548ba3cda6b085fa01 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 23:09:34 +0300 Subject: [PATCH 17/81] remove dev branch ci --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b749c10..22b5ecd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,7 +2,7 @@ name: Go on: push: - branches: [ main, dev ] + branches: [ main ] jobs: From 2c3e4ac2632a396e440ee14299c19a3279798638 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 23:13:17 +0300 Subject: [PATCH 18/81] remove build from tests --- .github/workflows/tests.yml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 22b5ecd..7f6c282 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,7 +2,7 @@ name: Go on: push: - branches: [ main ] + branches: [ main, dev ] jobs: @@ -10,24 +10,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v3 with: go-version: 1.21 - id: go - name: Test run: go mod tidy && make test - - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5 - with: - distribution: goreleaser - version: latest - args: release --clean - env: - GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }} From 225507097876417b3177521927a62c30b26844d2 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 23:14:06 +0300 Subject: [PATCH 19/81] add separate for releases --- .github/workflows/build.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..3c26f7f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,32 @@ +name: Go + +on: + push: + tags: + - "*" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.21 + id: go + + - name: Test + run: go mod tidy && make test + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }} From c6f0c2f71005c6682dd423ccc99cd36240517403 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 23:41:50 +0300 Subject: [PATCH 20/81] update gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 2631fb3..2443257 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,10 @@ nuru Notes.md tutorials/en/* config.json +*local* # For Nuru executables /nuru /Nuru + +dist/ From 5c270d16dc043a26edb15e8f1ea270cbccd17301 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sun, 15 Oct 2023 23:42:39 +0300 Subject: [PATCH 21/81] add goreleaser cofig --- .goreleaser.yaml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .goreleaser.yaml diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..62d214b --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,45 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com + +# The lines bellow are called `modelines`. See `:help modeline` +# Feel free to remove those if you don't want/need to use them. +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj + +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... + +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + - android + +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of `uname`. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives + format_overrides: + - goos: windows + format: zip + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" From 4ae7531a0c2149a3a893d00b1031e4af8ed32a55 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Mon, 16 Oct 2023 00:01:48 +0300 Subject: [PATCH 22/81] ignore 386 for android --- .goreleaser.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 62d214b..7c354db 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -21,6 +21,9 @@ builds: - windows - darwin - android + ignore: + - goos: android + goarch: 386 archives: - format: tar.gz From cc33f3b5cec14dcbf9da0a7ab55ebe783fadc899 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Mon, 16 Oct 2023 00:38:55 +0300 Subject: [PATCH 23/81] use nuru --- .goreleaser.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 7c354db..c00131d 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -29,7 +29,7 @@ archives: - format: tar.gz # this name template makes the OS and Arch compatible with the results of `uname`. name_template: >- - {{ .ProjectName }}_ + nuru_ {{- title .Os }}_ {{- if eq .Arch "amd64" }}x86_64 {{- else if eq .Arch "386" }}i386 From c046302843cf25d16b4af2f162b97512ccf1b1cb Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Mon, 16 Oct 2023 00:54:50 +0300 Subject: [PATCH 24/81] add deb release? --- .goreleaser.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index c00131d..8ef1a39 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -46,3 +46,7 @@ changelog: exclude: - "^docs:" - "^test:" + +nfpms: + - file_name_template: nuru + maintainer: AvicennaJr \ No newline at end of file From 4ca9cdeeaa6a1f27a852aa09710a2893a1e1ed04 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Mon, 16 Oct 2023 01:10:23 +0300 Subject: [PATCH 25/81] add output formats for nfpms --- .goreleaser.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 8ef1a39..d5fccfd 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -48,5 +48,11 @@ changelog: - "^test:" nfpms: - - file_name_template: nuru - maintainer: AvicennaJr \ No newline at end of file + - name: nuru + maintainer: AvicennaJr + arch: amd64 + platform: linux + section: default + priority: extra + homepage: "https://nuruprogramming.org" + description: "Nuru is a programming language built from the ground up" \ No newline at end of file From 7732a4b2796e4ef7a0a2328c13b28301a2cee18a Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Mon, 16 Oct 2023 01:36:34 +0300 Subject: [PATCH 26/81] figured it out alx --- .goreleaser.yaml | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index d5fccfd..dba4b11 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,16 +1,7 @@ -# This is an example .goreleaser.yml file with some sensible defaults. -# Make sure to check the documentation at https://goreleaser.com - -# The lines bellow are called `modelines`. See `:help modeline` -# Feel free to remove those if you don't want/need to use them. -# yaml-language-server: $schema=https://goreleaser.com/static/schema.json -# vim: set ts=2 sw=2 tw=0 fo=cnqoj - +project_name: nuru before: hooks: - # You may remove this if you don't use go modules. - go mod tidy - # you may remove this if you don't need go generate - go generate ./... builds: @@ -21,13 +12,14 @@ builds: - windows - darwin - android + ldflags: + - '-s -w' ignore: - goos: android goarch: 386 archives: - format: tar.gz - # this name template makes the OS and Arch compatible with the results of `uname`. name_template: >- nuru_ {{- title .Os }}_ @@ -35,7 +27,6 @@ archives: {{- else if eq .Arch "386" }}i386 {{- else }}{{ .Arch }}{{ end }} {{- if .Arm }}v{{ .Arm }}{{ end }} - # use zip for windows archives format_overrides: - goos: windows format: zip @@ -48,11 +39,9 @@ changelog: - "^test:" nfpms: - - name: nuru - maintainer: AvicennaJr - arch: amd64 - platform: linux - section: default - priority: extra + - maintainer: "AvicennaJr" homepage: "https://nuruprogramming.org" - description: "Nuru is a programming language built from the ground up" \ No newline at end of file + description: "Nuru is a programming language built from the ground up" + formats: + - deb + file_name_template: "{{ .ProjectName }}.{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" \ No newline at end of file From b243bd2b101fb20af212091d60ab2053a01444e5 Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Tue, 17 Oct 2023 22:15:38 +0300 Subject: [PATCH 27/81] Updated third-party hisabati package documentation. Removed redundant functionality: pow and used ** instead. sine because sin is implemented in a efficient way. Added reduce.nr under examples Used functions to return --- examples/Astart.nr | 179 +++++++++++++++++++++++++++++ examples/reduce.nr | 34 ++++++ examples/sarufi.nr | 48 ++++---- third_party/math/README.md | 211 ++++++++++++++++++++--------------- third_party/math/hisabati.nr | 190 +++++++++++++++---------------- 5 files changed, 453 insertions(+), 209 deletions(-) create mode 100644 examples/Astart.nr create mode 100644 examples/reduce.nr diff --git a/examples/Astart.nr b/examples/Astart.nr new file mode 100644 index 0000000..2ff03bd --- /dev/null +++ b/examples/Astart.nr @@ -0,0 +1,179 @@ +/*############ A*(A-star) Algorithm ############## + + By @VictorKariuki + + https://github.com/VictorKariuki + +################################################*/ + + +// create a list of numbers +fanya list = unda(first,last,interval){ + fanya list = [first]; + fanya i = first + interval; + wakati(i < last){ + list.sukuma(i) + i+=interval; + } + rudisha list; +} + +// Maths functions +// find the absolute value of a number +fanya abs_namba = unda(namba){ + kama(namba < 0){ + rudisha -1 * namba; + } + + rudisha namba; +} + +// square a number +fanya square = unda(n, i, j){ + fanya kati = (i+j)/2; + fanya mul = kati * kati; + fanya abs_diff = abs_namba(mul-n); + + kama (mul == n || abs_diff < 0.00001){ + rudisha kati; + }au kama(mul < n){ + rudisha square(n,kati,j) + }au{ + rudisha square(n,i,kati) + } +} + +// find the square root of a number +fanya sqrt = unda(namba){ + kwa i ktk list(0,namba,1) { + kama((i*i )== namba){ + rudisha i; + }au kama ((i*i )> namba){ + rudisha square(namba,i-1,i) + } + } +} + +// Main function +fanya aStar = unda(start, goal) { + // Initialize the open and closed lists + fanya openList = [start]; + fanya closedList = []; + + fanya reconstructPath = unda(node) { + fanya path = [node]; + wakati (node["parent"]) { + path = [node["parent"]] + path; + node = node["parent"]; + } + rudisha path; + } + + fanya heuristic = unda(node1, node2) { + // Calculate the Euclidean distance between the nodes' positions + fanya dx = node1["x"] - node2["x"]; + fanya dy = node1["y"] - node2["y"]; + rudisha sqrt(dx * dx + dy * dy); + } + + fanya findMinNode = unda(openList) { + fanya i = 1; + fanya minNode = openList[0]; + + wakati (i < openList.idadi()) { + fanya node = openList[i]; + kama (node["f"] < minNode["f"]) { + minNode = node; + } + i++ + } + + rudisha minNode; + } + + fanya removeNodeFromArray = unda(array, node) { + fanya newArray = []; + fanya i = 1; + wakati (i < array.idadi()) { + kama (array[i] != node) { + newArray.sukuma(array[i]); + } + i++; + } + rudisha newArray; + } + + fanya urefu = unda(node1, node2) { + // Assume all edges have a cost of 1 + rudisha 1; + } + + // Initialize the g and f scores of the starting node + start["g"] = 0; + start["f"] = start["g"] + heuristic(start, goal); + + + + // Start the search loop + wakati (openList.idadi() > 0) { + // Find the node with the lowest f score in the open list + fanya current = findMinNode(openList); + + // Check kama the goal node has been reached + kama (current == goal) { + rudisha reconstructPath(current); + } + + // Move the current node from the open to the closed list + openList = removeNodeFromArray(openList, current); + + closedList.sukuma(current); + + // Explore the neighbors of the current node + kwa neighbor ktk current["neighbors"] { + // Skip neighbors that are in the closed list + kama (neighbor ktk closedList) { + endelea + } + + // Calculate the tentative g score of the neighbor + fanya tentativeG = start["g"] + urefu(current, neighbor); + + // Check kama the neighbor is in the open list + fanya tentativeIsBetter = sikweli; + kama (!(neighbor ktk openList)) { + openList.sukuma(neighbor); + tentativeIsBetter = kweli; + } au kama (tentativeG < neighbor["g"]) { + tentativeIsBetter = kweli; + } + + // Update the neighbor's g score kama the tentative score is better + kama (tentativeIsBetter) { + neighbor["g"] = tentativeG; + neighbor["f"] = neighbor["g"] + heuristic(neighbor, goal); + neighbor["parent"] = current; + } + } + } + + // kama the open list is empty, no path was found + rudisha tupu; +} + +// Define the nodes of the graph +fanya nodeA = { "x": 0, "y": 0, "neighbors": [] }; +fanya nodeB = { "x": 1, "y": 2, "neighbors": [] }; +fanya nodeC = { "x": 3, "y": 1, "neighbors": [] }; +fanya nodeD = { "x": 4, "y": 3, "neighbors": [] }; + +// Define the edges between the nodes +nodeA["neighbors"] = [nodeB]; +nodeB["neighbors"] = [nodeA, nodeC]; +nodeC["neighbors"] = [nodeB, nodeD]; +nodeD["neighbors"] = [nodeC]; + +// Call the A* function with the start and goal nodes and the heuristic and distance functions +//fanya path = aStar(nodeA, nodeC); + +andika(nodeA); \ No newline at end of file diff --git a/examples/reduce.nr b/examples/reduce.nr new file mode 100644 index 0000000..2f09d00 --- /dev/null +++ b/examples/reduce.nr @@ -0,0 +1,34 @@ +fanya reduce = unda(iterator, callback, initialValue) { + fanya accumulator = initialValue; + + kwa thamani ktk iterator { + accumulator = callback(accumulator, thamani); + } + + rudisha accumulator; +} + +fanya list = [1,2,3,4,5]; +fanya employees = [{"salary":120},{"salary":135},{"salary":140}] + +fanya sum = unda(acc,value){ + rudisha acc + value; +} + +fanya mul = unda(acc,value){ + rudisha acc * value; +} + +fanya sumSalo = unda(acc,value){ + rudisha acc + value["salary"]; +} + +fanya sumSaloWithTax = unda(acc,value){ + rudisha acc + (value["salary"] * (1-0.34)); +} + +andika(reduce(list,sum,0)) +andika(reduce(list,mul,1)) + +andika(reduce(employees,sumSalo,0)) +andika(reduce(employees,sumSaloWithTax,0)) \ No newline at end of file diff --git a/examples/sarufi.nr b/examples/sarufi.nr index 8c19e51..39c7419 100644 --- a/examples/sarufi.nr +++ b/examples/sarufi.nr @@ -1,32 +1,32 @@ tumia mtandao tumia jsoni pakeji sarufi { - andaa = unda(file) { - config = fungua(file) - configString = config.soma() - configDict = jsoni.dikodi(configString) - clientID = configDict["client_id"] - clientSecret = configDict["client_secret"] - params = {"client_id": clientID, "client_secret": clientSecret} - tokenString = mtandao.tuma(yuareli="https://api.sarufi.io/api/access_token", mwili=params) - tokenDict = jsoni.dikodi(tokenString) - @.token = tokenDict["access_token"] - @.Auth = "Bearer " + @.token - } + andaa = unda(file) { + config = fungua(file) + configString = config.soma() + configDict = jsoni.dikodi(configString) + clientID = configDict["client_id"] + clientSecret = configDict["client_secret"] + params = {"client_id": clientID, "client_secret": clientSecret} + tokenString = mtandao.tuma(yuareli="https://api.sarufi.io/api/access_token", mwili=params) + tokenDict = jsoni.dikodi(tokenString) + @.token = tokenDict["access_token"] + @.Auth = "Bearer " + @.token + } - tokenYangu = unda() { - rudisha @.token - } + tokenYangu = unda() { + rudisha @.token + } - tengenezaChatbot = unda(data) { - majibu = mtandao.tuma(yuareli="https://api.sarufi.io/chatbot", vichwa={"Authorization": @.Auth}, mwili = data) - rudisha majibu - } + tengenezaChatbot = unda(data) { + majibu = mtandao.tuma(yuareli="https://api.sarufi.io/chatbot", vichwa={"Authorization": @.Auth}, mwili = data) + rudisha majibu + } - pataChatbotZote = unda() { - majibu = mtandao.peruzi(yuareli="https://api.sarufi.io/chatbots", vichwa={"Authorization": @.Auth}) - rudisha majibu - } - } + pataChatbotZote = unda() { + majibu = mtandao.peruzi(yuareli="https://api.sarufi.io/chatbots", vichwa={"Authorization": @.Auth}) + rudisha majibu + } +} diff --git a/third_party/math/README.md b/third_party/math/README.md index 5e084e6..4f8acef 100644 --- a/third_party/math/README.md +++ b/third_party/math/README.md @@ -1,121 +1,158 @@ # Math Package - -A math pacakage written in pure Nuru by [VictorKariuki](https://github.com/VictorKariuki) + ## Explanation +This math package provides a collection of mathematical functions and constants implemented in the Nuru programming language. These functions cover a wide range of mathematical operations, including trigonometric functions, logarithmic functions, and other common mathematical operations. Below is a detailed list of all methods along with their descriptions and examples: + +1. **abs(namba)** + - Description: Calculates the absolute value of a number. + - Example: `Hisabati.abs(-42)` returns `42`. + +2. **acos(x)** + - Description: Calculates the arccosine (inverse cosine) of a number in radians. + - Example: `Hisabati.acos(0.5)` returns the arccosine of 0.5. + +3. **acosh(x)** + - Description: Calculates the inverse hyperbolic cosine of a number. + - Example: `Hisabati.acosh(2)` returns the inverse hyperbolic cosine of 2. + +4. **arcsin(x)** + - Description: Calculates the arcsine (inverse sine) of a number using a Taylor series. + - Example: `Hisabati.arcsin(0.5)` returns the arcsine of 0.5. + +5. **arsinh(x)** + - Description: Calculates the inverse hyperbolic sine of a number. + - Example: `Hisabati.arsinh(1)` returns the inverse hyperbolic sine of 1. + +6. **atan(x)** + - Description: Calculates the arctangent (inverse tangent) of a number in radians using a Taylor series. + - Example: `Hisabati.atan(1)` returns the arctangent of 1. + +7. **atan2(y, x)** + - Description: Calculates the angle in radians between the positive x-axis and the point (x, y). + - Example: `Hisabati.atan2(1, 1)` returns the angle for the point (1, 1). + +8. **atanh(x)** + - Description: Calculates the inverse hyperbolic tangent of a number. + - Example: `Hisabati.atanh(0.5)` returns the inverse hyperbolic tangent of 0.5. + +9. **cbrt(x)** + - Description: Calculates the cube root of a number. + - Example: `Hisabati.cbrt(8)` returns the cube root of 8. + +10. **ceil(x)** + - Description: Rounds up to the smallest integer greater than or equal to a given number. + - Example: `Hisabati.ceil(4.2)` returns `5`. -A detailed list of all methods and - Description and - Example: +11. **cos(x, terms)** + - Description: Calculates the cosine of a number in radians using a Taylor series. + - Example: `Hisabati.cos(1)` returns the cosine of 1. -### abs(namba) +12. **cosh(x)** + - Description: Calculates the hyperbolic cosine of a number. + - Example: `Hisabati.cosh(2)` returns the hyperbolic cosine of 2. -- Description: Calculates the absolute value of a number. -- Example: Hisabati.abs(-42) returns 42. +13. **exp(x, precision)** + - Description: Calculates the value of the mathematical constant e raised to the power of x using a Taylor series. + - Example: `Hisabati.exp(2)` returns `e^2`. -### acos(x) -- Description: Calculates the arccosine (inverse cosine) of a number in radians. -- Example: Hisabati.acos(0.5) returns the arccosine of 0.5. +14. **expm1(x)** + - Description: Calculates the value of e^x - 1 using a Taylor series. + - Example: `Hisabati.expm1(1)` returns `e - 1`. -### acosh(x) -- Description: Calculates the inverse hyperbolic cosine of a number. -- Example: Hisabati.acosh(2) returns the inverse hyperbolic cosine of 2. +15. **floor(x)** + - Description: Rounds down to the largest integer less than or equal to a given number. + - Example: `Hisabati.floor(4.9)` returns `4`. -### arcsin(x) -- Description: Calculates the arcsine (inverse sine) of a number using a Taylor series. -- Example: Hisabati.arcsin(0.5) returns the arcsine of 0.5. +16. **hypot(values)** + - Description: Calculates the Euclidean norm (square root of the sum of squares) of a list of values. + - Example: `Hisabati.hypot([3, 4])` returns `5`, which is the hypotenuse of a right triangle. -### arsinh(x) -- Description: Calculates the inverse hyperbolic sine of a number. -- Example: Hisabati.arsinh(1) returns the inverse hyperbolic sine of 1. +17. **log(x)** + - Description: Calculates the natural logarithm of a number using a Taylor series. + - Example: `Hisabati.log(2)` returns the natural logarithm of 2. -### atan(x) -- Description: Calculates the arctangent (inverse tangent) of a number in radians using a Taylor series. -- Example: Hisabati.atan(1) returns the arctangent of 1. +18. **log10(x)** + - Description: Calculates the base 10 logarithm of a number using the natural logarithm. + - Example: `Hisabati.log10(100)` returns `2`. -### atan2(y, x) -- Description: Calculates the angle in radians between the positive x-axis and the point (x, y). -- Example: Hisabati.atan2(1, 1) returns the angle for the point (1, 1). +19. **log1p(x)** + - Description: Calculates the natural logarithm of 1 + x using a Taylor series. + - Example: `Hisabati.log1p(0.5)` returns the natural logarithm of 1.5. -### atanh(x) -- Description: Calculates the inverse hyperbolic tangent of a number. -- Example: Hisabati.atanh(0.5) returns the inverse hyperbolic tangent of 0.5. +20. **log2(x)** -### cbrt(x) -- Description: Calculates the cube root of a number. -- Example: Hisabati.cbrt(8) returns the cube root of 8. -### ceil(x) -- Description: Rounds up to the smallest integer greater than or equal to a given number. -- Example: Hisabati.ceil(4.2) returns 5. + - Description: Calculates the base 2 logarithm of a number. + - Example: `Hisabati.log2(8)` returns `3`. -### cos(x, terms) -- Description: Calculates the cosine of a number in radians using a Taylor series. -- Example: Hisabati.cos(1) returns the cosine of 1. +21. **max(numbers)** + - Description: Returns the largest number from a list of numbers. + - Example: `Hisabati.max([3, 7, 2, 9])` returns `9`. -### cosh(x) -- Description: Calculates the hyperbolic cosine of a number. -- Example: Hisabati.cosh(2) returns the hyperbolic cosine of 2. +22. **min(numbers)** + - Description: Returns the smallest number from a list of numbers. + - Example: `Hisabati.min([3, 7, 2, 9])` returns `2`. -### exp(x, precision) -- Description: Calculates the value of the mathematical constant e raised to the power of x using a Taylor series. -- Example: Hisabati.exp(2) returns e^2. +23. **round(x, method)** + - Description: Rounds a number to the nearest integer using different rounding methods. + - Example: `Hisabati.round(3.6, "rpi")` rounds to the nearest integer (`4`) using "round half up." -### expm1(x) -- Description: Calculates the value of e^x - 1 using a Taylor series. -- Example: Hisabati.expm1(1) returns e - 1. +24. **sign(x)** + - Description: Returns the sign of a number: `1` for positive, `-1` for negative, and `0` for zero. + - Example: `Hisabati.sign(-7)` returns `-1`. -### floor(x) -- Description: Rounds down to the largest integer less than or equal to a given number. -- Example: Hisabati.floor(4.9) returns 4. +25. **sin(x, terms)** + - Description: Calculates the sine of a number in radians using a Taylor series. + - Example: `Hisabati.sin(0.5)` returns the sine of 0.5. -### hypot(values) -- Description: Calculates the Euclidean norm (square root of the sum of squares) of a list of values. -- Example: Hisabati.hypot([3, 4]) returns 5, which is the hypotenuse of a right triangle. +26. **sinh(x)** + - Description: Calculates the hyperbolic sine of a number. + - Example: `Hisabati.sinh(1)` returns the hyperbolic sine of 1. -### log(x) -- Description: Calculates the natural logarithm of a number using a Taylor series. -- Example: Hisabati.log(2) returns the natural logarithm of 2. +27. **sqrt(x)** + - Description: Calculates the square root of a number using the Newton-Raphson method. + - Example: `Hisabati.sqrt(16)` returns `4`. -### log10(x) -- Description: Calculates the base 10 logarithm of a number using the natural logarithm. -- Example: Hisabati.log10(100) returns 2. +28. **tangent(x)** + - Description: Calculates the tangent of a number in radians. + - Example: `Hisabati.tangent(1)` returns the tangent of 1. -### log1p(x) -- Description: Calculates the natural logarithm of 1 + x using a Taylor series. -- Example: Hisabati.log1p(0.5) returns the natural logarithm of 1.5. +29. **tanh(x)** + - Description: Calculates the hyperbolic tangent of a number. + - Example: `Hisabati.tanh(0.5)` returns the hyperbolic tangent of 0.5. -### log2(x) -- Description: Calculates the base 2 logarithm of a number. -- Example: Hisabati.log2(8) returns 3. +30. **isNegativeZero(num)** + - Description: Checks if a number is negative zero (0 with a negative sign). + - Example: `Hisabati.isNegativeZero(-0)` returns `true`. -### max(numbers) -- Description: Returns the largest number from a list of numbers. -- Example: Hisabati.max([3, 7, 2, 9]) returns 9. +31. **factorial(n)** + - Description: Calculates the factorial of a number. + - Example: `Hisabati.factorial(5)` returns `120`. -### min(numbers) -- Description: Returns the smallest number from a list of numbers. -- Example: Hisabati.min([3, 7, 2, 9]) returns 2. +32. **pow(base, exponent)** + - Description: Calculates the power of a number. + - Example: `Hisabati.pow(2, 3)` returns `8`. -### round(x, method) -- Description: Rounds a number to the nearest integer using different rounding methods. -- Example: Hisabati.round(3.6, "rpi") rounds to the nearest integer (4) using "round half up." +33. **isNegative(num)** + - Description: Checks if a number is negative. + - Example: `Hisabati.isNegative(-5)` returns `true`. -### sign(x) -- Description: Returns the sign of a number: 1 for positive, -1 for negative, and 0 for zero. -- Example: Hisabati.sign(-7) returns -1. +34. **isInteger(num)** + - Description: Checks if a number is an integer. + - Example: `Hisabati.isInteger(42)` returns `true`. -### sin(x, terms) -- Description: Calculates the sine of a number in radians using a Taylor series. -- Example: Hisabati.sin(0.5) returns the sine of 0.5. +35. **getIntegerPart(num)** + - Description: Gets the integer part of a number. + - Example: `Hisabati.getIntegerPart(5.8)` returns `5`. -### sinh(x) -- Description: Calculates the hyperbolic sine of a number. -- Example: Hisabati.sinh(1) returns the hyperbolic sine of 1. +36. **list(first, last, interval)** + - Description: Creates a list of numbers within a specified range with a given interval. + - Example: `Hisabati.list(0, 10, 2)` returns `[0, 2, 4, 6, 8]`. -### sqrt(x) -- Description: Calculates the square root of a number using the Newton-Raphson method. -- Example: Hisabati.sqrt(16) returns 4. +37. **square(n, i, j)** + - Description: Finds the square root of a number using a method that iteratively narrows down the root. + - Example: `Hisabati.square(16)` returns `4`. -### sine(x) -- Description: Calculates the sine of a number in radians using a Taylor series. -- Example: Hisabati.sine(1.5) returns the sine of 1.5 \ No newline at end of file +Feel free to use this package for your mathematical calculations and applications. \ No newline at end of file diff --git a/third_party/math/hisabati.nr b/third_party/math/hisabati.nr index bdbd67e..2691b19 100644 --- a/third_party/math/hisabati.nr +++ b/third_party/math/hisabati.nr @@ -1,45 +1,70 @@ pakeji hisabati{ - andaa = unda() { // the andaa function is mandatory even kama its empty - // π (Pi): The ratio of the circumference of a circle to its diameter. - @.PI = 3.141592653589793; + //CONSTRUCTOR METHOD + andaa = unda() {} - // e (Euler's Number): The base of the natural logarithm and used in various mathematical contexts. - @.e = 2.718281828459045; + // Constants + // π (Pi) + PI = unda() { + rudisha 3.141592653589793; + } - // φ (Phi, Golden Ratio): A mathematical fanyaant with applications in nature, art, and architecture. - @.phi = 1.618033988749895; + // e (Euler's Number) + e = unda() { + rudisha 2.718281828459045; + } - // Natural logarithm of 10. - @.ln10 = 2.302585092994046; + // φ (Phi, Golden Ratio) + phi = unda() { + rudisha 1.618033988749895; + } - // Natural logarithm of 2. - @.ln2 = 0.6931471805599453; + // Natural logarithm of 10 + ln10 = unda() { + rudisha 2.302585092994046; + } - // Base 10 logarithm of Euler's number (e). - @.log10e = 0.4342944819032518; + // Natural logarithm of 2 + ln2 = unda() { + rudisha 0.6931471805599453; + } - // Base 2 logarithm of Euler's number (e). - @.log2e = 1.4426950408889634; + // Base 10 logarithm of Euler's number (e) + log10e = unda() { + rudisha 0.4342944819032518; + } - // √1/2 (equivalent to 1 / sqrt(2)). - @.sqrt1_2 = 0.7071067811865476; + // Base 2 logarithm of Euler's number (e) + log2e = unda() { + rudisha 1.4426950408889634; + } - // √2 (Square Root of 2): Used in geometry and mathematical proofs. - @.sqrt2 = 1.414213562373095; + // √1/2 (equivalent to 1 / sqrt(2)) + sqrt1_2 = unda() { + rudisha 0.7071067811865476; + } - // √3 (Square Root of 3): Used in geometry, trigonometry, and mathematics. - @.sqrt3 = 1.732050807568877; + // √2 (Square Root of 2) + sqrt2 = unda() { + rudisha 1.414213562373095; + } - // √5 (Square Root of 5): Used in various mathematical contexts. - @.sqrt5 = 2.236067977499790; + // √3 (Square Root of 3) + sqrt3 = unda() { + rudisha 1.732050807568877; + } - //@.EPSILON = 2.220446049250313e-16; + // √5 (Square Root of 5) + sqrt5 = unda() { + rudisha 2.236067977499790; + } + // @.EPSILON + EPSILON = unda() { + rudisha 2.220446049250313e-16; } - // Methods - + //abs(namba), calculates the absolute value of a number. abs = unda(namba){ kama(namba < 0){ rudisha - 1 * namba; @@ -48,6 +73,7 @@ pakeji hisabati{ rudisha namba; } + //acos(x), calculates the arccosine of a number. acos = unda(x) { kama(x < -1 || x > 1) { rudisha 0; @@ -72,6 +98,7 @@ pakeji hisabati{ } } + //acosh(x), calculates the inverse hyperbolic cosine of a number. acosh = unda(x) { kama(x < 1) { rudisha 0; @@ -80,7 +107,7 @@ pakeji hisabati{ rudisha @.log(x + @.sqrt(x * x - 1)); } - // method to calculate arcsin using Taylor series + //arcsin(x), calculates the arcsine of a number using the Taylor series. arcsin = unda(x) { kama(x < -1 || x > 1) { rudisha 0; @@ -91,7 +118,7 @@ pakeji hisabati{ fanya n = 0; wakati(n < maxIterations) { - fanya numerator = @.pow(-1, n) * @.pow(x, 2 * n + 1); + fanya numerator = (-1) ** n * x ** (2 * n + 1); fanya denominator = @.factorial(2 * n + 1); // You'll need to implement a factorial function result += numerator / denominator; @@ -101,6 +128,7 @@ pakeji hisabati{ rudisha result; } + //arsinh(x), calculates the inverse hyperbolic sine of a number. arsinh = unda(x) { // Calculate arsinh using the formula: arsinh(x) = ln(x + sqrt(x^2 + 1)) kama(x >= 0) { @@ -111,6 +139,7 @@ pakeji hisabati{ } } + //atan(x), calculates the arctangent of a number using the Taylor series. atan = unda(x) { kama(x == 0) { rudisha 0; @@ -145,6 +174,7 @@ pakeji hisabati{ rudisha result; } + //atanh(x), calculates the inverse hyperbolic tangent of a number. atan2 = unda(y, x) { kama(x > 0) { rudisha @.atan(y / x); @@ -161,6 +191,7 @@ pakeji hisabati{ } } + //atanh(x), calculates the inverse hyperbolic tangent of a number. atanh = unda(x) { kama(x < -1 || x > 1) { rudisha 0; @@ -168,7 +199,7 @@ pakeji hisabati{ rudisha 0.5 * @.log((1 + x) / (1 - x)); } - // Cube Root + //cbrt(x), calculates the cube root of a number. cbrt = unda(x) { kama(x >= 0) { rudisha @.root(x, 3); @@ -177,13 +208,13 @@ pakeji hisabati{ } } - // Helper method to calculate the nth root using the Newton-Raphson method + //root(x, n), calculates the nth root of a number using the Newton-Raphson method. root = unda(x, n) { fanya guess = x / 2; // Initial guess fanya tolerance = 1e-10; // Tolerance for convergence wakati(true) { - fanya nextGuess = ((n - 1) * guess + x / @.pow(guess, n - 1)) / n; + fanya nextGuess = ((n - 1) * guess + x / guess ** n - 1) / n; kama(@.abs(nextGuess - guess) < tolerance) { rudisha nextGuess; } @@ -191,7 +222,7 @@ pakeji hisabati{ } } - // Rounds up to the smallest integer greater than or equal to a given number + //ceil(x), rounds up to the smallest integer greater than or equal to a given number. ceil = unda(x) { kama(x >= 0) { kama(x % 1 == 0) { @@ -203,6 +234,7 @@ pakeji hisabati{ } } + //cos(x), calculates the cosine of an angle in radians using the Taylor series. cos = unda(x, terms = 10) { // Initialize the result fanya n = 0; @@ -216,7 +248,7 @@ pakeji hisabati{ } sivyo { numerator = -x ** (2 * n + 1); } - fanya denominator = factorial(2 * n); + fanya denominator = @.factorial(2 * n); // Add the nth term to the result result += numerator / denominator; @@ -227,12 +259,14 @@ pakeji hisabati{ rudisha result; } + //cosh(x), calculates the hyperbolic cosine of a number. cosh = unda(x) { fanya eToX = @.exp(x); fanya eToMinusX = @.exp(-x); rudisha(eToX + eToMinusX) / 2; } + //exp(x), calculates the value of Euler's number raised to the power of a given number. exp = unda(x, precision = 15) { fanya result = 1; fanya term = 1; @@ -248,6 +282,7 @@ pakeji hisabati{ rudisha result; } + //expm1(x), calculates the value of Euler's number raised to the power of a given number minus 1. expm1 = unda(x) { fanya epsilon = 1e-15; // A small value to improve accuracy fanya result = 0; @@ -263,6 +298,7 @@ pakeji hisabati{ rudisha result; } + //floor(x), rounds down to the largest integer less than or equal to a given number. floor = unda(x) { kama(x >= 0) { rudisha x - (x % 1); @@ -271,6 +307,7 @@ pakeji hisabati{ } } + //hypot(values), calculates the square root of the sum of squares of the given values. hypot = unda(values) { // Calculate the sum of squares of the values fanya exp = unda(acc, value){ @@ -285,6 +322,7 @@ pakeji hisabati{ rudisha result; } + //log(x), calculates the natural logarithm of a number. log = unda(x) { kama(x <= 0) { rudisha 0; @@ -295,7 +333,7 @@ pakeji hisabati{ fanya i = 1; wakati(i <= n) { - approx += (1 / i) * @.pow((x - 1) / (x + 1), 2 * i - 1); + approx += (1 / i) * ((x - 1) / (x + 1)) ** (2 * i - 1); i++; } @@ -303,7 +341,7 @@ pakeji hisabati{ rudisha 2 * approx; } - // method to calculate the base 10 logarithm + //log10(x), calculates the base 10 logarithm of a number. log10 = unda(x) { kama(x <= 0) { rudisha 0; @@ -313,6 +351,7 @@ pakeji hisabati{ rudisha this.log(x) / this.log(10); } + //log1p(x), calculates the natural logarithm of 1 plus the given number. log1p = unda(x) { kama(x < -1) { rudisha 0; @@ -344,6 +383,7 @@ pakeji hisabati{ rudisha result; } + //log2(x), calculates the base 2 logarithm of a number. log2 = unda(x) { kama(x <= 0) { rudisha 0; @@ -360,6 +400,7 @@ pakeji hisabati{ rudisha result; } + //max(numbers), finds the maximum value in a list of numbers. max = unda(numbers) { // Initialize a variable to store the largest number fanya largest = -Infinity; @@ -375,6 +416,7 @@ pakeji hisabati{ rudisha largest; } + //min(numbers), finds the minimum value in a list of numbers. min = unda(numbers) { kama(numbers.length == 0) { rudisha Infinity; @@ -393,6 +435,7 @@ pakeji hisabati{ rudisha minVal; } + //round(x, method), rounds a number to the nearest integer using the specified method. round = unda(x, method = "ri") { kama(method == "rpi") { rudisha floor(x + 0.5); @@ -409,6 +452,7 @@ pakeji hisabati{ } } + //sign(x), determines the sign of a number. sign = unda(x) { kama(x == 0 || x == -0) { rudisha x; @@ -419,6 +463,7 @@ pakeji hisabati{ } } + //sin(x), calculates the sine of an angle in radians using the Taylor series. sin = unda(x, terms = 10) { // Initialize the result fanya n = 0; @@ -444,6 +489,7 @@ pakeji hisabati{ rudisha result; } + //sinh(x), calculates the hyperbolic sine of a number. sinh = unda(x) { // sinh(x) = (e^x - e^(-x)) / 2 fanya eToX = @.exp(x); @@ -451,6 +497,7 @@ pakeji hisabati{ rudisha(eToX - eToMinusX) / 2; } + //sqrt(x), calculates the square root of a number. sqrt = unda(x) { kama(x < 0) { rudisha 0; @@ -472,23 +519,8 @@ pakeji hisabati{ } } - sine = unda(x) { - fanya tolerance = @.e-15; // Tolerance for convergence - fanya result = x; - fanya term = x; - fanya n = 1; - - wakati(@.abs(term) > tolerance) { - term *= (-x * x) / ((2 * n + 1) * (2 * n)); - result += term; - n++; - } - - rudisha result; - } - - // Calculate the tangent of a number in radians - tangent = unda(x) { + //tan(x), calculates the tangent of an angle in radians. + tan = unda(x) { fanya sineX = @.sine(x); fanya cosineX = @.sqrt(1 - sineX * sineX); @@ -499,6 +531,7 @@ pakeji hisabati{ rudisha sineX / cosineX; } + //tanh(x), calculates the hyperbolic tangent of a number. tanh = unda(x) { kama(x == Infinity) { rudisha 1; @@ -512,11 +545,7 @@ pakeji hisabati{ } // utility methods - // Function to check kama a number is negative zero - isNegativeZero = unda(num) { - rudisha num == 0 && 1 / num == -Infinity; - } - // Helper function to calculate the factorial of a number + //factorial(n), calculates the factorial of a number. factorial = unda(n) { kama(n == 0){ rudisha 1; @@ -533,27 +562,17 @@ pakeji hisabati{ } - // Helper function to calculate pow using Taylor series - pow = unda(base, exponent) { - fanya result = 1; - fanya i = 0; - wakati(i < exponent) { - result *= base; - i++; - } - rudisha result; - } - - // Helper function to check kama a number is negative + //isNegative(num), checks if a number is negative. isNegative = unda(num) { rudisha num < 0; } + //isInteger(num), checks if a number is an integer. isInteger = unda(num) { rudisha num == @.floor(num); } - // method to get the integer part of a number + //getIntegerPart(num), gets the integer part of a number. getIntegerPart = unda(num) { // Handle negative numbers separately kama(@.isNegative(num)) { @@ -565,7 +584,8 @@ pakeji hisabati{ } } - // create a list of numbers + //Arrray Methods + //list(first, last, interval), creates a list of numbers with the specified interval between theM. list = unda(first, last, interval){ fanya list = [first]; fanya i = first + interval; @@ -576,33 +596,7 @@ pakeji hisabati{ rudisha list; } - // Maths functions - // square a number - square = unda(n, i, j){ - fanya kati = (i + j) / 2; - fanya mul = kati * kati; - fanya abs_diff = abs(mul - n); - - kama(mul == n || abs_diff < 0.00001){ - rudisha kati; - }au kama(mul < n){ - rudisha square(n, kati, j); - }au{ - rudisha square(n, i, kati); - } - } - - // find the square root of a number - sqrt = unda(namba){ - kwa i ktk list(0, namba, 1) { - kama((i * i) == namba){ - rudisha i; - }au kama((i * i) > namba){ - rudisha square(namba, i - 1, i); - } - } - } - + //reduce(iterator, callback, initialValue), reduces the elements of an array to a single value using a specified callback function. reduce = unda(iterator, callback, initialValue) { fanya accumulator = initialValue; From 8cd4c60da14e70d244ac18c468d70b561c1e9485 Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Wed, 18 Oct 2023 08:11:50 +0300 Subject: [PATCH 28/81] Pakeji Hisabati Documentation redo --- third_party/math/README.md | 283 ++++++++++++++++++++++++------------- 1 file changed, 186 insertions(+), 97 deletions(-) diff --git a/third_party/math/README.md b/third_party/math/README.md index 4f8acef..387f241 100644 --- a/third_party/math/README.md +++ b/third_party/math/README.md @@ -1,158 +1,247 @@ -# Math Package - - - -## Explanation -This math package provides a collection of mathematical functions and constants implemented in the Nuru programming language. These functions cover a wide range of mathematical operations, including trigonometric functions, logarithmic functions, and other common mathematical operations. Below is a detailed list of all methods along with their descriptions and examples: +# Pakeji Hisabati (Math Package) + +A math package written in pure Nuru by [VictorKariuki](https://github.com/VictorKariuki). + +This package provides various mathematical functions and constants implemented in a custom programming language. It includes methods for `trigonometric functions`, `logarithmic functions`, `array operations`, and `utility functions`. + + +## Usage +To use the `pakeji hisabati` package and its third-party packages, follow the steps below: + +1. Copy the `hisabati.nr` file and any required third-party package files into the same directory as your project. + +2. Ensure that the third-party package file names end with the `.nr` extension and match the package names. For example, if the package name is `hisabati`, the corresponding file name should be `hisabati.nr`. + +3. You can directly import the `hisabati.nr` package and any required third-party packages in your Nuru code using the `ingiza` keyword. For example: + + ```nuru + tumia "hisabati.nr" + ``` + Example of usage: + ```nuru + andika(hisabati.e()) + +## What is in +These package covers a wide range of mathematical operations, including `basic arithmetic`, `trigonometry`, `exponential and logarithmic functions`, `rounding and comparison operations`, as well as some `utility and array operations`. + + +Here's an overview of the available methods and their functionalities: +The methods provided in the `hisabati` package can be classified into different categories based on their functionalities. Here is a classification of the methods: + +1. Trigonometric Functions: + - `cos(x)` + - `sin(x)` + - `tan(x)` + - `acos(x)` + - `asin(x)` + - `atan(x)` + +2. Hyperbolic Functions: + - `cosh(x)` + - `sinh(x)` + - `tanh(x)` + - `acosh(x)` + - `asinh(x)` + - `atanh(x)` + +3. Exponential and Logarithmic Functions: + - `exp(x)` + - `expm1(x)` + - `log(x)` + - `log10(x)` + - `log1p(x)` + +4. Other Mathematical Functions: + - `abs(namba)` + - `ceil(x)` + - `floor(x)` + - `sqrt(x)` + - `cbrt(x)` + - `root(x, n)` + - `hypot(values)` + - `factorial(n)` + +5. Rounding and Comparison Functions: + - `round(x, method)` + - `max(numbers)` + - `min(numbers)` + +6. Utility Functions: + - `sign(x)` + - `isNegative(num)` + - `isInteger(num)` + - `getIntegerPart(num)` + +7. Array and List Operations: + - `list(first, last, interval)` + - `reduce(iterator, callback, initialValue)` + + +### 1. Constants: + - **PI**: Represents the mathematical constant `π`. + - **e**: Represents `Euler's Number`. + - **phi**: Represents the `Golden Ratio`. + - **ln10**: Represents the `natural logarithm of 10`. + - **ln2**: Represents the `natural logarithm of 2`. + - **log10e**: Represents the `base 10 logarithm` of Euler's number `(e)`. + - **log2e**: Represents the `base 2 logarithm` of Euler's number` (e)`. + - **sqrt1_2**: Represents the `square root` of `1/2`. + - **sqrt2**: Represents the `square root` of `2`. + - **sqrt3**: Represents the `square root`of `3`. + - **sqrt5**: Represents the `square root` of `5`. + - **EPSILON**: Represents a small value (2.220446049250313e-16). + +### 2. Methods: 1. **abs(namba)** - Description: Calculates the absolute value of a number. - - Example: `Hisabati.abs(-42)` returns `42`. + - Example: `hisabati.abs(-42)` returns `42`. 2. **acos(x)** - - Description: Calculates the arccosine (inverse cosine) of a number in radians. - - Example: `Hisabati.acos(0.5)` returns the arccosine of 0.5. + - Description: Calculates the arccosine of a number. + - Example: `hisabati.acos(0.5)` returns `1.0471975511965979`. 3. **acosh(x)** - Description: Calculates the inverse hyperbolic cosine of a number. - - Example: `Hisabati.acosh(2)` returns the inverse hyperbolic cosine of 2. + - Example: `hisabati.acosh(2)` returns `1.3169578969248166`. 4. **arcsin(x)** - - Description: Calculates the arcsine (inverse sine) of a number using a Taylor series. - - Example: `Hisabati.arcsin(0.5)` returns the arcsine of 0.5. + - Description: Calculates the arcsine of a number using the Taylor series. + - Example: `hisabati.arcsin(0.5)` returns `0.5235987755982988`. 5. **arsinh(x)** - Description: Calculates the inverse hyperbolic sine of a number. - - Example: `Hisabati.arsinh(1)` returns the inverse hyperbolic sine of 1. + - Example: `hisabati.arsinh(2)` returns `1.4436354751788103`. 6. **atan(x)** - - Description: Calculates the arctangent (inverse tangent) of a number in radians using a Taylor series. - - Example: `Hisabati.atan(1)` returns the arctangent of 1. + - Description: Calculates the arctangent of a number using the Taylor series. + - Example: `hisabati.atan(1)` returns `0.7853981633974483`. 7. **atan2(y, x)** - - Description: Calculates the angle in radians between the positive x-axis and the point (x, y). - - Example: `Hisabati.atan2(1, 1)` returns the angle for the point (1, 1). + - Description: Calculates the arctangent of the quotient of its arguments. + - Example: `hisabati.atan2(1, 1)` returns `0.7853981633974483`. 8. **atanh(x)** - Description: Calculates the inverse hyperbolic tangent of a number. - - Example: `Hisabati.atanh(0.5)` returns the inverse hyperbolic tangent of 0.5. + - Example: `hisabati.atanh(0.5)` returns `0.5493061443340549`. 9. **cbrt(x)** - Description: Calculates the cube root of a number. - - Example: `Hisabati.cbrt(8)` returns the cube root of 8. + - Example: `hisabati.cbrt(8)` returns `2`. -10. **ceil(x)** +10. **root(x, n)** + - Description: Calculates the nth root of a number using the Newton-Raphson method. + - Example: `hisabati.root(27, 3)` returns `3`. + +11. **ceil(x)** - Description: Rounds up to the smallest integer greater than or equal to a given number. - - Example: `Hisabati.ceil(4.2)` returns `5`. + - Example: `hisabati.ceil(4.3)` returns `5`. -11. **cos(x, terms)** - - Description: Calculates the cosine of a number in radians using a Taylor series. - - Example: `Hisabati.cos(1)` returns the cosine of 1. +12. **cos(x)** + - Description: Calculates the cosine of an angle in radians using the Taylor series. + - Example: `hisabati.cos(0)` returns `1`. -12. **cosh(x)** +13. **cosh(x)** - Description: Calculates the hyperbolic cosine of a number. - - Example: `Hisabati.cosh(2)` returns the hyperbolic cosine of 2. + - Example: `hisabati.cosh(0)` returns `1`. -13. **exp(x, precision)** - - Description: Calculates the value of the mathematical constant e raised to the power of x using a Taylor series. - - Example: `Hisabati.exp(2)` returns `e^2`. +14. **exp(x)** + - Description: Calculates the value of Euler's number raised to the power of a given number. + - Example: `hisabati.exp(2)` returns `7.38905609893065`. -14. **expm1(x)** - - Description: Calculates the value of e^x - 1 using a Taylor series. - - Example: `Hisabati.expm1(1)` returns `e - 1`. +15. **expm1(x)** + - Description: Calculates Euler's number raised to the power of a number minus 1. + - Example: `hisabati.expm1(1)` returns `1.718281828459045`. -15. **floor(x)** +16. **floor(x)** - Description: Rounds down to the largest integer less than or equal to a given number. - - Example: `Hisabati.floor(4.9)` returns `4`. - -16. **hypot(values)** - - Description: Calculates the Euclidean norm (square root of the sum of squares) of a list of values. - - Example: `Hisabati.hypot([3, 4])` returns `5`, which is the hypotenuse of a right triangle. - -17. **log(x)** - - Description: Calculates the natural logarithm of a number using a Taylor series. - - Example: `Hisabati.log(2)` returns the natural logarithm of 2. + - Example: `hisabati.floor(4.7)` returns `4`. -18. **log10(x)** - - Description: Calculates the base 10 logarithm of a number using the natural logarithm. - - Example: `Hisabati.log10(100)` returns `2`. +17. **hypot(values)** + - Description: Calculates the square root of the sum of squares of the given values. + - Example: `hisabati.hypot([3, 4])` returns `5`. -19. **log1p(x)** - - Description: Calculates the natural logarithm of 1 + x using a Taylor series. - - Example: `Hisabati.log1p(0.5)` returns the natural logarithm of 1.5. +18. **log(x)** + - Description: Calculates the natural logarithm of a number. + - Example: `hisabati.log(1)` returns `0`. -20. **log2(x)** +19. **log10(x)** + - Description: Calculates the base 10 logarithm of a number. + - Example: `hisabati.log10(100)` returns `2`. +20. **log1p(x)** + - Description: Calculates the natural logarithm of 1 plus the given number. + - Example: `hisabati.log1p(1)` returns `0.6931471805599453`. +21. **log2(x)** - Description: Calculates the base 2 logarithm of a number. - - Example: `Hisabati.log2(8)` returns `3`. + - Example: `hisabati.log2(8)` returns `3`. -21. **max(numbers)** - - Description: Returns the largest number from a list of numbers. - - Example: `Hisabati.max([3, 7, 2, 9])` returns `9`. +22. **max(numbers)** + - Description: Finds the maximum value in a list of numbers. + - Example: `hisabati.max([4, 2, 9, 5])` returns `9`. -22. **min(numbers)** - - Description: Returns the smallest number from a list of numbers. - - Example: `Hisabati.min([3, 7, 2, 9])` returns `2`. +23. **min(numbers)** + - Description: Finds the minimum value in a list of numbers. + - Example: `hisabati.min([4, 2, 9, 5])` returns `2`. -23. **round(x, method)** - - Description: Rounds a number to the nearest integer using different rounding methods. - - Example: `Hisabati.round(3.6, "rpi")` rounds to the nearest integer (`4`) using "round half up." +24. **round(x, method)** + - Description: Rounds a number to the nearest integer using the specified method. + - Example: `hisabati.round(4.6, "rpi")` returns `5`. -24. **sign(x)** - - Description: Returns the sign of a number: `1` for positive, `-1` for negative, and `0` for zero. - - Example: `Hisabati.sign(-7)` returns `-1`. +25. **sign(x)** + - Description: Determines the sign of a number. + - Example: `hisabati.sign(-5)` returns `-1`. -25. **sin(x, terms)** - - Description: Calculates the sine of a number in radians using a Taylor series. - - Example: `Hisabati.sin(0.5)` returns the sine of 0.5. +26. **sin(x)** + - Description: Calculates the sine of an angle in radians using the Taylor series. + - Example: `hisabati.sin(0)` returns `0`. -26. **sinh(x)** +27. **sinh(x)** - Description: Calculates the hyperbolic sine of a number. - - Example: `Hisabati.sinh(1)` returns the hyperbolic sine of 1. + - Example: `hisabati.sinh(0)` returns `0`. -27. **sqrt(x)** - - Description: Calculates the square root of a number using the Newton-Raphson method. - - Example: `Hisabati.sqrt(16)` returns `4`. +28. **sqrt(x)** + - Description: Calculates the square root of a number. + - Example: `hisabati.sqrt(4)` returns `2`. -28. **tangent(x)** - - Description: Calculates the tangent of a number in radians. - - Example: `Hisabati.tangent(1)` returns the tangent of 1. +29. **tan(x)** + - Description: Calculates the tangent of an angle in radians. + - Example: `hisabati.tan(0)` returns `0`. -29. **tanh(x)** +30. **tanh(x)** - Description: Calculates the hyperbolic tangent of a number. - - Example: `Hisabati.tanh(0.5)` returns the hyperbolic tangent of 0.5. - -30. **isNegativeZero(num)** - - Description: Checks if a number is negative zero (0 with a negative sign). - - Example: `Hisabati.isNegativeZero(-0)` returns `true`. + - Example: `hisabati.tanh(0)` returns `0`. 31. **factorial(n)** - Description: Calculates the factorial of a number. - - Example: `Hisabati.factorial(5)` returns `120`. - -32. **pow(base, exponent)** - - Description: Calculates the power of a number. - - Example: `Hisabati.pow(2, 3)` returns `8`. + - Example: `hisabati.factorial(5)` returns `120`. -33. **isNegative(num)** +32. **isNegative(num)** - Description: Checks if a number is negative. - - Example: `Hisabati.isNegative(-5)` returns `true`. + - Example: `hisabati.isNegative(-5)` returns `true`. -34. **isInteger(num)** +33. **isInteger(num)** - Description: Checks if a number is an integer. - - Example: `Hisabati.isInteger(42)` returns `true`. + - Example: `hisabati.isInteger(4.5)` returns `false`. -35. **getIntegerPart(num)** +34. **getIntegerPart(num)** - Description: Gets the integer part of a number. - - Example: `Hisabati.getIntegerPart(5.8)` returns `5`. + - Example: `hisabati.getIntegerPart(4.5)` returns `4`. + +35. **list(first, last, interval)** + - Description: Creates a list of numbers with the specified interval between them. + - Example: `hisabati.list(1, 5, 1)` returns `[1, 2, 3, 4]`. + +36. **reduce(iterator, callback, initialValue)** + - Description: Reduces the elements of an array to a single value using a specified callback function. + - Example: `hisabati.reduce([1, 2, 3, 4], (accumulator, currentValue) => accumulator + currentValue, 0)` returns `10`. + + +### Contributing -36. **list(first, last, interval)** - - Description: Creates a list of numbers within a specified range with a given interval. - - Example: `Hisabati.list(0, 10, 2)` returns `[0, 2, 4, 6, 8]`. +Contributions to the `pakeji hisabati` package are welcome. If you have any improvements or bug fixes, feel free to create a pull request. -37. **square(n, i, j)** - - Description: Finds the square root of a number using a method that iteratively narrows down the root. - - Example: `Hisabati.square(16)` returns `4`. +### License -Feel free to use this package for your mathematical calculations and applications. \ No newline at end of file +This package is available under the MIT License. See the [LICENSE](LICENSE) file for more information. \ No newline at end of file From 2a33c53695c415b270f03acf909716abc7c6c83d Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Wed, 18 Oct 2023 08:22:07 +0300 Subject: [PATCH 29/81] Pakeji Hisabati Documentation grammar corrections --- third_party/math/README.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/third_party/math/README.md b/third_party/math/README.md index 387f241..911f157 100644 --- a/third_party/math/README.md +++ b/third_party/math/README.md @@ -1,31 +1,29 @@ # Pakeji Hisabati (Math Package) -A math package written in pure Nuru by [VictorKariuki](https://github.com/VictorKariuki). +Pakeji Hisabati is a math package written in pure Nuru by [VictorKariuki](https://github.com/VictorKariuki). -This package provides various mathematical functions and constants implemented in a custom programming language. It includes methods for `trigonometric functions`, `logarithmic functions`, `array operations`, and `utility functions`. +This package provides various mathematical functions and constants implemented in nuru programming language. It includes methods for `trigonometric functions`, `logarithmic functions`, `array operations`, and `utility functions`. ## Usage -To use the `pakeji hisabati` package and its third-party packages, follow the steps below: +To use the `pakeji hisabati` package follow the steps below: 1. Copy the `hisabati.nr` file and any required third-party package files into the same directory as your project. -2. Ensure that the third-party package file names end with the `.nr` extension and match the package names. For example, if the package name is `hisabati`, the corresponding file name should be `hisabati.nr`. +2. Ensure that the package file names end with the `.nr` extension and match the package names. For example, if the package name is `hisabati`, the corresponding file name should be `hisabati.nr`. -3. You can directly import the `hisabati.nr` package and any required third-party packages in your Nuru code using the `ingiza` keyword. For example: +3. You can directly import the `hisabati.nr` package and any required third-party packages in your Nuru code using the `tumia` keyword. For example: ```nuru - tumia "hisabati.nr" + tumia "hisabati" ``` - Example of usage: + Example of calling the package methods: ```nuru andika(hisabati.e()) ## What is in -These package covers a wide range of mathematical operations, including `basic arithmetic`, `trigonometry`, `exponential and logarithmic functions`, `rounding and comparison operations`, as well as some `utility and array operations`. +This package covers a wide range of mathematical operations, including `basic arithmetic`, `trigonometry`, `exponential and logarithmic functions`, `rounding and comparison operations`, as well as some `utility and array operations`. - -Here's an overview of the available methods and their functionalities: The methods provided in the `hisabati` package can be classified into different categories based on their functionalities. Here is a classification of the methods: 1. Trigonometric Functions: @@ -83,11 +81,11 @@ The methods provided in the `hisabati` package can be classified into different - **phi**: Represents the `Golden Ratio`. - **ln10**: Represents the `natural logarithm of 10`. - **ln2**: Represents the `natural logarithm of 2`. - - **log10e**: Represents the `base 10 logarithm` of Euler's number `(e)`. + - **log10e**: Represents the `base 10 logarithms` of Euler's number `(e)`. - **log2e**: Represents the `base 2 logarithm` of Euler's number` (e)`. - **sqrt1_2**: Represents the `square root` of `1/2`. - **sqrt2**: Represents the `square root` of `2`. - - **sqrt3**: Represents the `square root`of `3`. + - **sqrt3**: Represents the `square root` of `3`. - **sqrt5**: Represents the `square root` of `5`. - **EPSILON**: Represents a small value (2.220446049250313e-16). From c17fd0ce37e24480b1b25d38f9fa6163dc590a6c Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sat, 21 Oct 2023 07:37:10 +0300 Subject: [PATCH 30/81] use amd64 for 64 bit executables --- .goreleaser.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index dba4b11..92e6585 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -13,7 +13,7 @@ builds: - darwin - android ldflags: - - '-s -w' + - "-s -w" ignore: - goos: android goarch: 386 @@ -23,7 +23,7 @@ archives: name_template: >- nuru_ {{- title .Os }}_ - {{- if eq .Arch "amd64" }}x86_64 + {{- if eq .Arch "amd64" }}amd64 {{- else if eq .Arch "386" }}i386 {{- else }}{{ .Arch }}{{ end }} {{- if .Arm }}v{{ .Arm }}{{ end }} @@ -44,4 +44,4 @@ nfpms: description: "Nuru is a programming language built from the ground up" formats: - deb - file_name_template: "{{ .ProjectName }}.{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" \ No newline at end of file + file_name_template: "{{ .ProjectName }}.{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" From e27bfa375e551efd7a8abd21d92d7d04298e8de7 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sat, 21 Oct 2023 07:52:58 +0300 Subject: [PATCH 31/81] update readme --- README.md | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 64b61c1..a23afd6 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,13 @@ To get started download the executables from the release page or follow the inst - Download the binary: ``` -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.0-alpha/nuru_linux_amd64_v0.5.0-alpha.tar.gz +curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Linux_amd64.tar.gz ``` - Extract the file to make global available: ``` -sudo tar -C /usr/local/bin -xzvf nuru_linux_amd64_v0.5.0-alpha.tar.gz +sudo tar -C /usr/local/bin -xzvf nuru_Linux_amd64.tar.gz ``` - Confirm installation with: @@ -41,17 +41,31 @@ nuru -v - Download the binary: -``` -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.0-alpha/nuru_mac_arm64_v0.5.0-alpha.tar.gz -``` + - For apple silicon mac use: - - Extract the file to make global available: + ``` + curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Darwin_arm64.tar.gz + ``` -``` -sudo tar -C /usr/local/bin -xzvf nuru_mac_arm64_v0.5.0-alpha.tar.gz -``` + - For apple intel mac use: - - Confirm installation with: + ``` + curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Darwin_amd64.tar.gz + ``` + +- Extract the file to make global available: + - For apple silicon mac use: + + ``` + sudo tar -C /usr/local/bin -xzvf nuru_Darwin_arm64.tar.gz + ``` + - For apple intel mac use: + + ``` + sudo tar -C /usr/local/bin -xzvf nuru_Darwin_amd64.tar.gz + ``` + +- Confirm installation with: ``` nuru -v @@ -64,12 +78,12 @@ nuru -v - Download the binary with this command: ``` -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.0-alpha/nuru_android_arm64_v0.5.0-alpha.tar.gz +curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Android_arm64.tar.gz ``` - Extract the file: ``` -tar -xzvf nuru_android_arm64_v0.5.0-alpha.tar.gz +tar -xzvf nuru_Android_arm64.tar.gz ``` - Add it to path: @@ -85,7 +99,8 @@ nuru -v ### Windows - Executable: - - Download the Nuru executable [Here](https://github.com/AvicennaJr/Nuru/releases/download/v0.5.0-alpha/nuru_windows_amd64_v0.5.0-alpha.exe) + - Download the Nuru zip file [Here](https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Windows_amd64.zip) + - Unzip to get the executable - Double click the executable - Nuru Installer From 1299c95300be635fdf1847dcc4e92c44c34fcf82 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sat, 21 Oct 2023 08:13:22 +0300 Subject: [PATCH 32/81] direct to website --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a23afd6..03bd1b2 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ nuru -v ## Syntax At A Glance **NOTE** -> There is a more detailed documentation of the language [here](./repl/docs/en/README.md). +> There is a more detailed documentation of the language [here](https://nuruprogramming.org). Nuru, although still in its early stage, intends to be a fully functional programming language, and thus it has been baked with many features. From a5bb2409b983f17be57a7feb37057dffafc3e25c Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Sat, 21 Oct 2023 09:59:09 +0300 Subject: [PATCH 33/81] add tests condition --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 03bd1b2..57d1068 100644 --- a/README.md +++ b/README.md @@ -360,6 +360,8 @@ There are documentations for two languages, English and Kiswahili, which are bot Clone the repo, hack it, make sure all tests are passing then submit a pull request. + > Make sure ALL tests are passing before making a pull request. You can confirm with running `make tests` + ## Community Nuru has a passionate community, join us on [Telegram](https://t.me/NuruProgrammingChat) From 2aabe878d09585f1eb91bef647eb955ecd19344f Mon Sep 17 00:00:00 2001 From: Gabriel-Dee Date: Sun, 22 Oct 2023 17:16:19 +0300 Subject: [PATCH 34/81] Initial Swahili documentation translation --- repl/docs/sw/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/repl/docs/sw/README.md b/repl/docs/sw/README.md index 698fdad..07f7b09 100644 --- a/repl/docs/sw/README.md +++ b/repl/docs/sw/README.md @@ -1 +1,3 @@ -# NURU PROGRAMMING LANGUAGE DOCUMENTATION \ No newline at end of file +# NYARAKA YA LUGHA YA PROGRAMU YA NURU + +Hii nyaraka imeandikwa ikilenga watu wenye uzoefu na kuandika au kupanga programu. Inaelezea sintaksia, aina na namna ya kufanya operesheni mbali mbali kutumia lugha ya NURU. \ No newline at end of file From b97608d99a415c93acf6e95f32e401c87a6de9dc Mon Sep 17 00:00:00 2001 From: Gabriel-Dee Date: Sun, 22 Oct 2023 18:01:56 +0300 Subject: [PATCH 35/81] Translated the Arrays part of the Table of content --- repl/docs/sw/README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/repl/docs/sw/README.md b/repl/docs/sw/README.md index 07f7b09..365567c 100644 --- a/repl/docs/sw/README.md +++ b/repl/docs/sw/README.md @@ -1,3 +1,16 @@ # NYARAKA YA LUGHA YA PROGRAMU YA NURU -Hii nyaraka imeandikwa ikilenga watu wenye uzoefu na kuandika au kupanga programu. Inaelezea sintaksia, aina na namna ya kufanya operesheni mbali mbali kutumia lugha ya NURU. \ No newline at end of file +Hii nyaraka imeandikwa ikilenga watu wenye uzoefu na kuandika au kupanga programu. Inaelezea sintaksia, aina na namna ya kufanya operesheni mbali mbali kutumia lugha ya NURU. + +## Yaliyomo + +- [Safu Kwenye Nuru](arrays.md#arrays-in-nuru) + - [Kutengeneza Safu](arrays.md#creating-arrays) + - [Kupata na Kurekebisha vipengele vya Safu](arrays.md#accessing-and-modifying-array-elements) + - [Kuunganisha Safu](arrays.md#concatenating-arrays) + - [Kuangalia uwepo wa vipengele ndani ya safu](arrays.md#checking-for-array-membership) + - [Looping Over Arrays](arrays.md#looping-over-arrays) + - [Mbinu za Safu](arrays.md#array-methods) + - [idadi()](arrays.md#idadi()) + - [sukuma()](arrays.md#sukuma()) + - [yamwisho()](arrays.md#yamwisho()) \ No newline at end of file From 0c67130c8d7bdbea8620995a5488a8722f3bcb6b Mon Sep 17 00:00:00 2001 From: Gabriel-Dee Date: Sun, 22 Oct 2023 18:09:51 +0300 Subject: [PATCH 36/81] Translated the Arrays part of the Table of content --- repl/docs/sw/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repl/docs/sw/README.md b/repl/docs/sw/README.md index 365567c..26e41ec 100644 --- a/repl/docs/sw/README.md +++ b/repl/docs/sw/README.md @@ -9,7 +9,7 @@ Hii nyaraka imeandikwa ikilenga watu wenye uzoefu na kuandika au kupanga program - [Kupata na Kurekebisha vipengele vya Safu](arrays.md#accessing-and-modifying-array-elements) - [Kuunganisha Safu](arrays.md#concatenating-arrays) - [Kuangalia uwepo wa vipengele ndani ya safu](arrays.md#checking-for-array-membership) - - [Looping Over Arrays](arrays.md#looping-over-arrays) + - [Kupita na Kurejea kwenye safu](arrays.md#looping-over-arrays) - [Mbinu za Safu](arrays.md#array-methods) - [idadi()](arrays.md#idadi()) - [sukuma()](arrays.md#sukuma()) From d8ce972b55e909cb44f4d4387d078f2193c61670 Mon Sep 17 00:00:00 2001 From: Gabriel-Dee Date: Sun, 22 Oct 2023 18:41:33 +0300 Subject: [PATCH 37/81] Built in Functions Translation --- repl/docs/sw/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/repl/docs/sw/README.md b/repl/docs/sw/README.md index 26e41ec..48b7e6a 100644 --- a/repl/docs/sw/README.md +++ b/repl/docs/sw/README.md @@ -13,4 +13,9 @@ Hii nyaraka imeandikwa ikilenga watu wenye uzoefu na kuandika au kupanga program - [Mbinu za Safu](arrays.md#array-methods) - [idadi()](arrays.md#idadi()) - [sukuma()](arrays.md#sukuma()) - - [yamwisho()](arrays.md#yamwisho()) \ No newline at end of file + - [yamwisho()](arrays.md#yamwisho()) +- [Visaidia-kazi vya Nuru](builtins.md#built-in-functions-in-nuru) + - [Kisaidia-kazi andika() ](builtins.md#the-andika()-function) + - [Kisaidia-kazi jaza()](builtins.md#the-jaza()-function) + - [Kisaidia-kazi aina()](builtins.md#the-aina()-function) + - [Kisaidia-kazi fungua()](builtins.md#the-fungua()-function) \ No newline at end of file From 1f7f261fc6397dd7c4766e1a2e1968819fb4a094 Mon Sep 17 00:00:00 2001 From: Gabriel-Dee Date: Sun, 22 Oct 2023 18:51:19 +0300 Subject: [PATCH 38/81] translated the comments section --- repl/docs/sw/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/repl/docs/sw/README.md b/repl/docs/sw/README.md index 48b7e6a..3c8532f 100644 --- a/repl/docs/sw/README.md +++ b/repl/docs/sw/README.md @@ -18,4 +18,7 @@ Hii nyaraka imeandikwa ikilenga watu wenye uzoefu na kuandika au kupanga program - [Kisaidia-kazi andika() ](builtins.md#the-andika()-function) - [Kisaidia-kazi jaza()](builtins.md#the-jaza()-function) - [Kisaidia-kazi aina()](builtins.md#the-aina()-function) - - [Kisaidia-kazi fungua()](builtins.md#the-fungua()-function) \ No newline at end of file + - [Kisaidia-kazi fungua()](builtins.md#the-fungua()-function) +- [Maoni kwenye Nuru](comments.md#comments-in-nuru) + - [Maoni ya mstari mmoja](comments.md#single-line-comments) + - [Maoni ya mistari mingi](comments.md#multi-line-comments) \ No newline at end of file From e2aabb832823feb055f11619bd7734a10894de9e Mon Sep 17 00:00:00 2001 From: Gabriel-Dee Date: Sun, 22 Oct 2023 18:56:49 +0300 Subject: [PATCH 39/81] Translated the conditional statements section --- repl/docs/sw/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/repl/docs/sw/README.md b/repl/docs/sw/README.md index 3c8532f..02d28f0 100644 --- a/repl/docs/sw/README.md +++ b/repl/docs/sw/README.md @@ -21,4 +21,7 @@ Hii nyaraka imeandikwa ikilenga watu wenye uzoefu na kuandika au kupanga program - [Kisaidia-kazi fungua()](builtins.md#the-fungua()-function) - [Maoni kwenye Nuru](comments.md#comments-in-nuru) - [Maoni ya mstari mmoja](comments.md#single-line-comments) - - [Maoni ya mistari mingi](comments.md#multi-line-comments) \ No newline at end of file + - [Maoni ya mistari mingi](comments.md#multi-line-comments) +- [Kauli za masharti kwenye Nuru](ifStatements.md#conditional-statements-in-nuru) + - [Kauli ya kama](ifStatements.md#if-statement-(kama)) + - [Kauli za Au Kama na Sivyo)](ifStatements.md#else-if-and-else-blocks-(au-kama-and-sivyo)) \ No newline at end of file From 01d1af4c98b63f1f247d57b08bf4645c615f03fe Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Tue, 31 Oct 2023 15:06:32 +0300 Subject: [PATCH 40/81] changed root to recursion instead of while --- third_party/math/README.md | 1 - third_party/math/hisabati.nr | 60 +++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/third_party/math/README.md b/third_party/math/README.md index 911f157..1d3b6f1 100644 --- a/third_party/math/README.md +++ b/third_party/math/README.md @@ -20,7 +20,6 @@ To use the `pakeji hisabati` package follow the steps below: Example of calling the package methods: ```nuru andika(hisabati.e()) - ## What is in This package covers a wide range of mathematical operations, including `basic arithmetic`, `trigonometry`, `exponential and logarithmic functions`, `rounding and comparison operations`, as well as some `utility and array operations`. diff --git a/third_party/math/hisabati.nr b/third_party/math/hisabati.nr index 2691b19..4e8b0d5 100644 --- a/third_party/math/hisabati.nr +++ b/third_party/math/hisabati.nr @@ -60,7 +60,7 @@ pakeji hisabati{ // @.EPSILON EPSILON = unda() { - rudisha 2.220446049250313e-16; + rudisha 0.0000000000000002220446049250313; } // Methods @@ -80,12 +80,12 @@ pakeji hisabati{ } // Define the precision for the approximation. - fanya precision = 1e-10; + fanya precision = 0.0000000001; // Initial guess for the angle in radians (between 0 and π). - fanya angle = @.PI / 4; + fanya angle = @.PI() / 4; - wakati(true) { + wakati(kweli) { fanya cosAngle = @.cos(angle); fanya error = @.abs(cosAngle - x); @@ -144,12 +144,12 @@ pakeji hisabati{ kama(x == 0) { rudisha 0; } // arctan(0) is 0 - kama(x == Infinity) { + kama(x == 1/0) { rudisha @.PI / 2; } - kama(x == -Infinity) { + kama(x == -1/0) { rudisha - @.PI / 2; - } // arctan(-Infinity) is -π/2 + } // arctan(-Inf) is -π/2 // Use the Taylor series expansion for arctan(x) // arctan(x) = x - (x^3) / 3 + (x^5) / 5 - (x^7) / 7 + ... @@ -158,7 +158,7 @@ pakeji hisabati{ fanya term = x * x; fanya sign = -1; - wakati(true) { + wakati(kweli) { fanya currentTerm = sign * (term / n); kama(currentTerm == 0) { @@ -209,17 +209,17 @@ pakeji hisabati{ } //root(x, n), calculates the nth root of a number using the Newton-Raphson method. - root = unda(x, n) { + root = unda(x, n) { fanya guess = x / 2; // Initial guess - fanya tolerance = 1e-10; // Tolerance for convergence + fanya tolerance = 0.0000000001; // Tolerance for convergence - wakati(true) { - fanya nextGuess = ((n - 1) * guess + x / guess ** n - 1) / n; - kama(@.abs(nextGuess - guess) < tolerance) { - rudisha nextGuess; - } - guess = nextGuess; + fanya calculateNthRoot = unda(x, n, guess, tolerance) { + fanya nextGuess = ((n - 1) * guess + x / (guess ** (n - 1))) / n; + kama (abs(nextGuess - guess) < tolerance) {rudisha nextGuess}; + rudisha calculateNthRoot(x, n, nextGuess, tolerance); } + + rudisha calculateNthRoot(x, n, guess, tolerance) } //ceil(x), rounds up to the smallest integer greater than or equal to a given number. @@ -235,11 +235,12 @@ pakeji hisabati{ } //cos(x), calculates the cosine of an angle in radians using the Taylor series. - cos = unda(x, terms = 10) { + cos = unda(x) { // Initialize the result fanya n = 0; + fanya terms = 10; fanya result = 0; - + wakati(n < terms) { // Calculate the numerator and denominator for the nth term fanya numerator = 0; @@ -248,10 +249,11 @@ pakeji hisabati{ } sivyo { numerator = -x ** (2 * n + 1); } - fanya denominator = @.factorial(2 * n); + andika(@.factorial(2 * n)); + //fanya denominator = @.factorial(2 * n); // Add the nth term to the result - result += numerator / denominator; + //result += numerator / denominator; n++; } @@ -358,11 +360,11 @@ pakeji hisabati{ } kama(x == -1) { - rudisha(-Infinity); + rudisha(-Inf); } - kama(x == Infinity) { - rudisha Infinity; + kama(x == Inf) { + rudisha Inf; } kama(x == 0) { @@ -403,7 +405,7 @@ pakeji hisabati{ //max(numbers), finds the maximum value in a list of numbers. max = unda(numbers) { // Initialize a variable to store the largest number - fanya largest = -Infinity; + fanya largest = -Inf; // Iterate through the numbers and update 'largest' kama a larger number is found kwa num ktk numbers { @@ -412,14 +414,14 @@ pakeji hisabati{ } } - // rudisha the largest number (or -Infinity kama there are no parameters) + // rudisha the largest number (or -Inf kama there are no parameters) rudisha largest; } //min(numbers), finds the minimum value in a list of numbers. min = unda(numbers) { kama(numbers.length == 0) { - rudisha Infinity; + rudisha Inf; } fanya minVal = numbers[0]; @@ -507,7 +509,7 @@ pakeji hisabati{ fanya guess = x / 2; fanya tolerance = 1e-7; // Tolerance for approximation - wakati(true) { + wakati(kweli) { fanya nextGuess = 0.5 * (guess + x / guess); // Check kama the guess is close enough to the actual square root @@ -533,9 +535,9 @@ pakeji hisabati{ //tanh(x), calculates the hyperbolic tangent of a number. tanh = unda(x) { - kama(x == Infinity) { + kama(x == Inf) { rudisha 1; - } au kama(x == -Infinity) { + } au kama(x == -Inf) { rudisha - 1; } sivyo { fanya expX = @.exp(x); From 2a113ef571d2bd47d53b039ac3518db2441422f6 Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Wed, 1 Nov 2023 12:55:57 +0300 Subject: [PATCH 41/81] Hisabati Module Hisabati Docs --- module/hisabati.go | 713 +++++++++++++++++++++++++++++++++++ module/module.go | 1 + repl/docs/en/README.md | 4 + repl/docs/en/hisabati.md | 257 +++++++++++++ third_party/math/hisabati.nr | 25 +- 5 files changed, 985 insertions(+), 15 deletions(-) create mode 100644 module/hisabati.go create mode 100644 repl/docs/en/hisabati.md diff --git a/module/hisabati.go b/module/hisabati.go new file mode 100644 index 0000000..4ac0ebf --- /dev/null +++ b/module/hisabati.go @@ -0,0 +1,713 @@ +package module + +import ( + "math" + + "github.com/AvicennaJr/Nuru/object" +) + +var MathFunctions = map[string]object.ModuleFunction{ + "PI": pi, + "e": e, + "phi": phi, + "ln10": ln10, + "ln2": ln2, + "log10e": log10e, + "log2e": log2e, + "log2": log2, + "sqrt1_2": sqrt1_2, + "sqrt2": sqrt2, + "sqrt3": sqrt3, + "sqrt5": sqrt5, + "EPSILON": epsilon, + "abs": abs, + "sign": sign, + "ceil": ceil, + "floor": floor, + "sqrt": sqrt, + "cbrt": cbrt, + "root": root, + "hypot": hypot, + "factorial":factorial, + "round": round, + "max": max, + "min": min, + "exp": exp, + "expm1": expm1, + "log": log, + "log10": log10, + "log1p": log1p, + "cos": cos, + "sin": sin, + "tan": tan, + "acos": acos, + "asin": asin, + "atan": atan, + "cosh": cosh, + "sinh": sinh, + "tanh": tanh, + "acosh": acosh, + "asinh": asinh, + "atanh": atanh, + "atan2": atan2, +} + +var Constants = map[string]object.Object{ + "PI": &object.Float{Value: math.Pi}, + "e": &object.Float{Value: math.E}, + "phi": &object.Float{Value: (1 + math.Sqrt(5)) / 2}, + "ln10": &object.Float{Value: math.Log10E}, + "ln2": &object.Float{Value: math.Ln2}, + "log10e": &object.Float{Value: math.Log10E}, + "log2e": &object.Float{Value: math.Log2E}, + "sqrt1_2": &object.Float{Value: 1 / math.Sqrt2}, + "sqrt2": &object.Float{Value: math.Sqrt2}, + "sqrt3": &object.Float{Value: math.Sqrt(3)}, + "sqrt5": &object.Float{Value: math.Sqrt(5)}, + "EPSILON": &object.Float{Value: 2.220446049250313e-16}, +} + +func pi(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Pi} +} + +func e(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.E} +} + +func phi(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: (1 + math.Sqrt(5)) / 2} +} + +func ln10(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Log10E} +} + +func ln2(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Ln2} +} + +func log10e(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Log10E} +} + +func log2e(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Log2E} +} + +func sqrt1_2(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: 1 / math.Sqrt2} +} + +func sqrt2(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Sqrt2} +} + +func sqrt3(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Sqrt(3)} +} + +func sqrt5(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: math.Sqrt(5)} +} + +func epsilon(args []object.Object, defs map[string]object.Object) object.Object { + return &object.Float{Value: 2.220446049250313e-16} +} + +func abs(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a number"} + } + switch arg := args[0].(type) { + case *object.Integer: + if arg.Value < 0 { + return &object.Integer{Value: -arg.Value} + } + return arg + case *object.Float: + if arg.Value < 0 { + return &object.Float{Value: -arg.Value} + } + return arg + default: + return &object.Error{Message: "Argument must be a number"} + } +} + +func sign(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + switch arg := args[0].(type) { + case *object.Integer: + if arg.Value == 0 { + return &object.Integer{Value: 0} + } else if arg.Value > 0 { + return &object.Integer{Value: 1} + } else { + return &object.Integer{Value: -1} + } + case *object.Float: + if arg.Value == 0 { + return &object.Integer{Value: 0} + } else if arg.Value > 0 { + return &object.Integer{Value: 1} + } else { + return &object.Integer{Value: -1} + } + default: + return &object.Error{Message: "Argument must be a number"} + } +} + +func ceil(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a number"} + } + switch arg := args[0].(type) { + case *object.Integer: + return &object.Integer{Value: arg.Value} + case *object.Float: + return &object.Integer{Value: int64(math.Ceil(arg.Value))} + default: + return &object.Error{Message: "Argument must be a number"} + } +} + +func floor(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a number"} + } + switch arg := args[0].(type) { + case *object.Integer: + return &object.Integer{Value: arg.Value} + case *object.Float: + return &object.Integer{Value: int64(math.Floor(arg.Value))} + default: + return &object.Error{Message: "Argument must be a number"} + } +} + +func sqrt(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a number"} + } + switch arg := args[0].(type) { + case *object.Integer: + return &object.Float{Value: math.Sqrt(float64(arg.Value))} + case *object.Float: + return &object.Float{Value: math.Sqrt(arg.Value)} + default: + return &object.Error{Message: "Argument must be a number"} + } +} + +func cbrt(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a number"} + } + switch arg := args[0].(type) { + case *object.Integer: + return &object.Float{Value: math.Cbrt(float64(arg.Value))} + case *object.Float: + return &object.Float{Value: math.Cbrt(arg.Value)} + default: + return &object.Error{Message: "Argument must be a number"} + } +} + +func root(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 2 { + return &object.Error{Message: "This function requires exactly two arguments"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "First argument must be a number"} + } + if args[1].Type() != object.INTEGER_OBJ { + return &object.Error{Message: "Second argument must be an integer"} + } + base, ok := args[0].(*object.Float) + if !ok { + base = &object.Float{Value: float64(args[0].(*object.Integer).Value)} + } + exp := args[1].(*object.Integer).Value + + if exp == 0 { + return &object.Float{Value: 1.0} + } else if exp < 0 { + return &object.Error{Message: "Second argument must be a non-negative integer"} + } + + x := 1.0 + for i := 0; i < 10; i++ { + x = x - (math.Pow(x, float64(exp))-base.Value)/(float64(exp)*math.Pow(x, float64(exp-1))) + } + + return &object.Float{Value: x} +} + +func hypot(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) < 2 { + return &object.Error{Message: "This function requires at least two arguments"} + } + var sumOfSquares float64 + for _, arg := range args { + if arg.Type() != object.INTEGER_OBJ && arg.Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Arguments must be numbers"} + } + switch num := arg.(type) { + case *object.Integer: + sumOfSquares += float64(num.Value) * float64(num.Value) + case *object.Float: + sumOfSquares += num.Value * num.Value + } + } + return &object.Float{Value: math.Sqrt(sumOfSquares)} +} + +func factorial(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.INTEGER_OBJ { + return &object.Error{Message: "Argument must be an integer"} + } + n := args[0].(*object.Integer).Value + if n < 0 { + return &object.Error{Message: "Argument must be a non-negative integer"} + } + result := int64(1) + for i := int64(2); i <= n; i++ { + result *= i + } + return &object.Integer{Value: result} +} + +func round(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + + num := args[0].(*object.Float).Value + return &object.Integer{Value: int64(num + 0.5)} +} + +func max(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + + arg, ok := args[0].(*object.Array) + if !ok { + return &object.Error{Message: "Argument must be an array"} + } + + if len(arg.Elements) == 0 { + return &object.Error{Message: "Array must not be empty"} + } + + var maxNum float64 + + for _, element := range arg.Elements { + if element.Type() != object.INTEGER_OBJ && element.Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Array elements must be numbers"} + } + + switch num := element.(type) { + case *object.Integer: + if float64(num.Value) > maxNum { + maxNum = float64(num.Value) + } + case *object.Float: + if num.Value > maxNum { + maxNum = num.Value + } + default: + return &object.Error{Message: "Array elements must be numbers"} + } + } + + return &object.Float{Value: maxNum} +} + +func min(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + + arg, ok := args[0].(*object.Array) + if !ok { + return &object.Error{Message: "Argument must be an array"} + } + + if len(arg.Elements) == 0 { + return &object.Error{Message: "Array must not be empty"} + } + + minNum := math.MaxFloat64 + + for _, element := range arg.Elements { + if element.Type() != object.INTEGER_OBJ && element.Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Array elements must be numbers"} + } + + switch num := element.(type) { + case *object.Integer: + if float64(num.Value) < minNum { + minNum = float64(num.Value) + } + case *object.Float: + if num.Value < minNum { + minNum = num.Value + } + default: + return &object.Error{Message: "Array elements must be numbers"} + } + } + + return &object.Float{Value: minNum} +} + +func exp(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Exp(num)} +} + +func expm1(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Expm1(num)} +} + +func log(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Log(num)} +} + +func log10(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Log10(num)} +} + +func log2(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a number"} + } + + arg := extractFloatValue(args[0]) + + if arg <= 0 { + return &object.Error{Message: "Argument must be greater than 0"} + } + + return &object.Float{Value: math.Log2(arg)} +} + +func extractFloatValue(obj object.Object) float64 { + switch obj := obj.(type) { + case *object.Integer: + return float64(obj.Value) + case *object.Float: + return obj.Value + default: + return 0 + } +} + +func log1p(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Log1p(num)} +} + +func cos(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Cos(num)} +} + +func sin(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Sin(num)} +} + +func tan(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Tan(num)} +} + +func acos(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Acos(num)} +} + +func asin(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Asin(num)} +} + +func atan(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Atan(num)} +} + +func cosh(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Cosh(num)} +} + +func sinh(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Sinh(num)} +} + +func tanh(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Tanh(num)} +} + +func acosh(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Acosh(num)} +} + +func asinh(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Asinh(num)} +} + +func atan2(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 2 { + return &object.Error{Message: "This function requires exactly two arguments"} + } + if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Arguments must be numbers"} + } + if args[1].Type() != object.INTEGER_OBJ && args[1].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Arguments must be numbers"} + } + + y := extractFloatValue(args[0]) + x := extractFloatValue(args[1]) + + return &object.Float{Value: math.Atan2(y, x)} +} + +func atanh(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "This function doesn't allow definitions"} + } + if len(args) != 1 { + return &object.Error{Message: "This function requires exactly one argument"} + } + if args[0].Type() != object.FLOAT_OBJ { + return &object.Error{Message: "Argument must be a float"} + } + num := args[0].(*object.Float).Value + return &object.Float{Value: math.Atanh(num)} +} \ No newline at end of file diff --git a/module/module.go b/module/module.go index e514a87..a82862a 100644 --- a/module/module.go +++ b/module/module.go @@ -9,4 +9,5 @@ func init() { Mapper["muda"] = &object.Module{Name: "time", Functions: TimeFunctions} Mapper["mtandao"] = &object.Module{Name: "net", Functions: NetFunctions} Mapper["jsoni"] = &object.Module{Name: "json", Functions: JsonFunctions} + Mapper["hisabati"] = &object.Module{Name: "hisabati", Functions: MathFunctions} } diff --git a/repl/docs/en/README.md b/repl/docs/en/README.md index e34c64d..ae3e1c8 100644 --- a/repl/docs/en/README.md +++ b/repl/docs/en/README.md @@ -69,6 +69,10 @@ This documentation is intended for people with some experience in programming. I - [Import JSONI](json.md#import-jsoni) - [Decoding JSON with dikodi()](json.md#decoding-json-with-dikodi()) - [Encoding JSON with enkodi()](json.md#encoding-json-with-enkodi()) +- [Hisabati in nuru](hisabati.md#module-hisabati) + - [Import Hisabati](hisabati.md#usage) + - [In-built Constants](hisabati.md#1-constants) + - [In-built Methods](hisabati.md#2-methods) - [KEYWORDS](keywords.md#keywords) - [Reserved Keywords](keywords.md#reserved-keywords) - [BuiltIns](keywords.md#builtins) diff --git a/repl/docs/en/hisabati.md b/repl/docs/en/hisabati.md new file mode 100644 index 0000000..b8f4afb --- /dev/null +++ b/repl/docs/en/hisabati.md @@ -0,0 +1,257 @@ +# Module Hisabati + +Module Hisabati is a inbuilt math module by [VictorKariuki](https://github.com/VictorKariuki). + +This in-built module provides various mathematical functions and constants. It includes methods for `trigonometric functions`, `logarithmic functions`, `array operations`, and `utility functions`. + +## Usage + +To use the `hisabati` in-built module follow the steps below: + +1. You directly import the `hisabati` in-built module and any required in-built modules in your Nuru code using the `tumia` keyword. + + ```nuru + tumia hisabati + ``` + +2. Calling the in-built module methods: + + ```nuru + andika(hisabati.e()) + ``` + +## Yaliyomo + +This in-built module covers a wide range of mathematical operations, including : + +- `Basic Mathematical Functions:` +- `Hyperbolic` & `Trigonometric Functions` +- `Exponential` & `Logarithmic Functions` +- `Rounding` & `Comparison Functions` + +Here is an in-depth classification of the methods: + +1. Trigonometric Functions: + + - `cos(n)` + - `sin(n)` + - `tan(n)` + - `acos(n)` + - `asin(n)` + - `atan(n)` + - `hypot(numbers)` + +2. Hyperbolic Functions: + + - `cosh(n)` + - `sinh(n)` + - `tanh(n)` + - `acosh(n)` + - `asinh(n)` + - `atanh(n)` + +3. Exponential and Logarithmic Functions: + + - `exp(n)` + - `expm1(n)` + - `log(n)` + - `log2(n)` + - `log10(n)` + - `log1p(n)` + +4. Basic Mathematical Functions: + + - `abs(n)` + - `sqrt(n)` + - `cbrt(n)` + - `root(x, n)` + - `factorial(n)` + - `sign(n)` + +5. Rounding and Comparison Functions: + + - `ceil(n)` + - `floor(n)` + - `round(n)` + - `max(numbers)` + - `min(numbers)` + +### 1. Constants: + +- **PI**: Represents the mathematical constant `π`. +- **e**: Represents `Euler's Number`. +- **phi**: Represents the `Golden Ratio`. +- **ln10**: Represents the `natural logarithm of 10`. +- **ln2**: Represents the `natural logarithm of 2`. +- **log10e**: Represents the `base 10 logarithms` of Euler's number `(e)`. +- **log2e**: Represents the `base 2 logarithm` of Euler's number` (e)`. +- **sqrt1_2**: Represents the `square root` of `1/2`. +- **sqrt2**: Represents the `square root` of `2`. +- **sqrt3**: Represents the `square root` of `3`. +- **sqrt5**: Represents the `square root` of `5`. +- **EPSILON**: Represents a small value `2.220446049250313e-16`. + +### 2. Methods: + +1. **abs(namba)** + + - Description: Calculates the absolute value of a number. + - Example: `hisabati.abs(-42)` returns `42`. + +2. **acos(n)** + + - Description: Calculates the arccosine of a number. + - Example: `hisabati.acos(0.5)` returns `1.0471975511965979`. + +3. **acosh(n)** + + - Description: Calculates the inverse hyperbolic cosine of a number. + - Example: `hisabati.acosh(2.0)` returns `1.3169578969248166`. + +4. **asin(n)** + + - Description: Calculates the arcsine of a number using the Taylor series. + - Example: `hisabati.arcsin(0.5)` returns `0.5235987755982988`. + +5. **asinh(n)** + + - Description: Calculates the inverse hyperbolic sine of a number. + - Example: `hisabati.arsinh(2.0)` returns `1.4436354751788103`. + +6. **atan(n)** + + - Description: Calculates the arctangent of a number using the Taylor series. + - Example: `hisabati.atan(1.0)` returns `0.7853981633974483`. + +7. **atan2(y, x)** + + - Description: Calculates the arctangent of the quotient of its arguments. + - Example: `hisabati.atan2(1.0, 1.0)` returns `0.7853981633974483`. + +8. **atanh(n)** + + - Description: Calculates the inverse hyperbolic tangent of a number. + - Example: `hisabati.atanh(0.5)` returns `0.5493061443340549`. + +9. **cbrt(n)** + + - Description: Calculates the cube root of a number. + - Example: `hisabati.cbrt(8)` returns `2`. + +10. **root(x, n)** + + - Description: Calculates the nth root of a number using the Newton-Raphson method. + - Example: `hisabati.root(27, 3)` returns `3`. + +11. **ceil(n)** + + - Description: Rounds up to the smallest integer greater than or equal to a given number. + - Example: `hisabati.ceil(4.3)` returns `5`. + +12. **cos(n)** + + - Description: Calculates the cosine of an angle in radians using the Taylor series. + - Example: `hisabati.cos(0.0)` returns `1`. + +13. **cosh(n)** + + - Description: Calculates the hyperbolic cosine of a number. + - Example: `hisabati.cosh(0.0)` returns `1`. + +14. **exp(n)** + + - Description: Calculates the value of Euler's number raised to the power of a given number. + - Example: `hisabati.exp(2.0)` returns `7.38905609893065`. + +15. **expm1(n)** + + - Description: Calculates Euler's number raised to the power of a number minus 1. + - Example: `hisabati.expm1(1.0)` returns `1.718281828459045`. + +16. **floor(n)** + + - Description: Rounds down to the largest integer less than or equal to a given number. + - Example: `hisabati.floor(4.7)` returns `4`. + +17. **hypot(values)** + + - Description: Calculates the square root of the sum of squares of the given values. + - Example: `hisabati.hypot([3, 4])` returns `5`. + +18. **log(n)** + + - Description: Calculates the natural logarithm of a number. + - Example: `hisabati.log(1.0)` returns `0`. + +19. **log10(n)** + + - Description: Calculates the base 10 logarithm of a number. + - Example: `hisabati.log10(100.0)` returns `2`. + +20. **log1p(n)** + + - Description: Calculates the natural logarithm of 1 plus the given number. + - Example: `hisabati.log1p(1.0)` returns `0.6931471805599453`. + +21. **log2(n)** + + - Description: Calculates the base 2 logarithm of a number. + - Example: `hisabati.log2(8)` returns `3`. + +22. **max(numbers)** + + - Description: Finds the maximum value in a list of numbers. + - Example: `hisabati.max([4, 2, 9, 5])` returns `9`. + +23. **min(numbers)** + + - Description: Finds the minimum value in a list of numbers. + - Example: `hisabati.min([4, 2, 9, 5])` returns `2`. + +24. **round(x, method)** + + - Description: Rounds a number to the nearest integer using the specified method. + - Example: `hisabati.round(4.6)` returns `5`. + +25. **sign(n)** + + - Description: Determines the sign of a number. + - Example: `hisabati.sign(-5)` returns `-1`. + +26. **sin(n)** + + - Description: Calculates the sine of an angle in radians using the Taylor series. + - Example: `hisabati.sin(1.0)` returns `0.8414709848078965`. + +27. **sinh(n)** + + - Description: Calculates the hyperbolic sine of a number. + - Example: `hisabati.sinh(1.0)` returns `1.1752011936438014`. + +28. **sqrt(n)** + + - Description: Calculates the square root of a number. + - Example: `hisabati.sqrt(4)` returns `2`. + +29. **tan(n)** + + - Description: Calculates the tangent of an angle in radians. + - Example: `hisabati.tan(1.0)` returns `1.557407724654902`. + +30. **tanh(n)** + + - Description: Calculates the hyperbolic tangent of a number. + - Example: `hisabati.tanh(1.0)` returns `0.7615941559557649`. + +31. **factorial(n)** + + - Description: Calculates the factorial of a number. + - Example: `hisabati.factorial(5)` returns `120`. + +### Contributing + +Contributions to the `module hisabati` are welcome. If you have any improvements or bug fixes, feel free to create a pull request. + +### License + +This in-built module is available under the MIT License. See the [LICENSE](LICENSE) file for more information. \ No newline at end of file diff --git a/third_party/math/hisabati.nr b/third_party/math/hisabati.nr index 4e8b0d5..9785c98 100644 --- a/third_party/math/hisabati.nr +++ b/third_party/math/hisabati.nr @@ -201,6 +201,10 @@ pakeji hisabati{ //cbrt(x), calculates the cube root of a number. cbrt = unda(x) { + kama(x == 0) { + rudisha 0; + } + kama(x >= 0) { rudisha @.root(x, 3); } sivyo { @@ -215,7 +219,8 @@ pakeji hisabati{ fanya calculateNthRoot = unda(x, n, guess, tolerance) { fanya nextGuess = ((n - 1) * guess + x / (guess ** (n - 1))) / n; - kama (abs(nextGuess - guess) < tolerance) {rudisha nextGuess}; + fanya ipotolerance = abs(nextGuess - guess); + kama (ipotolerance < tolerance) {rudisha nextGuess}; rudisha calculateNthRoot(x, n, nextGuess, tolerance); } @@ -504,20 +509,10 @@ pakeji hisabati{ kama(x < 0) { rudisha 0; } - - // Initial guess for the square root (you can choose a better initial guess) - fanya guess = x / 2; - fanya tolerance = 1e-7; // Tolerance for approximation - - wakati(kweli) { - fanya nextGuess = 0.5 * (guess + x / guess); - - // Check kama the guess is close enough to the actual square root - kama(@.abs(nextGuess - guess) < tolerance) { - rudisha nextGuess; - } - - guess = nextGuess; + kama(x >= 0) { + rudisha @.root(x, 2); + } sivyo { + rudisha - @.root(-x, 2); } } From 90c0c6f4f8383fcbfc3491d604640b2685b57c6d Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Wed, 1 Nov 2023 13:30:41 +0300 Subject: [PATCH 42/81] Hisabati error messages in swahili --- module/hisabati.go | 218 ++++++++++++++++++++++----------------------- 1 file changed, 109 insertions(+), 109 deletions(-) diff --git a/module/hisabati.go b/module/hisabati.go index 4ac0ebf..583905d 100644 --- a/module/hisabati.go +++ b/module/hisabati.go @@ -117,13 +117,13 @@ func epsilon(args []object.Object, defs map[string]object.Object) object.Object func abs(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } switch arg := args[0].(type) { case *object.Integer: @@ -137,16 +137,16 @@ func abs(args []object.Object, defs map[string]object.Object) object.Object { } return arg default: - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } } func sign(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } switch arg := args[0].(type) { case *object.Integer: @@ -166,19 +166,19 @@ func sign(args []object.Object, defs map[string]object.Object) object.Object { return &object.Integer{Value: -1} } default: - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } } func ceil(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } switch arg := args[0].(type) { case *object.Integer: @@ -186,19 +186,19 @@ func ceil(args []object.Object, defs map[string]object.Object) object.Object { case *object.Float: return &object.Integer{Value: int64(math.Ceil(arg.Value))} default: - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } } func floor(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } switch arg := args[0].(type) { case *object.Integer: @@ -206,19 +206,19 @@ func floor(args []object.Object, defs map[string]object.Object) object.Object { case *object.Float: return &object.Integer{Value: int64(math.Floor(arg.Value))} default: - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } } func sqrt(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } switch arg := args[0].(type) { case *object.Integer: @@ -226,19 +226,19 @@ func sqrt(args []object.Object, defs map[string]object.Object) object.Object { case *object.Float: return &object.Float{Value: math.Sqrt(arg.Value)} default: - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } } func cbrt(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } switch arg := args[0].(type) { case *object.Integer: @@ -246,22 +246,22 @@ func cbrt(args []object.Object, defs map[string]object.Object) object.Object { case *object.Float: return &object.Float{Value: math.Cbrt(arg.Value)} default: - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } } func root(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 2 { - return &object.Error{Message: "This function requires exactly two arguments"} + return &object.Error{Message: "Undo hili linahitaji hoja mbili tu"} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "First argument must be a number"} + return &object.Error{Message: "Hoja ya kwanza lazima iwe namba"} } if args[1].Type() != object.INTEGER_OBJ { - return &object.Error{Message: "Second argument must be an integer"} + return &object.Error{Message: "Hoja ya pili lazima iwe namba"} } base, ok := args[0].(*object.Float) if !ok { @@ -272,7 +272,7 @@ func root(args []object.Object, defs map[string]object.Object) object.Object { if exp == 0 { return &object.Float{Value: 1.0} } else if exp < 0 { - return &object.Error{Message: "Second argument must be a non-negative integer"} + return &object.Error{Message: "Second Hoja lazima iwe a non-negative integer"} } x := 1.0 @@ -285,15 +285,15 @@ func root(args []object.Object, defs map[string]object.Object) object.Object { func hypot(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) < 2 { - return &object.Error{Message: "This function requires at least two arguments"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } var sumOfSquares float64 for _, arg := range args { if arg.Type() != object.INTEGER_OBJ && arg.Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Arguments must be numbers"} + return &object.Error{Message: "Hoja lazima ziwe namba"} } switch num := arg.(type) { case *object.Integer: @@ -307,17 +307,17 @@ func hypot(args []object.Object, defs map[string]object.Object) object.Object { func factorial(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.INTEGER_OBJ { - return &object.Error{Message: "Argument must be an integer"} + return &object.Error{Message: "Hoja lazima iwe namba"} } n := args[0].(*object.Integer).Value if n < 0 { - return &object.Error{Message: "Argument must be a non-negative integer"} + return &object.Error{Message: "Hoja lazima iwe a non-negative integer"} } result := int64(1) for i := int64(2); i <= n; i++ { @@ -328,13 +328,13 @@ func factorial(args []object.Object, defs map[string]object.Object) object.Objec func round(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value @@ -343,26 +343,26 @@ func round(args []object.Object, defs map[string]object.Object) object.Object { func max(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } arg, ok := args[0].(*object.Array) if !ok { - return &object.Error{Message: "Argument must be an array"} + return &object.Error{Message: "Hoja lazima iwe an array"} } if len(arg.Elements) == 0 { - return &object.Error{Message: "Array must not be empty"} + return &object.Error{Message: "Orodha haipaswi kuwa tupu"} } var maxNum float64 for _, element := range arg.Elements { if element.Type() != object.INTEGER_OBJ && element.Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Array elements must be numbers"} + return &object.Error{Message: "Vipengee vya orodha lazima viwe namba"} } switch num := element.(type) { @@ -375,7 +375,7 @@ func max(args []object.Object, defs map[string]object.Object) object.Object { maxNum = num.Value } default: - return &object.Error{Message: "Array elements must be numbers"} + return &object.Error{Message: "Vipengee vya orodha lazima viwe namba"} } } @@ -384,26 +384,26 @@ func max(args []object.Object, defs map[string]object.Object) object.Object { func min(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } arg, ok := args[0].(*object.Array) if !ok { - return &object.Error{Message: "Argument must be an array"} + return &object.Error{Message: "Hoja lazima iwe an array"} } if len(arg.Elements) == 0 { - return &object.Error{Message: "Array must not be empty"} + return &object.Error{Message: "Orodha haipaswi kuwa tupu"} } minNum := math.MaxFloat64 for _, element := range arg.Elements { if element.Type() != object.INTEGER_OBJ && element.Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Array elements must be numbers"} + return &object.Error{Message: "Vipengee vya orodha lazima viwe namba"} } switch num := element.(type) { @@ -416,7 +416,7 @@ func min(args []object.Object, defs map[string]object.Object) object.Object { minNum = num.Value } default: - return &object.Error{Message: "Array elements must be numbers"} + return &object.Error{Message: "Vipengee vya orodha lazima viwe namba"} } } @@ -425,13 +425,13 @@ func min(args []object.Object, defs map[string]object.Object) object.Object { func exp(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Exp(num)} @@ -439,13 +439,13 @@ func exp(args []object.Object, defs map[string]object.Object) object.Object { func expm1(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Expm1(num)} @@ -453,13 +453,13 @@ func expm1(args []object.Object, defs map[string]object.Object) object.Object { func log(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Log(num)} @@ -467,13 +467,13 @@ func log(args []object.Object, defs map[string]object.Object) object.Object { func log10(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Log10(num)} @@ -481,19 +481,19 @@ func log10(args []object.Object, defs map[string]object.Object) object.Object { func log2(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a number"} + return &object.Error{Message: "Hoja lazima iwe namba"} } arg := extractFloatValue(args[0]) if arg <= 0 { - return &object.Error{Message: "Argument must be greater than 0"} + return &object.Error{Message: "Hoja lazima iwe kubwa kuliko 0"} } return &object.Float{Value: math.Log2(arg)} @@ -512,13 +512,13 @@ func extractFloatValue(obj object.Object) float64 { func log1p(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Log1p(num)} @@ -526,13 +526,13 @@ func log1p(args []object.Object, defs map[string]object.Object) object.Object { func cos(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Cos(num)} @@ -540,13 +540,13 @@ func cos(args []object.Object, defs map[string]object.Object) object.Object { func sin(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Sin(num)} @@ -554,13 +554,13 @@ func sin(args []object.Object, defs map[string]object.Object) object.Object { func tan(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Tan(num)} @@ -568,13 +568,13 @@ func tan(args []object.Object, defs map[string]object.Object) object.Object { func acos(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Acos(num)} @@ -582,13 +582,13 @@ func acos(args []object.Object, defs map[string]object.Object) object.Object { func asin(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Asin(num)} @@ -596,13 +596,13 @@ func asin(args []object.Object, defs map[string]object.Object) object.Object { func atan(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Atan(num)} @@ -610,13 +610,13 @@ func atan(args []object.Object, defs map[string]object.Object) object.Object { func cosh(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Cosh(num)} @@ -624,13 +624,13 @@ func cosh(args []object.Object, defs map[string]object.Object) object.Object { func sinh(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Sinh(num)} @@ -638,13 +638,13 @@ func sinh(args []object.Object, defs map[string]object.Object) object.Object { func tanh(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Tanh(num)} @@ -652,13 +652,13 @@ func tanh(args []object.Object, defs map[string]object.Object) object.Object { func acosh(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Acosh(num)} @@ -666,13 +666,13 @@ func acosh(args []object.Object, defs map[string]object.Object) object.Object { func asinh(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Asinh(num)} @@ -680,16 +680,16 @@ func asinh(args []object.Object, defs map[string]object.Object) object.Object { func atan2(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 2 { - return &object.Error{Message: "This function requires exactly two arguments"} + return &object.Error{Message: "Undo hili linahitaji hoja mbili tu."} } if args[0].Type() != object.INTEGER_OBJ && args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Arguments must be numbers"} + return &object.Error{Message: "Hoja lazima ziwe namba"} } if args[1].Type() != object.INTEGER_OBJ && args[1].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Arguments must be numbers"} + return &object.Error{Message: "Hoja lazima ziwe namba"} } y := extractFloatValue(args[0]) @@ -700,13 +700,13 @@ func atan2(args []object.Object, defs map[string]object.Object) object.Object { func atanh(args []object.Object, defs map[string]object.Object) object.Object { if len(defs) != 0 { - return &object.Error{Message: "This function doesn't allow definitions"} + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} } if len(args) != 1 { - return &object.Error{Message: "This function requires exactly one argument"} + return &object.Error{Message: "Undo hili linahitaji hoja moja tu"} } if args[0].Type() != object.FLOAT_OBJ { - return &object.Error{Message: "Argument must be a float"} + return &object.Error{Message: "Hoja lazima iwe desimali"} } num := args[0].(*object.Float).Value return &object.Float{Value: math.Atanh(num)} From ac2071fc05cc0194b40e10a9c27f5bd5fa7c2b42 Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Thu, 2 Nov 2023 22:33:32 +0300 Subject: [PATCH 43/81] fix negative powers --- evaluator/infix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evaluator/infix.go b/evaluator/infix.go index e17645a..f25ef9d 100644 --- a/evaluator/infix.go +++ b/evaluator/infix.go @@ -219,7 +219,7 @@ func evalIntegerInfixExpression(operator string, left, right object.Object, line case "*": return &object.Integer{Value: leftVal * rightVal} case "**": - return &object.Integer{Value: int64(math.Pow(float64(leftVal), float64(rightVal)))} + return &object.Float{Value: float64(math.Pow(float64(leftVal), float64(rightVal)))} case "/": x := float64(leftVal) / float64(rightVal) if math.Mod(x, 1) == 0 { From 31e20a6ac36826221478f07c3d1c402e029b44cb Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Thu, 2 Nov 2023 22:33:50 +0300 Subject: [PATCH 44/81] update tests --- evaluator/evaluator_test.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index ad9e925..452f552 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -22,7 +22,6 @@ func TestEvalIntegerExpression(t *testing.T) { {"5 + 5 + 5 + 5 - 10", 10}, {"2 * 2 * 2 * 2", 16}, {"2 / 2 + 1", 2}, - {"2**3", 8}, } for _, tt := range tests { @@ -31,6 +30,20 @@ func TestEvalIntegerExpression(t *testing.T) { } } +func TestEvalFloatExpression(t *testing.T) { + tests := []struct { + input string + expected float64 + }{ + {"2**3", 8.0}, + } + + for _, tt := range tests { + evaluated := testEval(tt.input) + testFloatObject(t, evaluated, tt.expected) + } +} + func TestEvalBooleanExpression(t *testing.T) { tests := []struct { input string From cf4236dda5b1fed5f5cfe690b3fca9102eee6dfa Mon Sep 17 00:00:00 2001 From: AvicennaJr Date: Thu, 2 Nov 2023 22:46:06 +0300 Subject: [PATCH 45/81] update version --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 57d1068..fd83cc4 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To get started download the executables from the release page or follow the inst - Download the binary: ``` -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Linux_amd64.tar.gz +curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Linux_amd64.tar.gz ``` - Extract the file to make global available: @@ -44,13 +44,13 @@ nuru -v - For apple silicon mac use: ``` - curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Darwin_arm64.tar.gz + curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Darwin_arm64.tar.gz ``` - For apple intel mac use: ``` - curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Darwin_amd64.tar.gz + curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Darwin_amd64.tar.gz ``` - Extract the file to make global available: @@ -78,7 +78,7 @@ nuru -v - Download the binary with this command: ``` -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Android_arm64.tar.gz +curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz ``` - Extract the file: @@ -99,7 +99,7 @@ nuru -v ### Windows - Executable: - - Download the Nuru zip file [Here](https://github.com/AvicennaJr/Nuru/releases/download/v0.5.15/nuru_Windows_amd64.zip) + - Download the Nuru zip file [Here](https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Windows_amd64.zip) - Unzip to get the executable - Double click the executable From d0ea599539dc4faf96fff89150e129d8adc5248c Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Sat, 4 Nov 2023 20:59:12 +0300 Subject: [PATCH 46/81] renamed hisabati package fixed bugs used hisabati module for constants added a test file for hesabu package update hesabu package documentation --- third_party/math/README.md | 107 ++++--- third_party/math/{hisabati.nr => hesabu.nr} | 319 ++++++++------------ third_party/math/test.nr | 41 +++ 3 files changed, 222 insertions(+), 245 deletions(-) rename third_party/math/{hisabati.nr => hesabu.nr} (62%) create mode 100644 third_party/math/test.nr diff --git a/third_party/math/README.md b/third_party/math/README.md index 1d3b6f1..08a2e38 100644 --- a/third_party/math/README.md +++ b/third_party/math/README.md @@ -1,29 +1,29 @@ -# Pakeji Hisabati (Math Package) +# Pakeji Hesabu (Math Package) -Pakeji Hisabati is a math package written in pure Nuru by [VictorKariuki](https://github.com/VictorKariuki). +Pakeji Hesabu is a math package written in pure Nuru by [VictorKariuki](https://github.com/VictorKariuki). This package provides various mathematical functions and constants implemented in nuru programming language. It includes methods for `trigonometric functions`, `logarithmic functions`, `array operations`, and `utility functions`. ## Usage -To use the `pakeji hisabati` package follow the steps below: +To use the `pakeji hesabu` package follow the steps below: -1. Copy the `hisabati.nr` file and any required third-party package files into the same directory as your project. +1. Copy the `hesabu.nr` file and any required third-party package files into the same directory as your project. -2. Ensure that the package file names end with the `.nr` extension and match the package names. For example, if the package name is `hisabati`, the corresponding file name should be `hisabati.nr`. +2. Ensure that the package file names end with the `.nr` extension and match the package names. For example, if the package name is `hesabu`, the corresponding file name should be `hesabu.nr`. -3. You can directly import the `hisabati.nr` package and any required third-party packages in your Nuru code using the `tumia` keyword. For example: +3. You can directly import the `hesabu.nr` package and any required third-party packages in your Nuru code using the `tumia` keyword. For example: ```nuru - tumia "hisabati" + tumia "hesabu" ``` Example of calling the package methods: ```nuru - andika(hisabati.e()) + andika(hesabu.e()) ## What is in This package covers a wide range of mathematical operations, including `basic arithmetic`, `trigonometry`, `exponential and logarithmic functions`, `rounding and comparison operations`, as well as some `utility and array operations`. -The methods provided in the `hisabati` package can be classified into different categories based on their functionalities. Here is a classification of the methods: +The methods provided in the `hesabu` package can be classified into different categories based on their functionalities. Here is a classification of the methods: 1. Trigonometric Functions: - `cos(x)` @@ -92,152 +92,161 @@ The methods provided in the `hisabati` package can be classified into different 1. **abs(namba)** - Description: Calculates the absolute value of a number. - - Example: `hisabati.abs(-42)` returns `42`. + - Example: `hesabu.abs(-42)` returns `42`. 2. **acos(x)** - Description: Calculates the arccosine of a number. - - Example: `hisabati.acos(0.5)` returns `1.0471975511965979`. + - Example: `hesabu.acos(0.5)` returns `1.0471975511965979`. 3. **acosh(x)** - Description: Calculates the inverse hyperbolic cosine of a number. - - Example: `hisabati.acosh(2)` returns `1.3169578969248166`. + - Example: `hesabu.acosh(2)` returns `1.3169578969248166`. -4. **arcsin(x)** +4. **asin(x)** - Description: Calculates the arcsine of a number using the Taylor series. - - Example: `hisabati.arcsin(0.5)` returns `0.5235987755982988`. + - Example: `hesabu.arcsin(0.5)` returns `0.5235987755982989`. -5. **arsinh(x)** +5. **asinh(x)** - Description: Calculates the inverse hyperbolic sine of a number. - - Example: `hisabati.arsinh(2)` returns `1.4436354751788103`. + - Example: `hesabu.arsinh(2)` returns `1.4436354751788103`. 6. **atan(x)** - Description: Calculates the arctangent of a number using the Taylor series. - - Example: `hisabati.atan(1)` returns `0.7853981633974483`. + - Example: `hesabu.atan(1)` returns `0.7853981633974485`. 7. **atan2(y, x)** - Description: Calculates the arctangent of the quotient of its arguments. - - Example: `hisabati.atan2(1, 1)` returns `0.7853981633974483`. + - Example: `hesabu.atan2(1, 1)` returns `0.7853981633974483`. 8. **atanh(x)** - Description: Calculates the inverse hyperbolic tangent of a number. - - Example: `hisabati.atanh(0.5)` returns `0.5493061443340549`. + - Example: `hesabu.atanh(0.5)` returns `0.5493061443340549`. 9. **cbrt(x)** - Description: Calculates the cube root of a number. - - Example: `hisabati.cbrt(8)` returns `2`. + - Example: `hesabu.cbrt(8)` returns `2`. 10. **root(x, n)** - Description: Calculates the nth root of a number using the Newton-Raphson method. - - Example: `hisabati.root(27, 3)` returns `3`. + - Example: `hesabu.root(27, 3)` returns `3`. 11. **ceil(x)** - Description: Rounds up to the smallest integer greater than or equal to a given number. - - Example: `hisabati.ceil(4.3)` returns `5`. + - Example: `hesabu.ceil(4.3)` returns `5`. 12. **cos(x)** - Description: Calculates the cosine of an angle in radians using the Taylor series. - - Example: `hisabati.cos(0)` returns `1`. + - Example: `hesabu.cos(5)` returns `0.28366218546322464`. 13. **cosh(x)** - Description: Calculates the hyperbolic cosine of a number. - - Example: `hisabati.cosh(0)` returns `1`. + - Example: `hesabu.cosh(5)` returns `74.20994842490012`. 14. **exp(x)** - Description: Calculates the value of Euler's number raised to the power of a given number. - - Example: `hisabati.exp(2)` returns `7.38905609893065`. + - Example: `hesabu.exp(2)` returns `7.389056098930649`. 15. **expm1(x)** - Description: Calculates Euler's number raised to the power of a number minus 1. - - Example: `hisabati.expm1(1)` returns `1.718281828459045`. + - Example: `hesabu.expm1(1)` returns `1.7182818284590455`. 16. **floor(x)** - Description: Rounds down to the largest integer less than or equal to a given number. - - Example: `hisabati.floor(4.7)` returns `4`. + - Example: `hesabu.floor(4.7)` returns `4`. 17. **hypot(values)** - Description: Calculates the square root of the sum of squares of the given values. - - Example: `hisabati.hypot([3, 4])` returns `5`. + - Example: `hesabu.hypot([3, 4])` returns `5`. 18. **log(x)** - Description: Calculates the natural logarithm of a number. - - Example: `hisabati.log(1)` returns `0`. + - Example: `hesabu.log(2)` returns `0.69314718056`. 19. **log10(x)** - Description: Calculates the base 10 logarithm of a number. - - Example: `hisabati.log10(100)` returns `2`. + - Example: `hesabu.log10(100)` returns `1.9999999999573126`. 20. **log1p(x)** - Description: Calculates the natural logarithm of 1 plus the given number. - - Example: `hisabati.log1p(1)` returns `0.6931471805599453`. + - Example: `hesabu.log1p(1)` returns `0.6931471805599451`. 21. **log2(x)** - Description: Calculates the base 2 logarithm of a number. - - Example: `hisabati.log2(8)` returns `3`. + - Example: `hesabu.log2(8)` returns `3`. 22. **max(numbers)** - Description: Finds the maximum value in a list of numbers. - - Example: `hisabati.max([4, 2, 9, 5])` returns `9`. + - Example: `hesabu.max([4, 2, 9, 5])` returns `9`. 23. **min(numbers)** - Description: Finds the minimum value in a list of numbers. - - Example: `hisabati.min([4, 2, 9, 5])` returns `2`. + - Example: `hesabu.min([4, 2, 9, 5])` returns `2`. 24. **round(x, method)** - Description: Rounds a number to the nearest integer using the specified method. - - Example: `hisabati.round(4.6, "rpi")` returns `5`. + - supported methods: + - "rpi" (round to the nearest integer using the principle of rounding half to the nearest even) + - "rni" (round to the nearest integer using the principle of rounding half away from zero) + - "ri" (round to the nearest integer using the standard rounding method) + - An invalid method results in returning NaN (Not a Number) + - Example: `hesabu.round(4.6, "rpi")` returns `5`. 25. **sign(x)** - Description: Determines the sign of a number. - - Example: `hisabati.sign(-5)` returns `-1`. + - Example: `hesabu.sign(-5)` returns `-1`. 26. **sin(x)** - Description: Calculates the sine of an angle in radians using the Taylor series. - - Example: `hisabati.sin(0)` returns `0`. + - Example: `hesabu.sin(1)` returns `0.8414709848078965`. 27. **sinh(x)** - Description: Calculates the hyperbolic sine of a number. - - Example: `hisabati.sinh(0)` returns `0`. + - Example: `hesabu.sinh(0)` returns `0`. 28. **sqrt(x)** - Description: Calculates the square root of a number. - - Example: `hisabati.sqrt(4)` returns `2`. + - Example: `hesabu.sqrt(4)` returns `2`. 29. **tan(x)** - Description: Calculates the tangent of an angle in radians. - - Example: `hisabati.tan(0)` returns `0`. + - Example: `hesabu.tan(1)` returns `1.557407724654902`. 30. **tanh(x)** - Description: Calculates the hyperbolic tangent of a number. - - Example: `hisabati.tanh(0)` returns `0`. + - Example: `hesabu.tanh(0)` returns `0`. 31. **factorial(n)** - Description: Calculates the factorial of a number. - - Example: `hisabati.factorial(5)` returns `120`. + - Example: `hesabu.factorial(5)` returns `120`. 32. **isNegative(num)** - Description: Checks if a number is negative. - - Example: `hisabati.isNegative(-5)` returns `true`. + - Example: `hesabu.isNegative(-5)` returns `kweli`. 33. **isInteger(num)** - Description: Checks if a number is an integer. - - Example: `hisabati.isInteger(4.5)` returns `false`. + - Example: `hesabu.isInteger(4.5)` returns `sikweli`. 34. **getIntegerPart(num)** - Description: Gets the integer part of a number. - - Example: `hisabati.getIntegerPart(4.5)` returns `4`. + - Example: `hesabu.getIntegerPart(4.5)` returns `4`. 35. **list(first, last, interval)** - Description: Creates a list of numbers with the specified interval between them. - - Example: `hisabati.list(1, 5, 1)` returns `[1, 2, 3, 4]`. + - Example: `hesabu.list(1, 5, 1)` returns `[1, 2, 3, 4]`. 36. **reduce(iterator, callback, initialValue)** - Description: Reduces the elements of an array to a single value using a specified callback function. - - Example: `hisabati.reduce([1, 2, 3, 4], (accumulator, currentValue) => accumulator + currentValue, 0)` returns `10`. - + - Example: `hesabu.reduce([1, 2, 3, 4], [callback function], 0)` + ```s + fanya callback = unda(accumulator, currentValue){ + rudisha accumulator + currentValue; + } + andika(hesabu.reduce([1, 2, 3, 4], callback, 0)) \\ returns 10. ### Contributing -Contributions to the `pakeji hisabati` package are welcome. If you have any improvements or bug fixes, feel free to create a pull request. +Contributions to the `pakeji hesabu` package are welcome. If you have any improvements or bug fixes, feel free to create a pull request. ### License diff --git a/third_party/math/hisabati.nr b/third_party/math/hesabu.nr similarity index 62% rename from third_party/math/hisabati.nr rename to third_party/math/hesabu.nr index 9785c98..ec113c8 100644 --- a/third_party/math/hisabati.nr +++ b/third_party/math/hesabu.nr @@ -1,4 +1,6 @@ -pakeji hisabati{ +tumia hisabati + +pakeji hesabu{ //CONSTRUCTOR METHOD andaa = unda() {} @@ -75,27 +77,25 @@ pakeji hisabati{ //acos(x), calculates the arccosine of a number. acos = unda(x) { - kama(x < -1 || x > 1) { - rudisha 0; + kama (x < -1 || x > 1) { + rudisha "NaN"; } - // Define the precision for the approximation. - fanya precision = 0.0000000001; + fanya EPSILON = 1*10.0**-10; // Small value for precision - // Initial guess for the angle in radians (between 0 and π). - fanya angle = @.PI() / 4; + fanya acosRecursive = unda(guess) { + fanya f = cos(guess) - x; + fanya fPrime = -sin(guess); + fanya nextGuess = guess - f / fPrime; - wakati(kweli) { - fanya cosAngle = @.cos(angle); - fanya error = @.abs(cosAngle - x); - - kama(error < precision) { - rudisha angle; + kama (abs(nextGuess - guess) < EPSILON) { + rudisha nextGuess; } - // Update the angle using the Newton-Raphson method. - angle -= (cosAngle - x) / (-@.sin(angle)); + rudisha acosRecursive(nextGuess); } + + rudisha acosRecursive(hisabati.PI() / 2); // Initial guess for acos } //acosh(x), calculates the inverse hyperbolic cosine of a number. @@ -104,90 +104,75 @@ pakeji hisabati{ rudisha 0; } - rudisha @.log(x + @.sqrt(x * x - 1)); + rudisha log(x + sqrt(x * x - 1)); } - //arcsin(x), calculates the arcsine of a number using the Taylor series. - arcsin = unda(x) { - kama(x < -1 || x > 1) { - rudisha 0; + //asin(x), calculates the arcsine of a number using the Newton Method. + asin = unda(x) { + kama (x < -1 || x > 1) { + rudisha "NaN"; } fanya maxIterations = 50; // Maximum number of iterations - fanya result = 0; - fanya n = 0; - wakati(n < maxIterations) { - fanya numerator = (-1) ** n * x ** (2 * n + 1); - fanya denominator = @.factorial(2 * n + 1); // You'll need to implement a factorial function + fanya newtonAsin = unda(guess, prev, iterations) { + fanya next = guess - (sin(guess) - x) / cos(guess); - result += numerator / denominator; - n++; + kama (abs(next - prev) < hisabati.EPSILON() || iterations >= maxIterations) { + rudisha next; + } + + rudisha newtonAsin(next, guess, iterations + 1); } - rudisha result; + rudisha newtonAsin(x, 1, 0); } - //arsinh(x), calculates the inverse hyperbolic sine of a number. - arsinh = unda(x) { + + //asinh(x), calculates the inverse hyperbolic sine of a number. + asinh = unda(x) { // Calculate arsinh using the formula: arsinh(x) = ln(x + sqrt(x^2 + 1)) kama(x >= 0) { - rudisha @.log(x + @.sqrt(x * x + 1)); + rudisha log(x + sqrt(x * x + 1)); } sivyo { // For negative values, arsinh(x) = -arsinh(-x) - rudisha - @.log(-x + @.sqrt(x * x + 1)); + rudisha - log(-x + sqrt(x * x + 1)); } } //atan(x), calculates the arctangent of a number using the Taylor series. atan = unda(x) { - kama(x == 0) { - rudisha 0; - } // arctan(0) is 0 - kama(x == 1/0) { - rudisha @.PI / 2; - } - kama(x == -1/0) { - rudisha - @.PI / 2; - } // arctan(-Inf) is -π/2 - - // Use the Taylor series expansion for arctan(x) - // arctan(x) = x - (x^3) / 3 + (x^5) / 5 - (x^7) / 7 + ... - fanya n = 3; - fanya result = 0; - fanya term = x * x; - fanya sign = -1; + fanya EPSILON = 1*10.0**-10; // Small value for precision - wakati(kweli) { - fanya currentTerm = sign * (term / n); + fanya atanRecursive = unda(guess) { + fanya f = tan(guess) - x; + fanya fPrime = 1 / (cos(guess) * cos(guess)); + fanya nextGuess = guess - f / fPrime; - kama(currentTerm == 0) { - vunja + kama (abs(nextGuess - guess) < EPSILON) { + rudisha nextGuess; } - result += currentTerm; - n += 2; - sign = -sign; - term *= x * x; + rudisha atanRecursive(nextGuess); } - rudisha result; + rudisha atanRecursive(x); // Initial guess for atan } //atanh(x), calculates the inverse hyperbolic tangent of a number. atan2 = unda(y, x) { kama(x > 0) { - rudisha @.atan(y / x); + rudisha atan(y / x); } au kama(x < 0 && y >= 0) { - rudisha @.atan(y / x) + @.PI; + rudisha atan(y / x) + hisabati.PI(); } au kama(x < 0 && y < 0) { - rudisha @.atan(y / x) - @.PI; + rudisha atan(y / x) - hisabati.PI(); } au kama(x == 0 && y > 0) { - rudisha @.PI / 2; + rudisha hisabati.PI() / 2; } au kama(x == 0 && y < 0) { - rudisha - @.PI / 2; + rudisha - hisabati.PI() / 2; } au kama(x == 0 && y == 0) { - rudisha NaN; // Undefined + rudisha "NaN"; // Undefined } } @@ -196,7 +181,7 @@ pakeji hisabati{ kama(x < -1 || x > 1) { rudisha 0; } - rudisha 0.5 * @.log((1 + x) / (1 - x)); + rudisha 0.5 * log((1.0 + x) / (1.0 - x)); } //cbrt(x), calculates the cube root of a number. @@ -206,9 +191,9 @@ pakeji hisabati{ } kama(x >= 0) { - rudisha @.root(x, 3); + rudisha root(x, 3); } sivyo { - rudisha - @.root(-x, 3); + rudisha - root(-x, 3); } } @@ -239,72 +224,53 @@ pakeji hisabati{ } } - //cos(x), calculates the cosine of an angle in radians using the Taylor series. + //cos(x), calculates the cosine of an angle. cos = unda(x) { - // Initialize the result - fanya n = 0; - fanya terms = 10; - fanya result = 0; - - wakati(n < terms) { - // Calculate the numerator and denominator for the nth term - fanya numerator = 0; - kama(n % 2 == 0) { - numerator = x ** (2 * n + 1); - } sivyo { - numerator = -x ** (2 * n + 1); - } - andika(@.factorial(2 * n)); - //fanya denominator = @.factorial(2 * n); - - // Add the nth term to the result - //result += numerator / denominator; + fanya result = 1; // Initialize the result + fanya term = 1; - n++; + kwa i ktk list(2,101,2) { + term = (-term * x * x) / (i * (i - 1)); + result += term; } - rudisha result; } //cosh(x), calculates the hyperbolic cosine of a number. cosh = unda(x) { - fanya eToX = @.exp(x); - fanya eToMinusX = @.exp(-x); + fanya eToX = exp(x); + fanya eToMinusX = exp(-x); rudisha(eToX + eToMinusX) / 2; } //exp(x), calculates the value of Euler's number raised to the power of a given number. - exp = unda(x, precision = 15) { + exp = unda(n) { fanya result = 1; fanya term = 1; - fanya i = 1; - - wakati(i <= precision) { - term *= x / i; - result += term; - i++; + + kwa i, v ktk list(1,23,1) { + term = term*(n/v); + result = result + term; } - rudisha result; } + //expm1(x), calculates the value of Euler's number raised to the power of a given number minus 1. expm1 = unda(x) { - fanya epsilon = 1e-15; // A small value to improve accuracy - fanya result = 0; - fanya term = x; - fanya n = 1; - - wakati(@.abs(term) > epsilon) { - result += term; - n++; - term *= x / n; + kama (x == -1) { + rudisha -0.6321205588285577; // Handling the special case for -1 + } au kama (x == 0) { + rudisha 0; // Handling the special case for 0 + } au kama (abs(x) < hisabati.EPSILON()) { + rudisha x + 0.5 * x * x; // Approximation for very small x + } sivyo { + rudisha exp(x) - 1; } - - rudisha result; } + //floor(x), rounds down to the largest integer less than or equal to a given number. floor = unda(x) { kama(x >= 0) { @@ -321,31 +287,33 @@ pakeji hisabati{ rudisha acc + value ** 2; } - fanya sumOfSquares = @.reduce(values, exp, 0); + fanya sumOfSquares = reduce(values, exp, 0); // Calculate the square root of the sum of squares - fanya result = @.sqrt(sumOfSquares); + fanya result = sqrt(sumOfSquares); rudisha result; } //log(x), calculates the natural logarithm of a number. log = unda(x) { - kama(x <= 0) { + kama (x <= 0) { + rudisha "NaN"; + } + kama (x == 1) { rudisha 0; } - - fanya approx = 0; - fanya n = 50; - fanya i = 1; - - wakati(i <= n) { - approx += (1 / i) * ((x - 1) / (x + 1)) ** (2 * i - 1); - i++; + kama (x < 0) { + rudisha -log(-x); } - - - rudisha 2 * approx; + fanya n = 1000; // Number of iterations + fanya y = (x - 1) / (x + 1); + fanya ySquared = y * y; + fanya result = 0; + kwa i ktk list(1,n+1,2) { + result += (1 / i) * y**i; + } + rudisha 2 * result; } //log10(x), calculates the base 10 logarithm of a number. @@ -355,39 +323,18 @@ pakeji hisabati{ } // Calculate natural logarithm and divide by the natural logarithm of 10 - rudisha this.log(x) / this.log(10); + rudisha log(x) / log(10.0); } //log1p(x), calculates the natural logarithm of 1 plus the given number. log1p = unda(x) { - kama(x < -1) { - rudisha 0; - } - - kama(x == -1) { - rudisha(-Inf); - } - - kama(x == Inf) { - rudisha Inf; - } - - kama(x == 0) { - rudisha 0; - } - - // Use the formula: ln(1 + x) = x - (x^2)/2 + (x^3)/3 - (x^4)/4 + ... - fanya result = 0; - fanya term = x; - fanya i = 2; - - wakati(@.abs(term) > @.EPSILON) { - result += term; - term *= -x / i; - i++; + kama (x <= -1) { + rudisha NaN; // Not a Number + } au kama (abs(x) < hisabati.EPSILON()) { + rudisha x - 0.5 * x * x; // Series expansion for small x + } sivyo { + rudisha log(1.0 + x); } - - rudisha result; } //log2(x), calculates the base 2 logarithm of a number. @@ -410,7 +357,7 @@ pakeji hisabati{ //max(numbers), finds the maximum value in a list of numbers. max = unda(numbers) { // Initialize a variable to store the largest number - fanya largest = -Inf; + fanya largest = 0; // Iterate through the numbers and update 'largest' kama a larger number is found kwa num ktk numbers { @@ -419,20 +366,20 @@ pakeji hisabati{ } } - // rudisha the largest number (or -Inf kama there are no parameters) + // rudisha the largest number (or 0 kama there are no parameters) rudisha largest; } //min(numbers), finds the minimum value in a list of numbers. min = unda(numbers) { - kama(numbers.length == 0) { - rudisha Inf; + kama(numbers.idadi() == 0) { + rudisha 0; } fanya minVal = numbers[0]; fanya i = 1; - wakati(i < numbers.length) { + wakati(i < numbers.idadi()) { kama(numbers[i] < minVal) { minVal = numbers[i]; } @@ -471,36 +418,22 @@ pakeji hisabati{ } //sin(x), calculates the sine of an angle in radians using the Taylor series. - sin = unda(x, terms = 10) { - // Initialize the result - fanya n = 0; - fanya result = 0; - - wakati(n < terms) { - // Calculate the numerator and denominator for the nth term - fanya numerator = 0; - kama(n % 2 == 0) { - numerator = x ** (2 * n + 1); - } sivyo { - numerator = -x ** (2 * n + 1); - } - - fanya denominator = @.factorial(2 * n + 1); - - // Add the nth term to the result - result += numerator / denominator; - - n++; + sin = unda(x) { + fanya result = x; // Initialize the result with the angle + fanya term = x; + // Using Maclaurin series expansion for sine + kwa i ktk list(3,101,2) { + term = (-term * x * x) / (i * (i - 1)); + result += term; } - rudisha result; } //sinh(x), calculates the hyperbolic sine of a number. sinh = unda(x) { // sinh(x) = (e^x - e^(-x)) / 2 - fanya eToX = @.exp(x); - fanya eToMinusX = @.exp(-x); + fanya eToX = exp(x); + fanya eToMinusX = exp(-x); rudisha(eToX - eToMinusX) / 2; } @@ -510,16 +443,16 @@ pakeji hisabati{ rudisha 0; } kama(x >= 0) { - rudisha @.root(x, 2); + rudisha root(x, 2); } sivyo { - rudisha - @.root(-x, 2); + rudisha - root(-x, 2); } } //tan(x), calculates the tangent of an angle in radians. tan = unda(x) { - fanya sineX = @.sine(x); - fanya cosineX = @.sqrt(1 - sineX * sineX); + fanya sineX = sin(x); + fanya cosineX = sqrt(1 - sineX * sineX); kama(cosineX == 0) { rudisha 0; @@ -530,15 +463,9 @@ pakeji hisabati{ //tanh(x), calculates the hyperbolic tangent of a number. tanh = unda(x) { - kama(x == Inf) { - rudisha 1; - } au kama(x == -Inf) { - rudisha - 1; - } sivyo { - fanya expX = @.exp(x); - fanya expNegX = @.exp(-x); - rudisha(expX - expNegX) / (expX + expNegX); - } + fanya expX = exp(x); + fanya expNegX = exp(-x); + rudisha(expX - expNegX) / (expX + expNegX); } // utility methods @@ -561,23 +488,23 @@ pakeji hisabati{ //isNegative(num), checks if a number is negative. isNegative = unda(num) { - rudisha num < 0; + rudisha sign(num)==-1; } //isInteger(num), checks if a number is an integer. isInteger = unda(num) { - rudisha num == @.floor(num); + rudisha num == floor(num); } //getIntegerPart(num), gets the integer part of a number. getIntegerPart = unda(num) { // Handle negative numbers separately - kama(@.isNegative(num)) { + kama(isNegative(num)) { // For negative numbers, we subtract the absolute value of the fractional part from 1 - rudisha - (@.ceil(-num) - 1); + rudisha - (ceil(-num) - 1); } sivyo { // For positive numbers, we simply truncate the fractional part - rudisha @.floor(num); + rudisha floor(num); } } diff --git a/third_party/math/test.nr b/third_party/math/test.nr new file mode 100644 index 0000000..29b9895 --- /dev/null +++ b/third_party/math/test.nr @@ -0,0 +1,41 @@ +tumia "hesabu" + +andika("abs: ",hesabu.abs(-42)); +andika("acos: ",hesabu.acos(0.5)); +andika("acosh: ",hesabu.acosh(2)); +andika("asin: ", hesabu.asin(0.5)); +andika("asinh: ",hesabu.asinh(2)); +andika("atan: ",hesabu.atan(1)); +andika("atan2: ",hesabu.atan2(1, 1)); +andika("atanh: ",hesabu.atanh(0.5)); +andika("cbrt: ",hesabu.cbrt(8)); +andika("root: ",hesabu.root(27, 3)); +andika("ceil: ",hesabu.ceil(4.3)); +andika("cos: ",hesabu.cos(5)); +andika("cosh: ",hesabu.cosh(5)); +andika("exp: ",hesabu.exp(2)); +andika("expm1: ",hesabu.expm1(1)); +andika("floor: ",hesabu.floor(4.7)); +andika("hypot: ",hesabu.hypot([3, 4])); +andika("log: ",hesabu.log(2)); +andika("log10: ",hesabu.log10(100)); +andika("log1p: ",hesabu.log1p(1)); +andika("log2: ",hesabu.log2(8)); +andika("max: ",hesabu.max([4, 2, 9, 5])); +andika("min: ",hesabu.min([4, 2, 9, 5])); +andika("round: ",hesabu.round(4.6, "rpi")); +andika("sign: ",hesabu.sign(-5)); +andika("sin: ",hesabu.sin(1)); +andika("sinh: ",hesabu.sinh(0)); +andika("sqrt: ",hesabu.sqrt(4)); +andika("tan: ",hesabu.tan(1)); +andika("tanh: ",hesabu.tanh(0)); +andika("factorial: ",hesabu.factorial(5)); +andika("isNegative: ",hesabu.isNegative(-5)); +andika("isInteger: ",hesabu.isInteger(4.5)); +andika("getIntegerPart: ",hesabu.getIntegerPart(4.5)); +andika("list: ",hesabu.list(1, 5, 1)); +fanya callback = unda(accumulator, currentValue){ + rudisha accumulator + currentValue; +} +andika("reduce: ",hesabu.reduce([1, 2, 3, 4],callback,0) ); From 96f5433a87c2c6f3112e6c1dec4ab3eb6101534a Mon Sep 17 00:00:00 2001 From: "brian.orwe" Date: Wed, 6 Dec 2023 15:01:18 +0300 Subject: [PATCH 47/81] Make Exit(0) use Exit(1) if exiting because of errors --- main.go | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/main.go b/main.go index 7bc900c..d88e762 100644 --- a/main.go +++ b/main.go @@ -38,41 +38,36 @@ func main() { help := styles.HelpStyle.Render("💡 Tumia exit() au toka() kuondoka") fmt.Println(lipgloss.JoinVertical(lipgloss.Left, NewLogo, "\n", help)) repl.Start() - os.Exit(0) + return } if len(args) == 2 { - switch args[1] { case "msaada", "-msaada", "--msaada", "help", "-help", "--help", "-h": fmt.Println(Help) - os.Exit(0) case "version", "-version", "--version", "-v", "v", "--toleo", "-toleo": fmt.Println(NewLogo) - os.Exit(0) case "-docs", "--docs", "-nyaraka", "--nyaraka": repl.Docs() - os.Exit(0) - } + default: + file := args[1] - file := args[1] + if strings.HasSuffix(file, "nr") || strings.HasSuffix(file, ".sw") { + contents, err := os.ReadFile(file) + if err != nil { + fmt.Println(styles.ErrorStyle.Render("Error: Nuru imeshindwa kusoma faili: ", args[1])) + os.Exit(1) + } - if strings.HasSuffix(file, "nr") || strings.HasSuffix(file, ".sw") { - contents, err := os.ReadFile(file) - if err != nil { - fmt.Println(styles.ErrorStyle.Render("Error: Nuru imeshindwa kusoma faili: ", args[1])) - os.Exit(0) + repl.Read(string(contents)) + } else { + fmt.Println(styles.ErrorStyle.Render("'"+file+"'", "sii faili sahihi. Tumia faili la '.nr' au '.sw'")) + os.Exit(1) } - - repl.Read(string(contents)) - } else { - fmt.Println(styles.ErrorStyle.Render("'"+file+"'", "sii faili sahihi. Tumia faili la '.nr' au '.sw'")) - os.Exit(0) } - } else { fmt.Println(styles.ErrorStyle.Render("Error: Operesheni imeshindikana boss.")) fmt.Println(Help) - os.Exit(0) + os.Exit(1) } } From 10f7bb21e7db95695191cdd0e6bcb573ec1bd259 Mon Sep 17 00:00:00 2001 From: Fuad Date: Mon, 8 Jan 2024 22:00:12 +0300 Subject: [PATCH 48/81] minor version fix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0df4787..eec06e6 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=0.5.0-alpha +VERSION=0.5.1 build_linux: @echo 'building linux binary...' From c52bb1dbda7ce7a42072a0faefa6622d16189f07 Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Wed, 31 Jan 2024 16:09:59 +0300 Subject: [PATCH 49/81] hisabati.random perceptron.nr --- examples/perceptron.nr | 141 +++++++++++++++++++++++++++++++++++++++++ module/hisabati.go | 19 +++++- 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 examples/perceptron.nr diff --git a/examples/perceptron.nr b/examples/perceptron.nr new file mode 100644 index 0000000..31bb5f5 --- /dev/null +++ b/examples/perceptron.nr @@ -0,0 +1,141 @@ +tumia hisabati + +// Kuanzisha uzani bila mpangilio +fanya mizani = [ + hisabati.random() * 2 - 1, + hisabati.random() * 2 - 1, + hisabati.random() * 2 - 1 +]; + +// Undo la uanzishaji wa Sigmoid +fanya sigmoid = unda(vekta) { + fanya tokeo = []; + kwa v ktk vekta { + tokeo.sukuma(1 / (1 + hisabati.exp(-1 * v))); + } + rudisha tokeo; +} + +// Derivative ya undo la sigmoid +fanya sigmoidDerivative = unda(vekta) { + fanya tokeo = []; + kwa v ktk vekta { + tokeo.sukuma(v * (1 - v)); + } + + rudisha tokeo; +} + +fanya kuzidishaTumboVekta = unda(tumbo, vekta) { + fanya tokeo = []; + kwa row ktk tumbo { + fanya jamii = 0; + kwa j, kipengee ktk row { + jamii += kipengee * vekta[j]; + } + tokeo.sukuma(jamii); + } + rudisha tokeo; +} + +fanya zidishaKwaNukta = unda(safu1, safu2) { + // Angalia ikiwa safu zina urefu sawa + kama (safu1.idadi() != safu2.idadi()) { + andika("Safu lazima ziwe na urefu sawa kwa kuzidisha kwa busara ya kipengele."); + } + + // Perform element-wise multiplication + fanya tokeo = []; + kwa i, kipengee ktk safu1 { + tokeo.sukuma(kipengee * safu2[i]); + } + rudisha tokeo; +} + +// Songa mbele kupitia mtandao wa neva +fanya waza = unda(pembejeo, mizani) { + fanya jumlaYaUzani = sigmoid(kuzidishaTumboVekta(pembejeo, mizani)); + rudisha jumlaYaUzani; +} + +// Funza mtandao wa neva +fanya funza = unda(mizani, mafunzoPembejeo, matokeoYaMafunzo, marudioYaMafunzo) { + fanya kurudia = 0 + + andika('mafunzoPembejeo: '); + andika(mafunzoPembejeo); + + andika('matokeoYaMafunzo: '); + andika(matokeoYaMafunzo); + + + + wakati (kurudia < marudioYaMafunzo) { + andika('kurudia: '); + andika(kurudia); + // Pitisha mafunzo yaliyowekwa kupitia mtandao wa neva + fanya pato = waza(mafunzoPembejeo, mizani); + + andika('pato: '); + andika(pato); + // Kuhesabu kiwango cha makosa + fanya upungufu = []; + kwa i, kipengee ktk matokeoYaMafunzo { + upungufu.sukuma(kipengee - pato[i]); + } + + fanya sigmoidDerivative = sigmoidDerivative(pato) + + andika('upungufu: '); + andika(upungufu); + + andika('sigmoidDerivative tokeo: '); + andika(sigmoidDerivative); + + fanya zidishaKwaNukta = zidishaKwaNukta(upungufu, sigmoidDerivative); + + andika('zidishaKwaNukta tokeo: '); + andika(zidishaKwaNukta); + + // Kuzidisha makosa kwa pembejeo na upinde rangi ya kitendakazi cha sigmoid + // Uzito mdogo wa ujasiri hurekebishwa zaidi kupitia asili ya kazi + fanya marekebisho = kuzidishaTumboVekta(mafunzoPembejeo, zidishaKwaNukta); + andika('marekebisho tokeo: '); + andika(marekebisho); + + + // Rekebisha uzani + kwa i, j ktk mizani { + mizani[i] = mizani[i] + marekebisho[i]; + } + + andika('mizani mpya: '); + andika(mizani); + kurudia++ + } + rudisha mizani; +} + + + +andika('Mizani ya Kuanzisha isiyo na mpangilio: '); +andika(mizani); + +// Seti ya mafunzo +fanya mafunzoPembejeo = [[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]]; +fanya matokeoYaMafunzo = [0, 1, 1, 0]; + +// Funza mtandao wa neva +fanya mafunzoMizani = funza(mizani, mafunzoPembejeo, matokeoYaMafunzo, 10000); + +andika('Mizani baada ya mafunzo:'); +andika(mafunzoMizani); + +// Ingizo la mtumiaji kwa hali mpya +fanya A = 1; +fanya B = 0; +fanya C = 0; + +andika('Hali mpya: data ya pembejeo = ', A, B, C); +andika('Data ya pato:'); +andika(waza([[A, B, C]], mafunzoMizani)); diff --git a/module/hisabati.go b/module/hisabati.go index 583905d..7323805 100644 --- a/module/hisabati.go +++ b/module/hisabati.go @@ -2,7 +2,8 @@ package module import ( "math" - + "math/rand" + "time" "github.com/AvicennaJr/Nuru/object" ) @@ -28,6 +29,7 @@ var MathFunctions = map[string]object.ModuleFunction{ "cbrt": cbrt, "root": root, "hypot": hypot, + "random": random, "factorial":factorial, "round": round, "max": max, @@ -710,4 +712,19 @@ func atanh(args []object.Object, defs map[string]object.Object) object.Object { } num := args[0].(*object.Float).Value return &object.Float{Value: math.Atanh(num)} +} + +func random(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 { + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} + } + + if len(args) != 0 { + return &object.Error{Message: "Undo hili halipaswi kupokea hoja."} + } + + rand.Seed(time.Now().UnixNano()) + value := rand.Float64() + + return &object.Float{Value: value} } \ No newline at end of file From 7dd07787b9ec337fe3e63c8f6bfcb9e17d537e55 Mon Sep 17 00:00:00 2001 From: Victor kariuki Date: Wed, 31 Jan 2024 20:13:42 +0300 Subject: [PATCH 50/81] * fixed --- examples/perceptron.nr | 105 +++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 29 deletions(-) diff --git a/examples/perceptron.nr b/examples/perceptron.nr index 31bb5f5..bc01b54 100644 --- a/examples/perceptron.nr +++ b/examples/perceptron.nr @@ -1,5 +1,17 @@ tumia hisabati +// Mbinu za Kupanga +//orodhesha(kwanza, mwisho, umbali), huunda orodha ya nambari na umbali uliowekwa kati yao. +fanya orodhesha = unda(kwanza, mwisho, umbali){ + fanya orodha = [kwanza]; + fanya i = kwanza + umbali; + wakati(i < mwisho){ + orodha.sukuma(i); + i += umbali; + } + rudisha orodha; +} + // Kuanzisha uzani bila mpangilio fanya mizani = [ hisabati.random() * 2 - 1, @@ -18,6 +30,7 @@ fanya sigmoid = unda(vekta) { // Derivative ya undo la sigmoid fanya sigmoidDerivative = unda(vekta) { + andika("vekta: ",vekta) fanya tokeo = []; kwa v ktk vekta { tokeo.sukuma(v * (1 - v)); @@ -26,9 +39,9 @@ fanya sigmoidDerivative = unda(vekta) { rudisha tokeo; } -fanya kuzidishaTumboVekta = unda(tumbo, vekta) { +fanya kuzidishaMatrikiVekta = unda(matriki, vekta) { fanya tokeo = []; - kwa row ktk tumbo { + kwa row ktk matriki { fanya jamii = 0; kwa j, kipengee ktk row { jamii += kipengee * vekta[j]; @@ -54,53 +67,87 @@ fanya zidishaKwaNukta = unda(safu1, safu2) { // Songa mbele kupitia mtandao wa neva fanya waza = unda(pembejeo, mizani) { - fanya jumlaYaUzani = sigmoid(kuzidishaTumboVekta(pembejeo, mizani)); + fanya jumlaYaUzani = sigmoid(kuzidishaMatrikiVekta(pembejeo, mizani)); rudisha jumlaYaUzani; } +fanya badiliMatriki = unda(matrix) { + // Pata idadi ya safu mlalo na safu wima katika matrix asili + fanya nambari_ya_safu_mlalo = matrix.idadi(); + fanya nambari_ya_safu_wima = matrix[0].idadi(); + + // Unda matrix mpya na safu mlalo na safu wima zilizobadilishwa + fanya matrikiIliyobadili = []; + + // Pita ndani ya safu wima + kwa safu_wima_ya, safuW ktk orodhesha(0, nambari_ya_safu_wima, 1){ + // Anzisha safu mlalo mpya kwa matriki iliyopitishwa + fanya transposed_safu_mlalo = []; + + // Pita ndani ya safu mlalo + kwa safu_mlalo_ya, safu ktk orodhesha(0, nambari_ya_safu_mlalo, 1){ + // Sukuma kipengele kwenye safu wima ya sasa na safu mlalo hadi safu iliyopitishwa + transposed_safu_mlalo.sukuma(matrix[safu_mlalo_ya][safu_wima_ya]); + } + + // Sukuma safu mlalo iliyopitishwa kwenye matriki lililopitishwa + matrikiIliyobadili.sukuma(transposed_safu_mlalo); + } + + rudisha matrikiIliyobadili; +} + // Funza mtandao wa neva fanya funza = unda(mizani, mafunzoPembejeo, matokeoYaMafunzo, marudioYaMafunzo) { fanya kurudia = 0 - andika('mafunzoPembejeo: '); + andika('\nmafunzoPembejeo: '); andika(mafunzoPembejeo); - andika('matokeoYaMafunzo: '); + andika('\nmatokeoYaMafunzo: '); andika(matokeoYaMafunzo); + fanya orodha = orodhesha(0, marudioYaMafunzo, 1) + // andika("orodha: ",orodha) - wakati (kurudia < marudioYaMafunzo) { - andika('kurudia: '); - andika(kurudia); + kwa i ktk orodha{ + andika('\n\nkurudia: '); + andika(i); // Pitisha mafunzo yaliyowekwa kupitia mtandao wa neva fanya pato = waza(mafunzoPembejeo, mizani); - andika('pato: '); + andika('\npato: '); andika(pato); - // Kuhesabu kiwango cha makosa + + // Kuhesabu kiwango cha upungufu fanya upungufu = []; kwa i, kipengee ktk matokeoYaMafunzo { upungufu.sukuma(kipengee - pato[i]); } - fanya sigmoidDerivative = sigmoidDerivative(pato) - - andika('upungufu: '); + andika('\nupungufu: '); andika(upungufu); - andika('sigmoidDerivative tokeo: '); - andika(sigmoidDerivative); + fanya sigmoidDerivative_ya_pato = sigmoidDerivative(pato) - fanya zidishaKwaNukta = zidishaKwaNukta(upungufu, sigmoidDerivative); + andika('\nsigmoidDerivative tokeo: '); + andika(sigmoidDerivative_ya_pato); - andika('zidishaKwaNukta tokeo: '); - andika(zidishaKwaNukta); + fanya zidishaKwaNukta_tokeo = zidishaKwaNukta(upungufu, sigmoidDerivative_ya_pato); - // Kuzidisha makosa kwa pembejeo na upinde rangi ya kitendakazi cha sigmoid + andika('\nzidishaKwaNukta tokeo: '); + andika(zidishaKwaNukta_tokeo); + + fanya mafunzoPembejeoYaliyobadili = badiliMatriki(mafunzoPembejeo) + + andika('\nmafunzo pembejeo yaliyobadili: '); + andika(mafunzoPembejeoYaliyobadili); + + // Kuzidisha upungufu kwa pembejeo na upinde rangi ya kitendakazi cha sigmoid // Uzito mdogo wa ujasiri hurekebishwa zaidi kupitia asili ya kazi - fanya marekebisho = kuzidishaTumboVekta(mafunzoPembejeo, zidishaKwaNukta); - andika('marekebisho tokeo: '); + fanya marekebisho = kuzidishaMatrikiVekta(mafunzoPembejeo, zidishaKwaNukta_tokeo); + andika('\nmarekebisho tokeo: '); andika(marekebisho); @@ -109,16 +156,16 @@ fanya funza = unda(mizani, mafunzoPembejeo, matokeoYaMafunzo, marudioYaMafunzo) mizani[i] = mizani[i] + marekebisho[i]; } - andika('mizani mpya: '); + andika('\nmizani mpya: '); andika(mizani); kurudia++ } + rudisha mizani; } - -andika('Mizani ya Kuanzisha isiyo na mpangilio: '); +andika('\nMizani ya Kuanzisha isiyo na mpangilio: '); andika(mizani); // Seti ya mafunzo @@ -128,14 +175,14 @@ fanya matokeoYaMafunzo = [0, 1, 1, 0]; // Funza mtandao wa neva fanya mafunzoMizani = funza(mizani, mafunzoPembejeo, matokeoYaMafunzo, 10000); -andika('Mizani baada ya mafunzo:'); +andika('\nMizani baada ya mafunzo:'); andika(mafunzoMizani); // Ingizo la mtumiaji kwa hali mpya -fanya A = 1; +fanya A = 0; fanya B = 0; -fanya C = 0; +fanya C = 1; -andika('Hali mpya: data ya pembejeo = ', A, B, C); -andika('Data ya pato:'); +andika('\nHali mpya: data ya pembejeo = ', A, B, C); +andika('\nData ya pato:'); andika(waza([[A, B, C]], mafunzoMizani)); From db8033a8256d38f139dfe6418627bc44539b4ea4 Mon Sep 17 00:00:00 2001 From: Gekko Wrld Date: Tue, 20 Feb 2024 00:52:32 +0300 Subject: [PATCH 51/81] chore: Add vim syntax highlighting The syntax file is written in the file "nuru.vim". It contains basic syntax highlighting for "nuru". `regex` is used so there is a chance that it will not be perfect. The following are highlighted: - Keywords - Types (most) - Operators (most) - Comments (better but not yet there) Only the definition is done, the actual highlighting (colours) is done by vim itself. A good theme is also a good investment in this case. This syntax highlighting `MAY` not work with neovim. No tests (opening and closing the files) were done. I currently don't have neovim so the burden falls to the future entity. Vim needs to be told of the syntax highlighting to actually work. This can be done through: ```vim au BufRead,BufBewFile *.nr set filetype=nuru ``` When the above line is inserted everything should work as expected. Signed-off-by: Gekko Wrld --- extensions/README.md | 14 +++++++++- extensions/vim/syntax/nuru.vim | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 extensions/vim/syntax/nuru.vim diff --git a/extensions/README.md b/extensions/README.md index b466671..6b8ccb2 100644 --- a/extensions/README.md +++ b/extensions/README.md @@ -2,4 +2,16 @@ ## [VSCODE](./vscode/) -Nuru syntax highlighting on VSCode \ No newline at end of file +Nuru syntax highlighting on VSCode + +## [VIM](./vim) + +The file contained herein has a basic syntax highlight for vim. +The file should be saved in `$HOME/.vim/syntax/nuru.vim`. +You should add the following line to your `.vimrc` or the appropriate location: + +```vim +au BufRead,BufNewFile *.nr set filetype=nuru +``` + +Only basic syntax highlighting is provided by the script. diff --git a/extensions/vim/syntax/nuru.vim b/extensions/vim/syntax/nuru.vim new file mode 100644 index 0000000..a3d60f0 --- /dev/null +++ b/extensions/vim/syntax/nuru.vim @@ -0,0 +1,51 @@ +" Sintaksia ya nuru kwenye programu ya "vim" +" Lugha: Nuru + +" Maneno tengwa +syntax keyword nuruKeyword unda pakeji rudisha vunja endelea tupu +syntax keyword nuruType fanya +syntax keyword nuruBool kweli sikweli +syntax keyword nuruConditional kama sivyo au +syntax match nuruComparision /[!\|<>]/ +syntax keyword nuruLoop ktk while badili +syntax keyword nuruLabel ikiwa kawaida + +" Nambari +syntax match nuruInt '[+-]\d\+' contained display +syntax match nuruFloat '[+-]\d+\.\d*' contained display + +" Viendeshaji +syntax match nuruAssignment '=' +syntax match nuruLogicalOP /[\&!|]/ + +" Vitendakazi +syntax keyword nuruFunction andika aina jaza fungua + +" Tungo +syntax region nuruString start=/"/ skip=/\\"/ end=/"/ +syntax region nuruString start=/'/ skip=/\\'/ end=/'/ + +" Maoni +syntax match nuruComment "//.*" +syntax region nuruComment start="/\*" end="\*/" + +" Fafanua sintaksia +let b:current_syntax = "nuru" + +highlight def link nuruComment Comment +highlight def link nuruBool Boolean +highlight def link nuruFunction Function +highlight def link nuruComparision Conditional +highlight def link nuruConditional Conditional +highlight def link nuruKeyword Keyword +highlight def link nuruString String +highlight def link nuruVariable Identifier +highlight def link nuruLoop Repeat +highlight def link nuruInt Number +highlight def link nuruFloat Float +highlight def link nuruAssignment Operator +highlight def link nuruLogicalOP Operator +highlight def link nuruAriOP Operator +highlight def link nuruType Type +highlight def link nuruLabel Label + From 226d721b728d6d2d34637685847b4ad992abce9e Mon Sep 17 00:00:00 2001 From: Gekko Wrld Date: Thu, 21 Mar 2024 15:20:21 +0300 Subject: [PATCH 52/81] fix: Handle `nil` dereference in expressions The code will fail if the second arg is `nil` then the code will fail with a panic. Fixes: https://github.com/NuruProgramming/Nuru/issues/79 Before only the left arg was checked for `nil` but not the right arg. Signed-off-by: Gekko Wrld --- evaluator/evaluator.go | 2 +- evaluator/infix.go | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go index 758f4dd..313ed4a 100644 --- a/evaluator/evaluator.go +++ b/evaluator/evaluator.go @@ -45,7 +45,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object { return left } right := Eval(node.Right, env) - if isError(right) { + if isError(right) && right != nil { return right } return evalInfixExpression(node.Operator, left, right, node.Token.Line) diff --git a/evaluator/infix.go b/evaluator/infix.go index f25ef9d..d11d867 100644 --- a/evaluator/infix.go +++ b/evaluator/infix.go @@ -8,6 +8,9 @@ import ( ) func evalInfixExpression(operator string, left, right object.Object, line int) object.Object { + if right == nil { + return newError("Mstari %d: Umekosea hapa", line) + } if left == nil { return newError("Mstari %d: Umekosea hapa", line) } From 19b1015568c96f2e231be7daccadc81912d3b11b Mon Sep 17 00:00:00 2001 From: Masterplan <76619967+isaka-james@users.noreply.github.com> Date: Wed, 5 Jun 2024 14:22:26 +0300 Subject: [PATCH 53/81] docs: Improve Android (Termux) installation instructions in README - Added step-by-step instructions for creating the target directory. - Included commands to download and extract the Nuru package. - Provided steps to set up an alias and reload .bashrc. - Added a one-liner command for streamlined installation. --- README.md | 54 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index fd83cc4..c0437fa 100644 --- a/README.md +++ b/README.md @@ -72,29 +72,51 @@ nuru -v ``` + + ### Android (Termux) - - Make sure you have [Termux](https://f-droid.org/repo/com.termux_118.apk) installed. - - Download the binary with this command: +To install Nuru on your Android device using Termux, follow these steps: -``` -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz -``` - - Extract the file: +1. **Ensure Termux is installed**: + - You can download and install [Termux](https://f-droid.org/en/packages/com.termux/). -``` -tar -xzvf nuru_Android_arm64.tar.gz -``` - - Add it to path: +2. **Create the target directory**: + ```bash + mkdir -p /data/data/com.termux/files/usr/share/nuru + ``` -``` -echo "alias nuru='~/nuru'" >> .bashrc -``` - - Confirm installation with: +3. **Download the Nuru package**: + ```bash + curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz + ``` +4. **Extract the files to the target directory**: + ```bash + tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru + ``` + +5. **Set up an alias for easy access**: + ```bash + echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc + ``` + +6. **Reload the .bashrc file to apply the alias**: + ```bash + source ~/.bashrc + ``` + +7. **Verify the installation**: + ```bash + nuru -v + ``` + +For a more streamlined installation, you can use the following one-liner: + +```bash +curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." ``` -nuru -v -``` + ### Windows From 72c4eb4b94e0a2e80518a25bcd6e2494e0b2732a Mon Sep 17 00:00:00 2001 From: Lugano Abel Date: Wed, 5 Jun 2024 14:56:18 +0300 Subject: [PATCH 54/81] update termux installation guide --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c0437fa..a01a4af 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ To install Nuru on your Android device using Termux, follow these steps: 3. **Download the Nuru package**: ```bash - curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz ``` 4. **Extract the files to the target directory**: From 31cbcf35599e5a7efa94a308d12f83fb627f4c47 Mon Sep 17 00:00:00 2001 From: Fuad Date: Sun, 9 Jun 2024 15:12:37 +0300 Subject: [PATCH 55/81] use NuruProgramming packages --- README.md | 26 ++++----- ast/ast.go | 4 +- ast/ast_test.go | 2 +- evaluator/assign.go | 4 +- evaluator/assignEqual.go | 4 +- evaluator/at.go | 4 +- evaluator/bang.go | 4 +- evaluator/block.go | 4 +- evaluator/builtins.go | 2 +- evaluator/call.go | 4 +- evaluator/dict.go | 6 +- evaluator/evaluator.go | 6 +- evaluator/evaluator_test.go | 6 +- evaluator/forin.go | 6 +- evaluator/function.go | 4 +- evaluator/identifier.go | 6 +- evaluator/if.go | 6 +- evaluator/import.go | 13 ++--- evaluator/in.go | 2 +- evaluator/index.go | 4 +- evaluator/infix.go | 4 +- evaluator/method.go | 4 +- evaluator/package.go | 4 +- evaluator/postfix.go | 6 +- evaluator/prefix.go | 2 +- evaluator/property.go | 4 +- evaluator/switch.go | 6 +- evaluator/while.go | 4 +- extensions/vscode/README.md | 4 +- go.mod | 2 +- lexer/lexer.go | 2 +- lexer/lexer_test.go | 2 +- main.go | 4 +- module/hisabati.go | 109 ++++++++++++++++++------------------ module/json.go | 2 +- module/module.go | 2 +- module/net.go | 2 +- module/os.go | 2 +- module/time.go | 2 +- object/function.go | 2 +- object/package.go | 2 +- parser/arrays.go | 4 +- parser/assignEqual.go | 2 +- parser/assignment.go | 3 +- parser/at.go | 2 +- parser/boolean.go | 4 +- parser/break.go | 4 +- parser/continue.go | 4 +- parser/dict.go | 4 +- parser/dot.go | 4 +- parser/float.go | 2 +- parser/for.go | 4 +- parser/function.go | 4 +- parser/identifier.go | 2 +- parser/if.go | 4 +- parser/import.go | 4 +- parser/index.go | 4 +- parser/integer.go | 2 +- parser/null.go | 2 +- parser/package.go | 4 +- parser/parser.go | 8 +-- parser/parser_test.go | 4 +- parser/statements.go | 5 +- parser/string.go | 2 +- parser/switch.go | 4 +- parser/while.go | 4 +- repl/docs.go | 10 ++-- repl/repl.go | 10 ++-- 68 files changed, 197 insertions(+), 201 deletions(-) diff --git a/README.md b/README.md index a01a4af..062d6f7 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@

NURU🔥PROGRAMMING🔥LANGUAGE

- Nuru Programming Language - Nuru Programming Language - Nuru Programming Language + Nuru Programming Language + Nuru Programming Language + Nuru Programming Language
- Nuru Programming Language - Nuru Programming Language - Nuru Programming Language + Nuru Programming Language + Nuru Programming Language + Nuru Programming Language
- Nuru Programming Language + Nuru Programming Language

A Swahili Programming Language of its kind built from the ground up. @@ -21,7 +21,7 @@ To get started download the executables from the release page or follow the inst - Download the binary: ``` -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Linux_amd64.tar.gz +curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Linux_amd64.tar.gz ``` - Extract the file to make global available: @@ -44,13 +44,13 @@ nuru -v - For apple silicon mac use: ``` - curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Darwin_arm64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Darwin_arm64.tar.gz ``` - For apple intel mac use: ``` - curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Darwin_amd64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Darwin_amd64.tar.gz ``` - Extract the file to make global available: @@ -114,14 +114,14 @@ To install Nuru on your Android device using Termux, follow these steps: For a more streamlined installation, you can use the following one-liner: ```bash -curl -O -L https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." +curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." ``` ### Windows - Executable: - - Download the Nuru zip file [Here](https://github.com/AvicennaJr/Nuru/releases/download/v0.5.16/nuru_Windows_amd64.zip) + - Download the Nuru zip file [Here](https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Windows_amd64.zip) - Unzip to get the executable - Double click the executable @@ -370,7 +370,7 @@ nuru myFile.nr ## Issues -Kindly open an [Issue](https://github.com/AvicennaJr/Nuru/issues) to make suggestions and anything else. +Kindly open an [Issue](https://github.com/NuruProgramming/Nuru/issues) to make suggestions and anything else. ## Contributions diff --git a/ast/ast.go b/ast/ast.go index bc15253..c42241f 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -4,12 +4,12 @@ import ( "bytes" "strings" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/token" ) type Node interface { TokenLiteral() string - String() string // to help debug the many errors lmao + String() string } type Statement interface { diff --git a/ast/ast_test.go b/ast/ast_test.go index c5ae5fa..f9eba0d 100644 --- a/ast/ast_test.go +++ b/ast/ast_test.go @@ -3,7 +3,7 @@ package ast import ( "testing" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/token" ) func TestString(t *testing.T) { diff --git a/evaluator/assign.go b/evaluator/assign.go index b78d931..f867321 100644 --- a/evaluator/assign.go +++ b/evaluator/assign.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalAssign(node *ast.Assign, env *object.Environment) object.Object { diff --git a/evaluator/assignEqual.go b/evaluator/assignEqual.go index 551ecd9..6ec2bf2 100644 --- a/evaluator/assignEqual.go +++ b/evaluator/assignEqual.go @@ -3,8 +3,8 @@ package evaluator import ( "strings" - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalAssignEqual(node *ast.AssignEqual, env *object.Environment) object.Object { diff --git a/evaluator/at.go b/evaluator/at.go index f1b5558..6cdb35f 100644 --- a/evaluator/at.go +++ b/evaluator/at.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalAt(node *ast.At, env *object.Environment) object.Object { diff --git a/evaluator/bang.go b/evaluator/bang.go index de9b340..ee7d6fb 100644 --- a/evaluator/bang.go +++ b/evaluator/bang.go @@ -1,6 +1,6 @@ package evaluator -import "github.com/AvicennaJr/Nuru/object" +import "github.com/NuruProgramming/Nuru/object" func evalBangOperatorExpression(right object.Object) object.Object { switch right { @@ -13,4 +13,4 @@ func evalBangOperatorExpression(right object.Object) object.Object { default: return FALSE } -} \ No newline at end of file +} diff --git a/evaluator/block.go b/evaluator/block.go index ba1286a..3e27ef5 100644 --- a/evaluator/block.go +++ b/evaluator/block.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalBlockStatement(block *ast.BlockStatement, env *object.Environment) object.Object { diff --git a/evaluator/builtins.go b/evaluator/builtins.go index 0cc4dfd..7b51767 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -7,7 +7,7 @@ import ( "os" "strings" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/object" ) var builtins = map[string]*object.Builtin{ diff --git a/evaluator/call.go b/evaluator/call.go index 4b75811..b936afe 100644 --- a/evaluator/call.go +++ b/evaluator/call.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalCall(node *ast.CallExpression, env *object.Environment) object.Object { diff --git a/evaluator/dict.go b/evaluator/dict.go index 05bbdcb..2d417ca 100644 --- a/evaluator/dict.go +++ b/evaluator/dict.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalDictLiteral(node *ast.DictLiteral, env *object.Environment) object.Object { @@ -29,4 +29,4 @@ func evalDictLiteral(node *ast.DictLiteral, env *object.Environment) object.Obje } return &object.Dict{Pairs: pairs} -} \ No newline at end of file +} diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go index 313ed4a..5fd219d 100644 --- a/evaluator/evaluator.go +++ b/evaluator/evaluator.go @@ -3,8 +3,8 @@ package evaluator import ( "fmt" - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) var ( @@ -134,7 +134,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object { return val } return evalPropertyAssignment(node.Name, val, env) - case *ast.Assign: // making let temporarily optional as I debug + case *ast.Assign: return evalAssign(node, env) case *ast.AssignEqual: return evalAssignEqual(node, env) diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index 452f552..b6e830d 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/AvicennaJr/Nuru/lexer" - "github.com/AvicennaJr/Nuru/object" - "github.com/AvicennaJr/Nuru/parser" + "github.com/NuruProgramming/Nuru/lexer" + "github.com/NuruProgramming/Nuru/object" + "github.com/NuruProgramming/Nuru/parser" ) func TestEvalIntegerExpression(t *testing.T) { diff --git a/evaluator/forin.go b/evaluator/forin.go index 28db0f5..f5db434 100644 --- a/evaluator/forin.go +++ b/evaluator/forin.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalForInExpression(fie *ast.ForIn, env *object.Environment, line int) object.Object { @@ -26,4 +26,4 @@ func evalForInExpression(fie *ast.ForIn, env *object.Environment, line int) obje default: return newError("Mstari %d: Huwezi kufanya operesheni hii na %s", line, i.Type()) } -} \ No newline at end of file +} diff --git a/evaluator/function.go b/evaluator/function.go index aa413d5..9e9605d 100644 --- a/evaluator/function.go +++ b/evaluator/function.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalFunction(node *ast.FunctionLiteral, env *object.Environment) object.Object { diff --git a/evaluator/identifier.go b/evaluator/identifier.go index 7745a23..49f8272 100644 --- a/evaluator/identifier.go +++ b/evaluator/identifier.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalIdentifier(node *ast.Identifier, env *object.Environment) object.Object { @@ -14,4 +14,4 @@ func evalIdentifier(node *ast.Identifier, env *object.Environment) object.Object } return newError("Mstari %d: Neno Halifahamiki: %s", node.Token.Line, node.Value) -} \ No newline at end of file +} diff --git a/evaluator/if.go b/evaluator/if.go index 890f24f..8a11e81 100644 --- a/evaluator/if.go +++ b/evaluator/if.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalIfExpression(ie *ast.IfExpression, env *object.Environment) object.Object { @@ -19,4 +19,4 @@ func evalIfExpression(ie *ast.IfExpression, env *object.Environment) object.Obje } else { return NULL } -} \ No newline at end of file +} diff --git a/evaluator/import.go b/evaluator/import.go index 130f20c..8b5eb23 100644 --- a/evaluator/import.go +++ b/evaluator/import.go @@ -2,16 +2,15 @@ package evaluator import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/lexer" - "github.com/AvicennaJr/Nuru/module" - "github.com/AvicennaJr/Nuru/object" - "github.com/AvicennaJr/Nuru/parser" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/lexer" + "github.com/NuruProgramming/Nuru/module" + "github.com/NuruProgramming/Nuru/object" + "github.com/NuruProgramming/Nuru/parser" ) var searchPaths []string @@ -62,7 +61,7 @@ func fileExists(file string) bool { } func evaluateFile(file string, env *object.Environment) (*object.Environment, object.Object) { - source, err := ioutil.ReadFile(file) + source, err := os.ReadFile(file) if err != nil { return nil, &object.Error{Message: fmt.Sprintf("Tumeshindwa kufungua pakeji: %s", file)} } diff --git a/evaluator/in.go b/evaluator/in.go index 446b35c..22bec49 100644 --- a/evaluator/in.go +++ b/evaluator/in.go @@ -3,7 +3,7 @@ package evaluator import ( "strings" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/object" ) func evalInExpression(left, right object.Object, line int) object.Object { diff --git a/evaluator/index.go b/evaluator/index.go index e5a182f..ee59c97 100644 --- a/evaluator/index.go +++ b/evaluator/index.go @@ -1,6 +1,6 @@ package evaluator -import "github.com/AvicennaJr/Nuru/object" +import "github.com/NuruProgramming/Nuru/object" func evalIndexExpression(left, index object.Object, line int) object.Object { switch { @@ -41,4 +41,4 @@ func evalDictIndexExpression(dict, index object.Object, line int) object.Object } return pair.Value -} \ No newline at end of file +} diff --git a/evaluator/infix.go b/evaluator/infix.go index d11d867..2e51052 100644 --- a/evaluator/infix.go +++ b/evaluator/infix.go @@ -4,13 +4,13 @@ import ( "math" "strings" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/object" ) func evalInfixExpression(operator string, left, right object.Object, line int) object.Object { if right == nil { return newError("Mstari %d: Umekosea hapa", line) - } + } if left == nil { return newError("Mstari %d: Umekosea hapa", line) } diff --git a/evaluator/method.go b/evaluator/method.go index 5109f9d..2bf2bd6 100644 --- a/evaluator/method.go +++ b/evaluator/method.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalMethodExpression(node *ast.MethodExpression, env *object.Environment) object.Object { diff --git a/evaluator/package.go b/evaluator/package.go index e7cc020..07e9bee 100644 --- a/evaluator/package.go +++ b/evaluator/package.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalPackage(node *ast.Package, env *object.Environment) object.Object { diff --git a/evaluator/postfix.go b/evaluator/postfix.go index ea90a88..14763d5 100644 --- a/evaluator/postfix.go +++ b/evaluator/postfix.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalPostfixExpression(env *object.Environment, operator string, node *ast.PostfixExpression) object.Object { @@ -37,4 +37,4 @@ func evalPostfixExpression(env *object.Environment, operator string, node *ast.P default: return newError("Haifahamiki: %s", operator) } -} \ No newline at end of file +} diff --git a/evaluator/prefix.go b/evaluator/prefix.go index 3038006..f46ca91 100644 --- a/evaluator/prefix.go +++ b/evaluator/prefix.go @@ -1,6 +1,6 @@ package evaluator -import "github.com/AvicennaJr/Nuru/object" +import "github.com/NuruProgramming/Nuru/object" func evalMinusPrefixOperatorExpression(right object.Object, line int) object.Object { switch obj := right.(type) { diff --git a/evaluator/property.go b/evaluator/property.go index 13ea8be..c935c4f 100644 --- a/evaluator/property.go +++ b/evaluator/property.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalPropertyExpression(node *ast.PropertyExpression, env *object.Environment) object.Object { diff --git a/evaluator/switch.go b/evaluator/switch.go index 53fe6f4..5963d6d 100644 --- a/evaluator/switch.go +++ b/evaluator/switch.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalSwitchStatement(se *ast.SwitchExpression, env *object.Environment) object.Object { @@ -27,4 +27,4 @@ func evalSwitchStatement(se *ast.SwitchExpression, env *object.Environment) obje } } return nil -} \ No newline at end of file +} diff --git a/evaluator/while.go b/evaluator/while.go index ffe76d3..89a3a3b 100644 --- a/evaluator/while.go +++ b/evaluator/while.go @@ -1,8 +1,8 @@ package evaluator import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/object" ) func evalWhileExpression(we *ast.WhileExpression, env *object.Environment) object.Object { diff --git a/extensions/vscode/README.md b/extensions/vscode/README.md index 7896dd8..c0c1c79 100644 --- a/extensions/vscode/README.md +++ b/extensions/vscode/README.md @@ -15,10 +15,10 @@ This is a syntax highliting extension for Nuru on vscode. It detects `.nr` and ` ### Windows -- Copy the whole [nuru folder](https://github.com/AvicennaJr/Nuru/tree/main/extensions/vscode/nuru) and paste it in the VSCode extensions directory found in `%USERPROFILE%\.vscode\extensions` +- Copy the whole [nuru folder](https://github.com/NuruProgramming/Nuru/tree/main/extensions/vscode/nuru) and paste it in the VSCode extensions directory found in `%USERPROFILE%\.vscode\extensions` - Restart VSCode ### Linux and MacOS -- Copy the whole [nuru folder](https://github.com/AvicennaJr/Nuru/tree/main/extensions/vscode/nuru) and paste it in the VSCode extensions directory found in `~/.vscode/extensions` +- Copy the whole [nuru folder](https://github.com/NuruProgramming/Nuru/tree/main/extensions/vscode/nuru) and paste it in the VSCode extensions directory found in `~/.vscode/extensions` - Restart VSCode diff --git a/go.mod b/go.mod index c4ce957..1ea346a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/AvicennaJr/Nuru +module github.com/NuruProgramming/Nuru go 1.18 diff --git a/lexer/lexer.go b/lexer/lexer.go index 73d4094..b191794 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -3,7 +3,7 @@ package lexer import ( - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/token" ) type Lexer struct { diff --git a/lexer/lexer_test.go b/lexer/lexer_test.go index 8743b2f..a9252bd 100644 --- a/lexer/lexer_test.go +++ b/lexer/lexer_test.go @@ -3,7 +3,7 @@ package lexer import ( "testing" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/token" ) func TestNextToken(t *testing.T) { diff --git a/main.go b/main.go index d88e762..2a0e4e8 100644 --- a/main.go +++ b/main.go @@ -5,8 +5,8 @@ import ( "os" "strings" - "github.com/AvicennaJr/Nuru/repl" - "github.com/AvicennaJr/Nuru/styles" + "github.com/NuruProgramming/Nuru/repl" + "github.com/NuruProgramming/Nuru/styles" "github.com/charmbracelet/lipgloss" ) diff --git a/module/hisabati.go b/module/hisabati.go index 7323805..c1d84f1 100644 --- a/module/hisabati.go +++ b/module/hisabati.go @@ -4,54 +4,55 @@ import ( "math" "math/rand" "time" - "github.com/AvicennaJr/Nuru/object" + + "github.com/NuruProgramming/Nuru/object" ) var MathFunctions = map[string]object.ModuleFunction{ - "PI": pi, - "e": e, - "phi": phi, - "ln10": ln10, - "ln2": ln2, - "log10e": log10e, - "log2e": log2e, - "log2": log2, - "sqrt1_2": sqrt1_2, - "sqrt2": sqrt2, - "sqrt3": sqrt3, - "sqrt5": sqrt5, - "EPSILON": epsilon, - "abs": abs, + "PI": pi, + "e": e, + "phi": phi, + "ln10": ln10, + "ln2": ln2, + "log10e": log10e, + "log2e": log2e, + "log2": log2, + "sqrt1_2": sqrt1_2, + "sqrt2": sqrt2, + "sqrt3": sqrt3, + "sqrt5": sqrt5, + "EPSILON": epsilon, + "abs": abs, "sign": sign, - "ceil": ceil, - "floor": floor, - "sqrt": sqrt, - "cbrt": cbrt, - "root": root, - "hypot": hypot, - "random": random, - "factorial":factorial, - "round": round, - "max": max, - "min": min, - "exp": exp, - "expm1": expm1, - "log": log, - "log10": log10, - "log1p": log1p, - "cos": cos, - "sin": sin, - "tan": tan, - "acos": acos, - "asin": asin, - "atan": atan, - "cosh": cosh, - "sinh": sinh, - "tanh": tanh, - "acosh": acosh, - "asinh": asinh, - "atanh": atanh, - "atan2": atan2, + "ceil": ceil, + "floor": floor, + "sqrt": sqrt, + "cbrt": cbrt, + "root": root, + "hypot": hypot, + "random": random, + "factorial": factorial, + "round": round, + "max": max, + "min": min, + "exp": exp, + "expm1": expm1, + "log": log, + "log10": log10, + "log1p": log1p, + "cos": cos, + "sin": sin, + "tan": tan, + "acos": acos, + "asin": asin, + "atan": atan, + "cosh": cosh, + "sinh": sinh, + "tanh": tanh, + "acosh": acosh, + "asinh": asinh, + "atanh": atanh, + "atan2": atan2, } var Constants = map[string]object.Object{ @@ -715,16 +716,16 @@ func atanh(args []object.Object, defs map[string]object.Object) object.Object { } func random(args []object.Object, defs map[string]object.Object) object.Object { - if len(defs) != 0 { - return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} - } + if len(defs) != 0 { + return &object.Error{Message: "Undo hili haliruhusu ufafanuzi."} + } - if len(args) != 0 { - return &object.Error{Message: "Undo hili halipaswi kupokea hoja."} - } + if len(args) != 0 { + return &object.Error{Message: "Undo hili halipaswi kupokea hoja."} + } - rand.Seed(time.Now().UnixNano()) - value := rand.Float64() + rand.Seed(time.Now().UnixNano()) + value := rand.Float64() - return &object.Float{Value: value} -} \ No newline at end of file + return &object.Float{Value: value} +} diff --git a/module/json.go b/module/json.go index 582359e..51a133f 100644 --- a/module/json.go +++ b/module/json.go @@ -3,7 +3,7 @@ package module import ( "encoding/json" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/object" ) var JsonFunctions = map[string]object.ModuleFunction{} diff --git a/module/module.go b/module/module.go index a82862a..f4c17c7 100644 --- a/module/module.go +++ b/module/module.go @@ -1,6 +1,6 @@ package module -import "github.com/AvicennaJr/Nuru/object" +import "github.com/NuruProgramming/Nuru/object" var Mapper = map[string]*object.Module{} diff --git a/module/net.go b/module/net.go index b8edb14..421d67b 100644 --- a/module/net.go +++ b/module/net.go @@ -6,7 +6,7 @@ import ( "io/ioutil" "net/http" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/object" ) var NetFunctions = map[string]object.ModuleFunction{} diff --git a/module/os.go b/module/os.go index 5397d6c..53194f4 100644 --- a/module/os.go +++ b/module/os.go @@ -5,7 +5,7 @@ import ( "os/exec" "strings" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/object" ) var OsFunctions = map[string]object.ModuleFunction{} diff --git a/module/time.go b/module/time.go index 69789f6..d1fbd0d 100644 --- a/module/time.go +++ b/module/time.go @@ -5,7 +5,7 @@ import ( "strconv" "time" - "github.com/AvicennaJr/Nuru/object" + "github.com/NuruProgramming/Nuru/object" ) var TimeFunctions = map[string]object.ModuleFunction{} diff --git a/object/function.go b/object/function.go index 444101b..f7ad6b8 100644 --- a/object/function.go +++ b/object/function.go @@ -4,7 +4,7 @@ import ( "bytes" "strings" - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) type Function struct { diff --git a/object/package.go b/object/package.go index 235d02c..3b104b5 100644 --- a/object/package.go +++ b/object/package.go @@ -3,7 +3,7 @@ package object import ( "fmt" - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) type Package struct { diff --git a/parser/arrays.go b/parser/arrays.go index 119a903..dca541d 100644 --- a/parser/arrays.go +++ b/parser/arrays.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseArrayLiteral() ast.Expression { diff --git a/parser/assignEqual.go b/parser/assignEqual.go index ed560be..82d2346 100644 --- a/parser/assignEqual.go +++ b/parser/assignEqual.go @@ -3,7 +3,7 @@ package parser import ( "fmt" - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) func (p *Parser) parseAssignEqualExpression(exp ast.Expression) ast.Expression { diff --git a/parser/assignment.go b/parser/assignment.go index b905329..2a4216c 100644 --- a/parser/assignment.go +++ b/parser/assignment.go @@ -3,12 +3,11 @@ package parser import ( "fmt" - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) func (p *Parser) parseAssignmentExpression(exp ast.Expression) ast.Expression { switch node := exp.(type) { - // temporarily making let keyword optional case *ast.Identifier: e := &ast.Assign{ Token: p.curToken, diff --git a/parser/at.go b/parser/at.go index 65587f3..7d0c6ad 100644 --- a/parser/at.go +++ b/parser/at.go @@ -1,6 +1,6 @@ package parser -import "github.com/AvicennaJr/Nuru/ast" +import "github.com/NuruProgramming/Nuru/ast" func (p *Parser) parseAt() ast.Expression { return &ast.At{Token: p.curToken} diff --git a/parser/boolean.go b/parser/boolean.go index 9ce95e6..0d3c125 100644 --- a/parser/boolean.go +++ b/parser/boolean.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseBoolean() ast.Expression { diff --git a/parser/break.go b/parser/break.go index 6c4c8ef..0bdc4a7 100644 --- a/parser/break.go +++ b/parser/break.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseBreak() *ast.Break { diff --git a/parser/continue.go b/parser/continue.go index a66b85f..09b6e52 100644 --- a/parser/continue.go +++ b/parser/continue.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseContinue() *ast.Continue { diff --git a/parser/dict.go b/parser/dict.go index 4b3b205..450e72a 100644 --- a/parser/dict.go +++ b/parser/dict.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseDictLiteral() ast.Expression { diff --git a/parser/dot.go b/parser/dot.go index 0503d93..b46882f 100644 --- a/parser/dot.go +++ b/parser/dot.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseMethod(obj ast.Expression) ast.Expression { diff --git a/parser/float.go b/parser/float.go index 77f6075..7544c21 100644 --- a/parser/float.go +++ b/parser/float.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) func (p *Parser) parseFloatLiteral() ast.Expression { diff --git a/parser/for.go b/parser/for.go index 7e36038..4548b7a 100644 --- a/parser/for.go +++ b/parser/for.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseForExpression() ast.Expression { diff --git a/parser/function.go b/parser/function.go index 50d604e..d1f710a 100644 --- a/parser/function.go +++ b/parser/function.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseFunctionLiteral() ast.Expression { diff --git a/parser/identifier.go b/parser/identifier.go index d9d5b7e..327993b 100644 --- a/parser/identifier.go +++ b/parser/identifier.go @@ -1,7 +1,7 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) func (p *Parser) parseIdentifier() ast.Expression { diff --git a/parser/if.go b/parser/if.go index b3eccc6..fff01ed 100644 --- a/parser/if.go +++ b/parser/if.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseIfExpression() ast.Expression { diff --git a/parser/import.go b/parser/import.go index 2a8027b..c2f75f7 100644 --- a/parser/import.go +++ b/parser/import.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseImport() ast.Expression { diff --git a/parser/index.go b/parser/index.go index 9104bc6..6e3cab7 100644 --- a/parser/index.go +++ b/parser/index.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseIndexExpression(left ast.Expression) ast.Expression { diff --git a/parser/integer.go b/parser/integer.go index c35bcd2..46d648a 100644 --- a/parser/integer.go +++ b/parser/integer.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) func (p *Parser) parseIntegerLiteral() ast.Expression { diff --git a/parser/null.go b/parser/null.go index 2f4c869..1cf11b5 100644 --- a/parser/null.go +++ b/parser/null.go @@ -1,7 +1,7 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) func (p *Parser) parseNull() ast.Expression { diff --git a/parser/package.go b/parser/package.go index 7d3c6a0..7e5a6c6 100644 --- a/parser/package.go +++ b/parser/package.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parsePackage() ast.Expression { diff --git a/parser/parser.go b/parser/parser.go index d5365ed..0bcf5f8 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -3,13 +3,12 @@ package parser import ( "fmt" - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/lexer" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/lexer" + "github.com/NuruProgramming/Nuru/token" ) const ( - // Think of BODMAS _ int = iota LOWEST ASSIGN // = @@ -89,7 +88,6 @@ func (p *Parser) registerPostfix(tokenType token.TokenType, fn postfixParseFn) { func New(l *lexer.Lexer) *Parser { p := &Parser{l: l, errors: []string{}} - // Gotta set these niggas p.nextToken() p.nextToken() diff --git a/parser/parser_test.go b/parser/parser_test.go index 91e00ee..50e880e 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/lexer" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/lexer" ) func TestLetStatements(t *testing.T) { diff --git a/parser/statements.go b/parser/statements.go index 8718130..7e07f23 100644 --- a/parser/statements.go +++ b/parser/statements.go @@ -3,12 +3,11 @@ package parser import ( "fmt" - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseStatement() ast.Statement { - // Remember to add switch statements to the language switch p.curToken.Type { case token.LET: return p.parseLetStatement() diff --git a/parser/string.go b/parser/string.go index cfd90f2..8a023fa 100644 --- a/parser/string.go +++ b/parser/string.go @@ -1,7 +1,7 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" + "github.com/NuruProgramming/Nuru/ast" ) func (p *Parser) parseStringLiteral() ast.Expression { diff --git a/parser/switch.go b/parser/switch.go index 88ce460..ebffc63 100644 --- a/parser/switch.go +++ b/parser/switch.go @@ -3,8 +3,8 @@ package parser import ( "fmt" - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseSwitchStatement() ast.Expression { diff --git a/parser/while.go b/parser/while.go index 3ae92fc..1d7a202 100644 --- a/parser/while.go +++ b/parser/while.go @@ -1,8 +1,8 @@ package parser import ( - "github.com/AvicennaJr/Nuru/ast" - "github.com/AvicennaJr/Nuru/token" + "github.com/NuruProgramming/Nuru/ast" + "github.com/NuruProgramming/Nuru/token" ) func (p *Parser) parseWhileExpression() ast.Expression { diff --git a/repl/docs.go b/repl/docs.go index 17969ab..b8fd428 100644 --- a/repl/docs.go +++ b/repl/docs.go @@ -4,11 +4,11 @@ import ( "fmt" "strings" - "github.com/AvicennaJr/Nuru/evaluator" - "github.com/AvicennaJr/Nuru/lexer" - "github.com/AvicennaJr/Nuru/object" - "github.com/AvicennaJr/Nuru/parser" - "github.com/AvicennaJr/Nuru/styles" + "github.com/NuruProgramming/Nuru/evaluator" + "github.com/NuruProgramming/Nuru/lexer" + "github.com/NuruProgramming/Nuru/object" + "github.com/NuruProgramming/Nuru/parser" + "github.com/NuruProgramming/Nuru/styles" "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" "github.com/charmbracelet/bubbles/textarea" diff --git a/repl/repl.go b/repl/repl.go index 3af10ed..9646b45 100644 --- a/repl/repl.go +++ b/repl/repl.go @@ -8,11 +8,11 @@ import ( "strings" prompt "github.com/AvicennaJr/GoPrompt" - "github.com/AvicennaJr/Nuru/evaluator" - "github.com/AvicennaJr/Nuru/lexer" - "github.com/AvicennaJr/Nuru/object" - "github.com/AvicennaJr/Nuru/parser" - "github.com/AvicennaJr/Nuru/styles" + "github.com/NuruProgramming/Nuru/evaluator" + "github.com/NuruProgramming/Nuru/lexer" + "github.com/NuruProgramming/Nuru/object" + "github.com/NuruProgramming/Nuru/parser" + "github.com/NuruProgramming/Nuru/styles" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" From 4d10d74696b028b2e6d6e5a7bea9066b663fe6f1 Mon Sep 17 00:00:00 2001 From: Fuad Date: Sat, 5 Oct 2024 09:49:12 +0300 Subject: [PATCH 56/81] remove error face --- repl/repl.go | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/repl/repl.go b/repl/repl.go index 9646b45..6bb0aeb 100644 --- a/repl/repl.go +++ b/repl/repl.go @@ -20,31 +20,6 @@ import ( ) const PROMPT = ">>> " -const ERROR_FACE = ` - ███████████████████████████ - ███████▀▀▀░░░░░░░▀▀▀███████ - ████▀░░░░░░░░░░░░░░░░░▀████ - ███│░░░░░░░░░░░░░░░░░░░│███ - ██▌│░░░░░░░░░░░░░░░░░░░│▐██ - ██░└┐░░░░░░░░░░░░░░░░░┌┘░██ - ██░░└┐░░░░░░░░░░░░░░░┌┘░░██ - ██░░┌┘▄▄▄▄▄░░░░░▄▄▄▄▄└┐░░██ - ██▌░│██████▌░░░▐██████│░▐██ - ███░│▐███▀▀░░▄░░▀▀███▌│░███ - ██▀─┘░░░░░░░▐█▌░░░░░░░└─▀██ - ██▄░░░▄▄▄▓░░▀█▀░░▓▄▄▄░░░▄██ - ████▄─┘██▌░░░░░░░▐██└─▄████ - █████░░▐█─┬┬┬┬┬┬┬─█▌░░█████ - ████▌░░░▀┬┼┼┼┼┼┼┼┬▀░░░▐████ - █████▄░░░└┴┴┴┴┴┴┴┘░░░▄█████ - ███████▄░░░░░░░░░░░▄███████ - ██████████▄▄▄▄▄▄▄██████████ - ███████████████████████████ - - █▄▀ █░█ █▄░█ ▄▀█   █▀ █░█ █ █▀▄ ▄▀█ - █░█ █▄█ █░▀█ █▀█   ▄█ █▀█ █ █▄▀ █▀█ - -` //go:embed docs var res embed.FS @@ -58,7 +33,6 @@ func Read(contents string) { program := p.ParseProgram() if len(p.Errors()) != 0 { - fmt.Println(styles.ErrorStyle.Italic(false).Render(ERROR_FACE)) fmt.Println(styles.ErrorStyle.Italic(false).Render("Kuna Errors Zifuatazo:")) for _, msg := range p.Errors() { From 890a4b0bcd79c8aae28a143b6be3085529c047b5 Mon Sep 17 00:00:00 2001 From: Fuad Date: Sat, 5 Oct 2024 09:49:41 +0300 Subject: [PATCH 57/81] update swahili documentation --- repl/docs/sw/arrays.md | 123 +++++++++++++++++- repl/docs/sw/bools.md | 98 ++++++++++++++- repl/docs/sw/builtins.md | 55 +++++++- repl/docs/sw/dictionaries.md | 135 +++++++++++++++++++- repl/docs/sw/for.md | 167 ++++++++++++++++++++++++- repl/docs/sw/functions.md | 92 +++++++++++++- repl/docs/sw/identifiers.md | 33 ++++- repl/docs/sw/{comments.md => maoni.md} | 0 repl/repl.go | 19 ++- 9 files changed, 714 insertions(+), 8 deletions(-) rename repl/docs/sw/{comments.md => maoni.md} (100%) diff --git a/repl/docs/sw/arrays.md b/repl/docs/sw/arrays.md index bbc6434..d9fbc6b 100644 --- a/repl/docs/sw/arrays.md +++ b/repl/docs/sw/arrays.md @@ -1 +1,122 @@ -# Orodha (Arrays) \ No newline at end of file +# Orodha Au Safu Katika Nuru + +Safu katika nuru ni miundo ya data ambayo inaweza kubeba vitu vingi, ikiwa ni pamoja na aina za data tofauti tofauti kama `namba`, `tungo`, `buliani`, `vitendakazi`, na thamani `tupu`. Ukurasa huu unaangazia vipengele mbalimbali vya safu, ikiwemo namna ya kutengeneza, kuchambua, na kuzunguka ndani yake kwa kutumia vitendakazi vilivyojengwa ndani ya Nuru. + +## Kutengeneza Safu + +Kutengeneza safu, tumia mabano mraba na tenganisha kila kitu kimoja kwa kutumia mkwaju: + +```s +orodha = [1, "pili", kweli] +``` + +## Kupata na Kubadilisha Vipengele vya Safu + +Safu katika Nuru ni zero-indexed; ikimaanisha kipengele cha kwanza katika safu kina kumbukumbu namba 0. Kupata kipengele, unaweza ukatumia kumbukumbu namba yake ndani ya mabano mraba: + +```s +namba = [10, 20, 30] +jina = namba[1] // jina is 20 +``` + +Unaweza ukabadilisha kipengele katika safu kwa kutumia kumbukumbu namba yake: + +```s +namba = [10, 20, 30] +namba[1] = 25 +andika(namba) // Tokeo: [10,25,30] +``` + +## Kuunganisha Safu + +Kuunganisha safu mbili au zaidi, tumia kiendeshi `+`: + +```s +a = [1, 2, 3] +b = [4, 5, 6] +c = a + b +// c is now [1, 2, 3, 4, 5, 6] +``` + +## Kuangalia Uanachama Katika Safu + +Tumia neno msingi `ktk` kuangalia kama kipengele kipo ndani ya safu: + +```s +namba = [10, 20, 30] +andika(20 ktk namba) // Tokeo: kweli +``` + +## Kuzunguka Ndani ya Safu + +Unaweza kutumia maneno msingi `kwa` na `ktk` kuzunguka ndani ya safu. Kuzunguka ndani ya safu na kupata kipengele peke yake tumia sintaksia ifuatayo: + +```s +namba = [1, 2, 3, 4, 5] + +kwa thamani ktk namba { + andika(thamani) +} + +//Tokeo: +1 +2 +3 +4 +5 +``` + +Kuzunguka ndani ya safu na kupata kumbukumbu namba na kipengele tumia sintaksi aifuatayo: + +```s +majina = ["Juma", "Asha", "Haruna"] + +kwa idx, jina ktk majina { + andika(idx, "-", jina) +} + +//Tokeo: +0-Juma +1-Asha +2-Haruna +``` + +## Vitendakazi vya Safu + +Nuru ina vitendakazi mbalimbali vilivyojengwa ndani kwa ajili ya Safu: + +### idadi() + +`idadi()` hurudisha urefu wa safu: + +```s +a = [1, 2, 3] +urefu = a.idadi() +andika(urefu) // Tokeo: 3 +``` + +### sukuma() + +`sukuma()` huongeza kipengele kimoja au zaidi mwishoni mwa safu: + +```s +a = [1, 2, 3] +a.sukuma("s", "g") +andika(a) // Tokeo [1, 2, 3, "s", "g"] +``` + +### yamwisho() + +`yamwisho()` hurudisha kipengele cha mwisho katika safu, au `tupu` kama safu haina kitu: + +```s +a = [1, 2, 3] +mwisho = a.yamwisho() +andika(mwisho) // Tokeo: 3 + +b = [] +mwisho = b.yamwisho() +andika(mwisho) // Tokeo: tupu +``` + +Kwa kutumia taarifa hii, unaweza ukafanyakazi na safu za Nuru kwa ufanisi, kufanya iwe rahisi kuchambua mikusanyo ya data katika programu zako. diff --git a/repl/docs/sw/bools.md b/repl/docs/sw/bools.md index 16f7a44..a43a5a2 100644 --- a/repl/docs/sw/bools.md +++ b/repl/docs/sw/bools.md @@ -1 +1,97 @@ -# Kweli/Sikweli (Bools) +# Kufanya Kazi na Buliani Katika Nuru + +Vitu vyote katika Nuru ni kweli, yaani thamani yoyote ni kweli isipokua tupu and sikweli. Hutumika kutathmini semi ambazo zinarudisha kweli au sikweli. + +## Kutathmini Semi za Buliani + +### Kutathmini Semi Rahisi + +Katika Nuru, unaweza kutathmini semi rahisi zinazorudisha thamani ya buliani: + +```go +andika(1 > 2) // Matokeo: `sikweli` + +andika(1 + 3 < 10) // Matokeo: `kweli` +``` + +### Kutathmini Semi Tata + +Katika Nuru, unaweza kutumia viendeshaji vya buliani kutathmini semi tata: + +```go +a = 5 +b = 10 +c = 15 + +tokeo = (a < b) && (b < c) + +kama (tokeo) { + andika("Hali zote mbili ni kweli") +} sivyo { + andika("Angalau hali moja ni sikweli") +} +// Tokeo: "Hali zote mbili ni kweli" +``` + +Hapa tumetengeneza vibadilika vitatu a,b,c. Kisha tukatathmini semi (a < b) && (b < c). Kwa sababu semi zote mbili ni kweli, tokeo litakua "Hali zote mbili ni kweli". + +## Vitendakazi vya Buliani + +Nuru ina vitendakazi vya buliani kadhaa ambavyo unaweza ukatumia kutathmini semi: + +### Kitendakazi `&&` + +Kitendakazi `&&` hutathmini kwenda kweli kama tu vitu vyote vinavyohusika ni kweli. Kwa mfano: + +```go +andika(kweli && kweli) // Tokeo: `kweli` + +andika(kweli && sikweli) // Tokeo: `sikweli` +``` + +### Kitendakazi `||` + +Kitendakazi || hutathmini kwenda kweli kama angalau kitu kimoja kati ya vyote vinavyohusika ni kweli. Kwa mfano: + +```go +andika(kweli || sikweli) // Tokeo: `kweli` + +andika(sikweli || sikweli) // Tokeo: `sikweli` +``` + +### Kitendakazi `!` + +Kitendakazi `!` hukanusha thamani ya kitu. Kwa mfano: + +```go +andika(!kweli) // Tokeo: `sikweli` + +andika(!sikweli) // Tokeo: `kweli` +``` + +## Kufanya Kazi na Thamani za Buliani Katika Vitanzi + +Katika Nuru, unaweza ukatumia semi za buliani katika vitanzi kuendesha tabia zake. Kwa mfano: + +```go +namba = [1, 2, 3, 4, 5] + +kwa thamani ktk namba { + kama (thamani % 2 == 0) { + andika(thamani, " ni namba shufwa") + } sivyo { + andika(thamani, " ni namba witiri") + } +} + +// Output: +// 1 ni namba witiri +// 2 ni namba shufwa +// 3 ni namba witiri +// 4 ni namba shufwa +// 5 ni namba witiri +``` + +Hapa , tumetengeneza safu yenye namba 1 hadi 5 kisha tukazunguka ndani ya safu hiyo na kwa kila namba tukatumia kitendakazi `%` ilikubaini kama namba ni shufwa au witiri. Matokeo yatakua ni "ni namba shufwa" kwa namba shufwa na "ni namba witiri" kwa namba witiri. + +Vitu buliani katika Nuru vinaweza kutumika kutathmini semi ambazo zinarudisha thamani ya kweli au sikweli. Unaweza kutumia vitendakazi vya buliani kutathmini semi tata na kuendesha tabia ya vitanzi. Kuelewa namna ya kufanya kazi na thamani za buliani ni ujuzi wamsingi kwa mtengenezaji programu yeyote wa Nuru. diff --git a/repl/docs/sw/builtins.md b/repl/docs/sw/builtins.md index f807886..b4c188a 100644 --- a/repl/docs/sw/builtins.md +++ b/repl/docs/sw/builtins.md @@ -1 +1,54 @@ -# Builtins \ No newline at end of file +# Vitendakazi Vilivyojengwa Ndani ya Nuru + +Nuru ina vitendakazi kadhaa vilivyojengwa ndani vinavyofanya kazi husika. + +## Kitendakazi andika() + +Kitendakazi `andika()` kinatumika kuchapisha ujumbe kwenye konsoli. Inawezakuchukua hoja sifuri au zaidi, na hoja zitachapishwa na nafasi kati yao. Kwa kuongeza, `andika()` huhimili uundaji wa msingi kama vile `/n` kwa ajili ya mstari mpya, `/t` kwa ajili ya nafasi ya kichupo, na `\\` kwa ajili ya mkwajunyuma. Mfano: + +```go +andika(1, 2, 3) // Output: 1 2 3 +``` + +```go +andika("Jina: Asha /n Umri: 20 /n Chuo: IFM") + +// Output: +// Jina: Asha +// Umri: 20 +// Chuo: IFM +``` + +## Kitendakazi jaza() + +Kitendakazi `jaza()` kinatumika kupata ingizo kutoka kwa mtumiaji. Inawezakuchukua hoja sifuri au moja, ambayo ni utungo utakao tumika kama kimahasishi kwa mtumiaji. Mfano: + +```go +fanya salamu = unda() { + fanya jina = jaza("Unaitwa nani? ") + andika("Mambo vipi", jina) +} + +salamu() +``` + +Katika mfano huu, tunaainisha kitendakazi `salamu()` ambacho kinamhamasisha mtumiaji kuingiza jina kwa kutumia kitendakazi `jaza()`. Kisha tunatumia kitendakazi `andika()` kuchapisha ujumbe unaobeba jina la mtumiaji aliloingiza. + +## Kitendakazi aina() + +Kitendakazi `aina()` kinatumika kutambua aina ya kitu. Inakubali hoja moja, na thamani inayorudi hua ni utungo unaoonyesha aina ya kitu. Mfano: + +```go +aina(2) // Output: "NAMBA" +aina("Nuru") // Output: "NENO" +``` + +## Kitendakazi fungua() + +Kitendakazi `fungua()` kinatumika kufungua faili. Inakubali hoja moja, ambayo ni njia ya faili unalotaka kufungua. Mfano: + +```go +faili = fungua("data.txt") +``` + +Katika mfano huu, tumetumia kitendakazi `fungua()` kufungua faili linaloitwa "data.txt". Kibadilika `faili` kinabeba kumbukumbu ya faili lililofunguliwa. diff --git a/repl/docs/sw/dictionaries.md b/repl/docs/sw/dictionaries.md index 469ad6d..04f2762 100644 --- a/repl/docs/sw/dictionaries.md +++ b/repl/docs/sw/dictionaries.md @@ -1 +1,134 @@ -# Kamusi (Dictionaries) \ No newline at end of file +# Kamusi Katika Nuru + +Kamusi katika Nuru ni miundo ya data inayotunza jozi za funguo-thamani. Ukurasa huu unatoa maelezo kuhusu Kamusi katika Nuru, ikiwemo namna ya kutengeneza, namna ya kubadilisha, na namna ya kuzunguka ndani yake. + +## Kutengeneza Kamusi + +Kamusi zinawekwa kwenye mabano singasinga na hujumuisha funguo na thamani zake zikitenganishwa na nukta pacha. Mfano wa uainishwaji wa kamusi: + +```go + +orodha = {"jina": "Juma", "umri": 25} +``` + +Funguo zinawezakua tungo, namba, desimali, au buliani na thamani inaweza kua aina ya data yoyote ikiwemo tungo, namba, desimali, buliani, tupu, au kitendakazi: + +```go +k = { + "jina": "Juma", + "umri": 25, + kweli: "kweli", + "salimu": unda(x) { andika("habari", x) }, + "sina thamani": tupu +} +``` + +## Kupata Vipengele + +Unaweza kupata vipengele vya kamusi kwa kutumia funguo zake: + +```go +k = { + "jina": "Juma", + "umri": 25, + kweli: "kweli", + "salimu": unda(x) { andika("habari", x) }, + "sina thamani": tupu +} + +andika(k[kweli]) // kweli +andika(k["salimu"]("Juma")) // habari Juma +``` + +## Kuboresha Vipengele + +Boresha thamani ya kipengele kwa kukipa thamani mpya kwenye funguo yake: + +```go +k = { + "jina": "Juma", + "umri": 25, + kweli: "kweli", + "salimu": unda(x) { andika("habari", x) }, + "sina thamani": tupu +} + +k['umri'] = 30 +andika(k['umri']) // 30 +``` + +## Kuongeza Vipengele Vipya + +Ongeza jozi mpya ya funguo-thamani kwenye kamusi kwa kuipa thamani funguo ambayo haipo kwenye kamusi husika: + +```go +k["lugha"] = "Kiswahili" +andika(k["lugha"]) // Kiswahili +``` + +## Kuunganisha Kamusi + +Unganisha kamusi mbili kwa kutumia kiendeshi `+`: + +```go +matunda = {"a": "apple", "b": "banana"} +mboga = {"c": "tembele", "d": "mchicha"} +vyakula = matunda + mboga +andika(vyakula) // {"a": "apple", "b": "banana", "c": "tembele", "d": "mchicha"} +``` + +## Angalia Kama Funguo Ipo Kwenye Kamusi + +Tumia neno msingi `ktk` kuangalia kama funguo ipo kwenye kamusi: + +```go + +k = { + "jina": "Juma", + "umri": 25, + kweli: "kweli", + "salimu": unda(x) { andika("habari", x) }, + "sina thamani": tupu +} + +"umri" ktk k // kweli +"urefu" ktk k // sikweli +``` + +## Kuzunguka Ndani Ya Kamusi + +Zunguka ndani ya kamusi kupata funguo na thamani zake: + +```go + +hobby = {"a": "kulala", "b": "kucheza mpira", "c": "kuimba"} + +kwa i, v ktk hobby { + andika(i, "=>", v) +} + +//Output + +a => kulala +b => kucheza mpira +c => kuimba +``` + +Kuzunguka ndani ya kamusi na kupata thamani peke yake: + +```go + +hobby = {"a": "kulala", "b": "kucheza mpira", "c": "kuimba"} + +kwa i, v ktk hobby { + andika(i, "=>", v) +} + +//Output + +kulala +kucheza mpira +kuimba +``` + +Kwa ufahamu huu, unaweza ukatumia kamusi kikamilifu katika Nuru kutunza na kusimamia jozi za funguo-thamani, na kupata namna nyumbufu ya kupangilia na kupata data katika programu zako. diff --git a/repl/docs/sw/for.md b/repl/docs/sw/for.md index 52b9109..7883698 100644 --- a/repl/docs/sw/for.md +++ b/repl/docs/sw/for.md @@ -1 +1,166 @@ -# Kwa (For) \ No newline at end of file +# Vitanzi Vya Kwa Katika Nuru + +Vitanzi vya `kwa` ni muundo msingi wa udhibiti katika Nuru ambavyo hutumika kuzunguka vitu vinavyozungukika kama tungo, safu, na kamusi. Ukurasahuu unaangazia sintaksia na matumizi ya Vitanzi katika Nuru, ikiwemo kuzunguka ndani ya jozi ya funguo-thamani, na matumizi ya matamshi `vunja` na `endelea`. + +## Sintaksia + +Kutengeneza kitanzi cha `kwa`, tumia neno msingi `kwa` likifwatiwa na kitambulishi cha muda mfupi kama vile `i` au `v` na kitu kinachozungukika. Funga mwili wa kitanzi na mabano singasinga `{}`. Mfano unaotumia tungo: + +```go +jina = "lugano" + +kwa i ktk jina { + andika(i) +} + +// Tokeo: +l +u +g +a +n +o +``` + +## Kuzunguka Ndani ya Jozi ya Funguo-Thamani + +### Kamusi + +Nuru inakuruhusu kuzunguka ndani ya kamusi kupata thamani moja moja au jozi ya funguo na thamani yake. Kupata tu thamani, tumia kitambulisha cha muda mfupi: + +```go +kamusi = {"a": "andaa", "b": "baba"} + +kwa v ktk kamusi { + andika(v) +} + +// Tokeo: + +andaa +baba +``` + +Kupata thamani ya funguo na thamani zake, tumia vitambulishi vya muda mfupi viwili: + +```go + +kwa k, v ktk kamusi { + andika(k + " ni " + v) +} + +// Tokeo: + +a ni andaa +b ni baba +``` + +### Tungo + +Kuzunguka juu ya thamani za tungo, tumia kitambulishi cha muda mfupi: + +```go +kwa v ktk "mojo" { + andika(v) +} + +// Tokeo: + +m +o +j +o +``` + +Kuzunguka juu ya funguo na thamani zake, tumia vitambulishi vya muda mfupi viwili: + +```go +kwa i, v ktk "mojo" { + andika(i, "->", v) +} + +// Tokeo: + +0 -> m +1 -> o +2 -> j +3 -> o +``` + +### Safu + +Kuzunguka juu ya thamani za safu, tumia kitambulishi cha muda mfupi: + +```go +majina = ["juma", "asha", "haruna"] + +kwa v ktk majina { + andika(v) +} + +// Tokeo: + +juma +asha +haruna +``` + +Kuzunguka juu ya funguo na thamani katika safy, tumia vitambulishi vya muda mfupi viwili: + +```go +kwa i, v ktk majina { + andika(i, "-", v) +} + +// Tokeo: + +0 - juma +1 - asha +2 - haruna +``` + +## Vunja na Endelea + +### Vunja + +Tumia neno msingi `vunja` kisitisha kitanzi: + +```go + +kwa i, v ktk "mojo" { + kama (i == 2) { + andika("nimevunja") + vunja + } + andika(v) +} + +// Tokeo: + +m +o +j +nimevunja + +``` + +### Endelea + +Tumia neno msingi `endelea` kuruka mzunguko maalum: + +```go +kwa i, v ktk "mojo" { + kama (i == 2) { + andika("nimeruka") + endelea + } + andika(v) +} + +// Tokeo: + +m +o +nimeruka +o +``` diff --git a/repl/docs/sw/functions.md b/repl/docs/sw/functions.md index ed2c3d8..d913a52 100644 --- a/repl/docs/sw/functions.md +++ b/repl/docs/sw/functions.md @@ -1 +1,91 @@ -# Undo (Functions) \ No newline at end of file +# Undo (Functions) + +Vitendakazi ni sehemu ya msingi ya Nuru inayokuwezesha kuainisha mapande ya msimbo yanayoweza kutumika tena. Ukurasa huu unaainisha sintaksia na matumizi ya vitendakazi katika nuru ikiwemo vipengele, vipengele vya msingi, matamshi ya kurudisha, kujirudia, na vifungizi. + +## Sintaksia + +Pande la kitendakazi huanza na neno msingi `unda` likifuatiwa na vipengele vinavyowekwa ndani ya mabano `()` na mwili unaowekwa ndani ya mabano singasinga `{}`. Vitendakazi lazima viwekwe kwenye kibadiliki: + +```go +jumla = unda(x, y) { + rudisha x + y +} + +jumla(2, 3) // 5 +``` + +## Vipengele + +Vitendakazi vinawezakuwa nazifuri au idadi yoyote ya vipengele. Vipengele vinawezakua vya aina yoyote hata vitendakazi vingine: + +```go +salamu = unda(jina) { + andika("Habari yako", jina) +} + +salamu("asha") // Habari yako asha +``` + +## Vipengele Vya Msingi + +Vitendakazi vinawezakupewa vipengele vya msingi: + +```go +salimu = unda(salamu="Habari") { + andika(salamu) +} + +salimu() // Habari +salimu("Mambo") // Mambo +``` + +## Rudisha + +Unaweza pia ukarudisha thamani kwa kutumia neno msingi `rudisha`. Neno msingi `rudisha` husitisha pande la msimbo na kurudisha thamani: + +```go +mfano = unda(x) { + rudisha "nimerudi" + andika(x) +} + +mfano("x") // nimerudi +``` + +## Kujirudia + +Nuru pia inahimili kujirudia. Mfano wa kujirudia kwa kitendakazi cha Fibonacci: + +```go + +fib = unda(n) { + kama (n <= 1) { + rudisha n + } sivyo { + rudisha fib(n-1) + fib(n-2) + } +} + +andika(fib(10)) // 55 +``` + +Kitendakazi fib kinakokotoa namba ya Fibonacci ya n kwa kujiita yenyewe ikiwa na n-1 na n-2 kama vipengele mpaka ambapo n ni ndogo kuliko au sawa na moja. + +## Vifungizi + +Vifungizi ni vitendakazi visivyo na jina ambayo vinaweza kudaka na kuhifadhi marejeo ya vibadilika kutoka katika muktadha unaovizunguka. Katika Nuru, unaweza kutengeneza vifungizi kwa kutumia neno msingin `unda` bila kuiweka kwenye kibadiliki. Mfano: + +```go +fanya jum = unda(x) { + rudisha unda(y) { + rudisha x + y + } +} + +fanya jum_x = jum(5) +andika(jum_x(3)) // 8 +``` + +Katika mfano hapo juu, kitendakazi `jum` kinarudisha kitendakazi kingine ambacho kinabeba kipengele kimoja tu `y`. Kitendakazi kinachorudisha kinawezakupata kibadiliki x kutoka katika muktadha unaokizunguka. + +Sasa umeshaelewa misingi ya vitendakazi katika Nuru, ikiwemo kujirudia na vifungizi, unaweza ukatengeneza mapande ya msimbo yanayoweza kutumika tena na tena na kurahisisha programu zako na kuboresha mpangilio wa msimbo wako. diff --git a/repl/docs/sw/identifiers.md b/repl/docs/sw/identifiers.md index d89ef81..6dd592b 100644 --- a/repl/docs/sw/identifiers.md +++ b/repl/docs/sw/identifiers.md @@ -1 +1,32 @@ -# Tambulishi (Identifiers) \ No newline at end of file +# Vitambulisho katika Nuru + +Vitambulisho hutumika kuweka majina kwenye vigezo, vitendakazi na vipengele vingine katika msimbo wako wa Nuru. Ukurasa huu unashughulikia sheria na mbinu bora za kuunda vitambulisho katika Nuru. + +## Sheria za Sintaksia + +Vitambulisho vinaweza kuwa na herufi, nambari na nistari wa chini `_`. Walakini, kuna sheria chache ambazo unapaswa kufuata wakati wa kuunda vitambulisho: + +- Vitambulisho haviwezi kuanza na nambari. +- Vitambulisho huwa na tofauti kulingana na matumizi ya herufi kubwa na ndogo. Kwa mfano, `kibadilikaChangu` na `kibadilikachangu` huchukuliwa kuwa vitambulisho tofauti. + +Hapa kuna mifano ya vitambulisho halali: + +```go +fanya mwaka_wa_kuzaliwa = 2020 +andika(mwaka_wa_kuzaliwa) // 2020 + +fanya badili_c_kwenda_p = "C kwenda P" +andika(badili_c_kwenda_p) // "C kwenda P" +``` + +Katika mifano iliyo hapo juu, mwaka_wa_kuzaliwa na badili_c_kwenda_p zote ni vitambulisho halali. + +## Mazoea Bora + +Wakati wa kuchagua vitambulisho, ni muhimu kufuata mazoea bora ili kuhakikisha kuwa msimbo wako uko wazi na rahisi kueleweka: + +- Tumia majina yanayoelezea wazi kusudi au maana ya kigezo au kitendakazi. +- Fuata kanuni thabiti ya kuweka majina, kama vile camelCase (kibadilikaChangu) au snake_case (kibadilika_changu). +- Epuka kutumia majina tofauti ya herufi moja, isipokuwa kwa vijisehemu vinavyokubalika kwa kawaida kama vile vihesabu vitanzi (i, j, k). + +Kwa kufuata mbinu bora hizi unapounda vitambulisho, utafanya code yako ya Nuru iwe rahisi kusoma na kutunza kwa wewe na wengine. diff --git a/repl/docs/sw/comments.md b/repl/docs/sw/maoni.md similarity index 100% rename from repl/docs/sw/comments.md rename to repl/docs/sw/maoni.md diff --git a/repl/repl.go b/repl/repl.go index 6bb0aeb..e9c73c0 100644 --- a/repl/repl.go +++ b/repl/repl.go @@ -148,6 +148,23 @@ var ( } kiswahiliItems = []list.Item{ - item{title: "Maoni Katika Nuru", desc: "💬 Toa mawazo yako na maoni (comments) katika Nuru", filename: "comments.md"}, + item{title: "Maoni Katika Nuru", desc: "💬 Toa mawazo yako na maoni (comments) katika Nuru", filename: "maoni.md"}, + item{title: "Vitambulishi", desc: "🔖 Toa utambulisho wa kipekee kwa vigezo vyako katika Nuru", filename: "identifiers.md"}, + item{title: "Nambari", desc: "🔢 Gundua uchawi wa nambari katika Nuru", filename: "numbers.md"}, + item{title: "Maneno", desc: "🎼 Tunga hadithi kwa kutumia maneno katika Nuru", filename: "strings.md"}, + item{title: "Kamusi", desc: "📚 Fungua maarifa ya kamusi katika Nuru", filename: "dictionaries.md"}, + item{title: "Buliani", desc: "👍👎 Kuwa mtaalam wa ulimwengu wa 'if' na 'else' kwa kutumia bool", filename: "bools.md"}, + item{title: "Tupu", desc: "🌌 Kubali utupu na Null katika Nuru", filename: "null.md"}, + item{title: "Safu", desc: "🚀 Fungua nguvu za safu (arrays) katika Nuru", filename: "arrays.md"}, + item{title: "Kwa", desc: "🔄 Rudia kama mtaalam kwa kutumia 'kwa' katika Nuru", filename: "for.md"}, + item{title: "Wakati", desc: "⌛ Jifunze sanaa ya subira na vitanzi vya 'wakati' katika Nuru", filename: "while.md"}, + item{title: "Undo", desc: "🔧 Unda kazi zenye nguvu katika Nuru", filename: "function.md"}, + item{title: "Badili", desc: "🧭 Elekeza hali ngumu kwa kutumia 'badili' katika Nuru", filename: "switch.md"}, + item{title: "Faili", desc: "💾 Shughulikia faili kwa urahisi katika Nuru", filename: "files.md"}, + item{title: "Muda", desc: "⏰ Simamia muda kwa urahisi katika Nuru", filename: "time.md"}, + item{title: "JSON", desc: "📄 Kuwa mtaalam wa sanaa ya JSON katika Nuru", filename: "json.md"}, + item{title: "Mtandao", desc: "🌐 Chunguza ulimwengu wa mitandao katika Nuru", filename: "net.md"}, + item{title: "Vifurushi", desc: "📦 Tumia nguvu za vifurushi katika Nuru", filename: "packages.md"}, + item{title: "Vijenzi", desc: "💡 Funua siri za kazi za kujengwa katika Nuru", filename: "builtins.md"}, } ) From 1e2f5ddf02f789fa6d92c9bcde452256a19d1d6f Mon Sep 17 00:00:00 2001 From: Fuad Date: Sat, 5 Oct 2024 09:49:52 +0300 Subject: [PATCH 58/81] by nuru org --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 2a0e4e8..2ddb725 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,7 @@ var ( █░░ █░█ █▀▀ █░█ ▄▀█   █▄█ ▄▀█   █▄░█ █░█ █▀█ █░█ █▄▄ █▄█ █▄█ █▀█ █▀█   ░█░ █▀█   █░▀█ █▄█ █▀▄ █▄█`) Version = styles.VersionStyle.Render("v0.5.1") - Author = styles.AuthorStyle.Render("by Avicenna") + Author = styles.AuthorStyle.Render("by Nuru Org") NewLogo = lipgloss.JoinVertical(lipgloss.Center, Title, lipgloss.JoinHorizontal(lipgloss.Center, Author, " | ", Version)) Help = styles.HelpStyle.Italic(false).Render(fmt.Sprintf(`💡 Namna ya kutumia Nuru: %s: Kuanza programu ya Nuru From de38a577bdc1d70db71ccea042e8a80e94d7d8d8 Mon Sep 17 00:00:00 2001 From: Fuad Date: Sat, 5 Oct 2024 10:50:29 +0300 Subject: [PATCH 59/81] add range builtin --- evaluator/builtins.go | 61 +++++++++++++++++++++++++++++++++++++++++++ repl/docs/en/range.md | 55 ++++++++++++++++++++++++++++++++++++++ repl/docs/sw/range.md | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 repl/docs/en/range.md create mode 100644 repl/docs/sw/range.md diff --git a/evaluator/builtins.go b/evaluator/builtins.go index 7b51767..945cbec 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -95,6 +95,58 @@ var builtins = map[string]*object.Builtin{ return &object.File{Filename: filename, Content: string(file)} }, }, + "mfululizo": { + Fn: func(args ...object.Object) object.Object { + if len(args) < 1 || len(args) > 3 { + return newError("Samahani, mfululizo inahitaji hoja 1 hadi 3, wewe umeweka %d", len(args)) + } + + var start, end, step int64 + var err error + + switch len(args) { + case 1: + end, err = getIntValue(args[0]) + if err != nil { + return newError("Hoja lazima iwe nambari nzima") + } + start, step = 0, 1 + case 2: + start, err = getIntValue(args[0]) + if err != nil { + return newError("Hoja ya kwanza lazima iwe nambari nzima") + } + end, err = getIntValue(args[1]) + if err != nil { + return newError("Hoja ya pili lazima iwe nambari nzima") + } + step = 1 + case 3: + start, err = getIntValue(args[0]) + if err != nil { + return newError("Hoja ya kwanza lazima iwe nambari nzima") + } + end, err = getIntValue(args[1]) + if err != nil { + return newError("Hoja ya pili lazima iwe nambari nzima") + } + step, err = getIntValue(args[2]) + if err != nil { + return newError("Hoja ya tatu lazima iwe nambari nzima") + } + if step == 0 { + return newError("Hatua haiwezi kuwa sifuri") + } + } + + elements := []object.Object{} + for i := start; (step > 0 && i < end) || (step < 0 && i > end); i += step { + elements = append(elements, &object.Integer{Value: i}) + } + + return &object.Array{Elements: elements} + }, + }, // "jumla": { // Fn: func(args ...object.Object) object.Object { @@ -135,3 +187,12 @@ var builtins = map[string]*object.Builtin{ // }, // }, } + +func getIntValue(obj object.Object) (int64, error) { + switch obj := obj.(type) { + case *object.Integer: + return obj.Value, nil + default: + return 0, fmt.Errorf("expected integer, got %T", obj) + } +} diff --git a/repl/docs/en/range.md b/repl/docs/en/range.md new file mode 100644 index 0000000..32d6eac --- /dev/null +++ b/repl/docs/en/range.md @@ -0,0 +1,55 @@ +## Range Function (mfululizo) + +The `mfululizo` function generates a sequence of numbers. It can be used in loops or to create arrays of sequential numbers. + +### Syntax + +```go +mfululizo(end) +mfululizo(start, end) +mfululizo(start, end, step) +``` + +### Parameters + +- `end`: The upper limit of the sequence (exclusive). +- `start` (optional): The starting value of the sequence. Default is 0. +- `step` (optional): The increment between each number in the sequence. Default is 1. + +### Return Value + +Returns an array of integers. + +### Examples + +```go +// Generate numbers from 0 to 4 +kwa i katika mfululizo(5) { + andika(i) +} +// Output: 0 1 2 3 4 + +// Generate numbers from 1 to 9 +kwa i katika mfululizo(1, 10) { + andika(i) +} +// Output: 1 2 3 4 5 6 7 8 9 + +// Generate even numbers from 0 to 8 +kwa i katika mfululizo(0, 10, 2) { + andika(i) +} +// Output: 0 2 4 6 8 + +// Generate numbers in reverse order +kwa i katika mfululizo(10, 0, -1) { + andika(i) +} +// Output: 10 9 8 7 6 5 4 3 2 1 +``` + +### Notes + +- The `end` value is exclusive, meaning the sequence will stop before reaching this value. +- If a negative `step` is provided, `start` should be greater than `end`. +- The `step` value cannot be zero. diff --git a/repl/docs/sw/range.md b/repl/docs/sw/range.md new file mode 100644 index 0000000..d8e73c3 --- /dev/null +++ b/repl/docs/sw/range.md @@ -0,0 +1,55 @@ +## Kitendakazi cha Mfululizo + +Kitendakazi cha `mfululizo` hutoa mfululizo wa nambari, sawa na kitendakazi cha `range()` cha Python. Kinaweza kutumika katika vitanzi au kuunda safu za nambari zinazofuatana. + +### Muundo + +```go +mfululizo(mwisho) +mfululizo(mwanzo, mwisho) +mfululizo(mwanzo, mwisho, hatua) +``` + +### Vipengele + +- `mwisho`: Kikomo cha juu cha mfululizo (haijumuishwi). +- `mwanzo` (si lazima): Thamani ya kuanzia ya mfululizo. Chaguo-msingi ni 0. +- `hatua` (si lazima): Ongezeko kati ya kila nambari katika mfululizo. Chaguo-msingi ni 1. + +### Thamani Inayorudishwa + +Hurudisha safu ya nambari kamili. + +### Mifano + +```go +// Toa nambari kutoka 0 hadi 4 +kwa i katika mfululizo(5) { + andika(i) +} +// Tokeo: 0 1 2 3 4 + +// Toa nambari kutoka 1 hadi 9 +kwa i katika mfululizo(1, 10) { + andika(i) +} +// Tokeo: 1 2 3 4 5 6 7 8 9 + +// Toa nambari shufwa kutoka 0 hadi 8 +kwa i katika mfululizo(0, 10, 2) { + andika(i) +} +// Tokeo: 0 2 4 6 8 + +// Toa nambari kwa mpangilio wa kurudi nyuma +kwa i katika mfululizo(10, 0, -1) { + andika(i) +} +// Tokeo: 10 9 8 7 6 5 4 3 2 1 +``` + +### Vidokezo + +- Thamani ya `mwisho` haijumuishwi, ikimaanisha mfululizo utasimama kabla ya kufikia thamani hii. +- Ikiwa `hatua` hasi imetolewa, `mwanzo` inapaswa kuwa kubwa kuliko `mwisho`. +- Thamani ya `hatua` haiwezi kuwa sifuri. From 0cf4fb71d6943b3275ba9d01dec767d2fdcff262 Mon Sep 17 00:00:00 2001 From: Fuad Date: Sat, 5 Oct 2024 10:59:18 +0300 Subject: [PATCH 60/81] update version --- README.md | 18 +++++++++--------- main.go | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 062d6f7..f5c6730 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To get started download the executables from the release page or follow the inst - Download the binary: ``` -curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Linux_amd64.tar.gz +curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Linux_amd64.tar.gz ``` - Extract the file to make global available: @@ -44,13 +44,13 @@ nuru -v - For apple silicon mac use: ``` - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Darwin_arm64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_arm64.tar.gz ``` - For apple intel mac use: ``` - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Darwin_amd64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_amd64.tar.gz ``` - Extract the file to make global available: @@ -88,7 +88,7 @@ To install Nuru on your Android device using Termux, follow these steps: 3. **Download the Nuru package**: ```bash - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Android_arm64.tar.gz ``` 4. **Extract the files to the target directory**: @@ -114,14 +114,14 @@ To install Nuru on your Android device using Termux, follow these steps: For a more streamlined installation, you can use the following one-liner: ```bash -curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." +curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." ``` ### Windows - Executable: - - Download the Nuru zip file [Here](https://github.com/NuruProgramming/Nuru/releases/download/v0.5.16/nuru_Windows_amd64.zip) + - Download the Nuru zip file [Here](https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Windows_amd64.zip) - Unzip to get the executable - Double click the executable @@ -176,8 +176,8 @@ Nuru supports both single line and multiple line comments as shown below: /* Multiple Line -Comment -*/ +Comment +*/ ``` ### Arithmetic Operations @@ -292,7 +292,7 @@ Nuru also supports dictionaries and you can do a lot with them as follows: ``` mtu = {"jina": "Mojo", "kabila": "Mnyakusa"} -// get value from key +// get value from key andika(mtu["jina"]) // output = Mojo andika(mtu["kabila"]); // output = Mnyakusa diff --git a/main.go b/main.go index 2ddb725..ba00894 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ var ( Render(` █░░ █░█ █▀▀ █░█ ▄▀█   █▄█ ▄▀█   █▄░█ █░█ █▀█ █░█ █▄▄ █▄█ █▄█ █▀█ █▀█   ░█░ █▀█   █░▀█ █▄█ █▀▄ █▄█`) - Version = styles.VersionStyle.Render("v0.5.1") + Version = styles.VersionStyle.Render("v0.5.17") Author = styles.AuthorStyle.Render("by Nuru Org") NewLogo = lipgloss.JoinVertical(lipgloss.Center, Title, lipgloss.JoinHorizontal(lipgloss.Center, Author, " | ", Version)) Help = styles.HelpStyle.Italic(false).Render(fmt.Sprintf(`💡 Namna ya kutumia Nuru: From 241143a7fec7dc6891858bdfe5fb4ce30e163051 Mon Sep 17 00:00:00 2001 From: lupyana Date: Sat, 5 Oct 2024 11:41:10 +0300 Subject: [PATCH 61/81] chore: update readme.md - updated instructions for building from source --- README.md | 110 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index f5c6730..58a39df 100644 --- a/README.md +++ b/README.md @@ -18,52 +18,53 @@ To get started download the executables from the release page or follow the inst ### Linux - - Download the binary: +- Download the binary: ``` curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Linux_amd64.tar.gz ``` - - Extract the file to make global available: +- Extract the file to make global available: ``` sudo tar -C /usr/local/bin -xzvf nuru_Linux_amd64.tar.gz ``` - - Confirm installation with: +- Confirm installation with: ``` nuru -v ``` - ### MacOs ( Apple silicon Mac ) - - Download the binary: +- Download the binary: - - For apple silicon mac use: + - For apple silicon mac use: - ``` - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_arm64.tar.gz - ``` + ``` + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_arm64.tar.gz + ``` - - For apple intel mac use: + - For apple intel mac use: - ``` - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_amd64.tar.gz - ``` + ``` + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_amd64.tar.gz + ``` - Extract the file to make global available: - - For apple silicon mac use: - ``` - sudo tar -C /usr/local/bin -xzvf nuru_Darwin_arm64.tar.gz - ``` - - For apple intel mac use: + - For apple silicon mac use: + + ``` + sudo tar -C /usr/local/bin -xzvf nuru_Darwin_arm64.tar.gz + ``` + + - For apple intel mac use: - ``` - sudo tar -C /usr/local/bin -xzvf nuru_Darwin_amd64.tar.gz - ``` + ``` + sudo tar -C /usr/local/bin -xzvf nuru_Darwin_amd64.tar.gz + ``` - Confirm installation with: @@ -71,37 +72,40 @@ nuru -v nuru -v ``` - - - ### Android (Termux) To install Nuru on your Android device using Termux, follow these steps: 1. **Ensure Termux is installed**: + - You can download and install [Termux](https://f-droid.org/en/packages/com.termux/). 2. **Create the target directory**: + ```bash mkdir -p /data/data/com.termux/files/usr/share/nuru ``` 3. **Download the Nuru package**: + ```bash curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Android_arm64.tar.gz ``` 4. **Extract the files to the target directory**: + ```bash tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru ``` 5. **Set up an alias for easy access**: + ```bash echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc ``` 6. **Reload the .bashrc file to apply the alias**: + ```bash source ~/.bashrc ``` @@ -117,27 +121,33 @@ For a more streamlined installation, you can use the following one-liner: curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." ``` - ### Windows - Executable: - - Download the Nuru zip file [Here](https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Windows_amd64.zip) - - Unzip to get the executable - - Double click the executable + + - Download the Nuru zip file [Here](https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Windows_amd64.zip) + - Unzip to get the executable + - Double click the executable - Nuru Installer - > Coming Soon + > Coming Soon ### Building From Source - - Make sure you have golang installed (atleast 1.19.0 and above) - - Run the following command: +- Make sure you have golang installed (atleast 1.19.0 and above) +- Run the following command: ``` -go build -o nuru main.go +go build -o nuru . ``` - - You can optionally add the binary to $PATH as shown above - - Confirm installtion with: + +- Copy nuru binary to path destination ~/go/bin + +``` +cp nuru ~/go/bin +``` + +- Confirm installtion with: ``` nuru -v @@ -146,6 +156,7 @@ nuru -v ## Syntax At A Glance **NOTE** + > There is a more detailed documentation of the language [here](https://nuruprogramming.org). Nuru, although still in its early stage, intends to be a fully functional programming language, and thus it has been baked with many features. @@ -160,10 +171,13 @@ y = 3; andika(x*y) // output is 6 ``` + You can also use the `fanya` keyword to define a variabe: + ``` fanya x = 3 ``` + **Note that `fanya` keyword is OPTIONAL** ### Comments @@ -194,15 +208,15 @@ For now Nuru supports `+`, `-`, `/`, `*` and `%`. Nuru also provides precedence Nuru has the following types: -Type | Syntax | Comments ---------- | ----------------------------------------- | ----------------------- -BOOL | `kweli sikweli` | kweli == true, sikweli == false -INT | `1, 100, 342, -4` | These are signed 64 bit integers -FLOAT | `2.3, 4.5. 100.8094` | Signed 64 bit floats -STRING | `"" "mambo" "habari yako"` | They can be in double `"` or single `'` quotes -ARRAY | `[] [1, 2, 3] [1, "moja", kweli]` | Arrays can hold any types -DICT | `{} {"a": 3, 1: "moja", kweli: 2}` | Keys can be int, string or bool. Values can be anything -NULL | `tupu` | These are nil objects +| Type | Syntax | Comments | +| ------ | ---------------------------------- | ------------------------------------------------------- | +| BOOL | `kweli sikweli` | kweli == true, sikweli == false | +| INT | `1, 100, 342, -4` | These are signed 64 bit integers | +| FLOAT | `2.3, 4.5. 100.8094` | Signed 64 bit floats | +| STRING | `"" "mambo" "habari yako"` | They can be in double `"` or single `'` quotes | +| ARRAY | `[] [1, 2, 3] [1, "moja", kweli]` | Arrays can hold any types | +| DICT | `{} {"a": 3, 1: "moja", kweli: 2}` | Keys can be int, string or bool. Values can be anything | +| NULL | `tupu` | These are nil objects | ### Functions @@ -260,6 +274,7 @@ wakati (i > 0) { ### Arrays This is how you initiliaze and perform other array operations in Nuru: + ``` arr = [] @@ -289,6 +304,7 @@ andika(arr[3]) // output = 3 ### Dictionaries Nuru also supports dictionaries and you can do a lot with them as follows: + ``` mtu = {"jina": "Mojo", "kabila": "Mnyakusa"} @@ -321,6 +337,7 @@ andika(mtu) // output = {"jina": "Avicenna", "kabila": "Mnyakusa", "anapoishi": ### For Loops These can iterate over strings, arrays and dictionaries: + ``` kwa i ktk "habari" { andika(i) @@ -338,6 +355,7 @@ i ### Getting Input From User In Nuru you can get input from users using the `jaza()` keyword as follows: + ``` jina = jaza("Unaitwa nani? ") // will prompt for input @@ -349,6 +367,7 @@ andika("Habari yako " + jina) ### Using The Intepreter: You can enter the intepreter by simply running the `nuru` command: + ``` nuru >>> andika("karibu") @@ -356,10 +375,13 @@ karibu >>> 2 + 2 4 ``` + Kindly Note that everything should be placed in a single line. Here's an example: + ``` >>> kama (x > y) {andika("X ni kubwa")} sivyo {andika("Y ni kubwa")} ``` + ### Running From File To run a Nuru script, write the `nuru` command followed by the name of the file with a `.nr` or `.sw` extension: @@ -382,7 +404,7 @@ There are documentations for two languages, English and Kiswahili, which are bot Clone the repo, hack it, make sure all tests are passing then submit a pull request. - > Make sure ALL tests are passing before making a pull request. You can confirm with running `make tests` +> Make sure ALL tests are passing before making a pull request. You can confirm with running `make tests` ## Community From 7f2636f12821c36df358bdc586edcba3f679d2eb Mon Sep 17 00:00:00 2001 From: Fuad Date: Tue, 29 Oct 2024 16:55:03 +0300 Subject: [PATCH 62/81] add ability to write and append to file --- object/file.go | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/object/file.go b/object/file.go index c9aa930..a502c9f 100644 --- a/object/file.go +++ b/object/file.go @@ -1,8 +1,12 @@ package object +import ( + "os" +) + type File struct { Filename string - Content string // To read the file + Content string } func (f *File) Type() ObjectType { return FILE_OBJ } @@ -11,6 +15,10 @@ func (f *File) Method(method string, args []Object) Object { switch method { case "soma": return f.read(args) + case "andika": + return f.write(args) + case "ongeza": + return f.append(args) } return nil } @@ -21,3 +29,40 @@ func (f *File) read(args []Object) Object { } return &String{Value: f.Content} } + +func (f *File) write(args []Object) Object { + if len(args) != 1 { + return newError("Samahani, tunahitaji Hoja 1, wewe umeweka %d", len(args)) + } + content, ok := args[0].(*String) + if !ok { + return newError("Samahani, hoja lazima iwe Tungo") + } + err := os.WriteFile(f.Filename, []byte(content.Value), 0644) + if err != nil { + return newError("Hitilafu katika kuandika faili: %s", err.Error()) + } + f.Content = content.Value + return &Boolean{Value: true} +} + +func (f *File) append(args []Object) Object { + if len(args) != 1 { + return newError("Samahani, tunahitaji Hoja 1, wewe umeweka %d", len(args)) + } + content, ok := args[0].(*String) + if !ok { + return newError("Samahani, hoja lazima iwe Tungo") + } + file, err := os.OpenFile(f.Filename, os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return newError("Hitilafu katika kufungua faili: %s", err.Error()) + } + defer file.Close() + _, err = file.WriteString(content.Value) + if err != nil { + return newError("Hitilafu katika kuongeza kwa faili: %s", err.Error()) + } + f.Content += content.Value + return &Boolean{Value: true} +} From 39741f4ee5fa7ad72d9697fdc03bf07eea34f685 Mon Sep 17 00:00:00 2001 From: Fuad Date: Tue, 29 Oct 2024 16:55:58 +0300 Subject: [PATCH 63/81] improve error message --- evaluator/builtins.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evaluator/builtins.go b/evaluator/builtins.go index 945cbec..d6fffd6 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -90,7 +90,7 @@ var builtins = map[string]*object.Builtin{ file, err := os.ReadFile(filename) if err != nil { - return &object.Error{Message: "Tumeshindwa kusoma faili"} + return &object.Error{Message: "Tumeshindwa kusoma faili au faili halipo"} } return &object.File{Filename: filename, Content: string(file)} }, From 9abd50f47c887785392da639d815ab6e489dd694 Mon Sep 17 00:00:00 2001 From: Fuad Date: Tue, 29 Oct 2024 17:02:31 +0300 Subject: [PATCH 64/81] add type casting helpers --- evaluator/type.go | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 evaluator/type.go diff --git a/evaluator/type.go b/evaluator/type.go new file mode 100644 index 0000000..43a3fe0 --- /dev/null +++ b/evaluator/type.go @@ -0,0 +1,72 @@ +package evaluator + +import ( + "strconv" + + "github.com/NuruProgramming/Nuru/object" +) + +func convertToInteger(obj object.Object) object.Object { + switch obj := obj.(type) { + case *object.Integer: + return obj + case *object.Float: + return &object.Integer{Value: int64(obj.Value)} + case *object.String: + i, err := strconv.ParseInt(obj.Value, 10, 64) + if err != nil { + return newError("Haiwezi kubadilisha '%s' kuwa NAMBA", obj.Value) + } + return &object.Integer{Value: i} + case *object.Boolean: + if obj.Value { + return &object.Integer{Value: 1} + } + return &object.Integer{Value: 0} + default: + return newError("Haiwezi kubadilisha %s kuwa NAMBA", obj.Type()) + } +} + +func convertToFloat(obj object.Object) object.Object { + switch obj := obj.(type) { + case *object.Float: + return obj + case *object.Integer: + return &object.Float{Value: float64(obj.Value)} + case *object.String: + f, err := strconv.ParseFloat(obj.Value, 64) + if err != nil { + return newError("Haiwezi kubadilisha '%s' kuwa DESIMALI", obj.Value) + } + return &object.Float{Value: f} + case *object.Boolean: + if obj.Value { + return &object.Float{Value: 1.0} + } + return &object.Float{Value: 0.0} + default: + return newError("Haiwezi kubadilisha %s kuwa DESIMALI", obj.Type()) + } +} + +func convertToString(obj object.Object) object.Object { + return &object.String{Value: obj.Inspect()} +} + +func convertToBoolean(obj object.Object) object.Object { + switch obj := obj.(type) { + case *object.Boolean: + return obj + case *object.Integer: + return &object.Boolean{Value: obj.Value != 0} + case *object.Float: + return &object.Boolean{Value: obj.Value != 0} + case *object.String: + return &object.Boolean{Value: len(obj.Value) > 0} + case *object.Null: + return &object.Boolean{Value: false} + default: + return &object.Boolean{Value: true} + } +} From 480eb0635c7b5ceae903a94bb1ecd2100812d01a Mon Sep 17 00:00:00 2001 From: Fuad Date: Tue, 29 Oct 2024 17:02:48 +0300 Subject: [PATCH 65/81] add badilisha built in function --- evaluator/builtins.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/evaluator/builtins.go b/evaluator/builtins.go index 945cbec..c29268f 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -148,6 +148,36 @@ var builtins = map[string]*object.Builtin{ }, }, + "badilisha": { + Fn: func(args ...object.Object) object.Object { + if len(args) != 2 { + return newError("Samahani, badili inahitaji hoja 2, wewe umeweka %d", len(args)) + } + + value := args[0] + targetType := args[1] + + if targetType.Type() != object.STRING_OBJ { + return newError("Aina ya lengo lazima iwe neno") + } + + targetTypeStr := targetType.(*object.String).Value + + switch targetTypeStr { + case "NAMBA": + return convertToInteger(value) + case "DESIMALI": + return convertToFloat(value) + case "NENO": + return convertToString(value) + case "BOOLEAN": + return convertToBoolean(value) + default: + return newError("Aina isiyojulikana: %s", targetTypeStr) + } + }, + }, + // "jumla": { // Fn: func(args ...object.Object) object.Object { // if len(args) != 1 { From 4e3c95c3bcdaffc1bb8766dbf6b37251104ee58f Mon Sep 17 00:00:00 2001 From: Gekko Wrld Date: Wed, 30 Oct 2024 14:26:42 +0300 Subject: [PATCH 66/81] chore: Extend the string object to format code. Strings now can be formatted using the `"Jina langu ni {0}".badilisha('Nuru')`. Sucessor to Instead of using a function, just do it on the string level. Signed-off-by: Gekko Wrld --- object/strings.go | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/object/strings.go b/object/strings.go index 5a428d0..a8eff11 100644 --- a/object/strings.go +++ b/object/strings.go @@ -1,7 +1,9 @@ package object import ( + "fmt" "hash/fnv" + "strconv" "strings" ) @@ -39,6 +41,8 @@ func (s *String) Method(method string, args []Object) Object { return s.lower(args) case "gawa": return s.split(args) + case "badilisha": + return s.format(args) default: return newError("Samahani, kiendesha hiki hakitumiki na tungo (Neno)") } @@ -81,3 +85,112 @@ func (s *String) split(args []Object) Object { } return &Array{Elements: elements} } + +func (s *String) format(args []Object) Object { + value, err := formatStr(s.Value, args) + + if err != nil { + return newError(err.Error()) + } + + return &String{Value: value} +} + +// Format the string like "Hello {0}", jina ... +func formatStr(format string, options []Object) (string, error) { + var str strings.Builder + var val strings.Builder + var check_val bool + var opts_len int = len(options) + + // This is to enable escaping the {} braces if you want them included + var escapeChar bool + + type optM struct { + val bool + obj Object + } + + var optionsMap = make(map[int]optM, opts_len) + + // convert the options into a map (may not be the most efficient but we are not going fast) + for i, optm := range options { + optionsMap[i] = optM{val: false, obj: optm} + } + + // Now go through the format string and do the replacement(s) + // this has approx time complexity of O(n) (bestest case) + for _, opt := range format { + + if !escapeChar && opt == '\\' { + escapeChar = true + continue + } + + if opt == '{' && !escapeChar { + check_val = true + continue + } + + if escapeChar { + if opt != '{' && opt != '}' { + str.WriteRune('\\') + } + escapeChar = false + } + + if check_val && opt == '}' { + vstr := strings.TrimSpace(val.String()) // remove accidental spaces + + // check the value and try to convert to int + arrv, err := strconv.Atoi(vstr) + if err != nil { + // return non-cryptic go errors + return "", fmt.Errorf(fmt.Sprintf("Ulichopeana si NAMBA, jaribu tena: `%s'", vstr)) + } + + oVal, exists := optionsMap[arrv] + + if !exists { + return "", fmt.Errorf(fmt.Sprintf("Nambari ya chaguo unalolitaka %d ni kubwa kuliko ulizopeana (%d)", arrv, opts_len)) + } + + str.WriteString(oVal.obj.Inspect()) + // may be innefficient + optionsMap[arrv] = optM{val: true, obj: oVal.obj} + + check_val = false + val.Reset() + continue + } + + if check_val { + val.WriteRune(opt) + continue + } + + str.WriteRune(opt) + } + + // A check if they never closed the formatting braces e.g '{0' + if check_val { + return "", fmt.Errorf(fmt.Sprintf("Haukufunga '{', tuliokota kabla ya kufika mwisho `%s'", val.String())) + } + + // Another innefficient loop + for _, v := range optionsMap { + if !v.val { + return "", fmt.Errorf(fmt.Sprintf("Ulipeana hili chaguo (%s) {%s} lakini haukutumia", v.obj.Inspect(), v.obj.Type())) + } + } + + // !start + // Here we can talk about wtf just happened + // 3 loops to do just formatting, formatting for codes sake. + // it can be done in 2 loops, the last one is just to confirm that you didn't forget anything. + // this is not required but a nice syntatic sugar, we are not here for speed, so ergonomics matter instead of speed + // finally we can say we are slower than python!, what an achievement + // done! + + return str.String(), nil +} From 42ff0555a692938b370a89f15f6eaee3444f3114 Mon Sep 17 00:00:00 2001 From: Avicenna <87450618+AvicennaJr@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:31:29 +0300 Subject: [PATCH 67/81] use panga keyword --- object/strings.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/object/strings.go b/object/strings.go index a8eff11..f1a0e92 100644 --- a/object/strings.go +++ b/object/strings.go @@ -41,7 +41,7 @@ func (s *String) Method(method string, args []Object) Object { return s.lower(args) case "gawa": return s.split(args) - case "badilisha": + case "panga": return s.format(args) default: return newError("Samahani, kiendesha hiki hakitumiki na tungo (Neno)") From aa194e8079237f5a73699bf55a983d86988826e8 Mon Sep 17 00:00:00 2001 From: Avicenna <87450618+AvicennaJr@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:33:19 +0300 Subject: [PATCH 68/81] remove comments --- object/strings.go | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/object/strings.go b/object/strings.go index f1a0e92..095a832 100644 --- a/object/strings.go +++ b/object/strings.go @@ -96,14 +96,12 @@ func (s *String) format(args []Object) Object { return &String{Value: value} } -// Format the string like "Hello {0}", jina ... func formatStr(format string, options []Object) (string, error) { var str strings.Builder var val strings.Builder var check_val bool var opts_len int = len(options) - // This is to enable escaping the {} braces if you want them included var escapeChar bool type optM struct { @@ -113,13 +111,10 @@ func formatStr(format string, options []Object) (string, error) { var optionsMap = make(map[int]optM, opts_len) - // convert the options into a map (may not be the most efficient but we are not going fast) for i, optm := range options { optionsMap[i] = optM{val: false, obj: optm} } - // Now go through the format string and do the replacement(s) - // this has approx time complexity of O(n) (bestest case) for _, opt := range format { if !escapeChar && opt == '\\' { @@ -140,12 +135,9 @@ func formatStr(format string, options []Object) (string, error) { } if check_val && opt == '}' { - vstr := strings.TrimSpace(val.String()) // remove accidental spaces - - // check the value and try to convert to int + vstr := strings.TrimSpace(val.String()) arrv, err := strconv.Atoi(vstr) if err != nil { - // return non-cryptic go errors return "", fmt.Errorf(fmt.Sprintf("Ulichopeana si NAMBA, jaribu tena: `%s'", vstr)) } @@ -156,7 +148,6 @@ func formatStr(format string, options []Object) (string, error) { } str.WriteString(oVal.obj.Inspect()) - // may be innefficient optionsMap[arrv] = optM{val: true, obj: oVal.obj} check_val = false @@ -172,25 +163,15 @@ func formatStr(format string, options []Object) (string, error) { str.WriteRune(opt) } - // A check if they never closed the formatting braces e.g '{0' if check_val { return "", fmt.Errorf(fmt.Sprintf("Haukufunga '{', tuliokota kabla ya kufika mwisho `%s'", val.String())) } - // Another innefficient loop for _, v := range optionsMap { if !v.val { return "", fmt.Errorf(fmt.Sprintf("Ulipeana hili chaguo (%s) {%s} lakini haukutumia", v.obj.Inspect(), v.obj.Type())) } } - // !start - // Here we can talk about wtf just happened - // 3 loops to do just formatting, formatting for codes sake. - // it can be done in 2 loops, the last one is just to confirm that you didn't forget anything. - // this is not required but a nice syntatic sugar, we are not here for speed, so ergonomics matter instead of speed - // finally we can say we are slower than python!, what an achievement - // done! - return str.String(), nil } From 13a0722b0586e0ea7a04d2f01522d09d3967889d Mon Sep 17 00:00:00 2001 From: Fuad Date: Wed, 30 Oct 2024 18:13:00 +0300 Subject: [PATCH 69/81] add shebang token --- token/token.go | 1 + 1 file changed, 1 insertion(+) diff --git a/token/token.go b/token/token.go index 0608580..18c4f6a 100644 --- a/token/token.go +++ b/token/token.go @@ -44,6 +44,7 @@ const ( ASTERISK_ASSIGN = "*=" SLASH_ASSIGN = "/=" MODULUS_ASSIGN = "%=" + SHEBANG = "#!" //Delimiters COMMA = "," From 5e7a29f1bd0682cc20207ab48f871c736b7ced19 Mon Sep 17 00:00:00 2001 From: Fuad Date: Wed, 30 Oct 2024 18:13:15 +0300 Subject: [PATCH 70/81] tokenize shebang --- lexer/lexer.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lexer/lexer.go b/lexer/lexer.go index b191794..7d83728 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -168,6 +168,11 @@ func (l *Lexer) NextToken() token.Token { } else { tok = newToken(token.MODULUS, l.line, l.ch) } + case rune('#'): + if l.peekChar() == rune('!') && l.line == 1 { + l.skipSingleLineComment() + return l.NextToken() + } case 0: tok.Literal = "" tok.Type = token.EOF From f1d48301bb7d516720fd8c97f3d10b7ac79536b8 Mon Sep 17 00:00:00 2001 From: Fuad Date: Sat, 22 Feb 2025 22:34:19 +0300 Subject: [PATCH 71/81] improve type casting builting use namba() to convert to integer and tungo() to convert to string --- evaluator/builtins.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/evaluator/builtins.go b/evaluator/builtins.go index f38a445..d35f1e9 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -177,6 +177,24 @@ var builtins = map[string]*object.Builtin{ } }, }, + "namba": { + Fn: func(args ...object.Object) object.Object { + if len(args) != 1 { + return newError("Samahani, namba inahitaji hoja 1, wewe umeweka %d", len(args)) + } + value := args[0] + return convertToInteger(value) + }, + }, + "tungo": { + Fn: func(args ...object.Object) object.Object { + if len(args) != 1 { + return newError("Samahani, tungo inahitaji hoja 1, wewe umeweka %d", len(args)) + } + value := args[0] + return convertToString(value) + }, + }, // "jumla": { // Fn: func(args ...object.Object) object.Object { From 54edb010178d98ab11f165c8f430856698315bcd Mon Sep 17 00:00:00 2001 From: Fuad Date: Sat, 22 Feb 2025 22:41:28 +0300 Subject: [PATCH 72/81] bump version --- README.md | 12 ++++++------ main.go | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 58a39df..276c936 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To get started download the executables from the release page or follow the inst - Download the binary: ``` -curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Linux_amd64.tar.gz +curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.18/nuru_Linux_amd64.tar.gz ``` - Extract the file to make global available: @@ -43,13 +43,13 @@ nuru -v - For apple silicon mac use: ``` - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_arm64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.18/nuru_Darwin_arm64.tar.gz ``` - For apple intel mac use: ``` - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Darwin_amd64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.18/nuru_Darwin_amd64.tar.gz ``` - Extract the file to make global available: @@ -89,7 +89,7 @@ To install Nuru on your Android device using Termux, follow these steps: 3. **Download the Nuru package**: ```bash - curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Android_arm64.tar.gz + curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.18/nuru_Android_arm64.tar.gz ``` 4. **Extract the files to the target directory**: @@ -118,14 +118,14 @@ To install Nuru on your Android device using Termux, follow these steps: For a more streamlined installation, you can use the following one-liner: ```bash -curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." +curl -O -L https://github.com/NuruProgramming/Nuru/releases/download/v0.5.18/nuru_Android_arm64.tar.gz && mkdir -p /data/data/com.termux/files/usr/share/nuru && tar -xzvf nuru_Android_arm64.tar.gz -C /data/data/com.termux/files/usr/share/nuru && echo "alias nuru='/data/data/com.termux/files/usr/share/nuru/nuru'" >> ~/.bashrc && source ~/.bashrc && echo "Installation complete.." ``` ### Windows - Executable: - - Download the Nuru zip file [Here](https://github.com/NuruProgramming/Nuru/releases/download/v0.5.17/nuru_Windows_amd64.zip) + - Download the Nuru zip file [Here](https://github.com/NuruProgramming/Nuru/releases/download/v0.5.18/nuru_Windows_amd64.zip) - Unzip to get the executable - Double click the executable diff --git a/main.go b/main.go index ba00894..ed36acb 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ var ( Render(` █░░ █░█ █▀▀ █░█ ▄▀█   █▄█ ▄▀█   █▄░█ █░█ █▀█ █░█ █▄▄ █▄█ █▄█ █▀█ █▀█   ░█░ █▀█   █░▀█ █▄█ █▀▄ █▄█`) - Version = styles.VersionStyle.Render("v0.5.17") + Version = styles.VersionStyle.Render("v0.5.18") Author = styles.AuthorStyle.Render("by Nuru Org") NewLogo = lipgloss.JoinVertical(lipgloss.Center, Title, lipgloss.JoinHorizontal(lipgloss.Center, Author, " | ", Version)) Help = styles.HelpStyle.Italic(false).Render(fmt.Sprintf(`💡 Namna ya kutumia Nuru: From b2a0e65b37e57804d2b9f9e5d6e6a0a96200d1c2 Mon Sep 17 00:00:00 2001 From: tacherasasi Date: Wed, 28 May 2025 14:22:17 +0300 Subject: [PATCH 73/81] add today function to return current date in specified format --- module/time.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/module/time.go b/module/time.go index d1fbd0d..625f2ac 100644 --- a/module/time.go +++ b/module/time.go @@ -80,3 +80,13 @@ func since(args []object.Object, defs map[string]object.Object) object.Object { return &object.Integer{Value: int64(durationInSeconds)} } + +func today(args []object.Object, defs map[string]object.Object) object.Object { + if len(args) != 0 || len(defs) != 0 { + return &object.Error{Message: "hatuhitaji hoja kwenye leo"} + } + + dateStr := time.Now().Format("02-01-2006") + return &object.String{Value: dateStr} +} + From 047838c8b486d178592fecb0bc0e5ca13bb66a25 Mon Sep 17 00:00:00 2001 From: tacherasasi Date: Wed, 28 May 2025 14:22:33 +0300 Subject: [PATCH 74/81] add after function to calculate future time based on seconds input --- module/time.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/module/time.go b/module/time.go index 625f2ac..7b4a00d 100644 --- a/module/time.go +++ b/module/time.go @@ -90,3 +90,18 @@ func today(args []object.Object, defs map[string]object.Object) object.Object { return &object.String{Value: dateStr} } +func after(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 || len(args) != 1 { + return &object.Error{Message: "tunahitaji hoja moja tu kwenye baada_ya"} + } + + secondsStr := args[0].Inspect() + seconds, err := strconv.Atoi(secondsStr) + if err != nil { + return &object.Error{Message: "hoja lazima iwe namba"} + } + + future := time.Now().Add(time.Duration(seconds) * time.Second) + return &object.Time{TimeValue: future.Format("15:04:05 02-01-2006")} +} + From 19cdacfe6327c9db45654ee930366baf5af45521 Mon Sep 17 00:00:00 2001 From: tacherasasi Date: Wed, 28 May 2025 14:22:49 +0300 Subject: [PATCH 75/81] add diff function to calculate the difference in seconds between two time inputs --- module/time.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/module/time.go b/module/time.go index 7b4a00d..1a6a204 100644 --- a/module/time.go +++ b/module/time.go @@ -105,3 +105,30 @@ func after(args []object.Object, defs map[string]object.Object) object.Object { return &object.Time{TimeValue: future.Format("15:04:05 02-01-2006")} } +func diff(args []object.Object, defs map[string]object.Object) object.Object { + if len(defs) != 0 || len(args) != 2 { + return &object.Error{Message: "tunahitaji hoja mbili kwenye tofauti"} + } + + parseTime := func(o object.Object) (time.Time, error) { + switch v := o.(type) { + case *object.Time: + return time.Parse("15:04:05 02-01-2006", v.TimeValue) + case *object.String: + return time.Parse("15:04:05 02-01-2006", v.Value) + default: + return time.Time{}, fmt.Errorf("aina batili") + } + } + + t1, err1 := parseTime(args[0]) + t2, err2 := parseTime(args[1]) + + if err1 != nil || err2 != nil { + return &object.Error{Message: "tofauti inahitaji nyakati halali mbili"} + } + + diff := t1.Sub(t2).Seconds() + return &object.Integer{Value: int64(diff)} +} + From 48e5eefc6ff2fc8bd9e5477958bf5c5aafbfe211 Mon Sep 17 00:00:00 2001 From: tacherasasi Date: Wed, 28 May 2025 14:24:46 +0300 Subject: [PATCH 76/81] add diff function to TimeFunctions for calculating time differences --- module/time.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/module/time.go b/module/time.go index 1a6a204..e68be82 100644 --- a/module/time.go +++ b/module/time.go @@ -132,3 +132,13 @@ func diff(args []object.Object, defs map[string]object.Object) object.Object { return &object.Integer{Value: int64(diff)} } +func init() { + TimeFunctions["hasahivi"] = now + TimeFunctions["lala"] = sleep + TimeFunctions["tangu"] = since + TimeFunctions["leo"] = today + TimeFunctions["baada_ya"] = after + TimeFunctions["tofauti"] = diff +} + + From bbc59c9164048dd4929c18d45d067013f9ce1e13 Mon Sep 17 00:00:00 2001 From: tacherasasi Date: Wed, 28 May 2025 14:25:12 +0300 Subject: [PATCH 77/81] refactor init function to remove duplicate function mappings --- module/time.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/module/time.go b/module/time.go index e68be82..2a6485c 100644 --- a/module/time.go +++ b/module/time.go @@ -14,6 +14,9 @@ func init() { TimeFunctions["hasahivi"] = now TimeFunctions["lala"] = sleep TimeFunctions["tangu"] = since + TimeFunctions["leo"] = today + TimeFunctions["baada_ya"] = after + TimeFunctions["tofauti"] = diff } func now(args []object.Object, defs map[string]object.Object) object.Object { @@ -132,13 +135,5 @@ func diff(args []object.Object, defs map[string]object.Object) object.Object { return &object.Integer{Value: int64(diff)} } -func init() { - TimeFunctions["hasahivi"] = now - TimeFunctions["lala"] = sleep - TimeFunctions["tangu"] = since - TimeFunctions["leo"] = today - TimeFunctions["baada_ya"] = after - TimeFunctions["tofauti"] = diff -} From 65ac71ca4163ed845dfbf75ad539f4ae48b23f19 Mon Sep 17 00:00:00 2001 From: tacherasasi Date: Wed, 28 May 2025 14:28:24 +0300 Subject: [PATCH 78/81] update time.md documentation for clarity and consistency in method descriptions --- repl/docs/en/time.md | 96 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 18 deletions(-) diff --git a/repl/docs/en/time.md b/repl/docs/en/time.md index c84caac..a0f6d13 100644 --- a/repl/docs/en/time.md +++ b/repl/docs/en/time.md @@ -3,55 +3,115 @@ ## Importing Time To use Time in Nuru, you first have to import the `muda` module as follows: + ```so tumia muda ``` +--- + ## Time Methods -### hasahivi() -To get the current time use the the `muda.hasahivi()` method. This will return a `muda` object with the current time: +### `hasahivi()` + +To get the current time, use `muda.hasahivi()`. It returns a `muda` object with the current time in the format `HH:mm:ss dd-MM-YYYY`. + ```so tumia muda saivi = muda.hasahivi() ``` -### tangu() -Use this method to get the total time elapsed in seconds. It accepts a time object or a string in the format `HH:mm:ss dd-MM-YYYY`: +--- + +### `leo()` + +To get today’s date in the format `dd-MM-YYYY`: ```so tumia muda -sasa = muda.hasahivi() +leo = muda.leo() +``` + +--- + +### `tangu(time)` + +Gets the total time elapsed **in seconds** from the given time to now. Accepts a `muda` object or string in `HH:mm:ss dd-MM-YYYY` format. + +```so +tumia muda + +muda_ulioyopita = muda.tangu("15:00:00 01-01-2024") +``` + +--- + +### `lala(sekunde)` + +Pauses the program for the given number of seconds: + +```so +tumia muda -muda.tangu(s) // will return the elapsed time +muda.lala(5) // sleeps for 5 seconds +``` + +--- + +### `baada_ya(sekunde)` -// alternatively: +Returns a `muda` object representing the time after the given number of seconds from now. + +```so +tumia muda -sasa.tangu("00:00:00 01-01-1900") // will return the elapsed time in seconds since that date +baadaye = muda.baada_ya(60) // one minute from now ``` -### lala() +--- + +### `tofauti(muda1, muda2)` + +Returns the difference between two time values in seconds. -Use lala if you want your program to sleep. It accepts one argument which is the total time to sleep in seconds: ```so -muda.lala(10) // will sleep for ten seconds +tumia muda + +saa1 = muda.hasahivi() +saa2 = muda.baada_ya(30) + +tofauti = muda.tofauti(saa2, saa1) // 30 ``` -### ongeza() +--- + +### `saa(muda)` + +Extracts and returns an object with the hour (`saa`), minute (`dakika`), and second (`sekunde`) from a `muda` or string. -Use this method to add to time, better explained with an example: ```so tumia muda sasa = muda.hasahivi() +vipimo = muda.saa(sasa) +// vipimo.saa +// vipimo.dakika +// vipimo.sekunde +``` + +--- + +### `ongeza(...)` *(planned method)* + +To add time to a `muda` object. You will be able to specify fields like `siku`, `saa`, `dakika`, `sekunde`, etc. Example: + +```so +tumia muda + +sasa = muda.hasahivi() kesho = sasa.ongeza(siku=1) -kesho_pia = sasa.ongeza(saa=24) mwakani = sasa.ongeza(miaka=1) -miezi_tatu_mbele = sasa.ongeza(miezi = 3) -wiki_ijayo = sasa.ongeza(siku=7) -idi = sasa.ongeza(siku=3, masaa=4, dakika=50, sekunde=3) ``` -It will return a muda object with the specified time. From 9a5d329389cc82062f6881e18a6b781f22303a88 Mon Sep 17 00:00:00 2001 From: tacherasasi Date: Thu, 29 May 2025 19:31:57 +0300 Subject: [PATCH 79/81] add addTime function to TimeFunctions for time manipulation and update time.md documentation --- module/time.go | 52 ++++++++++++++++++++++++++++++++++++++++++++ repl/docs/en/time.md | 19 +--------------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/module/time.go b/module/time.go index 2a6485c..a4b3258 100644 --- a/module/time.go +++ b/module/time.go @@ -17,6 +17,7 @@ func init() { TimeFunctions["leo"] = today TimeFunctions["baada_ya"] = after TimeFunctions["tofauti"] = diff + TimeFunctions["ongeza"] = addTime } func now(args []object.Object, defs map[string]object.Object) object.Object { @@ -136,4 +137,55 @@ func diff(args []object.Object, defs map[string]object.Object) object.Object { } +func addTime(args []object.Object, defs map[string]object.Object) object.Object { + if len(args) != 1 { + return &object.Error{Message: "ongeza inahitaji wakati mmoja wa kuanzia"} + } + + baseTimeObj := args[0] + baseTime, err := func() (time.Time, error) { + switch t := baseTimeObj.(type) { + case *object.Time: + return time.Parse("15:04:05 02-01-2006", t.TimeValue) + case *object.String: + return time.Parse("15:04:05 02-01-2006", t.Value) + default: + return time.Time{}, fmt.Errorf("aina ya wakati sio sahihi") + } + }() + if err != nil { + return &object.Error{Message: "wakati uliotolewa sio sahihi"} + } + + secs := getInt(defs["sekunde"]) + mins := getInt(defs["dakika"]) + hours := getInt(defs["masaa"]) + days := getInt(defs["siku"]) + weeks := getInt(defs["wiki"]) + months := getInt(defs["miezi"]) + years := getInt(defs["miaka"]) + + result := baseTime. + Add(time.Second * time.Duration(secs)). + Add(time.Minute * time.Duration(mins)). + Add(time.Hour * time.Duration(hours)). + AddDate(years, months, days+(weeks*7)) + + return &object.Time{TimeValue: result.Format("15:04:05 02-01-2006")} +} +func getInt(obj object.Object) int { + if obj == nil { + return 0 + } + switch o := obj.(type) { + case *object.Integer: + return int(o.Value) + case *object.String: + n, err := strconv.Atoi(o.Value) + if err == nil { + return n + } + } + return 0 +} diff --git a/repl/docs/en/time.md b/repl/docs/en/time.md index a0f6d13..a03d25b 100644 --- a/repl/docs/en/time.md +++ b/repl/docs/en/time.md @@ -87,24 +87,7 @@ tofauti = muda.tofauti(saa2, saa1) // 30 --- -### `saa(muda)` - -Extracts and returns an object with the hour (`saa`), minute (`dakika`), and second (`sekunde`) from a `muda` or string. - -```so -tumia muda - -sasa = muda.hasahivi() - -vipimo = muda.saa(sasa) -// vipimo.saa -// vipimo.dakika -// vipimo.sekunde -``` - ---- - -### `ongeza(...)` *(planned method)* +### `ongeza(...)` To add time to a `muda` object. You will be able to specify fields like `siku`, `saa`, `dakika`, `sekunde`, etc. Example: From 192c54b718e3d2bfa99a48f6627f75348ba321b7 Mon Sep 17 00:00:00 2001 From: Avicenna <87450618+AvicennaJr@users.noreply.github.com> Date: Fri, 30 May 2025 21:51:14 +0300 Subject: [PATCH 80/81] Specify exact fields --- repl/docs/en/time.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/repl/docs/en/time.md b/repl/docs/en/time.md index a03d25b..7809afe 100644 --- a/repl/docs/en/time.md +++ b/repl/docs/en/time.md @@ -89,7 +89,9 @@ tofauti = muda.tofauti(saa2, saa1) // 30 ### `ongeza(...)` -To add time to a `muda` object. You will be able to specify fields like `siku`, `saa`, `dakika`, `sekunde`, etc. Example: +To add time to a `muda` object. You must specify at least one of the following fields `sekunde`, `dakika`, `masaa`, `siku`, `wiki`, `miezi`, `miaka`. + +Example: ```so tumia muda From f07d4d5b321d05473fa5708498647cb839b67c04 Mon Sep 17 00:00:00 2001 From: Gekko Wrld Date: Sun, 1 Jun 2025 11:03:41 +0300 Subject: [PATCH 81/81] chore: Add install script The install script allows user to install the nuru executabe in 'correct' location. [1] Installation only uses the `nuru` executabe and discards the rest of the artifacts. The 'other' artifacts are `LICENSE` and `README.md` files. They are not useful as they contain little value to the end user. Proper documentation should be provided [1]. Issues: [1] Improve Installation Structure & Uninstallation Process - https://github.com/NuruProgramming/Nuru/issues/100 Signed-off-by: Gekko Wrld --- sh/install.sh | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100755 sh/install.sh diff --git a/sh/install.sh b/sh/install.sh new file mode 100755 index 0000000..cd29522 --- /dev/null +++ b/sh/install.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env sh + +# Hii ni skripti ya shell ili kusakinisha programu ya Nuru. +# Programu zinazohitajika: +# - curl/wget: Kupakua faili za 'tar' kutoka 'Github' +# - cp: Nakili faili kuenda mahali sahihi +# - jq: Kupata uhusiano kwenye fomati ya 'JSON' +# - tar: Kufungua faili za tar.gz + +set -e + +ARCH="$(uname -m)" +OSNAME="$(uname -s)" +PREFIX_PATH="/usr" +BIN="" +VERSION="latest" +RELEASE_URL="https://github.com/NuruProgramming/Nuru/releases" +TEMP="" + +# Cleanup function to remove temp directory on exit +cleanup() { + if [ -n "$TEMP" ] && [ -d "$TEMP" ]; then + rm -rf "$TEMP" + fi +} +trap cleanup EXIT + +# Check if command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Print usage information +usage() { + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " -p, --prefix The base path to be used when installing (default: /usr)" + echo " -v, --version The version to be downloaded from GitHub (default: latest)" + echo " -h, --help Show this help message" + echo "" +} + +# Normalize architecture names +arch_name() { + case "$ARCH" in + x86_64) + ARCH="amd64" + ;; + i386|i686) + ARCH="i386" + ;; + arm64|aarch64) + ARCH="arm64" + ;; + *) + echo "Unsupported architecture: $ARCH" + exit 2 + ;; + esac +} + +# Validate OS name +os_name() { + case "$OSNAME" in + Darwin|Linux|Android) + ;; + *) + echo "Unsupported Operating System: $OSNAME" + exit 2 + ;; + esac +} + +# Parse command line arguments +parse_args() { + while [ "$#" -gt 0 ]; do + case "$1" in + -h|--help) + usage + exit 0 + ;; + -p|--prefix) + shift + if [ -z "$1" ]; then + echo "Error: Missing argument for --prefix" + exit 1 + fi + PREFIX_PATH="$1" + ;; + -v|--version) + shift + if [ -z "$1" ]; then + echo "Error: Missing argument for --version" + exit 1 + fi + VERSION="$1" + ;; + --) + shift + break + ;; + *) + echo "Unknown argument: $1" + usage + exit 1 + ;; + esac + shift + done + BIN="$PREFIX_PATH/bin" +} + +# Download file using curl or wget +download() { + URL="$1" + if command_exists curl; then + curl -fSL "$URL" + elif command_exists wget; then + wget -qO- "$URL" + else + echo "Error: Neither curl nor wget is installed." + exit 1 + fi +} + +main() { + os_name + arch_name + parse_args "$@" + + # Check required commands + for cmd in jq tar cp; do + if ! command_exists "$cmd"; then + echo "Error: Required command '$cmd' not found." + exit 1 + fi + done + + if [ "$VERSION" = "latest" ]; then + echo "Fetching latest version tag from GitHub..." + VERSION="$(download "https://api.github.com/repos/NuruProgramming/Nuru/releases/latest" | jq -r .tag_name)" + if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then + echo "Error: Unable to determine latest version." + exit 1 + fi + fi + + TAR_URL="$RELEASE_URL/download/$VERSION/nuru_${OSNAME}_${ARCH}.tar.gz" + echo "Downloading Nuru version $VERSION for $OSNAME/$ARCH..." + + TEMP="$(mktemp -d)" + if ! download "$TAR_URL" | tar -xz -C "$TEMP"; then + echo "Error: Failed to download or extract archive." + exit 1 + fi + + # Ensure bin directory exists + if [ ! -d "$BIN" ]; then + echo "Creating directory $BIN" + mkdir -p "$BIN" + fi + + echo "Installing Nuru to $BIN/nuru" + if ! cp "$TEMP/nuru" "$BIN/"; then + echo "Error: Failed to copy binary to $BIN" + exit 1 + fi + + echo "Installation complete." +} + +main "$@"