Skip to content

Commit

Permalink
Added 'readline' extension to main makefile, 'potion_load' can figure…
Browse files Browse the repository at this point in the history
… out which file to load by the argument now, interactive mode uses readline.
  • Loading branch information
orangea committed Dec 23, 2010
1 parent 2efb901 commit ed9e1ff
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 26 deletions.
12 changes: 10 additions & 2 deletions Makefile
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ COMMIT = `git rev-list HEAD -1 --abbrev=7 --abbrev-commit`
RELEASE ?= ${VERSION}.${REVISION} RELEASE ?= ${VERSION}.${REVISION}
PKG := "potion-${RELEASE}" PKG := "potion-${RELEASE}"


all: potion all: pn
+${MAKE} -s usage +${MAKE} -s usage


pn: potion libpotion.a lib/readline/readline.so

rebuild: clean potion test rebuild: clean potion test


usage: usage:
Expand Down Expand Up @@ -114,7 +116,7 @@ tools/greg: tools/greg.c tools/compile.c tools/tree.c
@${ECHO} CC $@ @${ECHO} CC $@
@${CC} -O3 -DNDEBUG -o $@ tools/greg.c tools/compile.c tools/tree.c -Itools @${CC} -O3 -DNDEBUG -o $@ tools/greg.c tools/compile.c tools/tree.c -Itools


potion: ${OBJ_POTION} ${OBJ} libpotion.a potion: ${OBJ_POTION} ${OBJ}
@${ECHO} LINK potion @${ECHO} LINK potion
@${CC} ${CFLAGS} ${OBJ_POTION} ${OBJ} ${LIBS} -o potion @${CC} ${CFLAGS} ${OBJ_POTION} ${OBJ} ${LIBS} -o potion
@if [ "${DEBUG}" != "1" ]; then \ @if [ "${DEBUG}" != "1" ]; then \
Expand All @@ -127,6 +129,12 @@ libpotion.a: ${OBJ_POTION} ${OBJ}
@if [ -e $@ ]; then rm -f $@; fi @if [ -e $@ ]; then rm -f $@; fi
@${AR} rcs $@ core/*.o > /dev/null @${AR} rcs $@ core/*.o > /dev/null


lib/readline/readline.so:
@${ECHO} MAKE $@
@cd lib/readline; \
${MAKE} readline.so; \
cd ../..

bench: potion test/api/gc-bench bench: potion test/api/gc-bench
@${ECHO}; \ @${ECHO}; \
${ECHO} running GC benchmark; \ ${ECHO} running GC benchmark; \
Expand Down
90 changes: 73 additions & 17 deletions core/load.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,32 +16,23 @@


void potion_load_code(Potion *P, const char *filename) { void potion_load_code(Potion *P, const char *filename) {
PN buf, code; PN buf, code;
int fd = -1; int fd = open(filename, O_RDONLY | O_BINARY);
struct stat stats;
if (stat(filename, &stats) == -1) {
fprintf(stderr, "** %s does not exist.", filename);
goto done;
}
fd = open(filename, O_RDONLY | O_BINARY);
if (fd == -1) { if (fd == -1) {
fprintf(stderr, "** could not open %s. check permissions.", filename); fprintf(stderr, "** could not open %s. check permissions.", filename);
goto done; return;
} }
buf = potion_bytes(P, stats.st_size); buf = potion_bytes(P, stats.st_size);
if (read(fd, PN_STR_PTR(buf), stats.st_size) == stats.st_size) { if (read(fd, PN_STR_PTR(buf), stats.st_size) == stats.st_size) {
PN_STR_PTR(buf)[stats.st_size] = '\0'; PN_STR_PTR(buf)[stats.st_size] = '\0';
code = potion_source_load(P, PN_NIL, buf); code = potion_source_load(P, PN_NIL, buf);
if (!PN_IS_PROTO(code)) { if (!PN_IS_PROTO(code)) {
potion_run(P, potion_send( potion_run(P, potion_send(
potion_parse(P, buf), PN_compile, potion_str(P, filename), PN_NIL), POTION_JIT); potion_parse(P, buf), PN_compile, potion_str(P, filename), PN_NIL), POTION_JIT);
} }
} else { } else {
fprintf(stderr, "** could not read entire file: %s.", filename); fprintf(stderr, "** could not read entire file: %s.", filename);
}

done:
if (fd != -1)
close(fd); close(fd);
}
} }


static char *potion_initializer_name(Potion *P, const char *filename, PN_SIZE len) { static char *potion_initializer_name(Potion *P, const char *filename, PN_SIZE len) {
Expand Down Expand Up @@ -82,26 +73,91 @@ void potion_load_dylib(Potion *P, const char *filename) {
func(P); func(P);
} }


static PN pn_loader_path;
static char *pn_loader_extensions[] = {
".pn", ".so", ".dylib"
};

static char *find_extension(char *str) {
int i;
PN_SIZE str_len = strlen(str);
struct stat st;
for (i = 0;
i < sizeof(pn_loader_extensions) / sizeof(void *);
i++) {
PN_SIZE len = strlen(pn_loader_extensions[i]);
char buf[str_len + len + 1];
strncpy(buf, str, str_len);
strncpy(buf + str_len, pn_loader_extensions[i], len);
buf[str_len + len] = '\0';
if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
return pn_loader_extensions[i];
}
return NULL;
}

char *potion_find_file(char *str, PN_SIZE str_len) {
char *r = NULL;
struct stat st;
PN_TUPLE_EACH(pn_loader_path, i, prefix, {
PN_SIZE prefix_len = PN_STR_LEN(prefix);
char dirname[prefix_len + 1 + str_len + 1];
char *str_pos = dirname + prefix_len + 1;
char *dot;
memcpy(str_pos, str, str_len);
for (dot = str_pos; dot < str_pos + str_len; dot++)
if (*dot == '.') { *dot = '\0'; break; }
if (dot == str_pos + str_len)
dirname[prefix_len + 1 + str_len] = '\0';
memcpy(dirname, PN_STR_PTR(prefix), prefix_len);
dirname[prefix_len] = '/';
if (stat(dirname, &st) == 0 && S_ISREG(st.st_mode)) {
if (asprintf(&r, "%s", str) == -1) potion_allocation_error();
} else {
if (asprintf(&r, "%s/%s", dirname, str) == -1) potion_allocation_error();
if (stat(r, &st) != 0 || !S_ISREG(st.st_mode)) {
char *ext = find_extension(r);
int r_len = prefix_len + 1 + str_len * 2 + 1;
if (ext == NULL) { free(r); r = NULL; continue; }
r = realloc(r, r_len + strlen(ext));
if (r == NULL) potion_allocation_error();
strcpy(r + r_len, ext);
}
break;
}
});
return r;
}

PN potion_load(Potion *P, PN cl, PN self, PN file) { PN potion_load(Potion *P, PN cl, PN self, PN file) {
char *filename = PN_STR_PTR(file), char *filename = potion_find_file(PN_STR_PTR(file), PN_STR_LEN(file)), *file_ext;
*file_ext = filename + PN_STR_LEN(file); if (filename == NULL) {
fprintf(stderr, "** can't find %s\n", PN_STR_PTR(file));
return PN_NIL;
}
file_ext = filename + strlen(filename);
while (*--file_ext != '.' && file_ext >= filename); while (*--file_ext != '.' && file_ext >= filename);
if (file_ext++ != filename) { if (file_ext++ != filename) {
if (strcmp(file_ext, "pn") == 0) if (strcmp(file_ext, "pn") == 0)
potion_load_code(P, filename); potion_load_code(P, filename);
else if (strcmp(file_ext, "so") == 0 || else if (strcmp(file_ext, "so") == 0 ||
strcmp(file_ext, "dylib") == 0 strcmp(file_ext, "dylib") == 0
) )
potion_load_dylib(P, filename); potion_load_dylib(P, filename);
else else
fprintf(stderr, "** unrecognized file extension: %s\n", file_ext); fprintf(stderr, "** unrecognized file extension: %s\n", file_ext);
} else { } else {
fprintf(stderr, "** no file extension: %s\n", filename); fprintf(stderr, "** no file extension: %s\n", filename);
} }

free(filename);
return PN_NIL; return PN_NIL;
} }


void potion_loader_init(Potion *P) { void potion_loader_init(Potion *P) {
pn_loader_path = PN_TUP0();
PN_PUSH(pn_loader_path, potion_str(P, "."));
PN_PUSH(pn_loader_path, potion_str(P, "./lib"));

potion_define_global(P, potion_str(P, "LOADER_PATH"), pn_loader_path);
potion_method(P->lobby, "load", potion_load, "file=S"); potion_method(P->lobby, "load", potion_load, "file=S");
} }
10 changes: 5 additions & 5 deletions core/potion.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ int main(int argc, char *argv[]) {
if (!exec || verbose) potion_fatal("no filename given"); if (!exec || verbose) potion_fatal("no filename given");
Potion *P = potion_create(sp); Potion *P = potion_create(sp);
potion_eval(P, potion_byte_str(P, potion_eval(P, potion_byte_str(P,
"load 'readline'\n" \
"loop:\n" \ "loop:\n" \
" '>> ' print\n" \ " code = readline('>> ')\n" \
" code = read\n" \ " if (not code): \"\\n\" print, break.\n" \
" if (not code): break.\n" \ " if (code != ''):\n" \
" if (code != \"\\n\"):\n" \
" obj = code eval\n" \ " obj = code eval\n" \
" if (obj kind == Error):\n" \ " if (obj kind == Error):\n" \
" obj string print." \ " obj string print." \
Expand All @@ -257,4 +257,4 @@ int main(int argc, char *argv[]) {
potion_destroy(P); potion_destroy(P);
} }
return 0; return 0;
} }
4 changes: 2 additions & 2 deletions lib/readline/Makefile
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ CFLAGS = $(INCS) $(LIBS) -Wall -fno-strict-aliasing -Wno-return-type -fpic -Wl,-


all: readline.so all: readline.so


readline.so: %.so: %.c
@$(CC) -shared $(CFLAGS) -o $@ readline.c @$(CC) -shared $(CFLAGS) -o $@ $<

0 comments on commit ed9e1ff

Please sign in to comment.