From c0f6ddda50b47a4d4eb119a9c38ebda5f712e83b Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Tue, 10 Jan 2023 21:35:55 +0100 Subject: [PATCH] more examples! --- examples/arrow.noja | 11 ---- examples/int_to_str.noja | 65 +++++++++++++++++++ examples/rosetta_code/99_bottles_of_beer.noja | 43 ++++++++++++ .../arithmetic_and_geometric_mean.noja | 40 ++++++++++++ ...artesian_product_of_two_or_more_lists.noja | 40 ++++++++++++ src/lib/common/executable.c | 3 +- 6 files changed, 190 insertions(+), 12 deletions(-) delete mode 100644 examples/arrow.noja create mode 100644 examples/int_to_str.noja create mode 100644 examples/rosetta_code/99_bottles_of_beer.noja create mode 100644 examples/rosetta_code/arithmetic_and_geometric_mean.noja create mode 100644 examples/rosetta_code/cartesian_product_of_two_or_more_lists.noja diff --git a/examples/arrow.noja b/examples/arrow.noja deleted file mode 100644 index 5600cfd..0000000 --- a/examples/arrow.noja +++ /dev/null @@ -1,11 +0,0 @@ - -fun sayHello(self, other) - print("Hello ", other, " from ", self.name); - -person = { - name: "Francesco", - sayHello: sayHello -}; - -person->sayHello("Giovanni"); - diff --git a/examples/int_to_str.noja b/examples/int_to_str.noja new file mode 100644 index 0000000..7fba110 --- /dev/null +++ b/examples/int_to_str.noja @@ -0,0 +1,65 @@ + +# Shortcuts for some commonly used functions +chr = string.chr; +ord = string.ord; +cat = string.cat; + +# Some useful stuff +Numeric = int | float; + +# This function returns the magnitude of the +# argument and the power of 10 with the same +# magnitude. +fun getIntegerMagnitude(n: int) { + assert(n >= 0); + magn = 0; + powr = 1; + # Basically grow the power until it's + # bigger than the input. + while n >= powr * 10: { + powr = 10 * powr; + magn = 1 + magn; + } + return magn, powr; +} + +# Stringify a number between 0 and 9. +fun stringFromDigit(digit: int) { + assert(digit >= 0 and digit <= 9); + return chr(ord("0") + digit); +} + +fun abs(n: Numeric) { + if n < 0: + return -n; + return n; +} + +# Stringify an unsigned integer +fun stringFromInteger(n: int) { + + negative = (n < 0); + + # Get the power of 10 with the + # magnitude of the input. + _, power = getIntegerMagnitude(n); + + temp = abs(n); # Temporary copy of the input + text = ""; # The output we're about to compute + + while power >= 1: { + # Pop the leftmost digit from [temp]. + digit = temp / power; # Get the leftmost digit + temp = temp % power; # Remove it + + # Add the digit to the output. + text = cat(text, stringFromDigit(digit)); + + # Prep for the next iteration. + power = power / 10; + } + + if negative: + text = cat("-", text); + return text; +} \ No newline at end of file diff --git a/examples/rosetta_code/99_bottles_of_beer.noja b/examples/rosetta_code/99_bottles_of_beer.noja new file mode 100644 index 0000000..aa1a33b --- /dev/null +++ b/examples/rosetta_code/99_bottles_of_beer.noja @@ -0,0 +1,43 @@ +# == The beer song ================= +# +# The lyrics follow this form: +# +# > 99 bottles of beer on the wall +# > 99 bottles of beer +# > Take one down, pass it around +# > 98 bottles of beer on the wall +# > +# > 98 bottles of beer on the wall +# > 98 bottles of beer +# > Take one down, pass it around +# > 97 bottles of beer on the wall +# > +# > ... +# +# and go on until 0. +# +# ================================== + +stringFromInteger = import("../int_to_str.noja").stringFromInteger; +cat = string.cat; + +fun verse(n: int) + return cat( + stringFromInteger(n), " bottles of beer on the wall\n", + stringFromInteger(n), " bottles of beer\n", + "Take one down, pass it around\n", + stringFromInteger(n-1), " bottles of beer on the wall\n" + ); + +fun song(start: int = 99, end: int = 1) { + + text = ""; + i = start; + while i >= end: { + text = cat(text, verse(i), "\n"); + i = i-1; + } + return text; +} + +print(song()); \ No newline at end of file diff --git a/examples/rosetta_code/arithmetic_and_geometric_mean.noja b/examples/rosetta_code/arithmetic_and_geometric_mean.noja new file mode 100644 index 0000000..df84cfd --- /dev/null +++ b/examples/rosetta_code/arithmetic_and_geometric_mean.noja @@ -0,0 +1,40 @@ +Numeric = int | float; + +fun abs(n) { + if n < 0: + return -n; + return n; +} + +# Calculate the arithmetic-geometric mean of x,y. +fun agm(x: Numeric, y: Numeric, + epsilon: float = 0.00001) +{ + sqrt = math.sqrt; + + # Make sure they're floats by + # multiplying by 1.0 + a = 1.0 * x; + g = 1.0 * y; + + while abs(a - g) > epsilon: { + + a2 = (a + g) / 2; + g2 = sqrt(a * g); + + #print("a=", a, ", a2=", a2, "\n"); + #print("g=", g, ", g2=", g2, "\n"); + + # It must converge! + assert(abs(a2 - g2) < abs(a - g)); + + a = a2; + g = g2; + } + + return a, g; +} + +x = 24; +y = 6; +print(agm(x, y)); \ No newline at end of file diff --git a/examples/rosetta_code/cartesian_product_of_two_or_more_lists.noja b/examples/rosetta_code/cartesian_product_of_two_or_more_lists.noja new file mode 100644 index 0000000..25286ea --- /dev/null +++ b/examples/rosetta_code/cartesian_product_of_two_or_more_lists.noja @@ -0,0 +1,40 @@ + +# == CARTESIAN PRODUCT OF TWO OR MORE LISTS == +# +# > Show one or more idiomatic ways of +# > generating the cartesian product of +# > two arbitrary lists in your language. +# > +# > Demonstrate that your function/method +# > correctly returns: +# > +# > {1, 2} x {3, 4} = {(1, 3), (1, 4), (2, 3), (2, 4)} +# > +# > and, in contrast: +# > +# > {3, 4} x {1, 2} = {(3, 1), (3, 2), (4, 1), (4, 2)} +# > +# > Also demonstrate, ussing your function/method, +# > that the product of an empty list +# > with any other list is empty. +# > +# > {1, 2} x {} = {} +# > {} x {1, 2} = {} + +fun cartesianProduct(a: List, b: List) +{ + out = []; + i = 0; + while i < count(a): { + j = 0; + while j < count(b): { + out[count(out)] = [a[i], b[j]]; + j = j+1; + } + i = i+1; + } + return out; +} + +print(cartesianProduct([1, 2], [3, 4]), "\n"); +print(cartesianProduct([3, 4], [1, 2]), "\n"); \ No newline at end of file diff --git a/src/lib/common/executable.c b/src/lib/common/executable.c index 9f36dc2..dd75a94 100644 --- a/src/lib/common/executable.c +++ b/src/lib/common/executable.c @@ -86,6 +86,7 @@ static const InstrInfo instr_table[] = { INSTR(SUB) INSTR(MUL) INSTR(DIV) + INSTR(MOD) INSTR(EQL) INSTR(NQL) INSTR(LSS) @@ -523,7 +524,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * #ifndef NDEBUG if (info == NULL) { - Error_Report(error, 1, "Missing instruction table entry for opcode"); + Error_Report(error, 1, "Missing instruction table entry for opcode %d", opcode); return 0; } #endif