modified C api for native functions

This commit is contained in:
cozis
2022-08-17 04:33:00 +02:00
parent 919bc6fcbd
commit 6ba7fd21ef
15 changed files with 171 additions and 497 deletions
-271
View File
@@ -1,271 +0,0 @@
fun isSpace(c)
return c == ' '
or c == '\t'
or c == '\n';
fun isDigit(c)
return unicode(c) <= unicode('9')
and unicode(c) >= unicode('0');
fun skip(ctx, test)
while not ended(ctx) and test(current(ctx)):
next(ctx);
fun ended(ctx)
return ctx.i == count(ctx.str);
fun next(ctx) {
assert(ctx.i < count(ctx.str));
ctx.i = ctx.i + 1;
}
fun current(ctx) {
assert(ctx.i < count(ctx.str));
return ctx.str[ctx.i];
}
fun parse(str) {
if str == none:
str = '';
ctx = {str: str, i: 0};
skip(ctx, isSpace);
if ended(ctx):
return none, 'Source only contains whitespace';
res, err = parseAny(ctx);
return res, err;
}
fun parseArray(ctx) {
assert(current(ctx) == '[');
next(ctx); # Skip '['.
skip(ctx, isSpace);
if ended(ctx):
return none, "Source ended inside an array";
arr = [];
if current(ctx) == ']': {
next(ctx);
return arr;
}
while true: {
child = parseAny(ctx);
if child == none:
return none;
arr[count(arr)] = child;
skip(ctx, isSpace);
if ended(ctx):
return none, "Source ended inside an array";
if current(ctx) == ']':
break;
if current(ctx) != ',':
return none, "Bad character inside array";
next(ctx); # Skip ','.
skip(ctx, isSpace);
if ended(ctx):
return none, "Source ended inside an array";
}
next(ctx);
return arr;
}
fun parseObject(ctx) {
assert(current(ctx) == '{');
next(ctx); # Skip '{'.
skip(ctx, isSpace);
if ended(ctx):
return none, "Source ended inside an object";
obj = {};
if current(ctx) == '}': {
next(ctx);
return {};
}
while true: {
if current(ctx) != '"':
return none, "Bad character where a string was expected";
key = parseString(ctx);
if key == none:
return none;
skip(ctx, isSpace);
if current(ctx) != ':':
return none, "Bad character where ':' was expected";
next(ctx); # Skip ':'.
skip(ctx, isSpace);
child = parseAny(ctx);
if child == none:
return none;
obj[key] = child;
skip(ctx, isSpace);
if ended(ctx):
return none, "Source ended inside an arrays";
if current(ctx) == '}':
break;
if current(ctx) != ',':
return none, "Bad character inside array";
next(ctx); # Skip ','.
skip(ctx, isSpace);
if ended(ctx):
return none, "Source ended inside an array";
}
next(ctx);
return obj;
}
fun parseString(ctx) {
next(ctx); # Skip the '"'.
buff = '';
while not ended(ctx) and current(ctx) != '"': {
buff = strcat(buff, current(ctx));
next(ctx);
}
if ended(ctx):
return none, "Source ended inside a string";
next(ctx); # Skip the '"'.
return buff;
}
fun parseNumber(ctx) {
assert(isDigit(current(ctx)));
# Number (int or float)
parsed = 0;
while not ended(ctx) and isDigit(current(ctx)): {
parsed = parsed * 10 + unicode(current(ctx)) - unicode('0');
next(ctx);
}
if ended(ctx):
return parsed;
if current(ctx) == '.': {
next(ctx);
if ended(ctx):
return none, "Source string ended unexpectedly after dot";
if not isDigit(current(ctx)):
return none, "Got something other than a digit after dot";
fact = 1;
while not ended(ctx) and isDigit(current(ctx)): {
fact = fact / 10.0;
parsed = parsed + fact * (unicode(current(ctx)) - unicode('0'));
next(ctx);
}
}
return parsed;
}
fun parseAny(ctx) {
assert(not ended(ctx));
if current(ctx) == '[':
res, err = parseArray(ctx);
else if current(ctx) == '{':
res, err = parseObject(ctx);
else if current(ctx) == '"':
res, err = parseString(ctx);
else if isDigit(current(ctx)):
res, err = parseNumber(ctx);
else
error("Not implemented yet");
return res, err;
}
tests = [
'',
'1',
'10',
'1.@10',
'1.10',
'"jeje"',
'[]',
'[1,2,3]',
' [ ] ',
' [ 1 , 2 , 3 ]',
'{}',
' { } ',
'{"hoy":4}',
' { "hoy" : 4 } '
];
i = 0;
while i < count(tests): {
res, err = parse(tests[i]);
if res == none:
print('Test ', i, ' failed (', err, ')\n');
else
print('Test ', i, ' passed (', tests[i], ' -> ', res, ')\n');
i = i + 1;
}
#file = files.openFile('examples/large-file.json', files.READ);
#if file == none:
# error("Failed to open file");
#
#buff = newBuffer(30000000);
#if buff == none:
# error("Failed to create buffer");
#
#n = files.read(file, buff);
#
#text = bufferToString(sliceBuffer(buff, 0, n));
#
#print(parse(text));
+2 -1
View File
@@ -137,7 +137,8 @@ fun parseIntegerOrFloating(context: Map) {
fun parseString(context: Map) { fun parseString(context: Map) {
assert(context.cur < count(context.str) and context.str[context.cur] == '"'); assert(context.cur < count(context.str)
and context.str[context.cur] == '"');
context.cur = context.cur + 1; context.cur = context.cur + 1;
-9
View File
@@ -1,9 +0,0 @@
fun hello()
return [1, 2, 3], "hello";
print((a, b, c) = hello(), '\n');
print('a = ', a, '\n');
print('b = ', b, '\n');
print('c = ', c, '\n');
-33
View File
@@ -1,33 +0,0 @@
fun duplica_forse(a) {
if a >= 10:
return a*2;
return none, "Il numero è inferiore a 10!";
}
fun duplica_forse2(a) {
res, err = duplica_forse(a);
return res, err;
}
num = 5;
num2, err = duplica_forse2(num);
if num2 == none:
print('ERRORE!!! ', err, '\n');
else
print(num2, '\n');
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a,
a, a, a = print();
+35 -10
View File
@@ -1,8 +1,12 @@
# Implementation of a stack using a linked list. # Implementation of a stack using a linked list.
stack = {count: 0, head: none}; fun Stack_New(T)
return { count: 0, head: none, type: T };
fun push(stack, value) { fun Stack_Push(stack: Map, value) {
if type(value) != stack.type:
error("Invalid type");
node = {prev: none, item: value}; node = {prev: none, item: value};
@@ -11,7 +15,7 @@ fun push(stack, value) {
stack.count = stack.count + 1; stack.count = stack.count + 1;
} }
fun pop(stack) { fun Stack_Pop(stack: Map) {
if stack.head == none: if stack.head == none:
return none; return none;
@@ -23,15 +27,36 @@ fun pop(stack) {
return value; return value;
} }
push(stack, 1); fun Stack_Print(stack: Map) {
push(stack, 2); print("[");
push(stack, 3); curr = stack.head;
x = pop(stack); while curr != none: {
y = pop(stack); print(curr.item);
z = pop(stack); curr = curr.prev;
w = pop(stack); 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(x == 3);
assert(y == 2); assert(y == 2);
assert(z == 1); assert(z == 1);
assert(w == none); assert(w == none);
Stack_Print(stack);
print("\n");
+21 -71
View File
@@ -41,11 +41,10 @@
#include "../compiler/compile.h" #include "../compiler/compile.h"
#include "../runtime/runtime.h" #include "../runtime/runtime.h"
static int bin_print(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_print(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(runtime); UNUSED(runtime);
UNUSED(rets); UNUSED(rets);
UNUSED(maxretc);
UNUSED(error); UNUSED(error);
for(int i = 0; i < (int) argc; i += 1) for(int i = 0; i < (int) argc; i += 1)
@@ -53,7 +52,7 @@ static int bin_print(Runtime *runtime, Object **argv, unsigned int argc, Object
return 0; return 0;
} }
static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argc); UNUSED(argc);
ASSERT(argc == 1); ASSERT(argc == 1);
@@ -109,22 +108,15 @@ static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object
Source *src = Source_FromFile(full_path, &sub_error); Source *src = Source_FromFile(full_path, &sub_error);
if(src == NULL) { if(src == NULL) {
if(maxretc == 0)
return 0;
Object *o_none = Object_NewNone(heap, error); Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL) if(o_none == NULL)
return -1; return -1;
if(maxretc == 1) {
rets[0] = o_none;
return 1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error); Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL) if(o_err == NULL)
return -1; return -1;
Error_Free(&sub_error);
Error_Free(&sub_error);
rets[0] = o_none; rets[0] = o_none;
rets[1] = o_err; rets[1] = o_err;
return 2; return 2;
@@ -142,85 +134,61 @@ static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object
} }
UNUSED(errname); UNUSED(errname);
{
if(maxretc == 0)
return 0;
Object *o_none = Object_NewNone(heap, error); Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL) if(o_none == NULL)
return -1; return -1;
if(maxretc == 1) {
rets[0] = o_none;
return 1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error); Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL) if(o_err == NULL)
return -1; return -1;
Error_Free(&sub_error);
Error_Free(&sub_error);
rets[0] = o_none; rets[0] = o_none;
rets[1] = o_err; rets[1] = o_err;
return 2; return 2;
} }
}
{
Object *sub_rets[8]; Object *sub_rets[8];
int sub_maxretc = sizeof(sub_rets)/sizeof(sub_rets[0]); {
int retc = run(runtime, &sub_error, exe, 0, NULL, NULL, 0, sub_rets, sub_maxretc); int retc = run(runtime, &sub_error, exe, 0, NULL, NULL, 0, sub_rets);
if(retc < 0) if(retc < 0)
{ {
const char *errname = "Runtime"; const char *errname = "Runtime";
// Snapshot? // Snapshot?
UNUSED(errname); UNUSED(errname);
{
if(maxretc == 0)
return 0;
Object *o_none = Object_NewNone(heap, error); Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL) if(o_none == NULL)
return -1; return -1;
if(maxretc == 1) {
rets[0] = o_none;
return 1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error); Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL) if(o_err == NULL)
return -1; return -1;
Error_Free(&sub_error);
Error_Free(&sub_error);
rets[0] = o_none; rets[0] = o_none;
rets[1] = o_err; rets[1] = o_err;
return 2; return 2;
} }
}
ASSERT(retc == 1); ASSERT(retc == 1);
}
if(maxretc == 0) Error_Free(&sub_error);
return 0;
rets[0] = sub_rets[0]; rets[0] = sub_rets[0];
return 1; return 1;
}
return 0;
} }
static int bin_type(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_type(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
ASSERT(argc == 1); ASSERT(argc == 1);
UNUSED(runtime); UNUSED(runtime);
UNUSED(error); UNUSED(error);
UNUSED(argc); UNUSED(argc);
if(maxretc == 0)
return 0;
rets[0] = (Object*) argv[0]->type; rets[0] = (Object*) argv[0]->type;
return 1; return 1;
} }
static int bin_unicode(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_unicode(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(runtime); UNUSED(runtime);
UNUSED(error); UNUSED(error);
@@ -257,13 +225,11 @@ static int bin_unicode(Runtime *runtime, Object **argv, unsigned int argc, Objec
if(temp == NULL) if(temp == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = temp; rets[0] = temp;
return 1; return 1;
} }
static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argc); UNUSED(argc);
ASSERT(argc == 1); ASSERT(argc == 1);
@@ -295,13 +261,11 @@ static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object **
if(temp == NULL) if(temp == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = temp; rets[0] = temp;
return 1; return 1;
} }
static int bin_count(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_count(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argc); UNUSED(argc);
ASSERT(argc == 1); ASSERT(argc == 1);
@@ -316,13 +280,11 @@ static int bin_count(Runtime *runtime, Object **argv, unsigned int argc, Object
if(temp == NULL) if(temp == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = temp; rets[0] = temp;
return 1; return 1;
} }
static int bin_input(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_input(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argv); UNUSED(argv);
UNUSED(argc); UNUSED(argc);
@@ -368,17 +330,14 @@ static int bin_input(Runtime *runtime, Object **argv, unsigned int argc, Object
if(res == NULL) if(res == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = res; rets[0] = res;
return 1; return 1;
} }
static int bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(runtime); UNUSED(runtime);
UNUSED(rets); UNUSED(rets);
UNUSED(maxretc);
for(unsigned int i = 0; i < argc; i += 1) for(unsigned int i = 0; i < argc; i += 1)
if(!Object_ToBool(argv[i], error)) if(!Object_ToBool(argv[i], error))
@@ -390,11 +349,10 @@ static int bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Object
return 0; return 0;
} }
static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argc); UNUSED(argc);
UNUSED(rets); UNUSED(rets);
UNUSED(maxretc);
ASSERT(argc == 1); ASSERT(argc == 1);
int length; int length;
@@ -409,7 +367,7 @@ static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object
return -1; return -1;
} }
static int bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
unsigned int total_count = 0; unsigned int total_count = 0;
@@ -467,13 +425,11 @@ done:
if(result == NULL) if(result == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = result; rets[0] = result;
return 1; return 1;
} }
static int bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argc); UNUSED(argc);
ASSERT(argc == 1); ASSERT(argc == 1);
@@ -488,13 +444,11 @@ static int bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Obj
if(temp == NULL) if(temp == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = temp; rets[0] = temp;
return 1; return 1;
} }
static int bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argc); UNUSED(argc);
ASSERT(argc == 3); ASSERT(argc == 3);
@@ -510,13 +464,11 @@ static int bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, O
if(temp == NULL) if(temp == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = temp; rets[0] = temp;
return 1; return 1;
} }
static int bin_bufferToString(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) static int bin_bufferToString(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
UNUSED(argc); UNUSED(argc);
ASSERT(argc == 1); ASSERT(argc == 1);
@@ -534,8 +486,6 @@ static int bin_bufferToString(Runtime *runtime, Object **argv, unsigned int argc
if(temp == NULL) if(temp == NULL)
return -1; return -1;
if(maxretc == 0)
return 0;
rets[0] = temp; rets[0] = temp;
return 1; return 1;
} }
@@ -568,7 +518,7 @@ StaticMapSlot bins_basic[] = {
{ "Dir", 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, }, { "math", SM_SMAP, .as_smap = bins_math, },
// { "files", SM_SMAP, .as_smap = bins_files, }, { "files", SM_SMAP, .as_smap = bins_files, },
// { "net", SM_SMAP, .as_smap = bins_net, }, // { "net", SM_SMAP, .as_smap = bins_net, },
{ "import", SM_FUNCT, .as_funct = bin_import, .argc = 1, }, { "import", SM_FUNCT, .as_funct = bin_import, .argc = 1, },
+61 -45
View File
@@ -27,11 +27,10 @@
** | with The Noja Interpreter. If not, see <http://www.gnu.org/licenses/>. | ** | with The Noja Interpreter. If not, see <http://www.gnu.org/licenses/>. |
** +--------------------------------------------------------------------------+ ** +--------------------------------------------------------------------------+
*/ */
#warning "Commented out whole file"
/*
#include <assert.h>
#include <errno.h> #include <errno.h>
#include "files.h" #include "files.h"
#include "../utils/defs.h"
enum { enum {
MD_READ = 0, MD_READ = 0,
@@ -39,20 +38,21 @@ enum {
MD_APPEND = 2, MD_APPEND = 2,
}; };
static Object *bin_openFile(Runtime *runtime, Object **argv, unsigned int argc, Error *error) static int bin_openFile(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
assert(argc == 2); UNUSED(argc);
ASSERT(argc == 2);
if(!Object_IsString(argv[0])) if(!Object_IsString(argv[0]))
{ {
Error_Report(error, 0, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0])); Error_Report(error, 0, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0]));
return NULL; return -1;
} }
if(!Object_IsInt(argv[1])) if(!Object_IsInt(argv[1]))
{ {
Error_Report(error, 0, "Expected second argument to be an int, but it's a %s", Object_GetName(argv[1])); Error_Report(error, 0, "Expected second argument to be an int, but it's a %s", Object_GetName(argv[1]));
return NULL; return -1;
} }
Heap *heap = Runtime_GetHeap(runtime); Heap *heap = Runtime_GetHeap(runtime);
@@ -60,12 +60,12 @@ static Object *bin_openFile(Runtime *runtime, Object **argv, unsigned int argc,
const char *path = Object_ToString(argv[0], NULL, heap, error); const char *path = Object_ToString(argv[0], NULL, heap, error);
if(error->occurred) if(error->occurred)
return NULL; return -1;
int mode = Object_ToInt(argv[1], error); int mode = Object_ToInt(argv[1], error);
if(error->occurred) if(error->occurred)
return NULL; return -1;
FILE *fp; FILE *fp;
{ {
@@ -87,22 +87,27 @@ static Object *bin_openFile(Runtime *runtime, Object **argv, unsigned int argc,
break; break;
default: default:
assert(0); UNREACHABLE;
mode2 = NULL;
break; break;
} }
fp = fopen(path, mode2); fp = fopen(path, mode2);
if(fp == NULL) if(fp == NULL)
return Object_NewNone(heap, error); return 0;
} }
return Object_FromStream(fp, heap, error); rets[0] = Object_FromStream(fp, heap, error);
if(rets[0] == NULL)
return -1;
return 1;
} }
static Object *bin_read(Runtime *runtime, Object **argv, unsigned int argc, Error *error) static int bin_read(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
assert(argc == 3); UNUSED(argc);
ASSERT(argc == 3);
// Arg 0: file // Arg 0: file
// Arg 1: buffer // Arg 1: buffer
@@ -111,13 +116,13 @@ static Object *bin_read(Runtime *runtime, Object **argv, unsigned int argc, Erro
if(!Object_IsFile(argv[0])) if(!Object_IsFile(argv[0]))
{ {
Error_Report(error, 0, "Expected first argument to be a file, but it's a %s", Object_GetName(argv[0])); Error_Report(error, 0, "Expected first argument to be a file, but it's a %s", Object_GetName(argv[0]));
return NULL; return -1;
} }
if(!Object_IsBuffer(argv[1])) if(!Object_IsBuffer(argv[1]))
{ {
Error_Report(error, 0, "Expected second argument to be a buffer, but it's a %s", Object_GetName(argv[1])); Error_Report(error, 0, "Expected second argument to be a buffer, but it's a %s", Object_GetName(argv[1]));
return NULL; return -1;
} }
Heap *heap = Runtime_GetHeap(runtime); Heap *heap = Runtime_GetHeap(runtime);
@@ -138,7 +143,7 @@ static Object *bin_read(Runtime *runtime, Object **argv, unsigned int argc, Erro
long long int temp = Object_ToInt(argv[2], error); long long int temp = Object_ToInt(argv[2], error);
if(error->occurred) if(error->occurred)
return NULL; return -1;
read_size = temp; // TODO: Handle potential overflow. read_size = temp; // TODO: Handle potential overflow.
@@ -148,22 +153,26 @@ static Object *bin_read(Runtime *runtime, Object **argv, unsigned int argc, Erro
else else
{ {
Error_Report(error, 0, "Expected third argument to be an int or none, but it's a %s", Object_GetName(argv[0])); Error_Report(error, 0, "Expected third argument to be an int or none, but it's a %s", Object_GetName(argv[0]));
return NULL; return -1;
} }
FILE *fp = Object_ToStream(argv[0], error); FILE *fp = Object_ToStream(argv[0], error);
if(fp == NULL) if(fp == NULL)
return NULL; return -1;
size_t n = fread(buff_addr, 1, read_size, fp); size_t n = fread(buff_addr, 1, read_size, fp);
return Object_FromInt(n, heap, error); rets[0] = Object_FromInt(n, heap, error);
if(rets[0] == NULL)
return -1;
return 1;
} }
static Object *bin_write(Runtime *runtime, Object **argv, unsigned int argc, Error *error) static int bin_write(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
assert(argc == 3); UNUSED(argc);
ASSERT(argc == 3);
// Arg 0: file // Arg 0: file
// Arg 1: buffer // Arg 1: buffer
@@ -172,13 +181,13 @@ static Object *bin_write(Runtime *runtime, Object **argv, unsigned int argc, Err
if(!Object_IsFile(argv[0])) if(!Object_IsFile(argv[0]))
{ {
Error_Report(error, 0, "Expected first argument to be a file, but it's a %s", Object_GetName(argv[0])); Error_Report(error, 0, "Expected first argument to be a file, but it's a %s", Object_GetName(argv[0]));
return NULL; return -1;
} }
if(!Object_IsBuffer(argv[1])) if(!Object_IsBuffer(argv[1]))
{ {
Error_Report(error, 0, "Expected second argument to be a buffer, but it's a %s", Object_GetName(argv[1])); Error_Report(error, 0, "Expected second argument to be a buffer, but it's a %s", Object_GetName(argv[1]));
return NULL; return -1;
} }
Heap *heap = Runtime_GetHeap(runtime); Heap *heap = Runtime_GetHeap(runtime);
@@ -199,7 +208,7 @@ static Object *bin_write(Runtime *runtime, Object **argv, unsigned int argc, Err
long long int temp = Object_ToInt(argv[2], error); long long int temp = Object_ToInt(argv[2], error);
if(error->occurred) if(error->occurred)
return NULL; return -1;
write_size = temp; // TODO: Handle potential overflow. write_size = temp; // TODO: Handle potential overflow.
@@ -209,29 +218,33 @@ static Object *bin_write(Runtime *runtime, Object **argv, unsigned int argc, Err
else else
{ {
Error_Report(error, 0, "Expected third argument to be an int or none, but it's a %s", Object_GetName(argv[0])); Error_Report(error, 0, "Expected third argument to be an int or none, but it's a %s", Object_GetName(argv[0]));
return NULL; return -1;
} }
FILE *fp = Object_ToStream(argv[0], error); FILE *fp = Object_ToStream(argv[0], error);
if(fp == NULL) if(fp == NULL)
return NULL; return -1;
size_t n = fwrite(buff_addr, 1, write_size, fp); size_t n = fwrite(buff_addr, 1, write_size, fp);
return Object_FromInt(n, heap, error); rets[0] = Object_FromInt(n, heap, error);
if(rets[0] == NULL)
return -1;
return 1;
} }
static Object *bin_openDir(Runtime *runtime, Object **argv, unsigned int argc, Error *error) static int bin_openDir(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
assert(argc == 1); UNUSED(argc);
ASSERT(argc == 1);
// Arg 0: path // Arg 0: path
if(!Object_IsString(argv[0])) if(!Object_IsString(argv[0]))
{ {
Error_Report(error, 0, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0])); Error_Report(error, 0, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0]));
return NULL; return -1;
} }
Heap *heap = Runtime_GetHeap(runtime); Heap *heap = Runtime_GetHeap(runtime);
@@ -239,42 +252,44 @@ static Object *bin_openDir(Runtime *runtime, Object **argv, unsigned int argc, E
const char *path = Object_ToString(argv[0], NULL, heap, error); const char *path = Object_ToString(argv[0], NULL, heap, error);
if(error->occurred) if(error->occurred)
return NULL; return -1;
DIR *dir = opendir(path); DIR *dir = opendir(path);
if(dir == NULL) if(dir == NULL)
return Object_NewNone(heap, error); return 0;
Object *dob = Object_FromDIR(dir, heap, error); Object *dob = Object_FromDIR(dir, heap, error);
if(error->occurred) if(error->occurred)
{ {
(void) closedir(dir); (void) closedir(dir);
return NULL; return -1;
} }
return dob; rets[0] = dob;
return 1;
} }
static Object *bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, Error *error) static int bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error)
{ {
assert(argc == 1); UNUSED(argc);
ASSERT(argc == 1);
// Arg 0: path // Arg 0: path
if(!Object_IsDir(argv[0])) if(!Object_IsDir(argv[0]))
{ {
Error_Report(error, 0, "Expected first argument to be a directory, but it's a %s", Object_GetName(argv[0])); Error_Report(error, 0, "Expected first argument to be a directory, but it's a %s", Object_GetName(argv[0]));
return NULL; return -1;
} }
DIR *dir = Object_ToDIR(argv[0], error); DIR *dir = Object_ToDIR(argv[0], error);
if(error->occurred) if(error->occurred)
return NULL; return -1;
assert(dir != NULL); ASSERT(dir != NULL);
Heap *heap = Runtime_GetHeap(runtime); Heap *heap = Runtime_GetHeap(runtime);
@@ -285,15 +300,17 @@ static Object *bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int arg
if(ent == NULL) if(ent == NULL)
{ {
if(errno == 0) if(errno == 0)
// Nothing left to read. return 0; // Nothing left to read.
return Object_NewNone(heap, error);
// An error occurred. // An error occurred.
Error_Report(error, 1, "Failed to read directory item"); Error_Report(error, 1, "Failed to read directory item");
return NULL; return -1;
} }
return Object_FromString(ent->d_name, -1, heap, error); rets[0] = Object_FromString(ent->d_name, -1, heap, error);
if(rets[0] == NULL)
return -1;
return 1;
} }
StaticMapSlot bins_files[] = { StaticMapSlot bins_files[] = {
@@ -307,4 +324,3 @@ StaticMapSlot bins_files[] = {
{ "write", SM_FUNCT, .as_funct = bin_write, .argc = 3, }, { "write", SM_FUNCT, .as_funct = bin_write, .argc = 3, },
{ NULL, SM_END, {}, {} }, { NULL, SM_END, {}, {} },
}; };
*/
+2 -7
View File
@@ -33,7 +33,7 @@
#include "../utils/defs.h" #include "../utils/defs.h"
#define WRAP_FUNC(name) \ #define WRAP_FUNC(name) \
static int bin_ ## name(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) \ static int bin_ ## name(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error) \
{ \ { \
UNUSED(argc); \ UNUSED(argc); \
ASSERT(argc == 1); \ ASSERT(argc == 1); \
@@ -45,15 +45,11 @@
if(error->occurred) \ if(error->occurred) \
return -1; \ return -1; \
\ \
if(maxretc > 0) \
{ \
rets[0] = Object_FromFloat(name(v), Runtime_GetHeap(runtime), error); \ rets[0] = Object_FromFloat(name(v), Runtime_GetHeap(runtime), error); \
if(rets[0] == NULL) \ if(rets[0] == NULL) \
return -1; \ return -1; \
return 1; \ return 1; \
} \ } \
return 0; \
} \
else \ else \
{ \ { \
Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); \ Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); \
@@ -62,7 +58,7 @@
} }
#define WRAP_FUNC_2(name) \ #define WRAP_FUNC_2(name) \
static int bin_ ## name(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error) \ static int bin_ ## name(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Error *error) \
{ \ { \
UNUSED(argc); \ UNUSED(argc); \
ASSERT(argc == 2); \ ASSERT(argc == 2); \
@@ -91,7 +87,6 @@
\ \
Object *res = Object_FromFloat(name(v1, v2), Runtime_GetHeap(runtime), error); \ Object *res = Object_FromFloat(name(v1, v2), Runtime_GetHeap(runtime), error); \
if(res == NULL) return -1; \ if(res == NULL) return -1; \
if(maxretc == 0) return 0; \
rets[0] = res; \ rets[0] = res; \
return 1; \ return 1; \
} }
+1 -3
View File
@@ -70,9 +70,7 @@ static _Bool interpret(Executable *exe)
Runtime_SetBuiltins(runt, bins); Runtime_SetBuiltins(runt, bins);
Object *rets[8]; Object *rets[8];
unsigned int maxretc = sizeof(rets)/sizeof(rets[0]); int retc = run(runt, (Error*) &error, exe, 0, NULL, NULL, 0, rets);
int retc = run(runt, (Error*) &error, exe, 0, NULL, NULL, 0, rets, maxretc);
// NOTE: The pointer to the builtins object is invalidated // NOTE: The pointer to the builtins object is invalidated
// now because it may be moved by the garbage collector. // now because it may be moved by the garbage collector.
+2 -2
View File
@@ -125,7 +125,7 @@ Object *Object_Copy(Object *obj, Heap *heap, Error *err)
return type->copy(obj, heap, err); return type->copy(obj, heap, err);
} }
int Object_Call(Object *obj, Object **argv, unsigned int argc, Object **rets, unsigned int maxrets, Heap *heap, Error *err) int Object_Call(Object *obj, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *err)
{ {
ASSERT(err != NULL && obj != NULL); ASSERT(err != NULL && obj != NULL);
@@ -138,7 +138,7 @@ int Object_Call(Object *obj, Object **argv, unsigned int argc, Object **rets, un
return -1; return -1;
} }
return type->call(obj, argv, argc, rets, maxrets, heap, err); return type->call(obj, argv, argc, rets, heap, err);
} }
void Object_Print(Object *obj, FILE *fp) void Object_Print(Object *obj, FILE *fp)
+4 -2
View File
@@ -35,6 +35,8 @@
#include <stdio.h> #include <stdio.h>
#include "../utils/error.h" #include "../utils/error.h"
#define MAX_RETS 8
typedef struct TypeObject TypeObject; typedef struct TypeObject TypeObject;
typedef struct Object Object; typedef struct Object Object;
typedef struct xHeap Heap; typedef struct xHeap Heap;
@@ -70,7 +72,7 @@ struct TypeObject {
_Bool (*free)(Object *self, Error *err); _Bool (*free)(Object *self, Error *err);
int (*hash)(Object *self); int (*hash)(Object *self);
Object* (*copy)(Object *self, Heap *heap, Error *err); Object* (*copy)(Object *self, Heap *heap, Error *err);
int (*call)(Object *self, Object **argv, unsigned int argc, Object **rets, unsigned int maxrets, Heap *heap, Error *err); int (*call)(Object *self, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *err);
void (*print)(Object *self, FILE *fp); void (*print)(Object *self, FILE *fp);
unsigned int (*deepsize)(const Object *self); unsigned int (*deepsize)(const Object *self);
@@ -123,7 +125,7 @@ unsigned int Object_GetDeepSize(const Object *obj, Error *err);
void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error); void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error);
int Object_Hash (Object *obj); int Object_Hash (Object *obj);
Object* Object_Copy (Object *obj, Heap *heap, Error *err); Object* Object_Copy (Object *obj, Heap *heap, Error *err);
int Object_Call (Object *obj, Object **argv, unsigned int argc, Object **rets, unsigned int maxrets, 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); void Object_Print (Object *obj, FILE *fp);
Object* Object_Select(Object *coll, Object *key, Heap *heap, Error *err); Object* Object_Select(Object *coll, Object *key, Heap *heap, Error *err);
Object* Object_Delete(Object *coll, Object *key, Heap *heap, Error *err); Object* Object_Delete(Object *coll, Object *key, Heap *heap, Error *err);
+2 -2
View File
@@ -57,7 +57,7 @@ static void walk(Object *self, void (*callback)(Object **referer, void *userp),
callback(&func->closure, userp); callback(&func->closure, userp);
} }
static int call(Object *self, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Heap *heap, Error *error) static int call(Object *self, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *error)
{ {
assert(self != NULL && heap != NULL && error != NULL); assert(self != NULL && heap != NULL && error != NULL);
@@ -108,7 +108,7 @@ static int call(Object *self, Object **argv, unsigned int argc, Object **rets, u
// The right amount of arguments was provided. // The right amount of arguments was provided.
argv2 = argv; argv2 = argv;
int retc = run(func->runtime, error, func->exe, func->index, func->closure, argv2, expected_argc, rets, maxretc); int retc = run(func->runtime, error, func->exe, func->index, func->closure, argv2, expected_argc, rets);
// NOTE: Every object reference is invalidated from here. // NOTE: Every object reference is invalidated from here.
+4 -4
View File
@@ -43,11 +43,11 @@
typedef struct { typedef struct {
Object base; Object base;
Runtime *runtime; Runtime *runtime;
int (*callback)(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error); int (*callback)(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[MAX_RETS], Error *error);
int argc; int argc;
} NativeFunctionObject; } NativeFunctionObject;
static int call(Object *self, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Heap *heap, Error *error) static int call(Object *self, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *error)
{ {
assert(self != NULL); assert(self != NULL);
assert(heap != NULL); assert(heap != NULL);
@@ -112,7 +112,7 @@ static int call(Object *self, Object **argv, unsigned int argc, Object **rets, u
} }
assert(func->callback != NULL); assert(func->callback != NULL);
int retc = func->callback(func->runtime, argv2, argc2, rets, maxretc, error); int retc = func->callback(func->runtime, argv2, argc2, rets, error);
// NOTE: Since the callback may have executed some bytecode, a GC // NOTE: Since the callback may have executed some bytecode, a GC
// cycle may have been triggered, therefore we must assume // cycle may have been triggered, therefore we must assume
@@ -156,7 +156,7 @@ static TypeObject t_nfunc = {
* The newly created object. If an error occurred, NULL is returned * The newly created object. If an error occurred, NULL is returned
* and information about the error is stored in the [error] argument. * and information about the error is stored in the [error] argument.
*/ */
Object *Object_FromNativeFunction(Runtime *runtime, int (*callback)(Runtime*, Object**, unsigned int, Object**, unsigned int, Error*), int argc, Heap *heap, Error *error) Object *Object_FromNativeFunction(Runtime *runtime, int (*callback)(Runtime*, Object**, unsigned int, Object*[static MAX_RETS], Error*), int argc, Heap *heap, Error *error)
{ {
assert(callback != NULL); assert(callback != NULL);
+5 -5
View File
@@ -916,9 +916,7 @@ static _Bool step(Runtime *runtime, Error *error)
ASSERT(error->occurred == 0); ASSERT(error->occurred == 0);
Object *rets[8]; Object *rets[8];
unsigned int maxrets = sizeof(rets)/sizeof(rets[0]); int num_rets = Object_Call(callable, argv, argc, rets, runtime->heap, error);
int num_rets = Object_Call(callable, argv, argc, rets, maxrets, runtime->heap, error);
if(num_rets < 0) if(num_rets < 0)
return 0; return 0;
@@ -1278,6 +1276,7 @@ static _Bool step(Runtime *runtime, Error *error)
int retc = ops[0].as_int; int retc = ops[0].as_int;
UNUSED(retc); UNUSED(retc);
ASSERT(retc >= 0); ASSERT(retc >= 0);
ASSERT(retc <= MAX_RETS);
ASSERT(retc == runtime->frame->used); ASSERT(retc == runtime->frame->used);
return 0; return 0;
} }
@@ -1400,7 +1399,7 @@ int run(Runtime *runtime, Error *error,
Executable *exe, int index, Executable *exe, int index,
Object *closure, Object *closure,
Object **argv, int argc, Object **argv, int argc,
Object **rets, int maxretc) Object *rets[static MAX_RETS])
{ {
ASSERT(runtime != NULL); ASSERT(runtime != NULL);
ASSERT(error != NULL); ASSERT(error != NULL);
@@ -1484,7 +1483,8 @@ int run(Runtime *runtime, Error *error,
// If an error occurred, we want to return NULL. // If an error occurred, we want to return NULL.
if(error->occurred == 0) if(error->occurred == 0)
{ {
retc = MIN(frame.used, maxretc); retc = frame.used;
ASSERT(retc <= MAX_RETS);
for(int i = 0; i < retc; i += 1) for(int i = 0; i < retc; i += 1)
{ {
+3 -3
View File
@@ -56,7 +56,7 @@ const char *Runtime_GetCurrentScriptAbsolutePath(Runtime *runtime);
Snapshot *Snapshot_New(Runtime *runtime); Snapshot *Snapshot_New(Runtime *runtime);
void Snapshot_Free(Snapshot *snapshot); void Snapshot_Free(Snapshot *snapshot);
void Snapshot_Print(Snapshot *snapshot, FILE *fp); void Snapshot_Print(Snapshot *snapshot, FILE *fp);
int run(Runtime *runtime, Error *error, Executable *exe, int index, Object *closure, Object **argv, int argc, Object **rets, int maxretc); int run(Runtime *runtime, Error *error, Executable *exe, int index, Object *closure, Object **argv, int argc, Object *rets[static MAX_RETS]);
typedef enum { typedef enum {
SM_END, SM_END,
@@ -81,7 +81,7 @@ struct StaticMapSlot {
_Bool as_bool; _Bool as_bool;
long long int as_int; long long int as_int;
double as_float; double as_float;
int (*as_funct)(Runtime*, Object**, unsigned int, Object**, unsigned int, Error*); int (*as_funct)(Runtime*, Object**, unsigned int, Object*[static MAX_RETS], Error*);
TypeObject *as_type; TypeObject *as_type;
}; };
union { int argc; int length; }; union { int argc; int length; };
@@ -89,7 +89,7 @@ struct StaticMapSlot {
Object *Object_NewStaticMap(StaticMapSlot slots[], void (*initfn)(StaticMapSlot[]), Runtime *runt, Error *error); Object *Object_NewStaticMap(StaticMapSlot slots[], void (*initfn)(StaticMapSlot[]), Runtime *runt, Error *error);
Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *closure, Heap *heap, Error *error); Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *closure, Heap *heap, Error *error);
Object *Object_FromNativeFunction(Runtime *runtime, int (*callback)(Runtime*, Object**, unsigned int, Object**, unsigned int, Error*), int argc, Heap *heap, Error *error); Object *Object_FromNativeFunction(Runtime *runtime, int (*callback)(Runtime*, Object**, unsigned int, Object*[static MAX_RETS], Error*), int argc, Heap *heap, Error *error);
typedef struct { typedef struct {
Error base; Error base;
Runtime *runtime; Runtime *runtime;