--- /dev/null
+#include <cerise.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define DEFAULT_MPATH "/usr/share/cerise/modules"
+size_t Num_Paths = 0;
+char** Paths = NULL;
+
+static char* strmcat(char* first, ...) {
+ va_list args;
+ /* calculate the length of the final string */
+ size_t len = strlen(first);
+ va_start(args, first);
+ for (char* s = NULL; (s = va_arg(args, char*));)
+ len += strlen(s);
+ va_end(args);
+ /* allocate the final string and copy the args into it */
+ char *str = malloc(len+1), *curr = str;
+ while (first && *first) *(curr++) = *(first++);
+ va_start(args, first);
+ for (char* s = NULL; (s = va_arg(args, char*));)
+ while (s && *s) *(curr++) = *(s++);
+ va_end(args);
+ /* null terminate and return */
+ *curr = '\0';
+ return str;
+}
+
+void fs_init(void)
+{
+ /* get path variable */
+ char* paths = getenv("CERISE_MPATH");
+ if (!paths)
+ {
+ paths = DEFAULT_MPATH;
+ }
+ paths = strdup(paths);
+
+ /* now let's process it */
+ char* path = strtok(paths, ":");
+ while (path)
+ {
+ Num_Paths++;
+ Paths = realloc(Paths, sizeof(char*) * Num_Paths);
+ Paths[Num_Paths-1] = path;
+ path = strtok(NULL, ":");
+ }
+}
+
+char* fs_read(char* path)
+{
+ int fd = -1, nread = 0, length = 0;
+ struct stat sb = {0};
+ char* contents = NULL;
+ if (((fd = open(path, O_RDONLY, 0)) >= 0) && (fstat(fd, &sb) >= 0) && (sb.st_size > 0))
+ {
+ contents = calloc(sb.st_size + 1u, 1u);
+ while (sb.st_size && (nread = read(fd, contents+length, sb.st_size)) > 0)
+ {
+ length += nread, sb.st_size -= nread;
+ }
+ }
+ if (fd > 0)
+ {
+ close(fd);
+ }
+ return contents;
+
+}
+
+char* fs_modname(char* path)
+{
+ char* name = NULL;
+ char* last_slash = strrchr(path, '/');
+ if (last_slash)
+ {
+ char* last_dot = strrchr(last_slash, '.');
+ if (last_dot)
+ {
+ name = strndup(last_slash+1, last_dot-last_slash-1);
+ if (*name == '\0')
+ {
+ name = NULL;
+ }
+ }
+ }
+ return name;
+}
+
+static char* dirname(char* path)
+{
+ char* last_slash = strrchr(path, '/');
+ if (last_slash)
+ {
+ char* new_path = strdup(path);
+ new_path[last_slash - path] = '\0';
+ path = new_path;
+ }
+ return path;
+}
+
+static char* check_modpath(char* path, char* name)
+{
+ char* retpath = NULL;
+ char* full_path = strmcat(path, "/", name, ".m", 0);
+ if (access(full_path, F_OK) == 0)
+ {
+ retpath = full_path;
+ }
+ else
+ {
+ free(full_path);
+ }
+ return retpath;
+}
+
+char* fs_modfind(Parser* p, char* name)
+{
+ char* curr_dir = dirname(p->file->path);
+ char* path = check_modpath(curr_dir, name);
+ for(size_t i = 0; !path && i < Num_Paths; i++)
+ {
+ path = check_modpath(Paths[i], name);
+ }
+ return path;
+}
#include "cerise.h"
#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
//#define TRACE
#ifdef TRACE
#define EXIT_RULE() ((void)0)
#endif
+static void import(Parser* curr, char* modname, char* alias);
/* Item Handling
*****************************************************************************/
alias = name;
name = expect_text(p, IDENT);
}
- (void)name, (void)alias;
-// symbol_import(p, name, alias);
+ import(p, name, alias);
}
while (matches(p, IDENT));
static void module(Parser* p)
{
ENTER_RULE();
- size_t scope = symbol_openscope(p);
+ symbol_openscope(p);
if (matches(p, IMPORT))
{
{
error(p, "expected end of file");
}
-
- symbol_closescope(p, scope);
EXIT_RULE();
}
-static inline char* file_load(char* path)
+static void init_parser(Parser* p, char* path)
{
- int fd = -1, nread = 0, length = 0;
- struct stat sb = {0};
- char* contents = NULL;
- if (((fd = open(path, O_RDONLY, 0)) >= 0) && (fstat(fd, &sb) >= 0) && (sb.st_size > 0))
- {
- contents = calloc(sb.st_size + 1u, 1u);
- while (sb.st_size && (nread = read(fd, contents+length, sb.st_size)) > 0)
- {
- length += nread, sb.st_size -= nread;
- }
- }
- if (fd > 0)
- {
- close(fd);
- }
- return contents;
+ char* fcontents = fs_read(path);
+ p->name = fs_modname(path);
+ p->file = calloc(1, sizeof(LexFile));
+ p->file->path = path;
+ p->file->fbeg = fcontents;
+ p->file->fpos = fcontents;
+ p->curr_reg = 0;
+ if (p->name == NULL)
+ {
+ fatal("could not determine module name from path");
+ }
+ p->mtypes = 8;
+ p->types = calloc(p->mtypes, sizeof(Type*));
+ symbol_new(p, 0, "$", SYM_VAR, 0);
+ symbol_new(p, 0, "Bool", SYM_TYPE, 0)->type = &BoolType;
+ p->types[p->ntypes++] = &BoolType;
+ symbol_new(p, 0, "Int", SYM_TYPE, 0)->type = &IntType;
+ p->types[p->ntypes++] = &IntType;
+ symbol_new(p, 0, "Real", SYM_TYPE, 0)->type = &RealType;
+ p->types[p->ntypes++] = &RealType;
+ symbol_new(p, 0, "String", SYM_TYPE, 0)->type = &StringType;
+ p->types[p->ntypes++] = &StringType;
}
-static char* get_module_name(char* path)
+static void import(Parser* curr, char* modname, char* alias)
{
- char* name = NULL;
- char* last_slash = strrchr(path, '/');
- if (last_slash)
+ Parser p = {0};
+ char* path = fs_modfind(curr, modname);
+ if (!path)
{
- char* last_dot = strrchr(last_slash, '.');
- if (last_dot)
- {
- name = strndup(last_slash+1, last_dot-last_slash-1);
- if (*name == '\0')
- {
- name = NULL;
- }
- }
+ error(curr, "unable to find module '%s'", modname);
}
- return name;
+ init_parser(&p, path);
+ module(&p);
+ (void)alias;
+
+// Symbol* sym = symbol_new(p, 0, modname, SYM_MODULE, 0);
+// size_t modid = sym - &p->syms[0];
+//
+// for (size_t i = 0; i < p.nsyms; i++)
+// {
+// if (p.syms[i].export)
+// {
+//// printf("sym: %s\n", p.syms[i].name);
+//// (void)alias;
+// }
+// }
}
-void compile(char* fname)
+void compile(char* path)
{
- char* fcontents = file_load(fname);
- Parser p = {
- .name = get_module_name(fname),
- .file = &(LexFile){
- .path = fname,
- .fbeg = fcontents,
- .fpos = fcontents,
- },
- .curr_reg = 0
- };
-
- if (p.name == NULL)
- {
- error(&p, "could not determine module name from path");
- }
-
- p.mtypes = 8;
- p.types = calloc(p.mtypes, sizeof(Type*));
- symbol_new(&p, 0, "$", SYM_VAR, 0);
- symbol_new(&p, 0, "Bool", SYM_TYPE, 0)->type = &BoolType;
- p.types[p.ntypes++] = &BoolType;
- symbol_new(&p, 0, "Int", SYM_TYPE, 0)->type = &IntType;
- p.types[p.ntypes++] = &IntType;
- symbol_new(&p, 0, "Real", SYM_TYPE, 0)->type = &RealType;
- p.types[p.ntypes++] = &RealType;
- symbol_new(&p, 0, "String", SYM_TYPE, 0)->type = &StringType;
- p.types[p.ntypes++] = &StringType;
-
- codegen_init(&p);
+ Parser p = {0};
+ init_parser(&p, path);
+// codegen_init(&p);
module(&p);
}