modified C api for native functions
This commit is contained in:
@@ -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));
|
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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');
|
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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, {}, {} },
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
@@ -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
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user