Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Another pull request... #6

Merged
26 commits merged into from Oct 9, 2010
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3c1ddff
'Object()' now works, no more segmentation fault.
Oct 6, 2010
9899615
Added forgotten #includes, Made File class visible to scripts, gave i…
Oct 7, 2010
8e49110
objmodel.c: Added 'potion_type_constructor_is' function, like 'potion…
Oct 7, 2010
ddac3fb
Have file.c use potion_type_constructor_is.
Oct 7, 2010
5f811fc
file.c: Added 'string' method to the 'File' class.
Oct 7, 2010
68f5b09
file.c: Added 'close' method for files. I didn't know what to set the…
Oct 7, 2010
24eb536
file.c: Added 'read' method for files.
Oct 7, 2010
1660fdf
file.c: Added 'a' and 'a+' creation modes.
Oct 7, 2010
a21c187
gc.c: Not sure what this is for, but it probably fixes *something*.
Oct 7, 2010
46474d2
objmodel.c: in potion_object_new, allocate enough room for the type's…
Oct 7, 2010
e819507
file.c: better File#string method.
Oct 7, 2010
49276a4
gc.c: I made a typo in commit a21c187c6ed41bf4ccd2. This fixes it.
Oct 7, 2010
a54dc42
file.c: Added File#write method.
Oct 8, 2010
8216a43
file.c: Have File constructor create files with permissions 0755.
Oct 8, 2010
0f59856
string.c: Add 'potion_byte_str2' function, like 'potion_str2'.
Oct 8, 2010
fbfea2c
file.c: Return byte strings from IO read operations.
Oct 8, 2010
251aca7
string.c: Added 'bytes' method for strings.
Oct 8, 2010
2d78947
string.c: Added call function for byte strings.
Oct 8, 2010
addfda3
string.c: Print null characters in byte strings.
Oct 8, 2010
606bb9a
string.c: More consistent 'cl' instead of 'closure'.
Oct 8, 2010
d9c46e5
string.c: Added '+' method for strings.
Oct 8, 2010
fb8c57f
string.c: In potion_bytes_at, use potion_fwd before use of 'self'.
Oct 8, 2010
a056cdf
syntax.g: Made 'ord' a valid method name.
Oct 9, 2010
916bc02
string.c: Added 'ord' method for strings.
Oct 9, 2010
103a46d
number.c: Added 'chr' method for numbers.
Oct 9, 2010
a18e091
syntax.g: Added expression grouping syntax, for example: '|2 + 3. * 4…
Oct 9, 2010
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 87 additions & 2 deletions core/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,94 @@
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "potion.h"
#include "internal.h"
#include "table.h"

extern char **environ;

PN potion_file_with(Potion *P, PN cl, PN self, PN path) {
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 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;
}
if ((fd = open(PN_STR_PTR(path), mode, 0755)) == -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_file_close(Potion *P, PN cl, PN self) {
close(((struct PNFile *)self)->fd);
((struct PNFile *)self)->fd = -1;
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_byte_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;
PN str;
if (((struct PNFile *)self)->path != PN_NIL && fd != -1) {
rv = asprintf(&buf, "<file %s fd: %d>", PN_STR_PTR(((struct PNFile *)self)->path), fd);
} else if (fd != -1) {
rv = asprintf(&buf, "<file fd: %d>", fd);
} else {
rv = asprintf(&buf, "<closed file>");
}
if (rv == -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];
Expand All @@ -24,7 +103,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) {
Expand All @@ -35,4 +114,10 @@ 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);

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");
potion_method(file_vt, "write", potion_file_write, "str=S");
}
2 changes: 2 additions & 0 deletions core/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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_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);
Expand Down
1 change: 1 addition & 0 deletions core/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions core/number.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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);
}
13 changes: 10 additions & 3 deletions core/objmodel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -83,8 +88,8 @@ PN potion_obj_get_callset(Potion *P, PN obj) {
return cl;
}

PN potion_no_call(Potion *P, PN cl, PN self) {
return self;
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) {
Expand Down Expand Up @@ -293,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) {
Expand Down Expand Up @@ -367,6 +373,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));
Expand Down
5 changes: 4 additions & 1 deletion core/potion.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <limits.h>
#include <string.h>
#include <fcntl.h>
#include "config.h"

//
Expand Down Expand Up @@ -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, ...);
Expand Down Expand Up @@ -536,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 *, ...);
Expand All @@ -547,6 +549,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);
Expand Down
74 changes: 59 additions & 15 deletions core/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)));
Expand All @@ -154,12 +154,40 @@ 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_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_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_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));
}

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';
Expand Down Expand Up @@ -201,7 +229,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);
Expand All @@ -218,13 +246,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);
Expand All @@ -237,12 +265,22 @@ PN potion_bytes_string(Potion *P, PN closure, PN self) {
return exist;
}

static PN potion_bytes_print(Potion *P, PN closure, PN self) {
PN str = potion_fwd(self);
printf("%s", PN_STR_PTR(str));
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 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(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);
}
Expand All @@ -257,8 +295,14 @@ 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(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);
}
Loading