From 3c1ddff2dbdeb7c17814105167e2c59376c63c99 Mon Sep 17 00:00:00 2001 From: orangea Date: Wed, 6 Oct 2010 16:35:08 -0700 Subject: [PATCH 01/26] 'Object()' now works, no more segmentation fault. --- core/objmodel.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/objmodel.c b/core/objmodel.c index baf7605f..e46402a4 100644 --- a/core/objmodel.c +++ b/core/objmodel.c @@ -47,12 +47,17 @@ PN potion_closure_string(Potion *P, PN cl, PN self, PN len) { return PN_STR_B(out); } +PN potion_no_call(Potion *P, PN cl, PN self) { + return self; +} + PN potion_type_new(Potion *P, PNType t, PN self) { vPN(Vtable) vt = PN_CALLOC_N(PN_TVTABLE, struct PNVtable, 0); vt->type = t; vt->name = (PN)NULL; vt->parent = self; vt->methods = (struct PNTable *)potion_table_empty(P); + vt->ctor = PN_FUNC(potion_no_call, 0); PN_VTABLE(t) = (PN)vt; return (PN)vt; } @@ -83,10 +88,6 @@ PN potion_obj_get_callset(Potion *P, PN obj) { return cl; } -PN potion_no_call(Potion *P, PN cl, PN self) { - return self; -} - PN potion_class(Potion *P, PN cl, PN self, PN ivars) { PN parent = (self == P->lobby ? PN_VTABLE(PN_TOBJECT) : self); PN pvars = ((struct PNVtable *)parent)->ivars; From 9899615c7857e955e09d70209d7fc7dc9fd77c16 Mon Sep 17 00:00:00 2001 From: orangea Date: Wed, 6 Oct 2010 18:07:55 -0700 Subject: [PATCH 02/26] Added forgotten #includes, Made File class visible to scripts, gave it a constructor. --- core/file.c | 32 +++++++++++++++++++++++++++++--- core/internal.c | 1 + core/objmodel.c | 1 + core/potion.h | 3 ++- core/table.h | 4 ++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/core/file.c b/core/file.c index 8181661f..b12edba9 100644 --- a/core/file.c +++ b/core/file.c @@ -6,13 +6,37 @@ // #include #include +#include #include "potion.h" #include "internal.h" +#include "table.h" extern char **environ; -PN potion_file_with(Potion *P, PN cl, PN self, PN path) { - return PN_NIL; +PN potion_file_new(Potion *P, PN cl, PN self, PN path, PN modestr) { + int fd; + mode_t mode; + if (strcmp(PN_STR_PTR(modestr), "r") == 0) { + mode = O_RDONLY; + } else if (strcmp(PN_STR_PTR(modestr), "r+") == 0) { + mode = O_RDWR; + } else if (strcmp(PN_STR_PTR(modestr), "w") == 0) { + mode = O_WRONLY | O_TRUNC | O_CREAT; + } else if (strcmp(PN_STR_PTR(modestr), "w+") == 0) { + mode = O_RDWR | O_TRUNC | O_CREAT; + } else { + // invalid mode + return PN_NIL; + } + if ((fd = open(PN_STR_PTR(path), mode)) == -1) { + perror("open"); + // TODO: error + return PN_NIL; + } + ((struct PNFile *)self)->fd = fd; + ((struct PNFile *)self)->path = path; + ((struct PNFile *)self)->mode = mode; + return self; } PN potion_lobby_read(Potion *P, PN cl, PN self) { @@ -24,7 +48,7 @@ PN potion_lobby_read(Potion *P, PN cl, PN self) { } void potion_file_init(Potion *P) { - // PN file_vt = PN_VTABLE(PN_TFILE); + PN file_vt = PN_VTABLE(PN_TFILE); char **env = environ, *key; PN pe = potion_table_empty(P); while (*env != NULL) { @@ -35,4 +59,6 @@ void potion_file_init(Potion *P) { } potion_send(P->lobby, PN_def, potion_str(P, "Env"), pe); potion_method(P->lobby, "read", potion_lobby_read, 0); + + ((struct PNVtable *)file_vt)->ctor = PN_FUNC(potion_file_new, "path=S,mode=S"); } diff --git a/core/internal.c b/core/internal.c index e19ffafd..b7d2f8ff 100644 --- a/core/internal.c +++ b/core/internal.c @@ -33,6 +33,7 @@ static void potion_init(Potion *P) { potion_type_new(P, PN_TTABLE, obj_vt); potion_type_new(P, PN_TCLOSURE, obj_vt); potion_type_new(P, PN_TTUPLE, obj_vt); + potion_type_new(P, PN_TFILE, obj_vt); potion_type_new(P, PN_TSTATE, obj_vt); potion_type_new(P, PN_TSOURCE, obj_vt); potion_type_new(P, PN_TBYTES, obj_vt); diff --git a/core/objmodel.c b/core/objmodel.c index e46402a4..05efcbf3 100644 --- a/core/objmodel.c +++ b/core/objmodel.c @@ -368,6 +368,7 @@ void potion_lobby_init(Potion *P) { potion_init_class_reference(P, potion_str(P, "Table"), PN_VTABLE(PN_TTABLE)); potion_init_class_reference(P, potion_str(P, "Function"), PN_VTABLE(PN_TCLOSURE)); potion_init_class_reference(P, potion_str(P, "Tuple"), PN_VTABLE(PN_TTUPLE)); + potion_init_class_reference(P, potion_str(P, "File"), PN_VTABLE(PN_TFILE)); potion_init_class_reference(P, potion_str(P, "Potion"), PN_VTABLE(PN_TSTATE)); potion_init_class_reference(P, potion_str(P, "Source"), PN_VTABLE(PN_TSOURCE)); potion_init_class_reference(P, potion_str(P, "Bytes"), PN_VTABLE(PN_TBYTES)); diff --git a/core/potion.h b/core/potion.h index e79b7210..ee11bc82 100644 --- a/core/potion.h +++ b/core/potion.h @@ -18,6 +18,7 @@ #include #include +#include #include "config.h" // @@ -237,7 +238,7 @@ struct PNFile { PN_OBJECT_HEADER int fd; PN path; - PN mode; + mode_t mode; }; typedef PN (*PN_F)(Potion *, PN, PN, ...); diff --git a/core/table.h b/core/table.h index 5a7e0a22..a50f6933 100644 --- a/core/table.h +++ b/core/table.h @@ -7,6 +7,10 @@ #ifndef POTION_TABLE_H #define POTION_TABLE_H +#include "potion.h" +#include "internal.h" +#include "khash.h" + typedef PN (*PN_MCACHE_FUNC)(unsigned int hash); // TODO: ensure the random PNUniq is truly unique for strings typedef PN (*PN_IVAR_FUNC)(PNUniq hash); From 8e4911052f008b65b03e2d92141f158cf11582c2 Mon Sep 17 00:00:00 2001 From: orangea Date: Wed, 6 Oct 2010 18:13:22 -0700 Subject: [PATCH 03/26] objmodel.c: Added 'potion_type_constructor_is' function, like 'potion_type_call_is'. --- core/objmodel.c | 4 ++++ core/potion.h | 1 + 2 files changed, 5 insertions(+) diff --git a/core/objmodel.c b/core/objmodel.c index 05efcbf3..173437c9 100644 --- a/core/objmodel.c +++ b/core/objmodel.c @@ -88,6 +88,10 @@ PN potion_obj_get_callset(Potion *P, PN obj) { return cl; } +void potion_type_constructor_is(PN vt, PN cl) { + ((struct PNVtable *)vt)->ctor = cl; +} + PN potion_class(Potion *P, PN cl, PN self, PN ivars) { PN parent = (self == P->lobby ? PN_VTABLE(PN_TOBJECT) : self); PN pvars = ((struct PNVtable *)parent)->ivars; diff --git a/core/potion.h b/core/potion.h index ee11bc82..b98e01be 100644 --- a/core/potion.h +++ b/core/potion.h @@ -548,6 +548,7 @@ PN potion_type_new(Potion *, PNType, PN); PN potion_type_new2(Potion *, PNType, PN, PN); void potion_type_call_is(PN, PN); void potion_type_callset_is(PN, PN); +void potion_type_constructor_is(PN, PN); PN potion_class(Potion *, PN, PN, PN); PN potion_ivars(Potion *, PN, PN, PN); PN potion_obj_get_call(Potion *, PN); From ddac3fb9e1cab5c9c35b66f696c08aff05634e95 Mon Sep 17 00:00:00 2001 From: orangea Date: Wed, 6 Oct 2010 18:20:04 -0700 Subject: [PATCH 04/26] Have file.c use potion_type_constructor_is. --- core/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/file.c b/core/file.c index b12edba9..edafb2d3 100644 --- a/core/file.c +++ b/core/file.c @@ -60,5 +60,5 @@ void potion_file_init(Potion *P) { potion_send(P->lobby, PN_def, potion_str(P, "Env"), pe); potion_method(P->lobby, "read", potion_lobby_read, 0); - ((struct PNVtable *)file_vt)->ctor = PN_FUNC(potion_file_new, "path=S,mode=S"); + potion_type_constructor_is(file_vt, PN_FUNC(potion_file_new, "path=S,mode=S")); } From 5f811fc8f2800096792c3f839ce76091af66a25e Mon Sep 17 00:00:00 2001 From: orangea Date: Wed, 6 Oct 2010 19:47:09 -0700 Subject: [PATCH 05/26] file.c: Added 'string' method to the 'File' class. --- core/file.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/file.c b/core/file.c index edafb2d3..6ee0aee8 100644 --- a/core/file.c +++ b/core/file.c @@ -39,6 +39,19 @@ PN potion_file_new(Potion *P, PN cl, PN self, PN path, PN modestr) { return self; } +PN potion_file_string(Potion *P, PN cl, PN self) { + int fd = ((struct PNFile *)self)->fd; + char *buf; + PN str; + if (asprintf(&buf, "", fd) == -1) { + fprintf(stderr, "** Couldn't allocate memory.\n"); + exit(1); + } + str = potion_str(P, buf); + free(buf); + return str; +} + PN potion_lobby_read(Potion *P, PN cl, PN self) { const int linemax = 1024; char line[linemax]; @@ -61,4 +74,5 @@ void potion_file_init(Potion *P) { potion_method(P->lobby, "read", potion_lobby_read, 0); potion_type_constructor_is(file_vt, PN_FUNC(potion_file_new, "path=S,mode=S")); + potion_method(file_vt, "string", potion_file_string, 0); } From 68f5b09fb081ab2bdcb52d9aad5471877f835d11 Mon Sep 17 00:00:00 2001 From: orangea Date: Wed, 6 Oct 2010 19:56:44 -0700 Subject: [PATCH 06/26] file.c: Added 'close' method for files. I didn't know what to set the fd to afterwards, so I used -1. --- core/file.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/file.c b/core/file.c index 6ee0aee8..deb1ea77 100644 --- a/core/file.c +++ b/core/file.c @@ -6,6 +6,7 @@ // #include #include +#include #include #include "potion.h" #include "internal.h" @@ -39,6 +40,12 @@ PN potion_file_new(Potion *P, PN cl, PN self, PN path, PN modestr) { return self; } +PN potion_file_close(Potion *P, PN cl, PN self) { + close(((struct PNFile *)self)->fd); + ((struct PNFile *)self)->fd = -1; + return PN_NIL; +} + PN potion_file_string(Potion *P, PN cl, PN self) { int fd = ((struct PNFile *)self)->fd; char *buf; @@ -75,4 +82,5 @@ void potion_file_init(Potion *P) { potion_type_constructor_is(file_vt, PN_FUNC(potion_file_new, "path=S,mode=S")); potion_method(file_vt, "string", potion_file_string, 0); + potion_method(file_vt, "close", potion_file_close, 0); } From 24eb536db266ea698cf151e0220246972134feb5 Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 07:24:03 -0700 Subject: [PATCH 07/26] file.c: Added 'read' method for files. --- core/file.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/file.c b/core/file.c index deb1ea77..d1ccf2a0 100644 --- a/core/file.c +++ b/core/file.c @@ -46,6 +46,20 @@ PN potion_file_close(Potion *P, PN cl, PN self) { return PN_NIL; } +PN potion_file_read(Potion *P, PN cl, PN self, PN n) { + n = PN_INT(n); + char buf[n]; + int r = read(((struct PNFile *)self)->fd, buf, n); + if (r == -1) { + perror("read"); + // TODO: error + return PN_NUM(-1); + } else if (r == 0) { + return PN_NIL; + } + return potion_str2(P, buf, r); +} + PN potion_file_string(Potion *P, PN cl, PN self) { int fd = ((struct PNFile *)self)->fd; char *buf; @@ -83,4 +97,5 @@ void potion_file_init(Potion *P) { potion_type_constructor_is(file_vt, PN_FUNC(potion_file_new, "path=S,mode=S")); potion_method(file_vt, "string", potion_file_string, 0); potion_method(file_vt, "close", potion_file_close, 0); + potion_method(file_vt, "read", potion_file_read, "n=N"); } From 1660fdf88bf9ee4cc8340187b28814aafb116681 Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 08:06:50 -0700 Subject: [PATCH 08/26] file.c: Added 'a' and 'a+' creation modes. --- core/file.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/file.c b/core/file.c index d1ccf2a0..3f64eefd 100644 --- a/core/file.c +++ b/core/file.c @@ -25,6 +25,10 @@ PN potion_file_new(Potion *P, PN cl, PN self, PN path, PN modestr) { mode = O_WRONLY | O_TRUNC | O_CREAT; } else if (strcmp(PN_STR_PTR(modestr), "w+") == 0) { mode = O_RDWR | O_TRUNC | O_CREAT; + } else if (strcmp(PN_STR_PTR(modestr), "a") == 0) { + mode = O_WRONLY | O_CREAT | O_APPEND; + } else if (strcmp(PN_STR_PTR(modestr), "a+") == 0) { + mode = O_RDWR | O_CREAT | O_APPEND; } else { // invalid mode return PN_NIL; From a21c187c6ed41bf4ccd2e4517f7d3cad52ebe1be Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 11:35:27 -0700 Subject: [PATCH 09/26] gc.c: Not sure what this is for, but it probably fixes *something*. --- core/gc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/gc.c b/core/gc.c index adeca6f9..a7a2b0d5 100644 --- a/core/gc.c +++ b/core/gc.c @@ -383,6 +383,7 @@ void *potion_mark_minor(Potion *P, const struct PNObject *ptr) { break; case PN_TVTABLE: GC_MINOR_UPDATE(((struct PNVtable *)ptr)->parent); + GC_MINOR_UPDATE(((struct PNVtable *)ptr)->name); GC_MINOR_UPDATE(((struct PNVtable *)ptr)->ivars); GC_MINOR_UPDATE(((struct PNVtable *)ptr)->methods); GC_MINOR_UPDATE(((struct PNVtable *)ptr)->ctor); @@ -475,6 +476,7 @@ void *potion_mark_major(Potion *P, const struct PNObject *ptr) { break; case PN_TVTABLE: GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->parent); + GC_MINOR_UPDATE(((struct PNVtable *)ptr)->name); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->ivars); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->methods); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->ctor); From 46474d2d6141c193bfb82e369fc474377797866c Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 13:35:39 -0700 Subject: [PATCH 10/26] objmodel.c: in potion_object_new, allocate enough room for the type's struct's members. --- core/objmodel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/objmodel.c b/core/objmodel.c index 173437c9..ac34f07f 100644 --- a/core/objmodel.c +++ b/core/objmodel.c @@ -298,7 +298,8 @@ PN potion_object_send(Potion *P, PN cl, PN self, PN method) { PN potion_object_new(Potion *P, PN cl, PN self) { vPN(Vtable) vt = (struct PNVtable *)self; - return (PN)PN_ALLOC_N(vt->type, struct PNObject, vt->ivlen * sizeof(PN)); + return (PN)PN_ALLOC_N(vt->type, struct PNObject, + potion_type_size(P, (struct PNObject *)self) - sizeof(struct PNObject) + vt->ivlen * sizeof(PN)); } static PN potion_lobby_self(Potion *P, PN cl, PN self) { From e8195072a498e3faecfcf52dfe6f321f0d546429 Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 13:39:25 -0700 Subject: [PATCH 11/26] file.c: better File#string method. --- core/file.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/core/file.c b/core/file.c index 3f64eefd..81f88651 100644 --- a/core/file.c +++ b/core/file.c @@ -64,11 +64,18 @@ PN potion_file_read(Potion *P, PN cl, PN self, PN n) { return potion_str2(P, buf, r); } -PN potion_file_string(Potion *P, PN cl, PN self) { - int fd = ((struct PNFile *)self)->fd; +PN potion_file_string(Potion *P, PN cl, vPN(File) self) { + int fd = ((struct PNFile *)self)->fd, rv; char *buf; PN str; - if (asprintf(&buf, "", fd) == -1) { + if (((struct PNFile *)self)->path != PN_NIL && fd != -1) { + rv = asprintf(&buf, "", PN_STR_PTR(((struct PNFile *)self)->path), fd); + } else if (fd != -1) { + rv = asprintf(&buf, "", fd); + } else { + rv = asprintf(&buf, ""); + } + if (rv == -1) { fprintf(stderr, "** Couldn't allocate memory.\n"); exit(1); } From 49276a49bd95e65a4d2a71dbb2ee44577b2103b8 Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 13:42:41 -0700 Subject: [PATCH 12/26] gc.c: I made a typo in commit a21c187c6ed41bf4ccd2. This fixes it. --- core/gc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/gc.c b/core/gc.c index a7a2b0d5..166bb2c0 100644 --- a/core/gc.c +++ b/core/gc.c @@ -476,7 +476,7 @@ void *potion_mark_major(Potion *P, const struct PNObject *ptr) { break; case PN_TVTABLE: GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->parent); - GC_MINOR_UPDATE(((struct PNVtable *)ptr)->name); + GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->name); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->ivars); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->methods); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->ctor); From a54dc420cd6643c8ef5399051f9b6ba2128e08bc Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 17:42:04 -0700 Subject: [PATCH 13/26] file.c: Added File#write method. --- core/file.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/file.c b/core/file.c index 81f88651..010ef00b 100644 --- a/core/file.c +++ b/core/file.c @@ -64,6 +64,16 @@ PN potion_file_read(Potion *P, PN cl, PN self, PN n) { return potion_str2(P, buf, r); } +PN potion_file_write(Potion *P, PN cl, PN self, PN str) { + int r = write(((struct PNFile *)self)->fd, PN_STR_PTR(str), PN_STR_LEN(str)); + if (r == -1) { + perror("write"); + // TODO: error + return PN_NIL; + } + return PN_NUM(r); +} + PN potion_file_string(Potion *P, PN cl, vPN(File) self) { int fd = ((struct PNFile *)self)->fd, rv; char *buf; @@ -109,4 +119,5 @@ void potion_file_init(Potion *P) { potion_method(file_vt, "string", potion_file_string, 0); potion_method(file_vt, "close", potion_file_close, 0); potion_method(file_vt, "read", potion_file_read, "n=N"); + potion_method(file_vt, "write", potion_file_write, "str=S"); } From 8216a43e4c8fafea17f42e8dd3650fc615c72a26 Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 17:44:52 -0700 Subject: [PATCH 14/26] file.c: Have File constructor create files with permissions 0755. --- core/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/file.c b/core/file.c index 010ef00b..2e7bf0da 100644 --- a/core/file.c +++ b/core/file.c @@ -33,7 +33,7 @@ PN potion_file_new(Potion *P, PN cl, PN self, PN path, PN modestr) { // invalid mode return PN_NIL; } - if ((fd = open(PN_STR_PTR(path), mode)) == -1) { + if ((fd = open(PN_STR_PTR(path), mode, 0755)) == -1) { perror("open"); // TODO: error return PN_NIL; From 0f59856c7792c64b8c6ba5141006fc90d7b797c9 Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 18:29:20 -0700 Subject: [PATCH 15/26] string.c: Add 'potion_byte_str2' function, like 'potion_str2'. --- core/potion.h | 1 + core/string.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/potion.h b/core/potion.h index b98e01be..98827cb2 100644 --- a/core/potion.h +++ b/core/potion.h @@ -537,6 +537,7 @@ PN potion_str(Potion *, const char *); PN potion_str2(Potion *, char *, size_t); PN potion_str_format(Potion *, const char *, ...); PN potion_byte_str(Potion *, const char *); +PN potion_byte_str2(Potion *, const char *, size_t len); PN potion_bytes(Potion *, size_t); PN potion_bytes_string(Potion *, PN, PN); PN_SIZE pn_printf(Potion *, PN, const char *, ...); diff --git a/core/string.c b/core/string.c index 422ee52e..f16ebe79 100644 --- a/core/string.c +++ b/core/string.c @@ -159,7 +159,10 @@ static PN potion_str_at(Potion *P, PN closure, PN self, PN index) { } PN potion_byte_str(Potion *P, const char *str) { - size_t len = strlen(str); + return potion_byte_str2(P, str, strlen(str)); +} + +PN potion_byte_str2(Potion *P, const char *str, size_t len) { vPN(Bytes) s = (struct PNBytes *)potion_bytes(P, len); PN_MEMCPY_N(s->chars, str, char, len); s->chars[len] = '\0'; From fbfea2cef0fae51b1d0647d54d1da9c1d2516f15 Mon Sep 17 00:00:00 2001 From: orangea Date: Thu, 7 Oct 2010 18:39:07 -0700 Subject: [PATCH 16/26] file.c: Return byte strings from IO read operations. --- core/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/file.c b/core/file.c index 2e7bf0da..6050c43b 100644 --- a/core/file.c +++ b/core/file.c @@ -61,7 +61,7 @@ PN potion_file_read(Potion *P, PN cl, PN self, PN n) { } else if (r == 0) { return PN_NIL; } - return potion_str2(P, buf, r); + return potion_byte_str2(P, buf, r); } PN potion_file_write(Potion *P, PN cl, PN self, PN str) { From 251aca71dd7b504bcf44b9abb5d7889205bf6c33 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 07:52:46 -0700 Subject: [PATCH 17/26] string.c: Added 'bytes' method for strings. --- core/string.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/string.c b/core/string.c index f16ebe79..8f01baa3 100644 --- a/core/string.c +++ b/core/string.c @@ -154,6 +154,10 @@ static PN potion_str_slice(Potion *P, PN closure, PN self, PN start, PN end) { return potion_str2(P, str + startoffset, endoffset - startoffset); } +static PN potion_str_bytes(Potion *P, PN closure, PN self) { + return potion_byte_str2(P, PN_STR_PTR(self), PN_STR_LEN(self)); +} + static PN potion_str_at(Potion *P, PN closure, PN self, PN index) { return potion_str_slice(P, closure, self, index, PN_NUM(PN_INT(index) + 1)); } @@ -260,6 +264,8 @@ void potion_str_init(Potion *P) { potion_method(str_vt, "print", potion_str_print, 0); potion_method(str_vt, "string", potion_str_string, 0); potion_method(str_vt, "slice", potion_str_slice, "start=N,end=N"); + potion_method(str_vt, "bytes", potion_str_bytes, 0); + potion_method(byt_vt, "append", potion_bytes_append, 0); potion_method(byt_vt, "length", potion_bytes_length, 0); potion_method(byt_vt, "print", potion_bytes_print, 0); From 2d789476922d63aa2d75a5c3ef01926516bdeac3 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 08:16:49 -0700 Subject: [PATCH 18/26] string.c: Added call function for byte strings. --- core/string.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/string.c b/core/string.c index 8f01baa3..b7fb4c57 100644 --- a/core/string.c +++ b/core/string.c @@ -250,6 +250,15 @@ static PN potion_bytes_print(Potion *P, PN closure, PN self) { return PN_NIL; } +static PN potion_bytes_at(Potion *P, PN closure, PN self, PN index) { + char c; + index = PN_INT(index); + if (index >= PN_STR_LEN(self) || index < 0) + return PN_NIL; + c = PN_STR_PTR(potion_fwd(self))[index]; + return potion_byte_str2(P, &c, 1); +} + void potion_str_hash_init(Potion *P) { P->strings = PN_CALLOC_N(PN_TSTRINGS, struct PNTable, 0); } @@ -266,6 +275,7 @@ void potion_str_init(Potion *P) { potion_method(str_vt, "slice", potion_str_slice, "start=N,end=N"); potion_method(str_vt, "bytes", potion_str_bytes, 0); + potion_type_call_is(byt_vt, PN_FUNC(potion_bytes_at, 0)); potion_method(byt_vt, "append", potion_bytes_append, 0); potion_method(byt_vt, "length", potion_bytes_length, 0); potion_method(byt_vt, "print", potion_bytes_print, 0); From addfda34403e729679c6e6e59e2e211894ef32ac Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 08:21:23 -0700 Subject: [PATCH 19/26] string.c: Print null characters in byte strings. --- core/string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/string.c b/core/string.c index b7fb4c57..185dd6be 100644 --- a/core/string.c +++ b/core/string.c @@ -245,8 +245,8 @@ PN potion_bytes_string(Potion *P, PN closure, PN self) { } static PN potion_bytes_print(Potion *P, PN closure, PN self) { - PN str = potion_fwd(self); - printf("%s", PN_STR_PTR(str)); + self = potion_fwd(self); + fwrite(PN_STR_PTR(self), 1, PN_STR_LEN(self), stdout); return PN_NIL; } From 606bb9a3de168384098a97b06ba891149ee7de59 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 08:33:06 -0700 Subject: [PATCH 20/26] string.c: More consistent 'cl' instead of 'closure'. --- core/string.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core/string.c b/core/string.c index 185dd6be..febb0906 100644 --- a/core/string.c +++ b/core/string.c @@ -76,15 +76,15 @@ PN potion_str_format(Potion *P, const char *format, ...) { return (PN)s; } -static PN potion_str_length(Potion *P, PN closure, PN self) { +static PN potion_str_length(Potion *P, PN cl, PN self) { return PN_NUM(potion_cp_strlen_utf8(PN_STR_PTR(self))); } -static PN potion_str_eval(Potion *P, PN closure, PN self) { +static PN potion_str_eval(Potion *P, PN cl, PN self) { return potion_eval(P, self); } -static PN potion_str_number(Potion *P, PN closure, PN self) { +static PN potion_str_number(Potion *P, PN cl, PN self) { char *str = PN_STR_PTR(self); int i = 0, dec = 0, sign = 0, len = PN_STR_LEN(self); if (len < 1) return PN_ZERO; @@ -103,11 +103,11 @@ static PN potion_str_number(Potion *P, PN closure, PN self) { return potion_decimal(P, PN_STR_PTR(self), PN_STR_LEN(self)); } -static PN potion_str_string(Potion *P, PN closure, PN self) { +static PN potion_str_string(Potion *P, PN cl, PN self) { return self; } -static PN potion_str_print(Potion *P, PN closure, PN self) { +static PN potion_str_print(Potion *P, PN cl, PN self) { fwrite(PN_STR_PTR(self), 1, PN_STR_LEN(self), stdout); return PN_NIL; } @@ -139,7 +139,7 @@ inline static PN potion_str_slice_index(PN index, size_t len, int nilvalue) { return PN_NUM(corrected); } -static PN potion_str_slice(Potion *P, PN closure, PN self, PN start, PN end) { +static PN potion_str_slice(Potion *P, PN cl, PN self, PN start, PN end) { char *str = PN_STR_PTR(self); size_t len = potion_cp_strlen_utf8(str); size_t startoffset = potion_utf8char_offset(str, PN_INT(potion_str_slice_index(start, len, 0))); @@ -154,12 +154,12 @@ static PN potion_str_slice(Potion *P, PN closure, PN self, PN start, PN end) { return potion_str2(P, str + startoffset, endoffset - startoffset); } -static PN potion_str_bytes(Potion *P, PN closure, PN self) { +static PN potion_str_bytes(Potion *P, PN cl, PN self) { return potion_byte_str2(P, PN_STR_PTR(self), PN_STR_LEN(self)); } -static PN potion_str_at(Potion *P, PN closure, PN self, PN index) { - return potion_str_slice(P, closure, self, index, PN_NUM(PN_INT(index) + 1)); +static PN potion_str_at(Potion *P, PN cl, PN self, PN index) { + return potion_str_slice(P, cl, self, index, PN_NUM(PN_INT(index) + 1)); } PN potion_byte_str(Potion *P, const char *str) { @@ -208,7 +208,7 @@ void potion_bytes_obj_string(Potion *P, PN bytes, PN obj) { potion_bytes_append(P, 0, bytes, potion_send(obj, PN_string)); } -PN potion_bytes_append(Potion *P, PN closure, PN self, PN str) { +PN potion_bytes_append(Potion *P, PN cl, PN self, PN str) { vPN(Bytes) s = (struct PNBytes *)potion_fwd(self); PN fstr = potion_fwd(str); PN_SIZE len = PN_STR_LEN(fstr); @@ -225,13 +225,13 @@ PN potion_bytes_append(Potion *P, PN closure, PN self, PN str) { return self; } -static PN potion_bytes_length(Potion *P, PN closure, PN self) { +static PN potion_bytes_length(Potion *P, PN cl, PN self) { PN str = potion_fwd(self); return PN_NUM(PN_STR_LEN(str)); } // TODO: ensure it's UTF-8 data -PN potion_bytes_string(Potion *P, PN closure, PN self) { +PN potion_bytes_string(Potion *P, PN cl, PN self) { PN exist = potion_lookup_str(P, PN_STR_PTR(self = potion_fwd(self))); if (exist == PN_NIL) { PN_SIZE len = PN_STR_LEN(self); @@ -244,13 +244,13 @@ PN potion_bytes_string(Potion *P, PN closure, PN self) { return exist; } -static PN potion_bytes_print(Potion *P, PN closure, PN self) { +static PN potion_bytes_print(Potion *P, PN cl, PN self) { self = potion_fwd(self); fwrite(PN_STR_PTR(self), 1, PN_STR_LEN(self), stdout); return PN_NIL; } -static PN potion_bytes_at(Potion *P, PN closure, PN self, PN index) { +static PN potion_bytes_at(Potion *P, PN cl, PN self, PN index) { char c; index = PN_INT(index); if (index >= PN_STR_LEN(self) || index < 0) From d9c46e5c1155cc3e4cf792c3e70c1a7d4fdb42c8 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 09:13:31 -0700 Subject: [PATCH 21/26] string.c: Added '+' method for strings. --- core/string.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/string.c b/core/string.c index febb0906..87ed8c44 100644 --- a/core/string.c +++ b/core/string.c @@ -158,6 +158,20 @@ static PN potion_str_bytes(Potion *P, PN cl, PN self) { return potion_byte_str2(P, PN_STR_PTR(self), PN_STR_LEN(self)); } +static PN potion_str_add(Potion *P, PN cl, PN self, PN x) { + char *s = malloc(PN_STR_LEN(self) + PN_STR_LEN(x)); + PN str; + if (s == NULL) { + fprintf(stderr, "** Failed to allocate memory.\n"); + exit(1); + } + PN_MEMCPY_N(s, PN_STR_PTR(self), char, PN_STR_LEN(self)); + PN_MEMCPY_N(s + PN_STR_LEN(self), PN_STR_PTR(x), char, PN_STR_LEN(x)); + str = potion_str2(P, s, PN_STR_LEN(self) + PN_STR_LEN(x)); + free(s); + return str; +} + static PN potion_str_at(Potion *P, PN cl, PN self, PN index) { return potion_str_slice(P, cl, self, index, PN_NUM(PN_INT(index) + 1)); } @@ -274,6 +288,7 @@ void potion_str_init(Potion *P) { potion_method(str_vt, "string", potion_str_string, 0); potion_method(str_vt, "slice", potion_str_slice, "start=N,end=N"); potion_method(str_vt, "bytes", potion_str_bytes, 0); + potion_method(str_vt, "+", potion_str_add, "str=S"); potion_type_call_is(byt_vt, PN_FUNC(potion_bytes_at, 0)); potion_method(byt_vt, "append", potion_bytes_append, 0); From fb8c57f9fb55d0026506f2974ead5291724377b9 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 09:16:37 -0700 Subject: [PATCH 22/26] string.c: In potion_bytes_at, use potion_fwd before use of 'self'. --- core/string.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/string.c b/core/string.c index 87ed8c44..f8679668 100644 --- a/core/string.c +++ b/core/string.c @@ -266,10 +266,11 @@ static PN potion_bytes_print(Potion *P, PN cl, PN self) { static PN potion_bytes_at(Potion *P, PN cl, PN self, PN index) { char c; + self = potion_fwd(self); index = PN_INT(index); if (index >= PN_STR_LEN(self) || index < 0) return PN_NIL; - c = PN_STR_PTR(potion_fwd(self))[index]; + c = PN_STR_PTR(self)[index]; return potion_byte_str2(P, &c, 1); } From a056cdfe9b5b16d30f359bae69a44c8c61ee871a Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 18:16:25 -0700 Subject: [PATCH 23/26] syntax.g: Made 'ord' a valid method name. --- core/syntax.g | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/syntax.g b/core/syntax.g index e5a5c5d7..50330289 100644 --- a/core/syntax.g +++ b/core/syntax.g @@ -207,7 +207,7 @@ cmp = "<=>" -- and = ("&&" | "and" !utfw) -- or = ("||" | "or" !utfw) -- not = ("!" | "not" !utfw) -- -keyword = "and" | "or" | "not" +keyword = ("and" | "or" | "not") !utfw nil = "nil" !utfw true = "true" !utfw From 916bc024046b9d805edb440efa615039d72896c9 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 18:17:39 -0700 Subject: [PATCH 24/26] string.c: Added 'ord' method for strings. --- core/string.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/string.c b/core/string.c index f8679668..a676ca47 100644 --- a/core/string.c +++ b/core/string.c @@ -172,6 +172,13 @@ static PN potion_str_add(Potion *P, PN cl, PN self, PN x) { return str; } +static PN potion_str_ord(Potion *P, PN cl, PN self) { + self = potion_fwd(self); + if (PN_STR_LEN(self) != 1) + return PN_NIL; + return PN_NUM(PN_STR_PTR(self)[0]); +} + static PN potion_str_at(Potion *P, PN cl, PN self, PN index) { return potion_str_slice(P, cl, self, index, PN_NUM(PN_INT(index) + 1)); } @@ -290,10 +297,12 @@ void potion_str_init(Potion *P) { potion_method(str_vt, "slice", potion_str_slice, "start=N,end=N"); potion_method(str_vt, "bytes", potion_str_bytes, 0); potion_method(str_vt, "+", potion_str_add, "str=S"); + potion_method(str_vt, "ord", potion_str_ord, 0); potion_type_call_is(byt_vt, PN_FUNC(potion_bytes_at, 0)); potion_method(byt_vt, "append", potion_bytes_append, 0); potion_method(byt_vt, "length", potion_bytes_length, 0); potion_method(byt_vt, "print", potion_bytes_print, 0); potion_method(byt_vt, "string", potion_bytes_string, 0); + potion_method(byt_vt, "ord", potion_str_ord, 0); } From 103a46dac9f382fef434555e50ea0bd2e68d4aa0 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 19:09:33 -0700 Subject: [PATCH 25/26] number.c: Added 'chr' method for numbers. --- core/number.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/number.c b/core/number.c index d1ad4d69..9a1057ca 100644 --- a/core/number.c +++ b/core/number.c @@ -122,6 +122,11 @@ PN potion_num_to(Potion *P, PN cl, PN self, PN end, PN block) { return PN_NUM(abs(i - j)); } +static PN potion_num_chr(Potion *P, PN cl, PN self) { + char c = PN_INT(self); + return potion_str2(P, &c, 1); +} + void potion_num_init(Potion *P) { PN num_vt = PN_VTABLE(PN_TNUMBER); potion_method(num_vt, "+", potion_add, "value=N"); @@ -139,4 +144,5 @@ void potion_num_init(Potion *P) { potion_method(num_vt, "string", potion_num_string, 0); potion_method(num_vt, "times", potion_num_times, "block=&"); potion_method(num_vt, "to", potion_num_to, "end=N"); + potion_method(num_vt, "chr", potion_num_chr, 0); } From a18e09184840dc2e013e40c598ae112ef3594fc3 Mon Sep 17 00:00:00 2001 From: orangea Date: Fri, 8 Oct 2010 20:02:38 -0700 Subject: [PATCH 26/26] syntax.g: Added expression grouping syntax, for example: '|2 + 3. * 4 == 20'. The syntax can easily be changed by modifying 'group-start' and 'group-end'. --- core/syntax.g | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/syntax.g b/core/syntax.g index 50330289..24a02e3f 100644 --- a/core/syntax.g +++ b/core/syntax.g @@ -116,7 +116,7 @@ expr = ( mminus a:atom { a = PN_OP(AST_INC, a, PN_NUM(-1) ^ 1); } (c:call { a = PN_PUSH(a, c) })* { $$ = PN_AST(EXPR, a); } -atom = e:value | e:closure | e:table | e:call +atom = e:value | e:closure | e:table | e:call | e:group call = (n:name { v = PN_NIL; b = PN_NIL; } (v:value | v:table)? | (v:value | v:table) { n = PN_AST(MESSAGE, PN_NIL); b = PN_NIL; }) @@ -146,6 +146,7 @@ closure = t:table? b:block { $$ = PN_AST2(PROTO, t, b); } table = table-start s:statements table-end { $$ = PN_AST(TABLE, s); } block = block-start s:statements block-end { $$ = PN_AST(BLOCK, s); } lick = lick-start i:lick-items lick-end { $$ = PN_AST(TABLE, i); } +group = group-start s:statements group-end { $$ = PN_AST(CODE, s); } path = '/' message { $$ = potion_str2(P, yytext, yyleng); } message = < utfw+ > - { $$ = potion_str2(P, yytext, yyleng); } @@ -181,6 +182,8 @@ table-start = '(' -- table-end = ')' - lick-start = '[' -- lick-end = ']' - +group-start = '|' -- +group-end = '.' - quiz = '?' -- assign = '=' -- pplus = "++" -