diff --git a/build.sh b/build.sh index c1d832e..f2f6d1f 100755 --- a/build.sh +++ b/build.sh @@ -49,14 +49,13 @@ gcc -c src/runtime/runtime_error.c -o temp/runtime/runtime_error.o $FLAGS gcc -c src/runtime/runtime.c -o temp/runtime/runtime.o $FLAGS gcc -c src/runtime/o_nfunc.c -o temp/runtime/o_nfunc.o $FLAGS gcc -c src/runtime/o_func.c -o temp/runtime/o_func.o $FLAGS +gcc -c src/runtime/o_staticmap.c -o temp/runtime/o_staticmap.o $FLAGS mkdir temp/builtins gcc -c src/builtins/basic.c -o temp/builtins/basic.o $FLAGS gcc -c src/builtins/file.c -o temp/builtins/file.o $FLAGS gcc -c src/builtins/math.c -o temp/builtins/math.o $FLAGS -gcc -c src/o_staticmap.c -o temp/o_staticmap.o $FLAGS - rm -rf build mkdir build @@ -82,7 +81,6 @@ ar rcs build/libnoja-runtime.a \ build/libnoja-objects.a gcc src/main.c \ - temp/o_staticmap.o \ temp/utils/hash.o \ temp/utils/stack.o \ temp/utils/source.o \ @@ -101,6 +99,7 @@ gcc src/main.c \ temp/runtime/runtime_error.o \ temp/runtime/o_nfunc.o \ temp/runtime/o_func.o \ + temp/runtime/o_staticmap.o \ temp/builtins/basic.o \ temp/builtins/file.o \ temp/builtins/math.o \ diff --git a/samples/buffer.noja b/samples/buffer.noja index 5130597..7e95a4f 100644 --- a/samples/buffer.noja +++ b/samples/buffer.noja @@ -5,16 +5,17 @@ b[2] = 10; print(b, '\n'); -fun toArray(buffer) - { - i = 0; - r = []; - while i < count(buffer): - { - r[i] = buffer[i]; - i = i+1; - } - return r; +fun toArray(buffer) { + + i = 0; + r = []; + + while i < count(buffer): { + r[i] = buffer[i]; + i = i+1; } + return r; +} + print(toArray(b), '\n'); diff --git a/samples/client.noja b/samples/client.noja deleted file mode 100644 index b5c11e8..0000000 --- a/samples/client.noja +++ /dev/null @@ -1,36 +0,0 @@ - -port = 8080; -addr = "127.0.0.1"; - -fd = net.socket(net.AF_INET, net.SOCK_STREAM, 0); - -if fd < 0: - { - print('Failed to create socket.\n'); - return none; - } - -sin_addr = {}; -if net.inet_aton(addr, sin_addr) == 0: - { - print('Bad address string format.\n'); - return none; - } - -if net.connect(fd, { sin_family: net.AF_INET, sin_port: net.htons(port), sin_addr: sin_addr }) != 0: - { - print('Failed to connect.\n'); - return none; - } - -print('Connected!\n'); - -buffer = newBuffer(16); - -buffer[0] = 9; -buffer[1] = 7; -buffer[2] = 255; - -n = net.send(fd, buffer, 0); - -print('Sent ', n, ' bytes: ', buffer, '\n'); \ No newline at end of file diff --git a/samples/hello-world.noja b/samples/hello-world.noja new file mode 100644 index 0000000..b8f8b46 --- /dev/null +++ b/samples/hello-world.noja @@ -0,0 +1 @@ +print('Hello, world!\n'); \ No newline at end of file diff --git a/samples/makegarbage.noja b/samples/makegarbage.noja index 27019fe..fdb9f4d 100644 --- a/samples/makegarbage.noja +++ b/samples/makegarbage.noja @@ -5,15 +5,15 @@ print('Start\n'); i = 0; n = 1000; -while i < n: - { - 1 + 1 * 1; - i = i + 1; +while i < n: { - fun printPercent() - print(100.0 * i / n, '%\n'); + 1 + 1 * 1; + i = i + 1; + + fun printPercent() + print(100.0 * i / n, '%\n'); - printPercent(); - } + printPercent(); +} print('End\n'); \ No newline at end of file diff --git a/samples/stack.noja b/samples/stack.noja index ae2666d..c1f6b6c 100644 --- a/samples/stack.noja +++ b/samples/stack.noja @@ -2,8 +2,8 @@ stack = {count: 0, head: none}; -fun push(stack, value) -{ +fun push(stack, value) { + node = {prev: none, item: value}; node.prev = stack.head; @@ -11,10 +11,10 @@ fun push(stack, value) stack.count = stack.count + 1; } -fun pop(stack) -{ +fun pop(stack) { + if stack.head == none: - return none; # return it; ? + return none; value = stack.head.item; stack.head = stack.head.prev; diff --git a/samples/strcat.noja b/samples/strcat.noja index e57a11a..d64ec3d 100644 --- a/samples/strcat.noja +++ b/samples/strcat.noja @@ -3,18 +3,4 @@ B = ', '; C = 'world'; D = strcat(A, B, C); -fun append_esclamation_mark(A, n) { - - if n == none: - n = 1; - - i = 0; - while i < n: { - A = strcat(A, '!'); - i = i + 1; - } - - return A; -} - -print(append_esclamation_mark(D, 3), '\n'); \ No newline at end of file +print(D, '\n'); \ No newline at end of file diff --git a/samples/tcp-server.noja b/samples/tcp-server.noja deleted file mode 100644 index 1f2731c..0000000 --- a/samples/tcp-server.noja +++ /dev/null @@ -1,108 +0,0 @@ -# Implementation of a basic TCP server that listen for connections and prints received bytes. - -fun startServer(callbacks, port, backlog) -{ - # Handle default arguments. - { - if callbacks == none: - callbacks = {}; - - if port == none: - port = 8000; - - if backlog == none: - backlog = 5; - } - - fd = net.socket(net.AF_INET, net.SOCK_STREAM, 0); - - if fd < 0: - { - print('Failed to create socket.\n'); - return none; - } - - if net.bind(fd, { - sin_family: net.AF_INET, - sin_port: net.htons(port), - sin_addr: { - s_addr: net.htonl(net.INADDR_ANY) - } - }) != 0: - { - print('Failed to bind.\n'); - return none; - } - - if net.listen(fd, backlog) != 0: - { - print('Failed to listen.\n'); - return none; - } - - { - on_datain = callbacks.on_datain; - on_connect = callbacks.on_connect; - on_disconnect = callbacks.on_disconnect; - - if on_datain == none: - fun on_datain() - none; - - if on_connect == none: - fun on_connect() - none; - - if on_disconnect == none: - fun on_disconnect() - none; - } - - buffer = newBuffer(1024); - - while true: - { - client_addr = {}; - client_fd = net.accept(fd, client_addr); - - if client_fd < 0: - { - print('Warning! Failed to accept!\n'); - continue; - } - - addr_str = net.inet_ntoa(client_addr.sin_addr); - - on_connect(addr_str); - - do - { - n = net.recv(client_fd, buffer, 0); - - if n < 0: - print('Warning! Failed to read from socket!\n'); - else if n == 0: - on_disconnect(addr_str); - else - on_datain(addr_str, sliceBuffer(buffer, 0, n)); - } - while n > 0; - } -} - -fun on_connect(addr) -{ - print(addr, ' connected.\n'); -} - -fun on_datain(addr, data) -{ - print('Received ', count(data), ' bytes from ', addr, ': ', data, '\n'); -} - -fun on_disconnect(addr) -{ - print(addr, ' disconnected.\n'); -} - -startServer({on_connect: on_connect, on_datain: on_datain, on_disconnect: on_disconnect}, 8080); \ No newline at end of file diff --git a/src/builtins/basic.h b/src/builtins/basic.h index 47693aa..b056b85 100644 --- a/src/builtins/basic.h +++ b/src/builtins/basic.h @@ -1,2 +1,2 @@ -#include "../o_staticmap.h" +#include "../runtime/o_staticmap.h" extern const StaticMapSlot bins_basic[]; \ No newline at end of file diff --git a/src/builtins/file.h b/src/builtins/file.h index b4b522f..ba697b9 100644 --- a/src/builtins/file.h +++ b/src/builtins/file.h @@ -1,2 +1,2 @@ -#include "../o_staticmap.h" +#include "../runtime/o_staticmap.h" extern const StaticMapSlot bins_file[]; \ No newline at end of file diff --git a/src/builtins/math.h b/src/builtins/math.h index 530cf13..a0870ae 100644 --- a/src/builtins/math.h +++ b/src/builtins/math.h @@ -1,2 +1,2 @@ -#include "../o_staticmap.h" +#include "../runtime/o_staticmap.h" extern const StaticMapSlot bins_math[]; \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5970187..0044d9a 100644 --- a/src/main.c +++ b/src/main.c @@ -2,11 +2,11 @@ #include #include #include -#include "o_staticmap.h" #include "compiler/parse.h" #include "compiler/compile.h" #include "runtime/runtime.h" #include "runtime/runtime_error.h" +#include "runtime/o_staticmap.h" #include "builtins/basic.h" static const char usage[] = @@ -16,11 +16,6 @@ static const char usage[] = " $ noja dis file.noja\n" " $ noja dis inline \"print('some noja code');\"\n"; -static _Bool interpret_file(const char *file); -static _Bool interpret_code(const char *code); -static _Bool disassemble_file(const char *file); -static _Bool disassemble_code(const char *code); - static void print_error(const char *type, Error *error) { if(type == NULL) @@ -47,93 +42,6 @@ static void print_error(const char *type, Error *error) fprintf(stderr, "\n"); } -int main(int argc, char **argv) -{ - assert(argc > 0); - - if(argc == 1) - { - // $ noja - fprintf(stderr, "Error: Incorrect usage.\n\n"); - fprintf(stderr, usage); - return -1; - } - - if(!strcmp(argv[1], "run")) - { - Error error; - Error_Init(&error); - - if(argc == 2) - { - Error_Report(&error, 0, "Missing source file"); - print_error(NULL, &error); - Error_Free(&error); - return -1; - } - - _Bool r; - - if(!strcmp(argv[2], "inline")) - { - if(argc == 3) - { - Error_Report(&error, 0, "Missing source string"); - print_error(NULL, &error); - Error_Free(&error); - return -1; - } - - r = interpret_code(argv[3]); - } - else - r = interpret_file(argv[2]); - return r ? 0 : -1; - } - - if(!strcmp(argv[1], "dis")) - { - Error error; - Error_Init(&error); - - if(argc == 2) - { - Error_Report(&error, 0, "Missing source file"); - print_error(NULL, &error); - Error_Free(&error); - return -1; - } - - _Bool r; - - if(!strcmp(argv[2], "inline")) - { - if(argc == 3) - { - Error_Report(&error, 0, "Missing source string"); - print_error(NULL, &error); - Error_Free(&error); - return -1; - } - - r = disassemble_code(argv[3]); - } - else - r = disassemble_file(argv[2]); - return r ? 0 : -1; - } - - if(!strcmp(argv[1], "help")) - { - fprintf(stdout, usage); - return 0; - } - - fprintf(stderr, "Error: Incorrect usage.\n\n"); - fprintf(stderr, usage); - return -1; -} - static _Bool interpret(Source *src) { // Compile the code. This section transforms @@ -374,4 +282,91 @@ static _Bool disassemble_code(const char *code) Source_Free(src); return r; -} \ No newline at end of file +} + +int main(int argc, char **argv) +{ + assert(argc > 0); + + if(argc == 1) + { + // $ noja + fprintf(stderr, "Error: Incorrect usage.\n\n"); + fprintf(stderr, usage); + return -1; + } + + if(!strcmp(argv[1], "run")) + { + Error error; + Error_Init(&error); + + if(argc == 2) + { + Error_Report(&error, 0, "Missing source file"); + print_error(NULL, &error); + Error_Free(&error); + return -1; + } + + _Bool r; + + if(!strcmp(argv[2], "inline")) + { + if(argc == 3) + { + Error_Report(&error, 0, "Missing source string"); + print_error(NULL, &error); + Error_Free(&error); + return -1; + } + + r = interpret_code(argv[3]); + } + else + r = interpret_file(argv[2]); + return r ? 0 : -1; + } + + if(!strcmp(argv[1], "dis")) + { + Error error; + Error_Init(&error); + + if(argc == 2) + { + Error_Report(&error, 0, "Missing source file"); + print_error(NULL, &error); + Error_Free(&error); + return -1; + } + + _Bool r; + + if(!strcmp(argv[2], "inline")) + { + if(argc == 3) + { + Error_Report(&error, 0, "Missing source string"); + print_error(NULL, &error); + Error_Free(&error); + return -1; + } + + r = disassemble_code(argv[3]); + } + else + r = disassemble_file(argv[2]); + return r ? 0 : -1; + } + + if(!strcmp(argv[1], "help")) + { + fprintf(stdout, usage); + return 0; + } + + fprintf(stderr, "Error: Incorrect usage.\n\n"); + fprintf(stderr, usage); + return -1; +} diff --git a/src/runtime/o_func.h b/src/runtime/o_func.h new file mode 100644 index 0000000..063d05d --- /dev/null +++ b/src/runtime/o_func.h @@ -0,0 +1,5 @@ +#ifndef NOJAFUNC_H +#define NOJAFUNC_H +#include "runtime.h" +Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *closure, Heap *heap, Error *error); +#endif \ No newline at end of file diff --git a/src/runtime/o_nfunc.h b/src/runtime/o_nfunc.h new file mode 100644 index 0000000..79a98f3 --- /dev/null +++ b/src/runtime/o_nfunc.h @@ -0,0 +1,5 @@ +#ifndef NOJAFUNC_H +#define NOJAFUNC_H +#include "runtime.h" +Object *Object_FromNativeFunction(Runtime *runtime, Object *(*callback)(Runtime*, Object**, unsigned int, Error*), int argc, Heap *heap, Error *error); +#endif \ No newline at end of file diff --git a/src/o_staticmap.c b/src/runtime/o_staticmap.c similarity index 97% rename from src/o_staticmap.c rename to src/runtime/o_staticmap.c index 848b8af..d280470 100644 --- a/src/o_staticmap.c +++ b/src/runtime/o_staticmap.c @@ -27,9 +27,10 @@ */ #include #include +#include "o_nfunc.h" #include "o_staticmap.h" -#include "utils/defs.h" -#include "objects/objects.h" +#include "../utils/defs.h" +#include "../objects/objects.h" typedef struct { Object base; diff --git a/src/o_staticmap.h b/src/runtime/o_staticmap.h similarity index 91% rename from src/o_staticmap.h rename to src/runtime/o_staticmap.h index db1893a..6ac3f64 100644 --- a/src/o_staticmap.h +++ b/src/runtime/o_staticmap.h @@ -1,8 +1,8 @@ #ifndef STATICMAP_H #define STATICMAP_H -#include "objects/objects.h" -#include "runtime/runtime.h" +#include "../objects/objects.h" +#include "runtime.h" typedef enum { SM_END, diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index e3ca8d3..2a0ecec 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -1,6 +1,7 @@ #include #include "../utils/defs.h" #include "../utils/stack.h" +#include "o_func.h" #include "runtime.h" #define MAX_FRAME_STACK 16 @@ -26,39 +27,6 @@ struct xRuntime { Heap *heap; }; -CallStackScanner *CallStackScanner_New(Runtime *runtime) -{ - return runtime->frame; -} - -_Bool CallStackScanner_Next(CallStackScanner **scanner, Object **locals, Object **closure, Executable **exe, int *index) -{ - assert(scanner != NULL); - - if(*scanner == NULL) - return 0; - - { - Frame *frame = *scanner; - - if(exe) - *exe = frame->exe; - - if(index) - *index = frame->index; - - if(locals) - *locals = frame->locals; - - if(closure) - *closure = frame->closure; - } - - (*scanner) = ((Frame*) (*scanner))->prev; - return 1; -} - - Stack *Runtime_GetStack(Runtime *runtime) { return Stack_Copy(runtime->stack, 1); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 4ad2799..16b4ee8 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -5,9 +5,8 @@ #include "../utils/stack.h" #include "../objects/objects.h" #include "../common/executable.h" - typedef struct xRuntime Runtime; -typedef void CallStackScanner; +typedef struct xSnapshot Snapshot; Runtime* Runtime_New(int stack_size, int heap_size, void *callback_userp, _Bool (*callback_addr)(Runtime*, void*)); Runtime* Runtime_New2(int stack_size, Heap *heap, _Bool free_heap, void *callback_userp, _Bool (*callback_addr)(Runtime*, void*)); void Runtime_Free(Runtime *runtime); @@ -19,18 +18,8 @@ Object* Runtime_GetBuiltins(Runtime *runtime); void Runtime_SetBuiltins(Runtime *runtime, Object *builtins); int Runtime_GetCurrentIndex(Runtime *runtime); Executable *Runtime_GetCurrentExecutable(Runtime *runtime); - -typedef struct xSnapshot Snapshot; -Snapshot *Snapshot_New(Runtime *runtime); -void Snapshot_Free(Snapshot *snapshot); -void Snapshot_Print(Snapshot *snapshot, FILE *fp); - -CallStackScanner *CallStackScanner_New(Runtime *runtime); -_Bool CallStackScanner_Next(CallStackScanner **scanner, Object **locals, Object **closure, Executable **exe, int *index); - - -Object *run(Runtime *runtime, Error *error, Executable *exe, int index, Object *closure, Object **argv, int argc); - -Object* Object_FromNativeFunction(Runtime *runtime, Object *(*callback)(Runtime*, Object**, unsigned int, Error*), int argc, Heap *heap, Error *error); -Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *closure, Heap *heap, Error *error); +Snapshot *Snapshot_New(Runtime *runtime); +void Snapshot_Free(Snapshot *snapshot); +void Snapshot_Print(Snapshot *snapshot, FILE *fp); +Object *run(Runtime *runtime, Error *error, Executable *exe, int index, Object *closure, Object **argv, int argc); #endif \ No newline at end of file