diff --git a/docs/04_Functions.md b/docs/04_Functions.md index ce85c78..3de95f7 100644 --- a/docs/04_Functions.md +++ b/docs/04_Functions.md @@ -209,6 +209,6 @@ someFunction(none); # No error. The argument value will be 4. fun someFunction2(a: int) {} someFunction2(none); # Error! -fun someFunction(a: int = 1.3) {} -someFunction(none); # Error! +fun someFunction3(a: int = 1.3) {} +someFunction3(none); # Error! ``` diff --git a/examples/importer.noja b/examples/importer.noja index 19011e5..9637174 100644 --- a/examples/importer.noja +++ b/examples/importer.noja @@ -1,7 +1,7 @@ vars, err = import("imported.noja"); if vars == none: { - print("L'import รจ fallito!! (", err, ")\n"); + print("Import failed!! (", err, ")\n"); return none; } diff --git a/makefile b/makefile index bb12c28..c430a75 100644 --- a/makefile +++ b/makefile @@ -59,8 +59,8 @@ BUILD_MODE = RELEASE # following set of flags to the CFLAGS and # LFLAGS. If the BUILD_MODE is COVERAGE, then # the flags are also determined based on the CC. -CFLAGS_DEBUG = -DDEBUG -g -LFLAGS_DEBUG = +CFLAGS_DEBUG = -DDEBUG -g +LFLAGS_DEBUG = CFLAGS_RELEASE = -DNDEBUG -O3 LFLAGS_RELEASE = @@ -150,15 +150,6 @@ $(CLI): $(CLI_OFILES) $(LIB) $(TST): $(TST_OFILES) $(LIB) gcc $^ -o $@ $(LFLAGS) -#$(REPORTDIR)/%.gcov: src/%.c -# @ mkdir -p $(@D) -# gcov --stdout $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.c, $^) > $@ -# -#report: $(patsubst $(SRCDIR)/%.c, $(REPORTDIR)/%.gcov, $(ALL_CFILES)) -# lcov --capture --directory $(OBJDIR) --output-file coverage.info -# genhtml coverage.info --output-directory . -# - report: lcov --capture --directory $(OBJDIR) --output-file $(OBJDIR)/coverage.info @ mkdir -p report @@ -172,4 +163,4 @@ clean: rm -rf $(OBJDIR) rm -rf $(REPORTDIR) rm -f $(LIB) - rm -f $(CLI) \ No newline at end of file + rm -f $(CLI) diff --git a/src/lib/builtins/basic.c b/src/lib/builtins/basic.c index b48baa4..33450a4 100644 --- a/src/lib/builtins/basic.c +++ b/src/lib/builtins/basic.c @@ -72,7 +72,7 @@ static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object } int n; - path = Object_ToString(o_path, &n, Runtime_GetHeap(runtime), error); + path = Object_GetString(o_path, &n); if (path == NULL) return -1; @@ -259,14 +259,21 @@ static int bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Object { UNUSED(runtime); UNUSED(rets); - + for(unsigned int i = 0; i < argc; i += 1) - if(!Object_ToBool(argv[i], error)) + { + if(!Object_IsBool(argv[i])) { - if(!error->occurred) - Error_Report(error, 0, "Assertion failed"); + Error_Report(error, 0, "Argument %d isn't a boolean", i); return -1; } + + if(!Object_GetBool(argv[i])) + { + Error_Report(error, 0, "Assertion failed"); + return -1; + } + } return 0; } @@ -274,15 +281,21 @@ static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object { UNUSED(argc); UNUSED(rets); + UNUSED(runtime); + ASSERT(argc == 1); - int length; + if(!Object_IsString(argv[0])) + { + Error_Report(error, 0, "Argument is not a string"); + return -1; + } + + int length; const char *string; - string = Object_ToString(argv[0], &length, Runtime_GetHeap(runtime), error); - - if(string == NULL) - return -1; + string = Object_GetString(argv[0], &length); + ASSERT(string != NULL); Error_Report(error, 0, "%s", string); return -1; diff --git a/src/lib/builtins/buffer.c b/src/lib/builtins/buffer.c index 8c24e9c..ce8f277 100644 --- a/src/lib/builtins/buffer.c +++ b/src/lib/builtins/buffer.c @@ -7,10 +7,13 @@ static int bin_new(Runtime *runtime, Object **argv, unsigned int argc, Object *r UNUSED(argc); ASSERT(argc == 1); - long long int size = Object_ToInt(argv[0], error); - - if(error->occurred == 1) + if(!Object_IsInt(argv[0])) + { + Error_Report(error, 0, "Argument is not an int"); return -1; + } + + long long int size = Object_GetInt(argv[0]); Object *temp = Object_NewBuffer(size, Runtime_GetHeap(runtime), error); @@ -26,11 +29,20 @@ static int bin_sliceUp(Runtime *runtime, Object **argv, unsigned int argc, Objec UNUSED(argc); ASSERT(argc == 3); - long long int offset = Object_ToInt(argv[1], error); - if(error->occurred == 1) return -1; + if(!Object_IsInt(argv[1])) + { + Error_Report(error, 0, "Argument 1 is not an int"); + return -1; + } - long long int length = Object_ToInt(argv[2], error); - if(error->occurred == 1) return -1; + if(!Object_IsInt(argv[2])) + { + Error_Report(error, 0, "Argument 2 is not an int"); + return -1; + } + + long long int offset = Object_GetInt(argv[1]); + long long int length = Object_GetInt(argv[2]); Object *temp = Object_SliceBuffer(argv[0], offset, length, Runtime_GetHeap(runtime), error); @@ -46,15 +58,19 @@ static int bin_toString(Runtime *runtime, Object **argv, unsigned int argc, Obje UNUSED(argc); ASSERT(argc == 1); - void *buffaddr; - int buffsize; - - buffaddr = Object_GetBufferAddrAndSize(argv[0], &buffsize, error); - - if(error->occurred) + if(!Object_IsBuffer(argv[0])) + { + Error_Report(error, 0, "Argument is not a buffer"); return -1; + } - Object *temp = Object_FromString(buffaddr, buffsize, Runtime_GetHeap(runtime), error); + void *buffaddr; + size_t buffsize; + + buffaddr = Object_GetBuffer(argv[0], &buffsize); + ASSERT(buffaddr != NULL); + + Object *temp = Object_FromString(buffaddr, buffsize, Runtime_GetHeap(runtime), error); if(temp == NULL) return -1; diff --git a/src/lib/builtins/files.c b/src/lib/builtins/files.c index 733f300..8aadde7 100644 --- a/src/lib/builtins/files.c +++ b/src/lib/builtins/files.c @@ -59,15 +59,9 @@ static int bin_openFile(Runtime *runtime, Object **argv, unsigned int argc, Obje Heap *heap = Runtime_GetHeap(runtime); - const char *path = Object_ToString(argv[0], NULL, heap, error); - - if(error->occurred) - return -1; - - int mode = Object_ToInt(argv[1], error); - - if(error->occurred) - return -1; + int mode = Object_GetInt(argv[1]); + const char *path = Object_GetString(argv[0], NULL); + ASSERT(path != NULL); // We know argv[0] is a string. FILE *fp; { @@ -155,12 +149,12 @@ static int bin_read(Runtime *runtime, Object **argv, unsigned int argc, Object * Heap *heap = Runtime_GetHeap(runtime); - void *buff_addr; - int buff_size; + void *buff_addr; + size_t buff_size; - buff_addr = Object_GetBufferAddrAndSize(argv[1], &buff_size, error); + buff_addr = Object_GetBuffer(argv[1], &buff_size); - int read_size; + size_t read_size; if(Object_IsNone(argv[2])) { @@ -168,12 +162,14 @@ static int bin_read(Runtime *runtime, Object **argv, unsigned int argc, Object * } else if(Object_IsInt(argv[2])) { - long long int temp = Object_ToInt(argv[2], error); - - if(error->occurred) + long long int temp = Object_GetInt(argv[2]); + if(temp < 0) + { + Error_Report(error, 0, "Expected third argument to be a positive integer"); return -1; + } - read_size = temp; // TODO: Handle potential overflow. + read_size = (size_t) temp; // TODO: Handle potential overflow. if(read_size > buff_size) read_size = buff_size; @@ -184,7 +180,7 @@ static int bin_read(Runtime *runtime, Object **argv, unsigned int argc, Object * return -1; } - FILE *fp = Object_ToStream(argv[0], error); + FILE *fp = Object_GetStream(argv[0]); if(fp == NULL) return -1; @@ -220,12 +216,12 @@ static int bin_write(Runtime *runtime, Object **argv, unsigned int argc, Object Heap *heap = Runtime_GetHeap(runtime); - void *buff_addr; - int buff_size; + void *buff_addr; + size_t buff_size; - buff_addr = Object_GetBufferAddrAndSize(argv[1], &buff_size, error); + buff_addr = Object_GetBuffer(argv[1], &buff_size); - int write_size; + size_t write_size; if(Object_IsNone(argv[2])) { @@ -233,12 +229,14 @@ static int bin_write(Runtime *runtime, Object **argv, unsigned int argc, Object } else if(Object_IsInt(argv[2])) { - long long int temp = Object_ToInt(argv[2], error); - - if(error->occurred) + long long int temp = Object_GetInt(argv[2]); + if(temp < 0) + { + Error_Report(error, 0, "Expected third argument to be a positive integer"); return -1; + } - write_size = temp; // TODO: Handle potential overflow. + write_size = (size_t) temp; // TODO: Handle potential overflow. if(write_size > buff_size) write_size = buff_size; @@ -249,7 +247,7 @@ static int bin_write(Runtime *runtime, Object **argv, unsigned int argc, Object return -1; } - FILE *fp = Object_ToStream(argv[0], error); + FILE *fp = Object_GetStream(argv[0]); if(fp == NULL) return -1; @@ -277,10 +275,8 @@ static int bin_openDir(Runtime *runtime, Object **argv, unsigned int argc, Objec Heap *heap = Runtime_GetHeap(runtime); - const char *path = Object_ToString(argv[0], NULL, heap, error); - - if(error->occurred) - return -1; + const char *path = Object_GetString(argv[0], NULL); + ASSERT(path != NULL); DIR *dir = opendir(path); @@ -312,11 +308,7 @@ static int bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, O return -1; } - DIR *dir = Object_ToDIR(argv[0], error); - - if(error->occurred) - return -1; - + DIR *dir = Object_GetDIR(argv[0]); ASSERT(dir != NULL); Heap *heap = Runtime_GetHeap(runtime); diff --git a/src/lib/builtins/math.c b/src/lib/builtins/math.c index 128190e..a3fc806 100644 --- a/src/lib/builtins/math.c +++ b/src/lib/builtins/math.c @@ -40,10 +40,7 @@ \ if(Object_IsFloat(argv[0])) \ { \ - double v = Object_ToFloat(argv[0], error); \ - \ - if(error->occurred) \ - return -1; \ + double v = Object_GetFloat(argv[0]); \ \ rets[0] = Object_FromFloat(name(v), Runtime_GetHeap(runtime), error); \ if(rets[0] == NULL) \ @@ -75,15 +72,8 @@ return -1; \ } \ \ - double v1 = Object_ToFloat(argv[0], error); \ - \ - if(error->occurred) \ - return -1; \ - \ - double v2 = Object_ToFloat(argv[1], error); \ - \ - if(error->occurred) \ - return -1; \ + double v1 = Object_GetFloat(argv[0]); \ + double v2 = Object_GetFloat(argv[1]); \ \ Object *res = Object_FromFloat(name(v1, v2), Runtime_GetHeap(runtime), error); \ if(res == NULL) return -1; \ diff --git a/src/lib/builtins/string.c b/src/lib/builtins/string.c index 693c6a6..7a64b13 100644 --- a/src/lib/builtins/string.c +++ b/src/lib/builtins/string.c @@ -23,10 +23,9 @@ static int bin_ord(Runtime *runtime, Object **argv, unsigned int argc, Object *r const char *string; int n; - string = Object_ToString(argv[0],&n,Runtime_GetHeap(runtime),error); - if (string == NULL) - return -1; - + string = Object_GetString(argv[0], &n); + ASSERT(string != NULL); + if(n == 0) { Error_Report(error, 0, "Argument #%d is an empty string", 1); @@ -38,7 +37,7 @@ static int bin_ord(Runtime *runtime, Object **argv, unsigned int argc, Object *r UNUSED(k); ASSERT(k >= 0); - Object *temp = Object_FromInt(ret,Runtime_GetHeap(runtime),error); + Object *temp = Object_FromInt(ret, Runtime_GetHeap(runtime), error); if(temp == NULL) return -1; @@ -60,11 +59,7 @@ static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object *r char buff[32]; - int value = Object_ToInt(argv[0],error); - - if(error->occurred) - return -1; - + int value = Object_GetInt(argv[0]); int k = utf8_sequence_from_utf32_codepoint(buff,sizeof(buff),value); @@ -120,11 +115,7 @@ static int bin_cat(Runtime *runtime, Object **argv, unsigned int argc, Object *r for(unsigned int i = 0, written = 0; i < argc; i += 1) { int n; - const char *s = Object_ToString(argv[i], &n, - Runtime_GetHeap(runtime), error); - - if(error->occurred) - goto done; + const char *s = Object_GetString(argv[i], &n); memcpy(buffer + written, s, n); written += n; @@ -133,8 +124,7 @@ static int bin_cat(Runtime *runtime, Object **argv, unsigned int argc, Object *r buffer[total_count] = '\0'; result = Object_FromString(buffer, total_count, Runtime_GetHeap(runtime), error); - -done: + if(starting != buffer) free(buffer); diff --git a/src/lib/common/executable.c b/src/lib/common/executable.c index ec29f58..bed2561 100644 --- a/src/lib/common/executable.c +++ b/src/lib/common/executable.c @@ -82,8 +82,6 @@ static const InstrInfo instr_table[] = { [OPCODE_GRT] = {"GRT", 0, NULL}, [OPCODE_LEQ] = {"LEQ", 0, NULL}, [OPCODE_GEQ] = {"GEQ", 0, NULL}, - [OPCODE_AND] = {"AND", 0, NULL}, - [OPCODE_OR] = {"OR", 0, NULL}, [OPCODE_ASS] = {"ASS", 1, (OperandType[]) {OPTP_STRING}}, [OPCODE_POP] = {"POP", 1, (OperandType[]) {OPTP_INT}}, [OPCODE_CALL] = {"CALL", 2, (OperandType[]) {OPTP_INT, OPTP_INT}}, diff --git a/src/lib/common/executable.h b/src/lib/common/executable.h index 28f5c46..600dd26 100644 --- a/src/lib/common/executable.h +++ b/src/lib/common/executable.h @@ -67,8 +67,6 @@ typedef enum { OPCODE_GRT, OPCODE_LEQ, OPCODE_GEQ, - OPCODE_AND, - OPCODE_OR, OPCODE_ASS, OPCODE_POP, OPCODE_CALL, diff --git a/src/lib/compiler/codegen.c b/src/lib/compiler/codegen.c index 86147c7..57fdc7f 100644 --- a/src/lib/compiler/codegen.c +++ b/src/lib/compiler/codegen.c @@ -187,8 +187,6 @@ static Opcode exprkind_to_opcode(ExprKind kind) case EXPR_LEQ: return OPCODE_LEQ; case EXPR_GRT: return OPCODE_GRT; case EXPR_GEQ: return OPCODE_GEQ; - case EXPR_AND: return OPCODE_AND; - case EXPR_OR: return OPCODE_OR; default: UNREACHABLE; break; diff --git a/src/lib/disassembler/disassembler.c b/src/lib/disassembler/disassembler.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/lib/objects/o_bool.c b/src/lib/objects/o_bool.c index 21282bc..76516fb 100644 --- a/src/lib/objects/o_bool.c +++ b/src/lib/objects/o_bool.c @@ -32,7 +32,6 @@ #include "objects.h" #include "../utils/defs.h" -static _Bool to_bool(Object *obj, Error *err); static void print(Object *obj, FILE *fp); static _Bool op_eql(Object *self, Object *other); static int hash(Object *self); @@ -41,11 +40,9 @@ static Object *copy(Object *self, Heap *heap, Error *err); static TypeObject t_bool = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "bool", - .size = sizeof (Object), - .atomic = ATMTP_BOOL, + .size = sizeof(Object), .hash = hash, .copy = copy, - .to_bool = to_bool, .print = print, .op_eql = op_eql, }; @@ -89,12 +86,15 @@ static _Bool op_eql(Object *self, Object *other) return self == other; } -static _Bool to_bool(Object *obj, Error *err) +bool Object_GetBool(Object *obj) { - UNUSED(err); - ASSERT(obj); - ASSERT(err); - ASSERT(Object_GetType(obj) == &t_bool); + if(!Object_IsBool(obj)) { + Error_Panic("%s expected a bool object, but " + "an %s was provided", __func__, + Object_GetName(obj)); + return -1; + } + return obj == &the_true_object; } diff --git a/src/lib/objects/o_buffer.c b/src/lib/objects/o_buffer.c index 9518d8f..982b686 100644 --- a/src/lib/objects/o_buffer.c +++ b/src/lib/objects/o_buffer.c @@ -34,17 +34,15 @@ #include "objects.h" typedef struct { - Object base; - int size; - unsigned char *body; -} BufferObject; + size_t refs, size; + unsigned char body[]; +} Payload; typedef struct { - Object base; - BufferObject *sliced; - int offset, - length; -} BufferSliceObject; + Object base; + Payload *payload; + size_t offset, length; +} BufferObject; static Object *buffer_select(Object *self, Object *key, Heap *heap, Error *err); static _Bool buffer_insert(Object *self, Object *key, Object *val, Heap *heap, Error *err); @@ -52,16 +50,10 @@ static int buffer_count(Object *self); static void buffer_print(Object *obj, FILE *fp); static _Bool buffer_free(Object *self, Error *error); -static Object *slice_select(Object *self, Object *key, Heap *heap, Error *err); -static _Bool slice_insert(Object *self, Object *key, Object *val, Heap *heap, Error *err); -static int slice_count(Object *self); -static void slice_print(Object *obj, FILE *fp); - - static TypeObject t_buffer = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "buffer", - .size = sizeof (BufferObject), + .size = sizeof(BufferObject), .select = buffer_select, .insert = buffer_insert, .count = buffer_count, @@ -69,16 +61,6 @@ static TypeObject t_buffer = { .free = buffer_free, }; -static TypeObject t_buffer_slice = { - .base = (Object) { .type = &t_type, .flags = Object_STATIC }, - .name = "buffer slice", - .size = sizeof (BufferSliceObject), - .select = slice_select, - .insert = slice_insert, - .count = slice_count, - .print = slice_print, -}; - #define THRESHOLD 128 TypeObject *Object_GetBufferType() @@ -88,44 +70,31 @@ TypeObject *Object_GetBufferType() _Bool Object_IsBuffer(Object *obj) { - return obj->type == &t_buffer_slice || obj->type == &t_buffer; + return Object_GetType(obj) == Object_GetBufferType(); } -Object *Object_NewBuffer(int size, Heap *heap, Error *error) +Object *Object_NewBuffer(size_t size, Heap *heap, Error *error) { - ASSERT(size >= 0); - // Make the thing. BufferObject *obj; { - obj = (BufferObject*) Heap_Malloc(heap, &t_buffer, error); + Payload *payload = malloc(sizeof(Payload) + size); + if(payload == NULL) + { + Error_Report(error, 1, "No memory"); + return NULL; + } + payload->refs = 1; + payload->size = size; + memset(payload->body, 0, size); + obj = (BufferObject*) Heap_Malloc(heap, &t_buffer, error); if(obj == NULL) return NULL; - unsigned char *body; - - if(size > THRESHOLD) - { - body = malloc(sizeof(unsigned char) * size); - - if(body == NULL) - { - Error_Report(error, 1, "No memory"); - return NULL; - } - } - else - { - body = Heap_RawMalloc(heap, sizeof(unsigned char) * size, error); - - if(body == NULL) - return NULL; - } - - obj->size = size; - obj->body = body; - memset(obj->body, 0, size); + obj->payload = payload; + obj->offset = 0; + obj->length = size; } return (Object*) obj; @@ -133,124 +102,63 @@ Object *Object_NewBuffer(int size, Heap *heap, Error *error) static _Bool buffer_free(Object *self, Error *error) { - (void) error; + UNUSED(error); BufferObject *buffer = (BufferObject*) self; - - if(buffer->size > THRESHOLD) - free(buffer->body); + + Payload *payload = buffer->payload; + ASSERT(payload != NULL && payload->refs > 0); + + payload->refs -= 1; + if(payload->refs == 0) + free(payload); return 1; } -Object *Object_SliceBuffer(Object *buffer, int offset, int length, Heap *heap, Error *error) +Object *Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap, Error *error) { - if(buffer->type != &t_buffer && buffer->type != &t_buffer_slice) + if(!Object_IsBuffer(obj)) { - Error_Report(error, 0, "Not a buffer or a buffer slice"); + Error_Report(error, 0, "Not a buffer"); return NULL; } - BufferSliceObject *slice; + Payload *payload = ((BufferObject*) obj)->payload; - if(buffer->type == &t_buffer) - { - BufferObject *original = (BufferObject*) buffer; - - if(offset == 0 && length == original->size) - return buffer; - - slice = (BufferSliceObject*) Heap_Malloc(heap, &t_buffer_slice, error); - - if(slice == NULL) - return NULL; - - if(offset < 0 || offset >= original->size) - { - Error_Report(error, 0, "offset out of range"); - return NULL; - } - - if(length < 0 || length >= original->size) - { - Error_Report(error, 0, "length out of range"); - return NULL; - } - - if(offset + length > original->size) - { - Error_Report(error, 0, "slice out of range"); - return NULL; - } - - slice->sliced = original; - slice->offset = offset; - slice->length = length; + if(offset >= payload->size) { + Error_Report(error, 0, "Offset out of range"); + return NULL; } - else - { - ASSERT(buffer->type == &t_buffer_slice); - slice = (BufferSliceObject*) Heap_Malloc(heap, &t_buffer_slice, error); - - if(slice == NULL) - return NULL; - - BufferSliceObject *original = (BufferSliceObject*) buffer; - - if(offset < 0 || offset >= original->length) - { - Error_Report(error, 0, "offset out of range"); - return NULL; - } - - if(length < 0 || length >= original->length) - { - Error_Report(error, 0, "length out of range"); - return NULL; - } - - if(offset + length > original->length) - { - Error_Report(error, 0, "slice out of range"); - return NULL; - } - - slice->sliced = original->sliced; - slice->offset = original->offset + offset; - slice->length = length; + if(offset + length > payload->size) { + Error_Report(error, 0, "Length out of range"); + return NULL; } + BufferObject *slice = (BufferObject*) Heap_Malloc(heap, &t_buffer, error); + if(slice == NULL) + return NULL; + + slice->payload = payload; + slice->offset = offset; + slice->length = length; + return (Object*) slice; } -void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error) +void *Object_GetBuffer(Object *obj, size_t *size) { - if(obj->type != &t_buffer && obj->type != &t_buffer_slice) + if(!Object_IsBuffer(obj)) { - Error_Report(error, 0, "Not a buffer or a buffer slice"); + Error_Panic("Not a buffer"); return NULL; } - if(obj->type == &t_buffer) - { - BufferObject *buffer = (BufferObject*) obj; - - if(size) - *size = buffer->size; + BufferObject *buffer = (BufferObject*) obj; + Payload *payload = buffer->payload; - return buffer->body; - } - else - { - ASSERT(obj->type == &t_buffer_slice); - - BufferSliceObject *slice = (BufferSliceObject*) obj; - - if(size) - *size = slice->length; - - return slice->sliced->body + slice->offset; - } + if(size) *size = buffer->length; + return payload->body + buffer->offset; } static Object *buffer_select(Object *self, Object *key, Heap *heap, Error *error) @@ -267,48 +175,19 @@ static Object *buffer_select(Object *self, Object *key, Heap *heap, Error *error return NULL; } - int idx = Object_ToInt(key, error); - ASSERT(error->occurred == 0); + int idx = Object_GetInt(key); BufferObject *buffer = (BufferObject*) self; - if(idx < 0 || idx >= buffer->size) + if(idx < 0 || (size_t) idx >= buffer->length) { - Error_Report(error, 0, "Out of range index"); + Error_Report(error, 0, "Index out of range"); return NULL; } - unsigned char byte = buffer->body[idx]; + Payload *payload = buffer->payload; - return Object_FromInt(byte, heap, error); -} - -static Object *slice_select(Object *self, Object *key, Heap *heap, Error *error) -{ - ASSERT(self != NULL); - ASSERT(self->type == &t_buffer_slice); - ASSERT(key != NULL); - ASSERT(heap != NULL); - ASSERT(error != NULL); - - if(!Object_IsInt(key)) - { - Error_Report(error, 0, "Non integer key"); - return NULL; - } - - int idx = Object_ToInt(key, error); - ASSERT(error->occurred == 0); - - BufferSliceObject *slice = (BufferSliceObject*) self; - - if(idx < 0 || idx >= slice->length) - { - Error_Report(error, 0, "Out of range index"); - return NULL; - } - - unsigned char byte = slice->sliced->body[slice->offset + idx]; + unsigned char byte = payload->body[buffer->offset + idx]; return Object_FromInt(byte, heap, error); } @@ -330,18 +209,18 @@ static _Bool buffer_insert(Object *self, Object *key, Object *val, Heap *heap, E Error_Report(error, 0, "Non integer key"); return NULL; } - - int idx = Object_ToInt(key, error); - ASSERT(error->occurred == 0); - - if(idx < 0 || idx >= buffer->size) + if(!Object_IsInt(val)) + { + Error_Report(error, 0, "Non integer value"); + return NULL; + } + int idx = Object_GetInt(key); + long long int qword = Object_GetInt(val); + if(idx < 0 || (size_t) idx >= buffer->length) { Error_Report(error, 0, "Out of range index"); return NULL; } - - long long int qword = Object_ToInt(val, error); - if(qword > 255 || qword < 0) { Error_Report(error, 0, "Not in range [0, 255]"); @@ -350,54 +229,8 @@ static _Bool buffer_insert(Object *self, Object *key, Object *val, Heap *heap, E unsigned char byte = qword & 0xff; - if(error->occurred == 1) - return 0; - - buffer->body[idx] = byte; - return 1; -} - -static _Bool slice_insert(Object *self, Object *key, Object *val, Heap *heap, Error *error) -{ - UNUSED(heap); - ASSERT(error != NULL); - ASSERT(key != NULL); - ASSERT(val != NULL); - ASSERT(heap != NULL); - ASSERT(self != NULL); - ASSERT(self->type == &t_buffer_slice); - - BufferSliceObject *slice = (BufferSliceObject*) self; - - if(!Object_IsInt(key)) - { - Error_Report(error, 0, "Non integer key"); - return NULL; - } - - int idx = Object_ToInt(key, error); - ASSERT(error->occurred == 0); - - if(idx < 0 || idx >= slice->length) - { - Error_Report(error, 0, "Out of range index"); - return NULL; - } - - long long int qword = Object_ToInt(val, error); - - if(qword > 255 || qword < 0) - { - Error_Report(error, 0, "Not in range [0, 255]"); - return NULL; - } - - unsigned char byte = qword & 0xff; - - if(error->occurred == 1) - return 0; - - slice->sliced->body[slice->offset + idx] = byte; + Payload *payload = buffer->payload; + payload->body[buffer->offset + idx] = byte; return 1; } @@ -405,14 +238,7 @@ static int buffer_count(Object *self) { BufferObject *buffer = (BufferObject*) self; - return buffer->size; -} - -static int slice_count(Object *self) -{ - BufferSliceObject *slice = (BufferSliceObject*) self; - - return slice->length; + return buffer->length; } static void print_bytes(FILE *fp, unsigned char *addr, int size) @@ -446,11 +272,5 @@ static void print_bytes(FILE *fp, unsigned char *addr, int size) static void buffer_print(Object *self, FILE *fp) { BufferObject *buffer = (BufferObject*) self; - print_bytes(fp, buffer->body, buffer->size); -} - -static void slice_print(Object *self, FILE *fp) -{ - BufferSliceObject *slice = (BufferSliceObject*) self; - print_bytes(fp, slice->sliced->body + slice->offset, slice->length); + print_bytes(fp, buffer->payload->body + buffer->offset, buffer->length); } \ No newline at end of file diff --git a/src/lib/objects/o_closure.c b/src/lib/objects/o_closure.c index d385abb..3d82d18 100644 --- a/src/lib/objects/o_closure.c +++ b/src/lib/objects/o_closure.c @@ -69,7 +69,8 @@ Object *Object_NewClosure(Object *parent, Object *new_map, Heap *heap, Error *er return (Object*) obj; } -static Object *select_(Object *self, Object *key, Heap *heap, Error *err) +static Object *select_(Object *self, Object *key, + Heap *heap, Error *err) { ClosureObject *closure = (ClosureObject*) self; diff --git a/src/lib/objects/o_dir.c b/src/lib/objects/o_dir.c index 0110d74..ae52208 100644 --- a/src/lib/objects/o_dir.c +++ b/src/lib/objects/o_dir.c @@ -51,7 +51,7 @@ TypeObject *Object_GetDirType() _Bool Object_IsDir(Object *obj) { - return obj->type == &t_dir; + return Object_GetType(obj) == Object_GetDirType(); } Object *Object_FromDIR(DIR *handle, Heap *heap, Error *error) @@ -66,11 +66,12 @@ Object *Object_FromDIR(DIR *handle, Heap *heap, Error *error) return (Object*) dob; } -DIR *Object_ToDIR(Object *obj, Error *error) + +DIR *Object_GetDIR(Object *obj) { - if(!Object_IsDir(obj)) - { - Error_Report(error, 0, "Object is not a directory"); + if(!Object_IsDir(obj)) { + Error_Panic("%s expected a directory object, but an %s " + "was provided", __func__, Object_GetName(obj)); return NULL; } diff --git a/src/lib/objects/o_file.c b/src/lib/objects/o_file.c index fa25cc3..69d43ed 100644 --- a/src/lib/objects/o_file.c +++ b/src/lib/objects/o_file.c @@ -54,11 +54,11 @@ _Bool Object_IsFile(Object *obj) return obj->type == &t_file; } -FILE *Object_ToStream(Object *obj, Error *error) +FILE *Object_GetStream(Object *obj) { - if(!Object_IsFile(obj)) - { - Error_Report(error, 0, "Object is not a file"); + if(!Object_IsDir(obj)) { + Error_Panic("%s expected a file object, but an %s " + "was provided", __func__, Object_GetName(obj)); return NULL; } diff --git a/src/lib/objects/o_float.c b/src/lib/objects/o_float.c index 8805deb..47561da 100644 --- a/src/lib/objects/o_float.c +++ b/src/lib/objects/o_float.c @@ -30,9 +30,9 @@ #include #include "objects.h" +#include "../utils/defs.h" #include "../utils/hash.h" -static double to_float(Object *obj, Error *err); static void print(Object *obj, FILE *fp); static _Bool op_eql(Object *self, Object *other); static int hash(Object *self); @@ -47,10 +47,8 @@ static TypeObject t_float = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "float", .size = sizeof (FloatObject), - .atomic = ATMTP_FLOAT, .hash = hash, .copy = copy, - .to_float = to_float, .print = print, .op_eql = op_eql }; @@ -67,17 +65,15 @@ static int hash(Object *self) static Object *copy(Object *self, Heap *heap, Error *err) { - (void) heap; - (void) err; - return self; + UNUSED(heap); + UNUSED(err); + return self; /* Float objects are immutable */ } static _Bool op_eql(Object *self, Object *other) { - assert(self != NULL); - assert(self->type == &t_float); - assert(other != NULL); - assert(other->type == &t_float); + assert(self != NULL && self->type == &t_float); + assert(other != NULL && other->type == &t_float); FloatObject *i1, *i2; @@ -87,13 +83,14 @@ static _Bool op_eql(Object *self, Object *other) return i1->val == i2->val; } -static double to_float(Object *obj, Error *err) +double Object_GetFloat(Object *obj) { - assert(obj); - assert(err); - assert(Object_GetType(obj) == &t_float); - - (void) err; + if(!Object_IsFloat(obj)) { + Error_Panic("%s expected a float object, but " + "an %s was provided", __func__, + Object_GetName(obj)); + return 0.0; + } return ((FloatObject*) obj)->val; } @@ -106,9 +103,8 @@ TypeObject *Object_GetFloatType() Object *Object_FromFloat(double val, Heap *heap, Error *error) { FloatObject *obj = (FloatObject*) Heap_Malloc(heap, &t_float, error); - - if(obj == 0) - return 0; + if(obj == NULL) + return NULL; obj->val = val; @@ -118,8 +114,7 @@ Object *Object_FromFloat(double val, Heap *heap, Error *error) static void print(Object *obj, FILE *fp) { assert(fp != NULL); - assert(obj != NULL); - assert(obj->type == &t_float); + assert(obj != NULL && obj->type == &t_float); fprintf(fp, "%2.2f", ((FloatObject*) obj)->val); } \ No newline at end of file diff --git a/src/lib/objects/o_int.c b/src/lib/objects/o_int.c index 7742b2f..03ff8b2 100644 --- a/src/lib/objects/o_int.c +++ b/src/lib/objects/o_int.c @@ -28,12 +28,11 @@ ** +--------------------------------------------------------------------------+ */ -#include #include #include "objects.h" +#include "../utils/defs.h" #include "../utils/hash.h" -static long long int to_int(Object *obj, Error *err); static void print(Object *obj, FILE *fp); static _Bool op_eql(Object *self, Object *other); static int hash(Object *self); @@ -47,19 +46,16 @@ typedef struct { static TypeObject t_int = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "int", - .size = sizeof (IntObject), - .atomic = ATMTP_INT, + .size = sizeof(IntObject), .hash = hash, .copy = copy, - .to_int = to_int, .print = print, .op_eql = op_eql, }; static int hash(Object *self) { - assert(self != NULL); - assert(self->type == &t_int); + ASSERT(self != NULL && self->type == &t_int); IntObject *iobj = (IntObject*) self; @@ -68,22 +64,11 @@ static int hash(Object *self) static Object *copy(Object *self, Heap *heap, Error *err) { - (void) heap; - (void) err; + UNUSED(heap); + UNUSED(err); return self; } -static long long int to_int(Object *obj, Error *err) -{ - assert(obj != NULL); - assert(err != NULL); - assert(Object_GetType(obj) == &t_int); - - (void) err; - - return ((IntObject*) obj)->val; -} - TypeObject *Object_GetIntType() { return &t_int; @@ -91,8 +76,8 @@ TypeObject *Object_GetIntType() Object *Object_FromInt(long long int val, Heap *heap, Error *error) { - assert(heap != NULL); - assert(error != NULL); + ASSERT(heap != NULL); + ASSERT(error != NULL); IntObject *obj = (IntObject*) Heap_Malloc(heap, &t_int, error); @@ -104,21 +89,33 @@ Object *Object_FromInt(long long int val, Heap *heap, Error *error) return (Object*) obj; } +long long int Object_GetInt(Object *obj) +{ + if(!Object_IsInt(obj)) { + Error_Panic("%s expected an int object, but " + "an %s was provided", __func__, + Object_GetName(obj)); + return 0; + } + + return ((IntObject*) obj)->val; +} + static void print(Object *obj, FILE *fp) { - assert(fp != NULL); - assert(obj != NULL); - assert(obj->type == &t_int); + ASSERT(fp != NULL); + ASSERT(obj != NULL); + ASSERT(obj->type == &t_int); fprintf(fp, "%lld", ((IntObject*) obj)->val); } static _Bool op_eql(Object *self, Object *other) { - assert(self != NULL); - assert(self->type == &t_int); - assert(other != NULL); - assert(other->type == &t_int); + ASSERT(self != NULL); + ASSERT(self->type == &t_int); + ASSERT(other != NULL); + ASSERT(other->type == &t_int); IntObject *i1, *i2; diff --git a/src/lib/objects/o_list.c b/src/lib/objects/o_list.c index 343b4a3..3528726 100644 --- a/src/lib/objects/o_list.c +++ b/src/lib/objects/o_list.c @@ -50,7 +50,7 @@ static int hash(Object *self); static TypeObject t_list = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "list", - .size = sizeof (ListObject), + .size = sizeof(ListObject), .copy = copy, .hash = hash, .select = select_, @@ -173,8 +173,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) return NULL; } - int idx = Object_ToInt(key, error); - ASSERT(error->occurred == 0); + int idx = Object_GetInt(key); ListObject *list = (ListObject*) self; @@ -228,8 +227,7 @@ static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *e return NULL; } - int idx = Object_ToInt(key, error); - ASSERT(error->occurred == 0); + int idx = Object_GetInt(key); if(idx < 0 || idx > list->count) { diff --git a/src/lib/objects/o_map.c b/src/lib/objects/o_map.c index a233ef4..aa7be39 100644 --- a/src/lib/objects/o_map.c +++ b/src/lib/objects/o_map.c @@ -51,7 +51,7 @@ static int hash(Object *self); static TypeObject t_map = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "map", - .size = sizeof (MapObject), + .size = sizeof(MapObject), .copy = copy, .hash = hash, .select = select_, diff --git a/src/lib/objects/o_none.c b/src/lib/objects/o_none.c index 7881c45..73356ca 100644 --- a/src/lib/objects/o_none.c +++ b/src/lib/objects/o_none.c @@ -40,7 +40,7 @@ static Object *copy(Object *self, Heap *heap, Error *err); static TypeObject t_none = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "none", - .size = sizeof (Object), + .size = sizeof(Object), .hash = hash, .copy = copy, .print = print, @@ -59,7 +59,7 @@ TypeObject *Object_GetNoneType() _Bool Object_IsNone(Object *obj) { - return obj == &the_none_object; + return Object_GetType(obj) == Object_GetNoneType(); } static int hash(Object *self) diff --git a/src/lib/objects/o_string.c b/src/lib/objects/o_string.c index 7c85efc..2500b62 100644 --- a/src/lib/objects/o_string.c +++ b/src/lib/objects/o_string.c @@ -45,7 +45,6 @@ static int hash(Object *self); static int count(Object *self); static Object *copy(Object *self, Heap *heap, Error *err); static void print(Object *obj, FILE *fp); -static char *to_string(Object *self, int *size, Heap *heap, Error *err); static _Bool op_eql(Object *self, Object *other); static void walkexts(Object *self, void (*callback)(void **referer, unsigned int size, void *userp), void *userp); static Object *select_(Object *self, Object *key, Heap *heap, Error *error); @@ -53,14 +52,12 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error); static TypeObject t_string = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "string", - .atomic = ATMTP_STRING, .size = sizeof(StringObject), .hash = hash, .count = count, .copy = copy, .print = print, .select = select_, - .to_string = to_string, .op_eql = op_eql, .walkexts = walkexts, }; @@ -99,9 +96,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) Error_Report(error, 0, "Non integer key"); return NULL; } - - int idx = Object_ToInt(key, error); - ASSERT(error->occurred == 0); + int idx = Object_GetInt(key); StringObject *str = (StringObject*) self; @@ -117,19 +112,17 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) return Object_FromString(str->body + byteoffset, codelength, heap, error); } -static char *to_string(Object *self, int *size, Heap *heap, Error *err) +const char *Object_GetString(Object *obj, int *size) { - ASSERT(self != NULL); - ASSERT(self->type == &t_string); - - (void) heap; - (void) err; - - StringObject *s = (StringObject*) self; - - if(size) - *size = s->bytes; + if(!Object_IsString(obj)) { + Error_Panic("%s expected a string object, but " + "an %s was provided", __func__, + Object_GetName(obj)); + return NULL; + } + StringObject *s = (StringObject*) obj; + if(size) *size = s->bytes; return s->body; } diff --git a/src/lib/objects/objects.c b/src/lib/objects/objects.c index f8a1e2d..e092e87 100644 --- a/src/lib/objects/objects.c +++ b/src/lib/objects/objects.c @@ -28,15 +28,15 @@ ** +--------------------------------------------------------------------------+ */ -#include "../utils/defs.h" #include "objects.h" +#include "../utils/defs.h" static _Bool op_eql(Object *self, Object *other); TypeObject t_type = { .base = (Object) { .type = &t_type, .flags = Object_STATIC }, .name = "type", - .size = sizeof (TypeObject), + .size = sizeof(TypeObject), .op_eql = op_eql, }; @@ -70,41 +70,11 @@ const TypeObject *Object_GetType(const Object *obj) return obj->type; } -unsigned int Object_GetSize(const Object *obj, Error *err) -{ - UNUSED(err); - ASSERT(err != NULL); - ASSERT(obj != NULL); - - const TypeObject *type = Object_GetType(obj); - ASSERT(type); - - return type->size; -} - -unsigned int Object_GetDeepSize(const Object *obj, Error *err) -{ - ASSERT(err != NULL); - ASSERT(obj != NULL); - - const TypeObject *type = Object_GetType(obj); - ASSERT(type); - - if(type->deepsize == NULL) - { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(obj), __func__); - return 0; - } - - return type->deepsize(obj); -} - int Object_Hash(Object *obj) { ASSERT(obj != NULL); const TypeObject *type = Object_GetType(obj); - ASSERT(type != NULL); - ASSERT(type->hash != NULL); + ASSERT(type != NULL && type->hash != NULL); return type->hash(obj); } @@ -225,158 +195,24 @@ int Object_Count(Object *coll, Error *err) return type->count(coll); } -Object *Object_Next(Object *iter, Heap *heap, Error *err) -{ - ASSERT(err); - ASSERT(iter); - - const TypeObject *type = Object_GetType(iter); - ASSERT(type); - - if(type->next == NULL) - { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(iter), __func__); - return NULL; - } - - return type->next(iter, heap, err); -} - -Object *Object_Prev(Object *iter, Heap *heap, Error *err) -{ - ASSERT(err); - ASSERT(iter); - - const TypeObject *type = Object_GetType(iter); - ASSERT(type); - - if(type->prev == NULL) - { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(iter), __func__); - return NULL; - } - - return type->prev(iter, heap, err); -} - _Bool Object_IsInt(Object *obj) { - ASSERT(obj != NULL); - ASSERT(obj->type != NULL); - return obj->type->atomic == ATMTP_INT; + return Object_GetType(obj) == Object_GetIntType(); } _Bool Object_IsBool(Object *obj) { - ASSERT(obj != NULL); - ASSERT(obj->type != NULL); - return obj->type->atomic == ATMTP_BOOL; + return Object_GetType(obj) == Object_GetBoolType(); } _Bool Object_IsFloat(Object *obj) { - ASSERT(obj != NULL); - ASSERT(obj->type != NULL); - return obj->type->atomic == ATMTP_FLOAT; + return Object_GetType(obj) == Object_GetFloatType(); } _Bool Object_IsString(Object *obj) { - ASSERT(obj != NULL); - ASSERT(obj->type != NULL); - return obj->type->atomic == ATMTP_STRING; -} - -long long int Object_ToInt(Object *obj, Error *err) -{ - ASSERT(err); - ASSERT(obj); - - if(!Object_IsInt(obj)) - { - Error_Report(err, 0, "Object is not an integer"); - return 0; - } - - const TypeObject *type = Object_GetType(obj); - ASSERT(type); - - if(type->to_int == NULL) - { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(obj), __func__); - return 0; - } - - return type->to_int(obj, err); -} - -_Bool Object_ToBool(Object *obj, Error *err) -{ - ASSERT(err); - ASSERT(obj); - - if(!Object_IsBool(obj)) - { - Error_Report(err, 0, "Object is not a boolean"); - return 0; - } - - const TypeObject *type = Object_GetType(obj); - ASSERT(type); - - if(type->to_bool == NULL) - { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(obj), __func__); - return 0; - } - - return type->to_bool(obj, err); -} - -double Object_ToFloat(Object *obj, Error *err) -{ - ASSERT(err); - ASSERT(obj); - - if(!Object_IsFloat(obj)) - { - Error_Report(err, 0, "Object is not a floating"); - return 0; - } - - const TypeObject *type = Object_GetType(obj); - ASSERT(type); - - if(type->to_float == NULL) - { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(obj), __func__); - return 0; - } - - return type->to_float(obj, err); -} - -const char *Object_ToString(Object *obj, int *size, Heap *heap, Error *err) -{ - ASSERT(err != NULL); - ASSERT(obj != NULL); - - if(!Object_IsString(obj)) - { - Error_Report(err, 0, "Object is not a string"); - return NULL; - } - - const TypeObject *type = Object_GetType(obj); - ASSERT(type); - - if(type->to_string == NULL) - { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(obj), __func__); - return NULL; - } - - return type->to_string(obj, size, heap, err); + return Object_GetType(obj) == Object_GetStringType(); } _Bool Object_Compare(Object *obj1, Object *obj2, Error *error) diff --git a/src/lib/objects/objects.h b/src/lib/objects/objects.h index 30d3128..36d56a6 100644 --- a/src/lib/objects/objects.h +++ b/src/lib/objects/objects.h @@ -31,8 +31,9 @@ #ifndef OBJECT_H #define OBJECT_H -#include #include +#include +#include #include "../utils/error.h" #define MAX_RETS 8 @@ -51,14 +52,6 @@ typedef struct { Object *new_location; } MovedObject; -typedef enum { - ATMTP_NOTATOMIC = 0, - ATMTP_INT, - ATMTP_BOOL, - ATMTP_FLOAT, - ATMTP_STRING, -} AtomicType; - struct TypeObject { Object base; @@ -66,10 +59,10 @@ struct TypeObject { // Any. const char *name; unsigned int size; - AtomicType atomic; + //AtomicType atomic; - _Bool (*init)(Object *self, Error *err); - _Bool (*free)(Object *self, Error *err); + bool (*init)(Object *self, Error *err); + bool (*free)(Object *self, Error *err); int (*hash)(Object *self); Object* (*copy)(Object *self, Heap *heap, Error *err); int (*call)(Object *self, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *err); @@ -79,22 +72,10 @@ struct TypeObject { // Collections. Object *(*select)(Object *self, Object *key, Heap *heap, Error *err); Object *(*delete)(Object *self, Object *key, Heap *heap, Error *err); - _Bool (*insert)(Object *self, Object *key, Object *val, Heap *heap, Error *err); + bool (*insert)(Object *self, Object *key, Object *val, Heap *heap, Error *err); int (*count)(Object *self); - // Iterators. - Object *(*next)(Object *self, Heap *heap, Error *err); - Object *(*prev)(Object *self, Heap *heap, Error *err); - - // Some. - union { - long long int (*to_int)(Object *self, Error *err); - _Bool (*to_bool)(Object *self, Error *err); - double (*to_float)(Object *self, Error *err); - char *(*to_string)(Object *self, int *size, Heap *heap, Error *err); - }; - - _Bool (*op_eql)(Object *self, Object *other); + bool (*op_eql)(Object *self, Object *other); // All. void (*walk) (Object *self, void (*callback)(Object **referer, void *userp), void *userp); @@ -110,8 +91,8 @@ Heap* Heap_New(int size); void Heap_Free(Heap *heap); void* Heap_Malloc (Heap *heap, TypeObject *type, Error *err); void* Heap_RawMalloc(Heap *heap, int size, Error *err); -_Bool Heap_StartCollection(Heap *heap, Error *error); -_Bool Heap_StopCollection(Heap *heap); +bool Heap_StartCollection(Heap *heap, Error *error); +bool Heap_StopCollection(Heap *heap); void Heap_CollectReference(Object **referer, void *heap); float Heap_GetUsagePercentage(Heap *heap); unsigned int Heap_GetObjectCount(Heap *heap); @@ -120,19 +101,14 @@ unsigned int Heap_GetSize(Heap *heap); const TypeObject* Object_GetType(const Object *obj); const char* Object_GetName(const Object *obj); -unsigned int Object_GetSize(const Object *obj, Error *err); -unsigned int Object_GetDeepSize(const Object *obj, Error *err); -void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error); int Object_Hash (Object *obj); Object* Object_Copy (Object *obj, Heap *heap, Error *err); int Object_Call (Object *obj, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *err); void Object_Print (Object *obj, FILE *fp); Object* Object_Select(Object *coll, Object *key, Heap *heap, Error *err); Object* Object_Delete(Object *coll, Object *key, Heap *heap, Error *err); -_Bool Object_Insert(Object *coll, Object *key, Object *val, Heap *heap, Error *err); +bool Object_Insert(Object *coll, Object *key, Object *val, Heap *heap, Error *err); int Object_Count (Object *coll, Error *err); -Object* Object_Next (Object *iter, Heap *heap, Error *err); -Object* Object_Prev (Object *iter, Heap *heap, Error *err); void Object_WalkReferences(Object *parent, void (*callback)(Object **referer, void *userp), void *userp); void Object_WalkExtensions(Object *parent, void (*callback)(void **referer, unsigned int size, void *userp), void *userp); @@ -140,12 +116,12 @@ Object* Object_NewMap(int num, Heap *heap, Error *error); Object* Object_NewList(int capacity, Heap *heap, Error *error); Object* Object_NewList2(int num, Object **items, Heap *heap, Error *error); Object* Object_NewNone(Heap *heap, Error *error); -Object* Object_NewBuffer(int size, Heap *heap, Error *error); +Object* Object_NewBuffer(size_t size, Heap *heap, Error *error); Object* Object_NewClosure(Object *parent, Object *new_map, Heap *heap, Error *error); -Object* Object_SliceBuffer(Object *buffer, int offset, int length, Heap *heap, Error *error); +Object* Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap, Error *error); Object* Object_FromInt (long long int val, Heap *heap, Error *error); -Object* Object_FromBool (_Bool val, Heap *heap, Error *error); +Object* Object_FromBool (bool val, Heap *heap, Error *error); Object* Object_FromFloat (double val, Heap *heap, Error *error); Object* Object_FromString(const char *str, int len, Heap *heap, Error *error); Object* Object_FromStream(FILE *fp, Heap *heap, Error *error); @@ -163,23 +139,24 @@ TypeObject *Object_GetBufferType(); TypeObject *Object_GetFileType(); TypeObject *Object_GetDirType(); -_Bool Object_IsNone(Object *obj); -_Bool Object_IsInt(Object *obj); -_Bool Object_IsBool(Object *obj); -_Bool Object_IsFloat(Object *obj); -_Bool Object_IsString(Object *obj); -_Bool Object_IsBuffer(Object *obj); -_Bool Object_IsFile(Object *obj); -_Bool Object_IsDir(Object *obj); +bool Object_IsNone(Object *obj); +bool Object_IsInt(Object *obj); +bool Object_IsBool(Object *obj); +bool Object_IsFloat(Object *obj); +bool Object_IsString(Object *obj); +bool Object_IsBuffer(Object *obj); +bool Object_IsFile(Object *obj); +bool Object_IsDir(Object *obj); -long long int Object_ToInt (Object *obj, Error *err); -_Bool Object_ToBool (Object *obj, Error *err); -double Object_ToFloat(Object *obj, Error *err); -const char *Object_ToString(Object *obj, int *size, Heap *heap, Error *err); -DIR *Object_ToDIR(Object *obj, Error *error); -FILE *Object_ToStream(Object *obj, Error *error); +long long int Object_GetInt (Object *obj); +bool Object_GetBool (Object *obj); +double Object_GetFloat(Object *obj); +const char *Object_GetString(Object *obj, int *size); +DIR *Object_GetDIR(Object *obj); +FILE *Object_GetStream(Object *obj); +void *Object_GetBuffer(Object *obj, size_t *size); -_Bool Object_Compare(Object *obj1, Object *obj2, Error *error); +bool Object_Compare(Object *obj1, Object *obj2, Error *error); extern TypeObject t_type; diff --git a/src/lib/runtime/o_staticmap.c b/src/lib/runtime/o_staticmap.c index 56d335a..f90bee0 100644 --- a/src/lib/runtime/o_staticmap.c +++ b/src/lib/runtime/o_staticmap.c @@ -116,7 +116,8 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) if(!Object_IsString(key)) return NULL; - const char *name = Object_ToString(key, NULL, heap, error); + const char *name = Object_GetString(key, NULL); + assert(name != NULL); if(map->slots == NULL) return NULL; diff --git a/src/lib/runtime/runtime.c b/src/lib/runtime/runtime.c index 9b540b7..ab43011 100644 --- a/src/lib/runtime/runtime.c +++ b/src/lib/runtime/runtime.c @@ -409,37 +409,22 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E if(Object_IsInt(lop)) { - long long int raw_lop = Object_ToInt(lop, error); - - if(error->occurred) - return NULL; + long long int raw_lop = Object_GetInt(lop); if(Object_IsInt(rop)) { // int + int - long long int raw_rop = Object_ToInt(rop, error); - - if(error->occurred) - return NULL; - + long long int raw_rop = Object_GetInt(rop); long long int raw_res = 0; - APPLY(raw_lop, raw_rop, raw_res, id) - res = Object_FromInt(raw_res, heap, error); } else if(Object_IsFloat(rop)) { // int + float - double raw_rop = Object_ToFloat(rop, error); - - if(error->occurred) - return NULL; - + double raw_rop = Object_GetFloat(rop); double raw_res = 0; - APPLY((double) raw_lop, raw_rop, raw_res, id) - res = Object_FromFloat(raw_res, heap, error); } else @@ -450,37 +435,22 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E } else if(Object_IsFloat(lop)) { - double raw_lop = Object_ToFloat(lop, error); - - if(error->occurred) - return NULL; + double raw_lop = Object_GetFloat(lop); if(Object_IsInt(rop)) { // float + int - long long int raw_rop = Object_ToInt(rop, error); - - if(error->occurred) - return NULL; - + long long int raw_rop = Object_GetInt(rop); double raw_res = 0; - APPLY(raw_lop, (double) raw_rop, raw_res, id) - res = Object_FromFloat(raw_res, heap, error); } else if(Object_IsFloat(rop)) { // float + float - double raw_rop = Object_ToFloat(rop, error); - - if(error->occurred) - return NULL; - + double raw_rop = Object_GetFloat(rop); double raw_res = 0; - APPLY(raw_lop, raw_rop, raw_res, id) - res = Object_FromFloat(raw_res, heap, error); } else @@ -519,29 +489,17 @@ static Object *do_relational_op(Object *lop, Object *rop, Opcode opcode, Heap *h if(Object_IsInt(lop)) { - long long int raw_lop = Object_ToInt(lop, error); - - if(error->occurred) - return NULL; - + long long int raw_lop = Object_GetInt(lop); if(Object_IsInt(rop)) { // int + int - long long int raw_rop = Object_ToInt(rop, error); - - if(error->occurred) - return NULL; - + long long int raw_rop = Object_GetInt(rop); APPLY(raw_lop, raw_rop, res, id) } else if(Object_IsFloat(rop)) { // int + float - double raw_rop = Object_ToFloat(rop, error); - - if(error->occurred) - return NULL; - + double raw_rop = Object_GetFloat(rop); APPLY((double) raw_lop, raw_rop, res, id) } else @@ -552,29 +510,17 @@ static Object *do_relational_op(Object *lop, Object *rop, Opcode opcode, Heap *h } else if(Object_IsFloat(lop)) { - double raw_lop = Object_ToFloat(lop, error); - - if(error->occurred) - return NULL; - + double raw_lop = Object_GetFloat(lop); if(Object_IsInt(rop)) { // float + int - long long int raw_rop = Object_ToInt(rop, error); - - if(error->occurred) - return NULL; - + long long int raw_rop = Object_GetInt(rop); APPLY(raw_lop, (double) raw_rop, res, id) } else if(Object_IsFloat(rop)) { // float + float - double raw_rop = Object_ToFloat(rop, error); - - if(error->occurred) - return NULL; - + double raw_rop = Object_GetFloat(rop); APPLY(raw_lop, raw_rop, res, id) } else @@ -651,20 +597,12 @@ static _Bool step(Runtime *runtime, Error *error) if(Object_IsInt(top)) { - long long n = Object_ToInt(top, error); - - if(error->occurred) - return 0; - + long long n = Object_GetInt(top); top = Object_FromInt(-n, heap, error); } else if(Object_IsFloat(top)) { - double f = Object_ToFloat(top, error); - - if(error->occurred) - return 0; - + double f = Object_GetFloat(top); top = Object_FromFloat(-f, heap, error); } else @@ -698,13 +636,15 @@ static _Bool step(Runtime *runtime, Error *error) ASSERT(top != NULL); - _Bool v = Object_ToBool(top, error); - - if(error->occurred) + if(!Object_IsBool(top)) + { + Error_Report(error, 0, "NOT operand isn't a boolean"); return 0; + } + + _Bool v = Object_GetBool(top); Object *negated = Object_FromBool(!v, runtime->heap, error); - if(negated == NULL) return 0; @@ -803,47 +743,6 @@ static _Bool step(Runtime *runtime, Error *error) return 1; } - case OPCODE_AND: - case OPCODE_OR: - { - ASSERT(opc == 0); - - Object *rop = Stack_Top(runtime->stack, 0); - Object *lop = Stack_Top(runtime->stack, -1); - - if(!Runtime_Pop(runtime, error, 2)) - return 0; - - // We managed to pop rop and lop, - // so we know they're not NULL. - ASSERT(rop != NULL); - ASSERT(lop != NULL); - - _Bool raw_rop, raw_lop, raw_res; - raw_lop = Object_ToBool(lop, error); - raw_rop = Object_ToBool(rop, error); - if(error->occurred) return 0; - - switch(opcode) - { - case OPCODE_AND: raw_res = raw_lop && raw_rop; break; - case OPCODE_OR: raw_res = raw_lop || raw_rop; break; - default: - UNREACHABLE; - raw_res = 0; - break; - } - - Object *res = Object_FromBool(raw_res, runtime->heap, error); - - if(res == NULL) - return 0; - - if(!Runtime_Push(runtime, error, res)) - return 0; - return 1; - } - case OPCODE_ASS: { ASSERT(opc == 1); @@ -1322,7 +1221,7 @@ static _Bool step(Runtime *runtime, Error *error) return 0; } - if(Object_ToBool(top, error)) // This can't fail because we know it's a bool. + if(Object_GetBool(top)) runtime->frame->index = target; return 1; @@ -1354,7 +1253,7 @@ static _Bool step(Runtime *runtime, Error *error) return 0; } - if(!Object_ToBool(top, error)) // This can't fail because we know it's a bool. + if(!Object_GetBool(top)) runtime->frame->index = target; return 1; diff --git a/src/lib/utils/error.c b/src/lib/utils/error.c index 51d11f2..a23ca20 100644 --- a/src/lib/utils/error.c +++ b/src/lib/utils/error.c @@ -30,9 +30,9 @@ #include #include -#include #include #include "error.h" +#include "defs.h" void Error_Init(Error *err) { @@ -66,18 +66,18 @@ void _Error_Report2(Error *err, _Bool internal, const char *file, const char *func, int line, const char *fmt, va_list va) { - assert(err); - assert(file); - assert(func); - assert(line > 0); - assert(fmt); + ASSERT(err); + ASSERT(file); + ASSERT(func); + ASSERT(line > 0); + ASSERT(fmt); #ifdef DEBUG if(err->occurred != 0) { fprintf(stderr, "Error previously reported at %s:%d (in %s) :: %s\n", err->file, err->line, err->func, err->message); } #endif - assert(err->occurred == 0); + ASSERT(err->occurred == 0); err->occurred = 1; err->internal = internal; @@ -90,7 +90,7 @@ void _Error_Report2(Error *err, _Bool internal, int p = vsnprintf(err->message2, sizeof(err->message2), fmt, va); - assert(p > -1); + ASSERT(p > -1); if((unsigned int) p > sizeof(err->message2)-1) { @@ -121,4 +121,18 @@ void _Error_Report2(Error *err, _Bool internal, if(err->on_report) err->on_report(err); +} + +void Error_Panic_(const char *file, int line, + const char *fmt, ...) +{ + FILE *fp = stderr; + + va_list args; + va_start(args, fmt); + fprintf(fp, "Panic: "); + vfprintf(fp, fmt, args); + fprintf(fp, " (reported in %s:%d)", file, line); + va_end(args); + abort(); } \ No newline at end of file diff --git a/src/lib/utils/error.h b/src/lib/utils/error.h index 3eea2d1..dae04da 100644 --- a/src/lib/utils/error.h +++ b/src/lib/utils/error.h @@ -53,4 +53,6 @@ void Error_Free(Error *err); #define Error_Report(err, internal, fmt, ...) _Error_Report(err, internal, __FILE__, __func__, __LINE__, fmt, ## __VA_ARGS__) void _Error_Report (Error *err, _Bool internal, const char *file, const char *func, int line, const char *fmt, ...); void _Error_Report2(Error *err, _Bool internal, const char *file, const char *func, int line, const char *fmt, va_list va); +void Error_Panic_(const char *file, int line, const char *fmt, ...); +#define Error_Panic(fmt, ...) Error_Panic_(__FILE__, __LINE__, fmt, ## __VA_ARGS__) #endif \ No newline at end of file