bugfix in buffer object. Didn't increase the refcount when slicing
This commit is contained in:
@@ -1,9 +1,4 @@
|
|||||||
|
|
||||||
fun dummy() {}
|
|
||||||
Func = type(dummy);
|
|
||||||
NFunc = type(print); # The function type is not a built-in at the moment,
|
|
||||||
# but we can define it manually.
|
|
||||||
|
|
||||||
fun copyList(list: List) {
|
fun copyList(list: List) {
|
||||||
|
|
||||||
list2 = [];
|
list2 = [];
|
||||||
@@ -17,10 +12,10 @@ fun copyList(list: List) {
|
|||||||
return list2;
|
return list2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fun numericLess(a: int | float, b: int | float)
|
fun numericLess(a: Numeric, b: Numeric)
|
||||||
return a < b;
|
return a < b;
|
||||||
|
|
||||||
fun bubbleSort(list: List, less: NFunc | Func = numericLess) {
|
fun bubbleSort(list: List, less: Callable = numericLess) {
|
||||||
|
|
||||||
list2 = copyList(list);
|
list2 = copyList(list);
|
||||||
|
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
# This script implements a circular queue and
|
|
||||||
# its relative tests!
|
|
||||||
|
|
||||||
fun newCircularQueue(T: Type = int, max: int = 3) {
|
|
||||||
|
|
||||||
if T == None:
|
|
||||||
error("Invalid type");
|
|
||||||
|
|
||||||
if max <= 0:
|
|
||||||
error("Maximum queue size must be positive");
|
|
||||||
|
|
||||||
list = [];
|
|
||||||
i = 0;
|
|
||||||
while i < max: {
|
|
||||||
list[i] = none;
|
|
||||||
i = i+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
max: max,
|
|
||||||
head: 0,
|
|
||||||
tail: 0,
|
|
||||||
list: list,
|
|
||||||
type: T
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSize(queue: Map) {
|
|
||||||
|
|
||||||
size = none;
|
|
||||||
if queue.tail == queue.head: {
|
|
||||||
if queue.list[queue.tail] == none: {
|
|
||||||
size = 0;
|
|
||||||
} else {
|
|
||||||
size = queue.max;
|
|
||||||
}
|
|
||||||
} else if queue.tail < queue.head: {
|
|
||||||
size = queue.head
|
|
||||||
- queue.tail;
|
|
||||||
} else {
|
|
||||||
size = queue.head
|
|
||||||
+ queue.max
|
|
||||||
- queue.tail;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
fun append(queue: Map, value) {
|
|
||||||
|
|
||||||
if type(value) != queue.type:
|
|
||||||
error("Invalid type");
|
|
||||||
|
|
||||||
size = getSize(queue);
|
|
||||||
|
|
||||||
queue.list[queue.head] = value;
|
|
||||||
|
|
||||||
if size == queue.max: {
|
|
||||||
queue.tail = queue.tail+1;
|
|
||||||
if queue.tail == queue.max:
|
|
||||||
queue.tail = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.head = queue.head+1;
|
|
||||||
if queue.head == queue.max:
|
|
||||||
queue.head = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fun pop(queue: Map) {
|
|
||||||
|
|
||||||
if getSize(queue) == 0:
|
|
||||||
return none;
|
|
||||||
|
|
||||||
value = queue.list[queue.tail];
|
|
||||||
queue.list[queue.tail] = none;
|
|
||||||
|
|
||||||
queue.tail = queue.tail+1;
|
|
||||||
if queue.tail == queue.max:
|
|
||||||
queue.tail = 0;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
utils = import("../utils.noja");
|
|
||||||
|
|
||||||
queue = newCircularQueue(int, 3);
|
|
||||||
assert(getSize(queue) == 0);
|
|
||||||
assert(queue.head == 0);
|
|
||||||
assert(queue.tail == 0);
|
|
||||||
|
|
||||||
append(queue, 1);
|
|
||||||
assert(queue.head == 1);
|
|
||||||
assert(queue.tail == 0);
|
|
||||||
assert(getSize(queue) == 1);
|
|
||||||
assert(utils.compareAny(queue.list, [1, none, none]));
|
|
||||||
|
|
||||||
append(queue, 2);
|
|
||||||
assert(queue.head == 2);
|
|
||||||
assert(queue.tail == 0);
|
|
||||||
assert(getSize(queue) == 2);
|
|
||||||
assert(utils.compareAny(queue.list, [1, 2, none]));
|
|
||||||
|
|
||||||
append(queue, 3);
|
|
||||||
assert(queue.head == 0);
|
|
||||||
assert(queue.tail == 0);
|
|
||||||
assert(getSize(queue) == 3);
|
|
||||||
assert(utils.compareAny(queue.list, [1, 2, 3]));
|
|
||||||
|
|
||||||
append(queue, 4);
|
|
||||||
assert(queue.head == 1);
|
|
||||||
assert(queue.tail == 1);
|
|
||||||
assert(getSize(queue) == 3);
|
|
||||||
assert(utils.compareAny(queue.list, [4, 2, 3]));
|
|
||||||
|
|
||||||
v = pop(queue);
|
|
||||||
assert(v == 2);
|
|
||||||
assert(queue.head == 1);
|
|
||||||
assert(queue.tail == 2);
|
|
||||||
assert(getSize(queue) == 2);
|
|
||||||
assert(utils.compareAny(queue.list, [4, none, 3]));
|
|
||||||
|
|
||||||
v = pop(queue);
|
|
||||||
assert(v == 3);
|
|
||||||
assert(queue.head == 1);
|
|
||||||
assert(queue.tail == 0);
|
|
||||||
assert(getSize(queue) == 1);
|
|
||||||
assert(utils.compareAny(queue.list, [4, none, none]));
|
|
||||||
|
|
||||||
v = pop(queue);
|
|
||||||
assert(v == 4);
|
|
||||||
assert(queue.head == 1);
|
|
||||||
assert(queue.tail == 1);
|
|
||||||
assert(getSize(queue) == 0);
|
|
||||||
assert(utils.compareAny(queue.list, [none, none, none]));
|
|
||||||
|
|
||||||
v = pop(queue);
|
|
||||||
assert(v == none);
|
|
||||||
assert(queue.head == 1);
|
|
||||||
assert(queue.tail == 1);
|
|
||||||
assert(getSize(queue) == 0);
|
|
||||||
assert(utils.compareAny(queue.list, [none, none, none]));
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
# Implementation of a stack using a linked list.
|
|
||||||
|
|
||||||
fun Stack_New(T) {
|
|
||||||
if T == None:
|
|
||||||
return none, "The type can't be None";
|
|
||||||
return { count: 0, head: none, type: T };
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Stack_Push(stack: Map, value) {
|
|
||||||
|
|
||||||
assert(stack.type != None);
|
|
||||||
|
|
||||||
if type(value) != stack.type:
|
|
||||||
error("Invalid type");
|
|
||||||
|
|
||||||
node = {prev: none, item: value};
|
|
||||||
|
|
||||||
node.prev = stack.head;
|
|
||||||
stack.head = node;
|
|
||||||
stack.count = stack.count + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Stack_Pop(stack: Map) {
|
|
||||||
|
|
||||||
if stack.head == none:
|
|
||||||
return none;
|
|
||||||
|
|
||||||
value = stack.head.item;
|
|
||||||
stack.head = stack.head.prev;
|
|
||||||
stack.count = stack.count - 1;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Stack_Print(stack: Map) {
|
|
||||||
print("[");
|
|
||||||
curr = stack.head;
|
|
||||||
while curr != none: {
|
|
||||||
print(curr.item);
|
|
||||||
curr = curr.prev;
|
|
||||||
if curr != none:
|
|
||||||
print(", ");
|
|
||||||
}
|
|
||||||
print("]");
|
|
||||||
}
|
|
||||||
|
|
||||||
stack = Stack_New(int);
|
|
||||||
|
|
||||||
Stack_Push(stack, 1);
|
|
||||||
Stack_Push(stack, 2);
|
|
||||||
Stack_Push(stack, 3);
|
|
||||||
|
|
||||||
Stack_Print(stack);
|
|
||||||
print("\n");
|
|
||||||
|
|
||||||
x = Stack_Pop(stack);
|
|
||||||
y = Stack_Pop(stack);
|
|
||||||
z = Stack_Pop(stack);
|
|
||||||
w = Stack_Pop(stack);
|
|
||||||
|
|
||||||
assert(x == 3);
|
|
||||||
assert(y == 2);
|
|
||||||
assert(z == 1);
|
|
||||||
assert(w == none);
|
|
||||||
|
|
||||||
Stack_Print(stack);
|
|
||||||
print("\n");
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
|
|
||||||
# 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;
|
|
||||||
}
|
|
||||||
+1
-6
@@ -85,7 +85,7 @@ fun parseArray(scan: Scanner) {
|
|||||||
val, err = parseValue(scan);
|
val, err = parseValue(scan);
|
||||||
if err != none:
|
if err != none:
|
||||||
return none, err;
|
return none, err;
|
||||||
array[count(array)] = val;
|
append(array, val);
|
||||||
|
|
||||||
char = scan->consumeSpaces();
|
char = scan->consumeSpaces();
|
||||||
if char == ']':
|
if char == ']':
|
||||||
@@ -166,11 +166,6 @@ fun parseNull(scan: Scanner) {
|
|||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
fun integerFromDigit(char: String) {
|
|
||||||
assert(isDigit(char));
|
|
||||||
return ord(char) - ord('0');
|
|
||||||
}
|
|
||||||
|
|
||||||
fun parseNumber(scan: Scanner) {
|
fun parseNumber(scan: Scanner) {
|
||||||
|
|
||||||
char = scan->current();
|
char = scan->current();
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#
|
#
|
||||||
# ==================================
|
# ==================================
|
||||||
|
|
||||||
stringFromInteger = import("../int_to_str.noja").stringFromInteger;
|
|
||||||
cat = string.cat;
|
cat = string.cat;
|
||||||
|
|
||||||
fun verse(n: int)
|
fun verse(n: int)
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
Numeric = int | float;
|
|
||||||
|
|
||||||
fun abs(n) {
|
|
||||||
if n < 0:
|
|
||||||
return -n;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Calculate the arithmetic-geometric mean of x,y.
|
# Calculate the arithmetic-geometric mean of x,y.
|
||||||
fun agm(x: Numeric, y: Numeric,
|
fun agm(x: Numeric, y: Numeric,
|
||||||
|
|||||||
+4
-14
@@ -1,15 +1,11 @@
|
|||||||
|
|
||||||
fun dummy() {}
|
|
||||||
Func = type(dummy)
|
|
||||||
| type(print);
|
|
||||||
|
|
||||||
Scanner = {
|
Scanner = {
|
||||||
src: String,
|
src: String,
|
||||||
i: int,
|
i: int,
|
||||||
hint: Func,
|
hint: Callable,
|
||||||
current: Func,
|
current: Callable,
|
||||||
consume: Func,
|
consume: Callable,
|
||||||
consumeSpaces: Func
|
consumeSpaces: Callable
|
||||||
};
|
};
|
||||||
|
|
||||||
fun hint(scan: Scanner, n: int = 1) {
|
fun hint(scan: Scanner, n: int = 1) {
|
||||||
@@ -60,9 +56,3 @@ fun isSpace(c: String)
|
|||||||
return c == ' '
|
return c == ' '
|
||||||
or c == '\t'
|
or c == '\t'
|
||||||
or c == '\n';
|
or c == '\n';
|
||||||
|
|
||||||
fun min(x, y) {
|
|
||||||
if x < y:
|
|
||||||
return x;
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
+1
-1
@@ -58,7 +58,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(out_stream, "\n};\n");
|
fprintf(out_stream, "\n\t0\n};\n");
|
||||||
|
|
||||||
fclose(in_stream);
|
fclose(in_stream);
|
||||||
fclose(out_stream);
|
fclose(out_stream);
|
||||||
|
|||||||
@@ -1 +1,88 @@
|
|||||||
name = "Francesco";
|
|
||||||
|
fun abs(n: Numeric) {
|
||||||
|
if n < 0:
|
||||||
|
return -n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun min(x, y) {
|
||||||
|
if x < y:
|
||||||
|
return x;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun max(x, y) {
|
||||||
|
if x > y:
|
||||||
|
return x;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Func = type(abs);
|
||||||
|
NFunc = type(print);
|
||||||
|
Numeric = int | float;
|
||||||
|
Callable = Func | NFunc;
|
||||||
|
Collection = List | Map;
|
||||||
|
|
||||||
|
# Stringify a number between 0 and 9.
|
||||||
|
fun stringFromDigit(digit: int) {
|
||||||
|
assert(digit >= 0 and digit <= 9);
|
||||||
|
return string.chr(string.ord("0") + digit);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stringify an unsigned integer
|
||||||
|
fun stringFromInteger(n: int) {
|
||||||
|
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = string.cat(text, stringFromDigit(digit));
|
||||||
|
|
||||||
|
# Prep for the next iteration.
|
||||||
|
power = power / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if negative:
|
||||||
|
text = string.cat("-", text);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatFromInteger(n: int)
|
||||||
|
return 1.0 * n;
|
||||||
|
|
||||||
|
fun integerFromDigit(char: String) {
|
||||||
|
res = ord(char) - ord('0');
|
||||||
|
if res < 0 or res > 9:
|
||||||
|
error("String isn't a digit");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun append(array: List, item)
|
||||||
|
array[count(array)] = item;
|
||||||
+16
-1
@@ -82,7 +82,7 @@ static _Bool interpret(Executable *exe)
|
|||||||
|
|
||||||
CompilationErrorType errtyp;
|
CompilationErrorType errtyp;
|
||||||
Executable *prelude_exe = compile(prelude, (Error*) &error, &errtyp);
|
Executable *prelude_exe = compile(prelude, (Error*) &error, &errtyp);
|
||||||
if(exe == NULL) {
|
if(prelude_exe == NULL) {
|
||||||
const char *errname;
|
const char *errname;
|
||||||
switch(errtyp) {
|
switch(errtyp) {
|
||||||
default:
|
default:
|
||||||
@@ -109,6 +109,21 @@ static _Bool interpret(Executable *exe)
|
|||||||
}
|
}
|
||||||
Object *noja_bins = rets[0];
|
Object *noja_bins = rets[0];
|
||||||
|
|
||||||
|
// Need to remake the native built-ins because
|
||||||
|
// running the script invalidated the previous
|
||||||
|
// pointer.
|
||||||
|
native_bins = Object_NewStaticMap(bins_basic, bins_basic_init, runt, (Error*) &error);
|
||||||
|
if(native_bins == NULL)
|
||||||
|
{
|
||||||
|
assert(error.base.occurred == 1);
|
||||||
|
print_error(NULL, (Error*) &error);
|
||||||
|
RuntimeError_Free(&error);
|
||||||
|
Runtime_Free(runt);
|
||||||
|
Source_Free(prelude);
|
||||||
|
Executable_Free(prelude_exe);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Object *all_bins = Object_NewClosure(native_bins, noja_bins, Runtime_GetHeap(runt), (Error*) &error);
|
Object *all_bins = Object_NewClosure(native_bins, noja_bins, Runtime_GetHeap(runt), (Error*) &error);
|
||||||
if (all_bins == NULL) {
|
if (all_bins == NULL) {
|
||||||
print_error(NULL, (Error*) &error);
|
print_error(NULL, (Error*) &error);
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ void Heap_Free(Heap *heap)
|
|||||||
// it now though.
|
// it now though.
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
Error_Init(&error);
|
Error_Init(&error);
|
||||||
|
// Continue the loop..
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ Object *Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap
|
|||||||
if(slice == NULL)
|
if(slice == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
payload->refs++;
|
||||||
slice->payload = payload;
|
slice->payload = payload;
|
||||||
slice->offset = offset;
|
slice->offset = offset;
|
||||||
slice->length = length;
|
slice->length = length;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ _Bool Object_IsFile(Object *obj)
|
|||||||
|
|
||||||
FILE *Object_GetStream(Object *obj)
|
FILE *Object_GetStream(Object *obj)
|
||||||
{
|
{
|
||||||
if(!Object_IsDir(obj)) {
|
if(!Object_IsFile(obj)) {
|
||||||
Error_Panic("%s expected a " TYPENAME_FILE
|
Error_Panic("%s expected a " TYPENAME_FILE
|
||||||
" object, but an %s was provided",
|
" object, but an %s was provided",
|
||||||
__func__, Object_GetName(obj));
|
__func__, Object_GetName(obj));
|
||||||
|
|||||||
Reference in New Issue
Block a user