diff --git a/src/Makefile b/src/Makefile index d0f4a73..a4d7681 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -files = pebblisp.c tokens.c object.c env.c +files = pebblisp.c tokens.c object.c env.c web.c libs = -lreadline -lmicrohttpd exe = pl diff --git a/src/env.c b/src/env.c index b323792..f6ae16d 100644 --- a/src/env.c +++ b/src/env.c @@ -215,6 +215,17 @@ struct symFunc { Object (* func)(Object, Object, struct Environment*); }; +struct Environment* _global; +struct Environment* global() +{ + return _global; +} + +void setGlobal(struct Environment *env) +{ + _global = env; +} + struct Environment defaultEnv() { char** strings = calloc(sizeof(char*), MAX_ENV_ELM); diff --git a/src/env.h b/src/env.h index a431d63..3a43718 100644 --- a/src/env.h +++ b/src/env.h @@ -16,7 +16,9 @@ struct Environment { int refs; }; -struct Environment* global; + +struct Environment* global(); +void setGlobal(struct Environment *env); Object fetchFromEnvironment(const char* name, struct Environment* env); diff --git a/src/examples/webby.pl b/src/examples/webby.pl index cf174c2..36f2f83 100755 --- a/src/examples/webby.pl +++ b/src/examples/webby.pl @@ -3,24 +3,60 @@ (struct post (title body)) +;(def element (fn (type) (fn (text) (cat "<" type ">" text "" type ">")))) +;(def link (element "link")) +;(prnl (link "howdy")) + (def html (fn (text) (cat "" text ""))) +(def head (fn (text) (cat "
" text ""))) (def body (fn (text) (cat "" text ""))) +(def link (fn (text) (cat ""))) (def h1 (fn (text) (cat "" text "
"))) -(def htmlize (fn (po) - (cat - (h2 po's title) - (p po's body)))) + +(def htmlize (fn (po) (cat + (h2 po's title) + (p po's body)))) (def p1 (post "Hey" "This is a post")) -(def p2 (post "This" "Is ALSO a post")) +(def p2 (post "This" +"Is ALSO a post. And frankly, what a great post! It's so long and flowing, +and the interpreter won't even instantly crash over it! It's truly astounding +stuff, when you think about it." +)) -(prnl (html (body (cat - (h1 "This is Sage's Blog") - (htmlize p1) - (htmlize p2) - )))) +(def homepage (fn () (html (cat + (head (link "rel='stylesheet' href='styles.css'")) + (body (cat + (h1 "This is Sage's Blog") + (htmlize p1) + (htmlize p2)))))) ) + +(addroute "/" homepage) + +(addroute "/styles.css" (fn () ( +"html { + background-color: #ddddff; +} +body { + width: 40%; + margin-left: auto; + margin-right: auto; + font-size: 200%; + font-family: sans; +} +" +))) + +(def PORT 9090) +(serve PORT) +(prnl (cat "Hosting server on " PORT ". Press enter to exit.")) +(def repl (fn () ( + (eval (inp)) + (repl) + ))) +(repl) diff --git a/src/object.c b/src/object.c index 4ef693e..8facbe6 100644 --- a/src/object.c +++ b/src/object.c @@ -267,9 +267,9 @@ void stringStruct(char* dest, const Object* obj) dest[0] = '{'; dest[1] = '\0'; - for (int i = 0; i < global->structDefs[so->definition].fieldCount; i++) { + for (int i = 0; i < global()->structDefs[so->definition].fieldCount; i++) { strcat(dest, " "); - strcat(dest, global->structDefs[so->definition].names[i]); + strcat(dest, global()->structDefs[so->definition].names[i]); strcat(dest, ": "); int isString = so->fields[i].type == TYPE_STRING; if (isString) { @@ -309,6 +309,11 @@ void stringStruct(char* dest, const Object* obj) * @param dest The string to copy the list text into * @param obj The list Object to make a string from */ +#ifdef STANDALONE +#define stringf(_dest, _len, _format, args...) sprintf(_dest, _format, ## args) +#else +#define stringf(_dest, _len, _format, args...) snprintf(_dest, _len, _format, ## args) +#endif char* stringNObj(char* dest, const Object* obj, const size_t len) { if (!dest || !obj) { @@ -317,16 +322,16 @@ char* stringNObj(char* dest, const Object* obj, const size_t len) switch (obj->type) { case TYPE_NUMBER: - snprintf(dest, len, "%d", obj->number); + stringf(dest, len, "%d", obj->number); break; case TYPE_BOOL: - snprintf(dest, len, "%s", obj->number ? "T" : "F"); + stringf(dest, len, "%s", obj->number ? "T" : "F"); break; case TYPE_STRING: - snprintf(dest, len, "%s", obj->string); + stringf(dest, len, "%s", obj->string); break; case TYPE_SYMBOL: - snprintf(dest, len, "`%s`", obj->string); + stringf(dest, len, "`%s`", obj->string); break; case TYPE_STRUCT: //snprintf(dest, len, "{%s}", obj->structObject->definition->names[0]); @@ -339,28 +344,28 @@ char* stringNObj(char* dest, const Object* obj, const size_t len) case TYPE_ERROR: { int code = getErrorCode(*obj); #ifdef SIMPLE_ERRORS - snprintf(dest, len, "E[%d]", (int)code); + stringf(dest, len, "E[%d]", (int)code); #else if (obj->error->context && obj->error->context[0] != '\0') { - snprintf(dest, len, "'%s': %s", errorText[code], + stringf(dest, len, "'%s': %s", errorText[code], obj->error->context); } else { - snprintf(dest, len, "%s", errorText[code]); + stringf(dest, len, "%s", errorText[code]); } #endif break; } case TYPE_FUNC: case TYPE_LAMBDA: - snprintf(dest, len, "X%d", obj->number); + stringf(dest, len, "X%d", obj->number); break; case TYPE_OTHER: - snprintf(dest, len, "%p", obj->other->data); + stringf(dest, len, "%p", obj->other->data); break; } if (!isValidType(*obj)) { - snprintf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number); + stringf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number); } return dest; @@ -506,7 +511,7 @@ void cleanObject(Object* target) free(target->lambda); break; case TYPE_STRUCT: - for (int i = 0; i < global->structDefs[target->structObject->definition].fieldCount; i++) { + for (int i = 0; i < global()->structDefs[target->structObject->definition].fieldCount; i++) { cleanObject(&target->structObject->fields[i]); } free(target->structObject->fields); @@ -657,7 +662,7 @@ inline Object structObject(int definition) Object structo = newObject(TYPE_STRUCT); structo.structObject = malloc(sizeof(struct StructObject)); structo.structObject->definition = definition; - structo.structObject->fields = malloc(sizeof(Object) * global->structDefs[definition].fieldCount); + structo.structObject->fields = malloc(sizeof(Object) * global()->structDefs[definition].fieldCount); return structo; } @@ -761,7 +766,7 @@ Object cloneStruct(const Object src) { Object structo = structObject(src.structObject->definition); struct StructObject* so = structo.structObject; - for (int i = 0; i < global->structDefs[so->definition].fieldCount; i++) { + for (int i = 0; i < global()->structDefs[so->definition].fieldCount; i++) { so->fields[i] = cloneObject(src.structObject->fields[i]); } return structo; diff --git a/src/pebblisp.c b/src/pebblisp.c index a22743f..10e14e6 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -1,5 +1,3 @@ -#pragma ide diagnostic ignored "misc-no-recursion" - #include "pebblisp.h" #include