reorganized build-ins and implement a circular queue as an example

This commit is contained in:
cozis
2022-08-18 19:01:26 +02:00
parent b5b3a3e315
commit 782985e8b7
36 changed files with 486 additions and 259 deletions
+9 -134
View File
@@ -35,11 +35,13 @@
#include "math.h"
#include "basic.h"
#include "files.h"
#include "string.h"
#include "buffer.h"
#include "../utils/utf8.h"
#include "../utils/defs.h"
#include "../objects/objects.h"
#include "../compiler/compile.h"
#include "../runtime/runtime.h"
#include "../compiler/compile.h"
static int bin_print(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
@@ -364,129 +366,6 @@ static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object
return -1;
}
static int bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
unsigned int total_count = 0;
for(unsigned int i = 0; i < argc; i += 1)
{
if(!Object_IsString(argv[i]))
{
Error_Report(error, 0, "Argument #%d is not a string", i+1);
return -1;
}
total_count += Object_Count(argv[i], error);
if(error->occurred)
return -1;
}
char starting[128];
char *buffer = starting;
if(total_count > sizeof(starting)-1)
{
buffer = malloc(total_count+1);
if(buffer == NULL)
{
Error_Report(error, 1, "No memory");
return -1;
}
}
Object *result = NULL;
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;
memcpy(buffer + written, s, n);
written += n;
}
buffer[total_count] = '\0';
result = Object_FromString(buffer, total_count, Runtime_GetHeap(runtime), error);
done:
if(starting != buffer)
free(buffer);
if(result == NULL)
return -1;
rets[0] = result;
return 1;
}
static int bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
UNUSED(argc);
ASSERT(argc == 1);
long long int size = Object_ToInt(argv[0], error);
if(error->occurred == 1)
return -1;
Object *temp = Object_NewBuffer(size, Runtime_GetHeap(runtime), error);
if(temp == NULL)
return -1;
rets[0] = temp;
return 1;
}
static int bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
UNUSED(argc);
ASSERT(argc == 3);
long long int offset = Object_ToInt(argv[1], error);
if(error->occurred == 1) return -1;
long long int length = Object_ToInt(argv[2], error);
if(error->occurred == 1) return -1;
Object *temp = Object_SliceBuffer(argv[0], offset, length, Runtime_GetHeap(runtime), error);
if(temp == NULL)
return -1;
rets[0] = temp;
return 1;
}
static int bin_bufferToString(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
UNUSED(argc);
ASSERT(argc == 1);
void *buffaddr;
int buffsize;
buffaddr = Object_GetBufferAddrAndSize(argv[0], &buffsize, error);
if(error->occurred)
return -1;
Object *temp = Object_FromString(buffaddr, buffsize, Runtime_GetHeap(runtime), error);
if(temp == NULL)
return -1;
rets[0] = temp;
return 1;
}
void bins_basic_init(StaticMapSlot slots[])
{
slots[0].as_type = Object_GetTypeType();
@@ -512,17 +391,13 @@ StaticMapSlot bins_basic[] = {
{ "Map", SM_TYPE, .as_type = NULL /* Until bins_basic_init is called */ },
{ "File", SM_TYPE, .as_type = NULL /* Until bins_basic_init is called */ },
{ "Dir", SM_TYPE, .as_type = NULL /* Until bins_basic_init is called */ },
{ "math", SM_SMAP, .as_smap = bins_math, },
{ "files", SM_SMAP, .as_smap = bins_files, },
{ "math", SM_SMAP, .as_smap = bins_math, },
{ "files", SM_SMAP, .as_smap = bins_files, },
{ "buffer", SM_SMAP, .as_smap = bins_buffer, },
{ "string", SM_SMAP, .as_smap = bins_string, },
{ "import", SM_FUNCT, .as_funct = bin_import, .argc = 1, },
{ "newBuffer", SM_FUNCT, .as_funct = bin_newBuffer, .argc = 1 },
{ "sliceBuffer", SM_FUNCT, .as_funct = bin_sliceBuffer, .argc = 3 },
{ "bufferToString", SM_FUNCT, .as_funct = bin_bufferToString, .argc = 1 },
{ "strcat", SM_FUNCT, .as_funct = bin_strcat, .argc = -1 },
{ "type", SM_FUNCT, .as_funct = bin_type, .argc = 1 },
{ "unicode", SM_FUNCT, .as_funct = bin_unicode, .argc = 1 },
{ "chr", SM_FUNCT, .as_funct = bin_chr, .argc = 1 },
+70
View File
@@ -0,0 +1,70 @@
#include "buffer.h"
#include "../utils/defs.h"
#include "../runtime/runtime.h"
static int bin_new(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
UNUSED(argc);
ASSERT(argc == 1);
long long int size = Object_ToInt(argv[0], error);
if(error->occurred == 1)
return -1;
Object *temp = Object_NewBuffer(size, Runtime_GetHeap(runtime), error);
if(temp == NULL)
return -1;
rets[0] = temp;
return 1;
}
static int bin_sliceUp(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
UNUSED(argc);
ASSERT(argc == 3);
long long int offset = Object_ToInt(argv[1], error);
if(error->occurred == 1) return -1;
long long int length = Object_ToInt(argv[2], error);
if(error->occurred == 1) return -1;
Object *temp = Object_SliceBuffer(argv[0], offset, length, Runtime_GetHeap(runtime), error);
if(temp == NULL)
return -1;
rets[0] = temp;
return 1;
}
static int bin_toString(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
UNUSED(argc);
ASSERT(argc == 1);
void *buffaddr;
int buffsize;
buffaddr = Object_GetBufferAddrAndSize(argv[0], &buffsize, error);
if(error->occurred)
return -1;
Object *temp = Object_FromString(buffaddr, buffsize, Runtime_GetHeap(runtime), error);
if(temp == NULL)
return -1;
rets[0] = temp;
return 1;
}
StaticMapSlot bins_buffer[] = {
{ "new", SM_FUNCT, .as_funct = bin_new, .argc = 1 },
{ "sliceUp", SM_FUNCT, .as_funct = bin_sliceUp, .argc = 3 },
{ "toString", SM_FUNCT, .as_funct = bin_toString, .argc = 1 },
};
+2
View File
@@ -0,0 +1,2 @@
#include "../runtime/runtime.h"
extern StaticMapSlot bins_buffer[];
+30 -2
View File
@@ -38,6 +38,8 @@ enum {
MD_APPEND = 2,
};
#include <errno.h>
static int bin_openFile(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
UNUSED(argc);
@@ -94,8 +96,34 @@ static int bin_openFile(Runtime *runtime, Object **argv, unsigned int argc, Obje
fp = fopen(path, mode2);
if(fp == NULL)
return 0;
if(fp == NULL) {
Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL)
return -1;
const char *errdesc;
switch(errno) {
case EACCES: errdesc = "Can't access file"; break;
case EPERM: errdesc = "Permission denied"; break;
case EEXIST: errdesc = "File or folder already exists"; break;
case EISDIR: errdesc = "Entity is a directory"; break;
case ENOTDIR: errdesc = "Entity is not a directory"; break;
case ELOOP: errdesc = "Too many symbolic links"; break;
case ENAMETOOLONG: errdesc = "Entity name is too long"; break;
case ENFILE: errdesc = "Open descriptors limit reached"; break;
case ENOENT: errdesc = "File or folder doesn't exist"; break;
default: errdesc = "Unexpected error"; break;
}
Object *o_error = Object_FromString(errdesc, -1, heap, error);
if(o_error == NULL)
return -1;
rets[0] = o_none;
rets[1] = o_error;
return 2;
}
}
rets[0] = Object_FromStream(fp, heap, error);
+71
View File
@@ -0,0 +1,71 @@
#include <string.h>
#include <stdlib.h>
#include "string.h"
#include "../utils/defs.h"
#include "../runtime/runtime.h"
static int bin_cat(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{
unsigned int total_count = 0;
for(unsigned int i = 0; i < argc; i += 1)
{
if(!Object_IsString(argv[i]))
{
Error_Report(error, 0, "Argument #%d is not a string", i+1);
return -1;
}
total_count += Object_Count(argv[i], error);
if(error->occurred)
return -1;
}
char starting[128];
char *buffer = starting;
if(total_count > sizeof(starting)-1)
{
buffer = malloc(total_count+1);
if(buffer == NULL)
{
Error_Report(error, 1, "No memory");
return -1;
}
}
Object *result = NULL;
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;
memcpy(buffer + written, s, n);
written += n;
}
buffer[total_count] = '\0';
result = Object_FromString(buffer, total_count, Runtime_GetHeap(runtime), error);
done:
if(starting != buffer)
free(buffer);
if(result == NULL)
return -1;
rets[0] = result;
return 1;
}
StaticMapSlot bins_string[] = {
{ "cat", SM_FUNCT, .as_funct = bin_cat, .argc = -1 },
};
+2
View File
@@ -0,0 +1,2 @@
#include "../runtime/runtime.h"
extern StaticMapSlot bins_string[];
+3 -3
View File
@@ -40,13 +40,13 @@ struct ClosureObject {
};
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp);
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
static Object *select_(Object *self, Object *key, Heap *heap, Error *err);
static TypeObject t_closure = {
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
.name = "closure",
.size = sizeof(ClosureObject),
.select = select,
.select = select_,
.walk = walk,
};
@@ -69,7 +69,7 @@ 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;
+3 -3
View File
@@ -38,7 +38,7 @@ typedef struct {
Object **vals;
} ListObject;
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
static Object *select_(Object *self, Object *key, Heap *heap, Error *err);
static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *err);
static int count(Object *self);
static void print(Object *obj, FILE *fp);
@@ -53,7 +53,7 @@ static TypeObject t_list = {
.size = sizeof (ListObject),
.copy = copy,
.hash = hash,
.select = select,
.select = select_,
.insert = insert,
.count = count,
.print = print,
@@ -158,7 +158,7 @@ static void walkexts(Object *self, void (*callback)(void **referer, unsigned int
callback((void**) &list->vals, sizeof(Object) * list->capacity, userp);
}
static Object *select(Object *self, Object *key, Heap *heap, Error *error)
static Object *select_(Object *self, Object *key, Heap *heap, Error *error)
{
UNUSED(heap);
ASSERT(self != NULL);
+3 -3
View File
@@ -39,7 +39,7 @@ typedef struct {
Object **vals;
} MapObject;
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
static Object *select_(Object *self, Object *key, Heap *heap, Error *err);
static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *err);
static int count(Object *self);
static void print(Object *self, FILE *fp);
@@ -54,7 +54,7 @@ static TypeObject t_map = {
.size = sizeof (MapObject),
.copy = copy,
.hash = hash,
.select = select,
.select = select_,
.insert = insert,
.count = count,
.print = print,
@@ -174,7 +174,7 @@ static void walkexts(Object *self, void (*callback)(void **referer, unsigned int
callback((void**) &map->vals, sizeof(Object*) * capacity, userp);
}
static Object *select(Object *self, Object *key, Heap *heap, Error *error)
static Object *select_(Object *self, Object *key, Heap *heap, Error *error)
{
UNUSED(heap);
ASSERT(self != NULL);
+3 -3
View File
@@ -48,7 +48,7 @@ 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);
static Object *select_(Object *self, Object *key, Heap *heap, Error *error);
static TypeObject t_string = {
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
@@ -59,7 +59,7 @@ static TypeObject t_string = {
.count = count,
.copy = copy,
.print = print,
.select = select,
.select = select_,
.to_string = to_string,
.op_eql = op_eql,
.walkexts = walkexts,
@@ -89,7 +89,7 @@ static int char_index_to_offset(StringObject *str, int idx)
return scanned_bytes;
}
static Object *select(Object *self, Object *key, Heap *heap, Error *error)
static Object *select_(Object *self, Object *key, Heap *heap, Error *error)
{
ASSERT(self != NULL && self->type == &t_string);
ASSERT(key != NULL && heap != NULL && error != NULL);
+3 -3
View File
@@ -57,7 +57,7 @@ typedef struct {
const StaticMapSlot *slots;
} StaticMapObject;
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
static Object *select_(Object *self, Object *key, Heap *heap, Error *err);
static Object *copy(Object *self, Heap *heap, Error *err);
static int hash(Object *self);
@@ -67,7 +67,7 @@ static TypeObject t_staticmap = {
.size = sizeof (StaticMapObject),
.copy = copy,
.hash = hash,
.select = select,
.select = select_,
};
static Object *copy(Object *self, Heap *heap, Error *err)
@@ -103,7 +103,7 @@ Object *Object_NewStaticMap(StaticMapSlot slots[], void (*initfn)(StaticMapSlot[
return (Object*) obj;
}
static Object *select(Object *self, Object *key, Heap *heap, Error *error)
static Object *select_(Object *self, Object *key, Heap *heap, Error *error)
{
assert(self != NULL);
assert(self->type == &t_staticmap);
+7 -7
View File
@@ -27,6 +27,8 @@
** | with The Noja Interpreter. If not, see <http://www.gnu.org/licenses/>. |
** +--------------------------------------------------------------------------+
*/
#include <stdio.h>
#include <stdlib.h> // just for [abort]
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -46,16 +48,14 @@
#define ASSERT(X) \
do { \
if(!(X)) { \
fprintf(stderr, "Assertion failure %s:%d (in %s): [" #X "] is false\n", __FILE__, __LINE__, __func__); \
fprintf(stderr, "Assertion failure %s:%d (in %s): [%s] is false\n", __FILE__, __LINE__, __func__, #X); \
abort(); \
} \
} while(0);
#define UNREACHABLE \
do { \
if(!(x)) { \
fprintf(stderr, "ABORT at %s:%d (in %s): Reached code assumed to be unreachable\n", __FILE__, __LINE__, __func__); \
abort(); \
} \
#define UNREACHABLE \
do { \
fprintf(stderr, "ABORT at %s:%d (in %s): Reached code assumed to be unreachable\n", __FILE__, __LINE__, __func__); \
abort(); \
} while(0);
#else
#define ASSERT(x)