]> git.mdlowis.com Git - proto/obnc.git/commitdiff
started implementing module imports
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 2 Dec 2022 04:48:15 +0000 (23:48 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 2 Dec 2022 04:48:15 +0000 (23:48 -0500)
cerise/inc/cerise.h
cerise/src/fs.c [new file with mode: 0644]
cerise/src/grammar.c
cerise/src/main.c
cerise/tests/A.m [new file with mode: 0644]
cerise/tests/Module.m

index a6b6accc4a2d63ea2acbbed135e184529218c97f..f132ae44f8547f40ec0d34a0a5888ea569197455 100644 (file)
@@ -237,6 +237,12 @@ typedef struct {
 void fatal(char* estr);
 void* emalloc(size_t size);
 
+// src/fs.c
+void fs_init(void);
+char* fs_read(char* path);
+char* fs_modname(char* path);
+char* fs_modfind(Parser* p, char* path);
+
 // src/lex.c
 void lexfile(Parser* ctx, char* path);
 void lex(Parser* ctx);
diff --git a/cerise/src/fs.c b/cerise/src/fs.c
new file mode 100644 (file)
index 0000000..1c1d944
--- /dev/null
@@ -0,0 +1,127 @@
+#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;
+}
index 96f6bd97deb76c82fe6e8a55bec79f6299398436..56870ab7ca2c336f010ccd4d457280c003dbf05a 100644 (file)
@@ -1,8 +1,5 @@
 #include "cerise.h"
 #include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
 
 //#define TRACE
 #ifdef TRACE
@@ -17,6 +14,7 @@
     #define EXIT_RULE() ((void)0)
 #endif
 
+static void import(Parser* curr, char* modname, char* alias);
 
 /* Item Handling
  *****************************************************************************/
@@ -613,8 +611,7 @@ static void import_list(Parser* p)
             alias = name;
             name = expect_text(p, IDENT);
         }
-        (void)name, (void)alias;
-//        symbol_import(p, name, alias);
+        import(p, name, alias);
     }
     while (matches(p, IDENT));
 
@@ -624,7 +621,7 @@ static void import_list(Parser* p)
 static void module(Parser* p)
 {
     ENTER_RULE();
-    size_t scope = symbol_openscope(p);
+    symbol_openscope(p);
 
     if (matches(p, IMPORT))
     {
@@ -686,80 +683,64 @@ static void module(Parser* p)
     {
         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);
 }
index 22e00520b8931bfba803b2913a41451f97ddda88..e1708912a305bd74d953a19fd17081c13ecba826 100644 (file)
@@ -6,9 +6,9 @@ int main(int argc, char **argv)
 {
     if (argc >= 2)
     {
+        fs_init();
         compile( argv[1] );
     }
-
     return 0;
 }
 
diff --git a/cerise/tests/A.m b/cerise/tests/A.m
new file mode 100644 (file)
index 0000000..d57ca9c
--- /dev/null
@@ -0,0 +1,2 @@
+const
+  FOO* = 42
\ No newline at end of file
index c96130015e9ce065535339c0e6e5778d259df896..a24ea430a337c52f6149b6237af714229aeec503 100644 (file)
@@ -1,5 +1,8 @@
+import A
+
 const
   FOO* = 42
+
 type
   FooRec* = record
     a : Int