bugfix in buffer object. Didn't increase the refcount when slicing

This commit is contained in:
Francesco Cozzuto
2023-01-12 16:11:53 +01:00
parent a56a302fd0
commit 189bfa030b
14 changed files with 117 additions and 315 deletions
+2 -7
View File
@@ -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) {
list2 = [];
@@ -17,10 +12,10 @@ fun copyList(list: List) {
return list2;
}
fun numericLess(a: int | float, b: int | float)
fun numericLess(a: Numeric, b: Numeric)
return a < b;
fun bubbleSort(list: List, less: NFunc | Func = numericLess) {
fun bubbleSort(list: List, less: Callable = numericLess) {
list2 = copyList(list);
-142
View File
@@ -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]));
}
-67
View File
@@ -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");
-65
View File
@@ -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
View File
@@ -85,7 +85,7 @@ fun parseArray(scan: Scanner) {
val, err = parseValue(scan);
if err != none:
return none, err;
array[count(array)] = val;
append(array, val);
char = scan->consumeSpaces();
if char == ']':
@@ -166,11 +166,6 @@ fun parseNull(scan: Scanner) {
return none;
}
fun integerFromDigit(char: String) {
assert(isDigit(char));
return ord(char) - ord('0');
}
fun parseNumber(scan: Scanner) {
char = scan->current();
@@ -18,7 +18,6 @@
#
# ==================================
stringFromInteger = import("../int_to_str.noja").stringFromInteger;
cat = string.cat;
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.
fun agm(x: Numeric, y: Numeric,
+4 -14
View File
@@ -1,15 +1,11 @@
fun dummy() {}
Func = type(dummy)
| type(print);
Scanner = {
src: String,
i: int,
hint: Func,
current: Func,
consume: Func,
consumeSpaces: Func
hint: Callable,
current: Callable,
consume: Callable,
consumeSpaces: Callable
};
fun hint(scan: Scanner, n: int = 1) {
@@ -60,9 +56,3 @@ fun isSpace(c: String)
return c == ' '
or c == '\t'
or c == '\n';
fun min(x, y) {
if x < y:
return x;
return y;
}
+1 -1
View File
@@ -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(out_stream);
+88 -1
View File
@@ -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
View File
@@ -82,7 +82,7 @@ static _Bool interpret(Executable *exe)
CompilationErrorType errtyp;
Executable *prelude_exe = compile(prelude, (Error*) &error, &errtyp);
if(exe == NULL) {
if(prelude_exe == NULL) {
const char *errname;
switch(errtyp) {
default:
@@ -109,6 +109,21 @@ static _Bool interpret(Executable *exe)
}
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);
if (all_bins == NULL) {
print_error(NULL, (Error*) &error);
+1
View File
@@ -170,6 +170,7 @@ void Heap_Free(Heap *heap)
// it now though.
Error_Free(&error);
Error_Init(&error);
// Continue the loop..
}
}
+2 -1
View File
@@ -108,7 +108,7 @@ static _Bool buffer_free(Object *self, Error *error)
UNUSED(error);
BufferObject *buffer = (BufferObject*) self;
Payload *payload = buffer->payload;
ASSERT(payload != NULL && payload->refs > 0);
@@ -142,6 +142,7 @@ Object *Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap
if(slice == NULL)
return NULL;
payload->refs++;
slice->payload = payload;
slice->offset = offset;
slice->length = length;
+2 -2
View File
@@ -57,9 +57,9 @@ _Bool Object_IsFile(Object *obj)
FILE *Object_GetStream(Object *obj)
{
if(!Object_IsDir(obj)) {
if(!Object_IsFile(obj)) {
Error_Panic("%s expected a " TYPENAME_FILE
"object, but an %s was provided",
" object, but an %s was provided",
__func__, Object_GetName(obj));
return NULL;
}