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));
|
||||
@@ -105,7 +105,7 @@ fun parseFloating(context: Map) {
|
||||
} while context.str[context.cur] != ".";
|
||||
|
||||
assert(isDigit(context.str[context.cur+1]));
|
||||
|
||||
|
||||
# Scan the decimal part.
|
||||
q = 1;
|
||||
do {
|
||||
@@ -137,7 +137,8 @@ fun parseIntegerOrFloating(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;
|
||||
|
||||
@@ -204,7 +205,7 @@ fun parseArray(context: Map) {
|
||||
}
|
||||
|
||||
fun parseValue(context: Map) {
|
||||
|
||||
|
||||
if context.cur == count(context.str):
|
||||
return none, "Source ended where a value was expected";
|
||||
|
||||
@@ -265,4 +266,4 @@ fun compareAny(A, B) {
|
||||
error("Maps aren't supported yet!");
|
||||
|
||||
return A == B;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
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};
|
||||
|
||||
@@ -11,7 +15,7 @@ fun push(stack, value) {
|
||||
stack.count = stack.count + 1;
|
||||
}
|
||||
|
||||
fun pop(stack) {
|
||||
fun Stack_Pop(stack: Map) {
|
||||
|
||||
if stack.head == none:
|
||||
return none;
|
||||
@@ -23,15 +27,36 @@ fun pop(stack) {
|
||||
return value;
|
||||
}
|
||||
|
||||
push(stack, 1);
|
||||
push(stack, 2);
|
||||
push(stack, 3);
|
||||
x = pop(stack);
|
||||
y = pop(stack);
|
||||
z = pop(stack);
|
||||
w = pop(stack);
|
||||
fun Stack_Print(stack: Map) {
|
||||
print("[");
|
||||
curr = stack.head;
|
||||
while curr != none: {
|
||||
print(curr.item);
|
||||
curr = curr.prev;
|
||||
if curr != none:
|
||||
print(", ");
|
||||
}
|
||||
print("]");
|
||||
}
|
||||
|
||||
stack = Stack_New(int);
|
||||
|
||||
Stack_Push(stack, 1);
|
||||
Stack_Push(stack, 2);
|
||||
Stack_Push(stack, 3);
|
||||
|
||||
Stack_Print(stack);
|
||||
print("\n");
|
||||
|
||||
x = Stack_Pop(stack);
|
||||
y = Stack_Pop(stack);
|
||||
z = Stack_Pop(stack);
|
||||
w = Stack_Pop(stack);
|
||||
|
||||
assert(x == 3);
|
||||
assert(y == 2);
|
||||
assert(z == 1);
|
||||
assert(w == none);
|
||||
|
||||
Stack_Print(stack);
|
||||
print("\n");
|
||||
Reference in New Issue
Block a user