From 3d18d9ccbc3ce131d122f8021fbc4f33dd31f438 Mon Sep 17 00:00:00 2001 From: Raja Mukherji Date: Wed, 15 Aug 2018 13:55:16 +0100 Subject: [PATCH 1/2] Small changes to help build nested projects. --- rabs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rabs.c b/rabs.c index c5f7476..1641243 100644 --- a/rabs.c +++ b/rabs.c @@ -36,7 +36,7 @@ static ml_value_t *rabs_ml_get(void *Data, const char *Name) { target_depends_auto(Target); return Value; } else { - return stringmap_search(Globals, Name) ?: ml_error("NameError", "%s undefined", Name); + return stringmap_search(Globals, Name) ?: MLNil; //ml_error("NameError", "%s undefined", Name); } } @@ -106,11 +106,11 @@ ml_value_t *subdir(void *Data, int Count, ml_value_t **Args) { //printf("FileName = %s\n", FileName); FileName = vfs_resolve(FileName); target_t *ParentDefault = CurrentContext->Default; - context_push(Path); + context_t *Context = context_push(Path); targetset_insert(ParentDefault->Depends, CurrentContext->Default); load_file(FileName); context_pop(); - return MLNil; + return (ml_value_t*)Context->Default; } ml_value_t *scope(void *Data, int Count, ml_value_t **Args) { From 29ed1096d44dccc9fecd5045407dd1a84967b918 Mon Sep 17 00:00:00 2001 From: Raja Mukherji Date: Thu, 16 Aug 2018 07:41:11 +0100 Subject: [PATCH 2/2] Contexts are now values, improving support for nested projects. --- context.c | 41 +++++++++++++++++++++++++++++++++++++++++ context.h | 1 + rabs.c | 6 +++--- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/context.c b/context.c index a0cb044..d7f8626 100644 --- a/context.c +++ b/context.c @@ -9,6 +9,7 @@ static stringmap_t ContextCache[1] = {STRINGMAP_INIT}; static ml_value_t *DefaultString; +static ml_type_t *ContextT; context_t *context_find(const char *Path) { return stringmap_search(ContextCache, Path); @@ -16,6 +17,7 @@ context_t *context_find(const char *Path) { context_t *context_push(const char *Path) { context_t *Context = new(context_t); + Context->Type = ContextT; Context->Parent = CurrentContext; Context->Path = Path; Context->Name = Path; @@ -26,12 +28,15 @@ context_t *context_push(const char *Path) { stringmap_insert(Context->Locals, "DEFAULT", Default); target_t *BuildDir = target_file_check(Path[0] == '/' ? Path + 1 : Path, 0); stringmap_insert(Context->Locals, "BUILDDIR", BuildDir); + stringmap_insert(Context->Locals, "PATH", BuildDir); + stringmap_insert(Context->Locals, "_", Context); stringmap_insert(ContextCache, Context->Name, Context); return Context; } context_t *context_scope(const char *Name) { context_t *Context = new(context_t); + Context->Type = ContextT; Context->Parent = CurrentContext; Context->Path = CurrentContext->Path; Context->Name = concat(CurrentContext->Name, ":", Name, NULL); @@ -61,6 +66,42 @@ void context_symb_set(context_t *Context, const char *Name, ml_value_t *Value) { stringmap_insert(Context->Locals, Name, Value); } +static ml_value_t *context_get_local(void *Data, int Count, ml_value_t **Args) { + context_t *Context = (context_t *)Args[0]; + const char *Name = ml_string_value(Args[1]); + return ml_property(Context, Name, (ml_getter_t)context_symb_get, (ml_setter_t)context_symb_set, NULL, NULL); +} + +static ml_value_t *context_get_parent(void *Data, int Count, ml_value_t **Args) { + context_t *Context = (context_t *)Args[0]; + return (ml_value_t *)Context->Parent ?: MLNil; +} + +static ml_value_t *context_path(void *Data, int Count, ml_value_t **Args) { + context_t *Context = (context_t *)Args[0]; + return ml_string(Context->Path, -1); +} + +static ml_value_t *context_get_subdir(void *Data, int Count, ml_value_t **Args) { + context_t *Context = (context_t *)Args[0]; + const char *Name = ml_string_value(Args[1]); + const char *Path = concat(Context->Path, "/", Name, NULL); + return (ml_value_t *)context_find(Path) ?: MLNil; +} + +static ml_value_t *context_get_scope(void *Data, int Count, ml_value_t **Args) { + context_t *Context = (context_t *)Args[0]; + const char *Name = ml_string_value(Args[1]); + const char *Path = concat(Context->Path, ":", Name, NULL); + return (ml_value_t *)context_find(Path) ?: MLNil; +} + void context_init() { DefaultString = ml_string("DEFAULT", -1); + ContextT = ml_class(MLAnyT, "context"); + ml_method_by_name(".", 0, context_get_local, ContextT, MLStringT, NULL); + ml_method_by_name("parent", 0, context_get_parent, ContextT, NULL); + ml_method_by_name("path", 0, context_path, ContextT, NULL); + ml_method_by_name("/", 0, context_get_subdir, ContextT, MLStringT, NULL); + ml_method_by_name("@", 0, context_get_scope, ContextT, MLStringT, NULL); } diff --git a/context.h b/context.h index 9e0e0f2..a67b20a 100644 --- a/context.h +++ b/context.h @@ -8,6 +8,7 @@ typedef struct context_t context_t; struct context_t { + const ml_type_t *Type; context_t *Parent; const char *Path, *Name, *FullPath; struct target_t *Default; diff --git a/rabs.c b/rabs.c index 1641243..347576d 100644 --- a/rabs.c +++ b/rabs.c @@ -110,14 +110,14 @@ ml_value_t *subdir(void *Data, int Count, ml_value_t **Args) { targetset_insert(ParentDefault->Depends, CurrentContext->Default); load_file(FileName); context_pop(); - return (ml_value_t*)Context->Default; + return (ml_value_t*)Context; } ml_value_t *scope(void *Data, int Count, ml_value_t **Args) { ML_CHECK_ARG_COUNT(2); ML_CHECK_ARG_TYPE(0, MLStringT); const char *Name = ml_string_value(Args[0]); - context_scope(Name); + context_t *Context = context_scope(Name); ml_value_t *Result = ml_call(Args[1], 0, NULL); if (Result->Type == MLErrorT) { printf("Error: %s\n", ml_error_message(Result)); @@ -127,7 +127,7 @@ ml_value_t *scope(void *Data, int Count, ml_value_t **Args) { exit(1); } context_pop(); - return MLNil; + return (ml_value_t *)Context; } ml_value_t *include(void *Data, int Count, ml_value_t **Args) {