From e2c977e95ab20c1f901a94f570f0aed350ce259b Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Fri, 7 Jan 2022 16:55:03 -0500 Subject: [PATCH] Finally some consistent styling. Centralized printf/printd defines in object.h Removed null/isList checking from FOR_POINTER_IN_LIST --- src/calc.c | 207 +++++++++++--------- src/calc.h | 2 +- src/env.c | 133 +++++++------ src/env.h | 31 +-- src/object.c | 294 ++++++++++++++-------------- src/object.h | 91 +++++++-- src/pebbleobject.c | 96 +++++----- src/pebbleobject.h | 32 ++-- src/pebblisp.c | 467 +++++++++++++++++++++++---------------------- src/pebblisp.h | 125 +++++++----- src/pebcom.c | 33 ++-- src/pebcom.h | 13 +- src/tokens.c | 71 ++++--- src/tokens.h | 5 +- 14 files changed, 892 insertions(+), 708 deletions(-) diff --git a/src/calc.c b/src/calc.c index ca0b080..c73d932 100644 --- a/src/calc.c +++ b/src/calc.c @@ -7,18 +7,18 @@ #include "calc.h" // Custom layers that users can build -Window *s_custom_window; -TextLayer *s_heading_text_layer; +Window* s_custom_window; +TextLayer* s_heading_text_layer; char header[30] = ""; // Code display -Window *s_code_window; -TextLayer *s_input_text_layer; -TextLayer *s_result_text_layer; +Window* s_code_window; +TextLayer* s_input_text_layer; +TextLayer* s_result_text_layer; // Script selection -Window *s_script_menu_window; -MenuLayer *s_script_select_layer; +Window* s_script_menu_window; +MenuLayer* s_script_select_layer; int current_script_num; // PebbLisp environment @@ -32,12 +32,12 @@ int excess_chars = 1; #define RESULT_PREFIX "R:" char result_text[RESULT_LENGTH] = RESULT_PREFIX; -const char *tokens[] = { +const char* tokens[] = { " ", "(", ")", "+ ", "- ", "* ", "/ ", - "1","2","3", - "4","5","6", - "7","8","9", "0", "x", + "1", "2", "3", + "4", "5", "6", + "7", "8", "9", "0", "x", "a", "b", "c", "d", "e", "= ", "< ", "> ", "\"", @@ -51,7 +51,7 @@ const char *tokens[] = { // Currently selected button, starts on '(' static int8_t selected_token = 1; -const char *func_tokens[] = { +const char* func_tokens[] = { "window ", "sc ", "cw ", "pw ", "rw ", "atl ", "utl ", "sec ", "mnt ", "hr ", "hrt ", "vibe ", "sub " @@ -68,16 +68,16 @@ const uint32_t outbox_size = 1024; // Get the number of tokens in the current list static inline int8_t tokenCount() { - return using_func_tokens? - sizeof(func_tokens) / sizeof(func_tokens[0]) : - sizeof(tokens) / sizeof(tokens[0]); + return using_func_tokens ? + sizeof(func_tokens) / sizeof(func_tokens[0]) : + sizeof(tokens) / sizeof(tokens[0]); } // Get current token from tokens[] or func_tokens[], as appropriate static inline const char* getToken(int8_t n) { int8_t t = n % tokenCount(); - return using_func_tokens? func_tokens[t] : tokens[t]; + return using_func_tokens ? func_tokens[t] : tokens[t]; } static void trim(size_t len) @@ -93,11 +93,11 @@ static void trim(size_t len) static void updateText() { trim(excess_chars); - const char *token = getToken(selected_token); + const char* token = getToken(selected_token); const char* add = - token[0] == ' ' ? "_": // Display space as underscore - token[0] == '\n'? "\\n": // Display newline as \n + token[0] == ' ' ? "_" : // Display space as underscore + token[0] == '\n' ? "\\n" : // Display newline as \n token; // Display others literally strcat(displayed_code, add); @@ -107,19 +107,19 @@ static void updateText() } // Cycle through the current list of tokens -static void cycle_tokens(ClickRecognizerRef recognizer, void *context) +static void cycle_tokens(ClickRecognizerRef recognizer, void* context) { // Change current token - if(click_recognizer_get_button_id(recognizer) == BUTTON_ID_DOWN) { + if (click_recognizer_get_button_id(recognizer) == BUTTON_ID_DOWN) { selected_token++; } else { selected_token--; } // If selected token is outside of range, wrap around - if(selected_token < 0) { + if (selected_token < 0) { selected_token = tokenCount() - 1; - } else if(selected_token >= tokenCount()) { + } else if (selected_token >= tokenCount()) { selected_token = 0; } @@ -127,7 +127,7 @@ static void cycle_tokens(ClickRecognizerRef recognizer, void *context) } static GFont tiny_font; -static const char *fonts[] = { +static const char* fonts[] = { FONT_KEY_GOTHIC_28_BOLD, FONT_KEY_GOTHIC_24_BOLD, FONT_KEY_GOTHIC_18_BOLD, @@ -140,26 +140,28 @@ static void adjustFont() { int i = 0; int size = 0; - while(displayed_code[i++]) { - if(displayed_code[i] == '\n') + while (displayed_code[i++]) { + if (displayed_code[i] == '\n') { size += 10; + } size++; } // Use various system fonts for most text - if(size <= 100) { - int f = size < 50 ? smallestFont - 3 : - size < 80 ? smallestFont - 2 : - size < 100 ? smallestFont - 1 : - smallestFont; - text_layer_set_font(s_input_text_layer, - fonts_get_system_font(fonts[f])); + if (size <= 100) { + const char* f = fonts[ + size < 50 ? smallestFont - 3 : + size < 80 ? smallestFont - 2 : + size < 100 ? smallestFont - 1 : + smallestFont + ]; + text_layer_set_font(s_input_text_layer, fonts_get_system_font(f)); } else { // Use custom extra small font for lots of text text_layer_set_font(s_input_text_layer, tiny_font); } } -static void custom_unload(Window *window) +static void custom_unload(Window* window) { text_layer_destroy(s_heading_text_layer); @@ -171,15 +173,15 @@ static void custom_unload(Window *window) * In normal token list, backspace if possible, otherwise return to script list * In function token list, return to normal token list */ -static void click_backspace(ClickRecognizerRef recognizer, void *context) +static void click_backspace(ClickRecognizerRef recognizer, void* context) { - if(s_custom_window) { + if (s_custom_window) { window_stack_remove(s_custom_window, true); return; } - if(!using_func_tokens) { - if(displayed_code[0] == '\0') { + if (!using_func_tokens) { + if (displayed_code[0] == '\0') { window_stack_remove(window_stack_get_top_window(), true); } else { trim(excess_chars + 1); @@ -198,7 +200,7 @@ static void add_token() { strcat(displayed_code, getToken(selected_token)); selected_token = 0; - if(using_func_tokens) { + if (using_func_tokens) { using_func_tokens = false; } @@ -219,21 +221,23 @@ static void calculate() updateText(); stringNObj(temp, &obj, RESULT_LENGTH); - if(obj.type == TYPE_ERROR) { - text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); + if (obj.type == TYPE_ERROR) { + text_layer_set_font(s_result_text_layer, + fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); } else { - text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); + text_layer_set_font(s_result_text_layer, + fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); } snprintf(result_text, RESULT_LENGTH, RESULT_PREFIX "%s", temp); text_layer_set_text(s_result_text_layer, result_text); } // Button press handler -static void click_select(ClickRecognizerRef recognizer, void *context) +static void click_select(ClickRecognizerRef recognizer, void* context) { - if(!using_func_tokens && selected_token == tokenCount() - 1) { + if (!using_func_tokens && selected_token == tokenCount() - 1) { calculate(); - } else if(!using_func_tokens && selected_token == tokenCount() - 2) { + } else if (!using_func_tokens && selected_token == tokenCount() - 2) { using_func_tokens = true; selected_token = 0; updateText(); @@ -243,13 +247,13 @@ static void click_select(ClickRecognizerRef recognizer, void *context) } // Saves text in editor to persistent storage -static void click_save(ClickRecognizerRef recognizer, void *context) +static void click_save(ClickRecognizerRef recognizer, void* context) { int8_t i = strlen(displayed_code); unsigned token_len = strlen(getToken(selected_token)); printf("%s", displayed_code); - for(unsigned j = 0; j < token_len; j++) { - displayed_code[i-(1 + j)] = '\0'; + for (unsigned j = 0; j < token_len; j++) { + displayed_code[i - (1 + j)] = '\0'; printf("%s", displayed_code); } @@ -258,7 +262,7 @@ static void click_save(ClickRecognizerRef recognizer, void *context) } // Sets the code_window click functions -static void code_click_subscribe(void *context) +static void code_click_subscribe(void* context) { window_single_repeating_click_subscribe(BUTTON_ID_UP, 100, cycle_tokens); window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 100, cycle_tokens); @@ -268,13 +272,13 @@ static void code_click_subscribe(void *context) } #ifdef LOW_MEM - #define TIME_FUNC \ +#define TIME_FUNC \ "(def time (fn ()(utl tt \n"\ " (cat \"Hey, it's \" \n"\ " (hrt) \":\" (mnt)\n" \ "))))\n" #else - #define TIME_FUNC \ +#define TIME_FUNC \ "(def time (fn () ((def m (mnt)) (utl tt \n"\ " (cat \"Hey, it's \"\n"\ " (hrt) \":\" (if (< m 10) \"0\" \"\") m)\n"\ @@ -290,9 +294,9 @@ static void code_click_subscribe(void *context) // Remove to re-enable #undef FORCE_TEXT -static void code_window_load(Window *window) +static void code_window_load(Window* window) { - Layer *window_layer = window_get_root_layer(window); + Layer* window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); // Register click config provider @@ -301,44 +305,51 @@ static void code_window_load(Window *window) // Input text layer setup s_input_text_layer = text_layer_create(bounds); text_layer_set_text(s_input_text_layer, getToken(1)); - text_layer_set_font(s_input_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); - layer_add_child(window_get_root_layer(s_code_window), text_layer_get_layer(s_input_text_layer)); + text_layer_set_font(s_input_text_layer, + fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); + layer_add_child(window_get_root_layer(s_code_window), + text_layer_get_layer(s_input_text_layer)); // Result text layer setup GRect result_bounds = GRect(6, 148, 132, 132); s_result_text_layer = text_layer_create(result_bounds); text_layer_set_text(s_result_text_layer, result_text); - text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); + text_layer_set_font(s_result_text_layer, + fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); text_layer_set_text_alignment(s_result_text_layer, GTextAlignmentRight); - layer_add_child(window_get_root_layer(s_code_window), text_layer_get_layer(s_result_text_layer)); + layer_add_child(window_get_root_layer(s_code_window), + text_layer_get_layer(s_result_text_layer)); // Push the window, setting the window animation to 'true' window_stack_push(s_code_window, true); // If possible, load the previous code text - #ifdef FORCE_TEXT +#ifdef FORCE_TEXT strncpy(displayed_code, FORCE_TEXT, SMAX_LENGTH); updateText(); adjustFont(); - #else - if(persist_exists(current_script_num)) { +#else + if (persist_exists(current_script_num)) { persist_read_string(current_script_num, displayed_code, SMAX_LENGTH); updateText(); adjustFont(); } - #endif +#endif } -void debug_result(const char* d) { +void debug_result(const char* d) +{ snprintf(result_text, RESULT_LENGTH, "%s", d); text_layer_set_text(s_result_text_layer, result_text); psleep(300); } -static Object run_script(Object script_num, Object obj, struct Environment *e) { +static Object run_script(Object script_num, Object obj, + struct Environment* e) +{ int n = script_num.number - 1; - if(persist_exists(n)) { - char *code = malloc(sizeof(char) * SMAX_LENGTH); + if (persist_exists(n)) { + char* code = malloc(sizeof(char) * SMAX_LENGTH); persist_read_string(n, code, SMAX_LENGTH); Object o = parseEval(code, e); free(code); @@ -347,7 +358,7 @@ static Object run_script(Object script_num, Object obj, struct Environment *e) { return errorObject(SCRIPT_NOT_FOUND); } -static void code_window_unload(Window *window) +static void code_window_unload(Window* window) { // Save the current code text persist_write_string(current_script_num, displayed_code); @@ -361,11 +372,11 @@ static void code_window_unload(Window *window) void code_window_push() { - if(!s_code_window) { + if (!s_code_window) { s_code_window = window_create(); WindowHandlers wh = { .load = code_window_load, - .unload = code_window_unload }; + .unload = code_window_unload}; window_set_window_handlers(s_code_window, wh); } @@ -374,47 +385,50 @@ void code_window_push() /** Menu Window **/ -static void select_callback(struct MenuLayer *menu_layer, - MenuIndex *cell_index, void *context) +static void select_callback(MenuLayer* menu_layer, MenuIndex* cell_index, + void* context) { current_script_num = cell_index->row; code_window_push(); } -static uint16_t get_num_rows_callback(MenuLayer *menu_layer, - uint16_t section_index, void *context) +static uint16_t get_num_rows_callback(MenuLayer* menu_layer, + uint16_t section_index, void* context) { return SCRIPT_COUNT; } -static void draw_row_callback(GContext *ctx, const Layer *cell_layer, - MenuIndex *cell_index, void *context) +static void draw_row_callback(GContext* ctx, const Layer* cell_layer, + MenuIndex* cell_index, void* context) { static char s_buff[16]; - snprintf(s_buff, sizeof(s_buff), "Script %d", 1 + (int)cell_index->row); + snprintf(s_buff, sizeof(s_buff), "Script %d", 1 + (int) cell_index->row); // Draw this row's index menu_cell_basic_draw(ctx, cell_layer, s_buff, NULL, NULL); } -static int16_t get_cell_height_callback(struct MenuLayer *menu_layer, - MenuIndex *cell_index, void *context) +static int16_t get_cell_height_callback(MenuLayer* menu_layer, + MenuIndex* cell_index, void* context) { return CELL_HEIGHT; } -static void script_menu_load(Window *window) +static void script_menu_load(Window* window) { - Layer *window_layer = window_get_root_layer(window); + Layer* window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); s_script_select_layer = menu_layer_create(bounds); menu_layer_set_click_config_onto_window(s_script_select_layer, window); - #if defined(PBL_COLOR) - menu_layer_set_normal_colors(s_script_select_layer, GColorBlack, GColorWhite); - menu_layer_set_highlight_colors(s_script_select_layer, GColorDukeBlue, GColorWhite); - #endif +#if defined(PBL_COLOR) + menu_layer_set_normal_colors(s_script_select_layer, + GColorBlack, GColorWhite); + + menu_layer_set_highlight_colors(s_script_select_layer, + GColorDukeBlue, GColorWhite); +#endif menu_layer_set_callbacks(s_script_select_layer, NULL, (MenuLayerCallbacks) { .get_num_rows = get_num_rows_callback, @@ -422,19 +436,20 @@ static void script_menu_load(Window *window) .get_cell_height = get_cell_height_callback, .select_click = select_callback, }); + layer_add_child(window_layer, menu_layer_get_layer(s_script_select_layer)); } -static void script_menu_unload(Window *window) +static void script_menu_unload(Window* window) { menu_layer_destroy(s_script_select_layer); } /** Custom Window **/ -static void custom_load(Window *window) +static void custom_load(Window* window) { - Layer *window_layer = window_get_root_layer(window); + Layer* window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); // Register click config provider @@ -443,7 +458,7 @@ static void custom_load(Window *window) // Header text layer setup s_heading_text_layer = text_layer_create(bounds); text_layer_set_text(s_heading_text_layer, header); - text_layer_set_font(s_heading_text_layer, + text_layer_set_font(s_heading_text_layer, fonts_get_system_font(FONT_KEY_BITHAM_30_BLACK)); layer_add_child(window_get_root_layer(s_custom_window), text_layer_get_layer(s_heading_text_layer)); @@ -452,16 +467,17 @@ static void custom_load(Window *window) window_stack_push(s_custom_window, true); } -Object add_window(Object obj1, Object _, struct Environment *env) +Object add_window(Object obj1, Object _, struct Environment* env) { printf("ADD_WINDOW\n"); stringObj(header, &obj1); - if(!s_custom_window) { + if (!s_custom_window) { s_custom_window = window_create(); WindowHandlers wh = { .load = custom_load, - .unload = custom_unload }; + .unload = custom_unload + }; window_set_window_handlers(s_custom_window, wh); } @@ -470,14 +486,15 @@ Object add_window(Object obj1, Object _, struct Environment *env) return numberObject(1); } -static void inbox_received_callback(DictionaryIterator *iter, void *context) { - Tuple *script_tuple = dict_find(iter, MESSAGE_KEY_ScriptText); - if(script_tuple) { - if(!s_code_window) { +static void inbox_received_callback(DictionaryIterator* iter, void* context) +{ + Tuple* script_tuple = dict_find(iter, MESSAGE_KEY_ScriptText); + if (script_tuple) { + if (!s_code_window) { current_script_num = 0; code_window_push(); } - char *script_text = script_tuple->value->cstring; + char* script_text = script_tuple->value->cstring; snprintf(displayed_code, sizeof(displayed_code), "%s", script_text); updateText(); } diff --git a/src/calc.h b/src/calc.h index 5044222..3e39935 100644 --- a/src/calc.h +++ b/src/calc.h @@ -9,6 +9,6 @@ #define SCRIPT_COUNT 5 -void debug_result(const char *d); +void debug_result(const char* d); #endif diff --git a/src/env.c b/src/env.c index 5b9f93a..3e83497 100644 --- a/src/env.c +++ b/src/env.c @@ -1,21 +1,18 @@ #include "env.h" -#include "pebblisp.h" + +#include #include #include -#include -#ifndef STANDALONE -#include -#undef printf -#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) -#endif +#include "pebblisp.h" -Object fetchFromEnvironment(const char *name, struct Environment *env) +Object fetchFromEnvironment(const char* name, struct Environment* env) { - if(!env) + if (!env) { return errorObject(NULL_ENV); + } - if(env->size == 0) { + if (env->size == 0) { if (env->outer) { return fetchFromEnvironment(name, env->outer); } else { @@ -23,52 +20,51 @@ Object fetchFromEnvironment(const char *name, struct Environment *env) } } - for(int i = 0; i < env->size; i++) { - if(env->strings[i] == NULL) { + for (int i = 0; i < env->size; i++) { + if (env->strings[i] == NULL) { printd("Try %d (NULL)\n", i); break; } printd("Try %d (%s)\n", i, env->strings[i]); debugObj(&env->objects[i]); - if(strcmp(name, env->strings[i]) == 0) { + if (strcmp(name, env->strings[i]) == 0) { printd("Returning!\n"); return cloneObject(env->objects[i]); } } printd("Trying outer %p\n", env->outer); - if(env->outer) { + if (env->outer) { return fetchFromEnvironment(name, env->outer); } return errorWithContext(DID_NOT_FIND_SYMBOL, name); } -struct Environment envForLambda(const Object *params, const Object *arg_forms, - struct Environment *outer) +struct Environment envForLambda(const Object* params, const Object* arg_forms, + struct Environment* outer) { int paramCount = listLength(params); - struct Environment env = { - .outer = outer, + struct Environment env = {.outer = outer, .strings = NULL, .objects = NULL, - .size = paramCount - }; + .size = paramCount}; - if(paramCount == 0) + if (paramCount == 0) { return env; + } env.strings = calloc(sizeof(char*), paramCount + 1); env.objects = malloc(sizeof(Object) * (paramCount + 1)); - const Object *march = arg_forms; - for(int i = 0; i < paramCount; i++) { - const char *newObjName = itemAt(params, i)->string; + const Object* march = arg_forms; + for (int i = 0; i < paramCount; i++) { + const char* newObjName = itemAt(params, i)->string; // Eval the `march` list Object newEnvObj = eval(march, outer); - addToEnv(&env, newObjName, newEnvObj); // Could use eval_forms? + addToEnv(&env, newObjName, newEnvObj); // Could use eval_forms? cleanObject(&newEnvObj); march = march->forward; } @@ -82,15 +78,15 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms, // symbol was found // // Returns the index of the symbol in the environment, if found. Otherwise, -1 -int findInEnv(struct Environment **env, const char *name) +int findInEnv(struct Environment** env, const char* name) { - struct Environment *temp_env = *env; - while(temp_env) { - for(int i = 0; i < temp_env->size; i++) { - if(temp_env->strings[i] == NULL) { + struct Environment* temp_env = *env; + while (temp_env) { + for (int i = 0; i < temp_env->size; i++) { + if (temp_env->strings[i] == NULL) { break; } - if(strcmp(temp_env->strings[i], name) == 0) { + if (strcmp(temp_env->strings[i], name) == 0) { *env = temp_env; return i; } @@ -101,7 +97,7 @@ int findInEnv(struct Environment **env, const char *name) } // TODO Maybe extend environment using a new outer, instead of realloc -void addToEnv(struct Environment *env, const char *name, const Object obj) +void addToEnv(struct Environment* env, const char* name, const Object obj) { // int sym_pos = findInEnv(&env, name); // if(sym_pos != -1) { @@ -112,20 +108,21 @@ void addToEnv(struct Environment *env, const char *name, const Object obj) // } int i; - struct Environment *temp_env = env; + struct Environment* temp_env = env; int is_local = 1; - while(temp_env) { - for(i = 0; i < temp_env->size; i++) { + while (temp_env) { + for (i = 0; i < temp_env->size; i++) { // Add *new* item to env only if we're in the local scope - if(temp_env->strings[i] == NULL) { + if (temp_env->strings[i] == NULL) { if (is_local) { - temp_env->strings[i] = calloc(sizeof(char), strlen(name) + 1); + temp_env->strings[i] = + calloc(sizeof(char), strlen(name) + 1); strncpy(temp_env->strings[i], name, strlen(name)); temp_env->objects[i] = cloneObject(obj); return; } break; - } else if(strcmp(temp_env->strings[i], name) == 0) { + } else if (strcmp(temp_env->strings[i], name) == 0) { Object o = cloneObject(obj); cleanObject(&temp_env->objects[i]); temp_env->objects[i] = o; @@ -143,7 +140,7 @@ void addToEnv(struct Environment *env, const char *name, const Object obj) env->strings = realloc(env->strings, sizeof(char*) * env->size); env->objects = realloc(env->objects, sizeof(Object) * env->size); - for(int j = 0; j < inc; j++) { + for (int j = 0; j < inc; j++) { env->strings[old_size + j] = NULL; } @@ -152,14 +149,14 @@ void addToEnv(struct Environment *env, const char *name, const Object obj) env->objects[old_size] = cloneObject(obj); } -void printEnv(struct Environment *env) +void printEnv(struct Environment* env) { - if(!env) { + if (!env) { printf("NULL env\n"); return; } - for(int i = 0; i < env->size; i++) { - if(env->strings[i] == NULL) { + for (int i = 0; i < env->size; i++) { + if (env->strings[i] == NULL) { printf("env[%d]: NULL %p\n", i, env->strings[i]); break; } @@ -170,19 +167,20 @@ void printEnv(struct Environment *env) } } -void addFunc(const char *name, Object (*func)(Object, Object, struct Environment*), - struct Environment *env) +void addFunc(const char* name, + Object (* func)(Object, Object, struct Environment*), + struct Environment* env) { Object o = newObject(TYPE_FUNC); o.func = func; addToEnv(env, name, o); } -void deleteEnv(struct Environment *e) +void deleteEnv(struct Environment* e) { if (e->strings) { int i = 0; - while(e->strings[i]) { + while (e->strings[i]) { free(e->strings[i]); cleanObject(&e->objects[i]); i++; @@ -196,8 +194,9 @@ void deleteEnv(struct Environment *e) } struct symFunc { - const char *sym; - Object (*func)(Object, Object, struct Environment*); + const char* sym; + + Object (* func)(Object, Object, struct Environment*); }; struct Environment defaultEnv() @@ -214,27 +213,43 @@ struct Environment defaultEnv() }; struct symFunc symFuncs[] = { - {"+", &add}, {"-", &sub}, {"*", &mul}, {"/", &dvi}, {"%", &mod}, - {"=", &equ}, {">", >h}, {"<", <h}, - {"cat", &catObjects}, {"fil", &filter}, {"len", &len}, - {"ap", &append}, {"pre", &prepend}, - {"at", &at}, {"rest", &rest}, + {"+", &add}, + {"-", &sub}, + {"*", &mul}, + {"/", &dvi}, + {"%", &mod}, + {"=", &equ}, + {">", >h}, + {"<", <h}, + {"&", &and}, + {"|", &or}, + {"cat", &catObjects}, + {"fil", &filter}, + {"len", &len}, + {"ap", &append}, + {"pre", &prepend}, + {"at", &at}, + {"rest", &rest}, {"chat", &charAt}, #ifndef LOW_MEM {"rev", &reverse}, #endif - {"isnum", &isNum}, {"isstr", &isString}, {"iserr", &isErr}, + {"isnum", &isNum}, + {"isstr", &isString}, + {"iserr", &isErr}, {"char", &charVal}, {"eval", &parseEvalO}, - #ifdef STANDALONE - {"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO}, +#ifdef STANDALONE + {"prn", &print}, + {"pch", &pChar}, + {"penv", &printEnvO}, {"sys", &systemCall}, {"loadfile", &loadFile}, {"inp", &takeInput}, - #endif +#endif }; - for(unsigned i = 0; i < sizeof(symFuncs)/sizeof(symFuncs[0]); i++) { + for (unsigned i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) { addFunc(symFuncs[i].sym, symFuncs[i].func, &e); } diff --git a/src/env.h b/src/env.h index bd12972..90dfe67 100644 --- a/src/env.h +++ b/src/env.h @@ -5,20 +5,27 @@ struct Environment; struct Environment { - char **strings; - Object *objects; - struct Environment *outer; - char size; + char** strings; + Object* objects; + struct Environment* outer; + int size; }; -Object fetchFromEnvironment(const char *name, struct Environment *env); -struct Environment envForLambda(const Object *params, const Object *arg_forms, - struct Environment *outer); -void addToEnv(struct Environment *env, const char *name, const Object obj); -void printEnv(struct Environment *env); -void addFunc(const char *name, Object (*func)(Object, Object, struct Environment*), - struct Environment *env); -void deleteEnv(struct Environment *e); +Object fetchFromEnvironment(const char* name, struct Environment* env); + +struct Environment envForLambda(const Object* params, const Object* arg_forms, + struct Environment* outer); + +void addToEnv(struct Environment* env, const char* name, const Object obj); + +void printEnv(struct Environment* env); + +void addFunc(const char* name, + Object (* func)(Object, Object, struct Environment*), + struct Environment* env); + +void deleteEnv(struct Environment* e); + struct Environment defaultEnv(); #endif diff --git a/src/object.c b/src/object.c index 671a5b4..cf641b7 100644 --- a/src/object.c +++ b/src/object.c @@ -1,40 +1,30 @@ #include "object.h" -#include + #include - -#ifdef DEBUG -#define printd(...) printf(__VA_ARGS__) -#else -#define printd(...) ; -#endif - -#ifndef STANDALONE -#include -#undef printf -#undef printd -#define printf(...) ; -#define printd(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) -#endif +#include /** * Returns the length of a given list Object * @param listObj The list to get the length of * @return Length of the list if non-null and of the list type. Otherwise -1 */ -int listLength(const Object *listObj) +int listLength(const Object* listObj) { - if(!listObj || !isListy(*listObj)) + if (!listObj || !isListy(*listObj)) { return -1; + } int len = 0; - FOR_POINTER_IN_LIST(listObj) { len++; } + FOR_POINTER_IN_LIST(listObj) { + len++; + } return len; } -Object len(Object obj1, Object o_ignore, struct Environment *e_ignore) +Object len(Object obj1, Object o_ignore, struct Environment* e_ignore) { Object o = numberObject(listLength(&obj1)); - if(o.number < 0) { + if (o.number < 0) { return errorObject(NOT_A_LIST); } return o; @@ -46,16 +36,19 @@ Object len(Object obj1, Object o_ignore, struct Environment *e_ignore) * @param n The index to to fetch from the list * @return A pointer to the Object, if it is found, or NULL on an error */ -Object *itemAt(const Object *listObj, int n) +Object* itemAt(const Object* listObj, int n) { - if(!listObj || !isListy(*listObj)) + if (!listObj || !isListy(*listObj)) { return NULL; + } FOR_POINTER_IN_LIST(listObj) { - if(POINTER == NULL) + if (POINTER == NULL) { return NULL; - if(n-- == 0) + } + if (n-- == 0) { return POINTER; + } } return NULL; } @@ -65,12 +58,13 @@ Object *itemAt(const Object *listObj, int n) * @param listObj The list to find the tail of * @return A pointer to the last Object if it is found, or NULL on an error */ -Object *tail(const Object *listObj) +Object* tail(const Object* listObj) { - if(!listObj || !isListy(*listObj)) + if (!listObj || !isListy(*listObj)) { return NULL; + } - Object *tail = NULL; + Object* tail = NULL; FOR_POINTER_IN_LIST(listObj) { tail = POINTER; } @@ -86,12 +80,13 @@ Object *tail(const Object *listObj) * @param obj A pointer to the object to check * @return True only if the non-null Object is empty/non-zero */ -inline int isEmpty(const Object *obj) +inline int isEmpty(const Object* obj) { - if(obj == NULL) + if (obj == NULL) { return 0; + } - switch(obj->type) { + switch (obj->type) { case TYPE_NUMBER: case TYPE_BOOL: return obj->number == 0; @@ -120,7 +115,7 @@ inline int isEmpty(const Object *obj) * @param spot A pointer to the Object pointer that needs allocating * @param src The Object to copy from */ -void allocObject(Object **spot, const Object src) +void allocObject(Object** spot, const Object src) { *spot = malloc(sizeof(struct Object)); **spot = src; @@ -138,20 +133,21 @@ void allocObject(Object **spot, const Object src) * @warning UNTESTED */ -void insertIntoList(Object *dest, int ind, const Object src) +void insertIntoList(Object* dest, int ind, const Object src) { - if(!dest || !isListy(*dest)) + if (!dest || !isListy(*dest)) { return; + } // Merely append, when possible - if(ind >= listLength(dest)) { + if (ind >= listLength(dest)) { nf_addToList(dest, src); return; } // The Objects to preceed and follow the new one - Object *beforeNew = itemAt(dest, ind - 1); - Object *afterNew = beforeNew->forward; + Object* beforeNew = itemAt(dest, ind - 1); + Object* afterNew = beforeNew->forward; // Replace the `before` Object's pointer allocObject(&beforeNew->forward, src); @@ -167,12 +163,13 @@ void insertIntoList(Object *dest, int ind, const Object src) * @param i The index of the element to replace * @param src The Object to copy into the list */ -void replaceListing(Object *list, int i, const Object src) +void replaceListing(Object* list, int i, const Object src) { - if(!list || isListy(*list)) + if (!list || isListy(*list)) { return; - Object *replace = itemAt(list, i); - Object *oldForward = replace->forward; + } + Object* replace = itemAt(list, i); + Object* oldForward = replace->forward; cleanObject(replace); *replace = src; replace->forward = oldForward; @@ -184,12 +181,13 @@ void replaceListing(Object *list, int i, const Object src) * @param dest The list to append to * @param src The Object to copy into the list */ -void nf_addToList(Object *dest, const Object src) +void nf_addToList(Object* dest, const Object src) { - if(!dest || !isListy(*dest)) + if (!dest || !isListy(*dest)) { return; + } - if(isEmpty(dest)) { + if (isEmpty(dest)) { allocObject(&dest->list, src); return; } @@ -198,32 +196,30 @@ void nf_addToList(Object *dest, const Object src) } #ifndef SIMPLE_ERRORS -static const char *errorText[] = { - "MISMATCHED_PARENS", - "BAD_LIST_OF_SYMBOL_STRINGS", - "TYPE_LIST_NOT_CAUGHT", - "NULL_ENV", - "EMPTY_ENV", - "BUILT_IN_NOT_FOUND", - "NULL_PARSE", - "NULL_LAMBDA_LIST", - "NULL_MAP_ARGS", - "LAMBDA_ARGS_NOT_LIST", - "DID_NOT_FIND_SYMBOL", - "BAD_TYPE", - "UNEXPECTED_FORM", - "LISTS_NOT_SAME_SIZE", - "BAD_NUMBER", - "UNSUPPORTED_NUMBER_TYPE", - "NOT_A_SYMBOL", - "ONLY_ONE_ARGUMENT", - "NOT_A_LIST", - "SCRIPT_NOT_FOUND", - "NO_CLONE_SPECIFIED", - "CAN_ONLY_EVAL_STRINGS", - "UNEXPECTED_EOF", - "INDEX_PAST_END" -}; +static const char* errorText[] = {"MISMATCHED_PARENS", + "BAD_LIST_OF_SYMBOL_STRINGS", + "TYPE_LIST_NOT_CAUGHT", + "NULL_ENV", + "EMPTY_ENV", + "BUILT_IN_NOT_FOUND", + "NULL_PARSE", + "NULL_LAMBDA_LIST", + "NULL_MAP_ARGS", + "LAMBDA_ARGS_NOT_LIST", + "DID_NOT_FIND_SYMBOL", + "BAD_TYPE", + "UNEXPECTED_FORM", + "LISTS_NOT_SAME_SIZE", + "BAD_NUMBER", + "UNSUPPORTED_NUMBER_TYPE", + "NOT_A_SYMBOL", + "ONLY_ONE_ARGUMENT", + "NOT_A_LIST", + "SCRIPT_NOT_FOUND", + "NO_CLONE_SPECIFIED", + "CAN_ONLY_EVAL_STRINGS", + "UNEXPECTED_EOF", + "INDEX_PAST_END"}; #endif /** @@ -233,10 +229,11 @@ static const char *errorText[] = { * @param dest The string to copy the list text into * @param obj The list Object to make a string from */ -void stringList(char *dest, const Object *obj) +void stringList(char* dest, const Object* obj) { - if(!dest || !isListy(*obj)) + if (!dest || !isListy(*obj)) { return; + } dest[0] = '('; dest[1] = '\0'; @@ -266,11 +263,13 @@ void stringList(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 */ -char* stringNObj(char *dest, const Object *obj, const size_t len) { - if(!dest || !obj) +char* stringNObj(char* dest, const Object* obj, const size_t len) +{ + if (!dest || !obj) { return NULL; + } - switch(obj->type) { + switch (obj->type) { case TYPE_NUMBER: snprintf(dest, len, "%d", obj->number); break; @@ -289,16 +288,16 @@ char* stringNObj(char *dest, const Object *obj, const size_t len) { break; case TYPE_ERROR: { int code = getErrorCode(*obj); - #ifdef SIMPLE_ERRORS +#ifdef SIMPLE_ERRORS snprintf(dest, len, "E[%d]", (int)code); - #else +#else if (obj->error->context && obj->error->context[0] != '\0') { - snprintf(dest, len, "'%s': %s", - errorText[code], obj->error->context); + snprintf(dest, len, "'%s': %s", errorText[code], + obj->error->context); } else { snprintf(dest, len, "%s", errorText[code]); } - #endif +#endif break; } case TYPE_FUNC: @@ -310,13 +309,15 @@ char* stringNObj(char *dest, const Object *obj, const size_t len) { break; } - if(!isValidType(*obj)) + if (!isValidType(*obj)) { snprintf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number); + } return dest; } -char* stringObj(char *dest, const Object *obj) { +char* stringObj(char* dest, const Object* obj) +{ return stringNObj(dest, obj, RESULT_LENGTH); } @@ -324,7 +325,7 @@ char* stringObj(char *dest, const Object *obj) { * Prints a given Object only if the DEBUG flag is set * @param obj The Object to debug */ -void debugObj(const Object *obj) +void debugObj(const Object* obj) { #ifdef DEBUG printObj(obj); @@ -333,9 +334,10 @@ void debugObj(const Object *obj) } #if defined(DEBUG) || defined(STANDALONE) -void printType(const Object *obj) + +void printType(const Object* obj) { - switch(obj->type) { + switch (obj->type) { case TYPE_NUMBER: printf("TYPE_NUMBER"); return; @@ -367,16 +369,18 @@ void printType(const Object *obj) return; } - if(!isValidType(*obj)) + if (!isValidType(*obj)) { printf("UNKNOWN TYPE (%d)", obj->type); + } } -void _printList(const Object *list, int newline); -void _printObj(const Object *obj, int newline) +void nestedPrintList(const Object* list, int newline); + +void _printObj(const Object* obj, int newline) { - #ifdef DEBUG +#ifdef DEBUG printType(obj); - #endif +#endif if (obj->type == TYPE_LAMBDA) { printObj(&obj->lambda->params); @@ -387,10 +391,11 @@ void _printObj(const Object *obj, int newline) char temp[100] = ""; stringObj(temp, obj); - if(newline) + if (newline) { printf("%s\n", temp); - else + } else { printf("%s", temp); + } } /** @@ -399,32 +404,36 @@ void _printObj(const Object *obj, int newline) * If the DEBUG flag is set, the Object's type will be printed first * @param obj The Object to print */ -inline void printObj(const Object *obj) +inline void printObj(const Object* obj) { _printObj(obj, 1); } -void _printList(const Object *list, int newline) +void nestedPrintList(const Object* list, int newline) { printf("("); - FOR_POINTER_IN_LIST(list) { - printf(" "); - _printObj(POINTER, 0); + if (list && isListy(*list)) { + FOR_POINTER_IN_LIST(list) { + printf(" "); + _printObj(POINTER, 0); + } } printf(" )"); - if(newline) + if (newline) { printf("\n"); + } } /** * Prints each Object in a given list, surrounded by parentheses * @param list The list Object to print */ -void printList(const Object *list) +void printList(const Object* list) { - _printList(list, 1); + nestedPrintList(list, 1); } + #endif /** @@ -437,12 +446,13 @@ void printList(const Object *list) * * @param target The object to clean */ -void cleanObject(Object *target) +void cleanObject(Object* target) { - if(target == NULL) + if (target == NULL) { return; + } - switch(target->type) { + switch (target->type) { case TYPE_STRING: case TYPE_SYMBOL: free(target->string); @@ -465,7 +475,7 @@ void cleanObject(Object *target) #endif break; case TYPE_OTHER: - if(target->other->cleanup) { + if (target->other->cleanup) { target->other->cleanup(target); } break; @@ -483,11 +493,13 @@ void cleanObject(Object *target) * @param target The object to print and clean */ #ifdef STANDALONE -void printAndClean(Object *target) + +void printAndClean(Object* target) { printObj(target); cleanObject(target); } + #endif /** @@ -496,19 +508,20 @@ void printAndClean(Object *target) * * @param dest The list object to clean up */ -void deleteList(Object *dest) +void deleteList(Object* dest) { - if(!dest) + if (!dest) { return; + } - if(!isListy(*dest)) { + if (!isListy(*dest)) { printf("Tried to delete something other than a list\n"); return; } - Object *march = dest->list; - while(march != NULL) { - Object *prevMarch = march; + Object* march = dest->list; + while (march != NULL) { + Object* prevMarch = march; march = march->forward; cleanObject(prevMarch); free(prevMarch); @@ -516,22 +529,23 @@ void deleteList(Object *dest) dest->list = NULL; } -void _copyList(Object *dest, const Object *src, int delete) +void _copyList(Object* dest, const Object* src, int delete) { - if(!dest || !src) { + if (!dest || !src) { printd("NULL\n"); return; } - if(!isListy(*dest) || !isListy(*src)) { + if (!isListy(*dest) || !isListy(*src)) { printd("NOT A LIST\n"); return; } - if(delete) + if (delete) { deleteList(dest); + } FOR_POINTER_IN_LIST(src) { - if(isListy(*POINTER)) { + if (isListy(*POINTER)) { nf_addToList(dest, *POINTER); tail(dest)->list = NULL; _copyList(tail(dest), POINTER, 0); @@ -552,7 +566,7 @@ void _copyList(Object *dest, const Object *src, int delete) * @param dest The list to copy to * @param src The list to copy from */ -void copyList(Object *dest, const Object *src) +void copyList(Object* dest, const Object* src) { _copyList(dest, src, 1); } @@ -565,7 +579,7 @@ void copyList(Object *dest, const Object *src) * @param dest The list to copy to * @param src The list to copy from */ -void appendList(Object *dest, const Object *src) +void appendList(Object* dest, const Object* src) { _copyList(dest, src, 0); } @@ -611,7 +625,7 @@ inline int isStringy(const Object test) inline int isValidType(const Object test) { - switch(test.type) { + switch (test.type) { case TYPE_NUMBER: case TYPE_BOOL: case TYPE_LIST: @@ -654,15 +668,14 @@ inline Object cloneList(const Object src) return list; } -inline Object cloneOther(const Object src) { - return src.other->clone? - src.other->clone(src.other) : - src; +inline Object cloneOther(const Object src) +{ + return src.other->clone ? src.other->clone(src.other) : src; } inline Object cloneObject(const Object src) { - switch(src.type) { + switch (src.type) { case TYPE_SLIST: case TYPE_LIST: return cloneList(src); @@ -677,7 +690,7 @@ inline Object cloneObject(const Object src) case TYPE_NUMBER: case TYPE_FUNC: case TYPE_OTHER: - ; // Fall through to plain return + return src; } return src; @@ -698,19 +711,19 @@ inline Object boolObject(int b) } // Skips first and last chars! Assumed to be '"' -inline Object objFromSlice(const char *string, int len) +inline Object objFromSlice(const char* string, int len) { return stringFromSlice(&string[1], len - 1); } -inline Object stringFromSlice(const char *string, int len) +inline Object stringFromSlice(const char* string, int len) { Object o = symFromSlice(string, len); o.type = TYPE_STRING; return o; } -inline Object symFromSlice(const char *string, int len) +inline Object symFromSlice(const char* string, int len) { Object o = newObject(TYPE_SYMBOL); o.string = calloc(sizeof(char), len + 1); @@ -718,13 +731,15 @@ inline Object symFromSlice(const char *string, int len) return o; } -inline Object constructLambda(const Object *params, const Object *body) +inline Object constructLambda(const Object* params, const Object* body) { - if(!params || !body) + if (!params || !body) { return errorObject(NULL_LAMBDA_LIST); + } - if(params->type != TYPE_LIST || body->type != TYPE_LIST) + if (params->type != TYPE_LIST || body->type != TYPE_LIST) { return errorObject(LAMBDA_ARGS_NOT_LIST); + } Object o = newObject(TYPE_LAMBDA); o.lambda = malloc(sizeof(struct Lambda)); @@ -740,17 +755,17 @@ inline int isError(const Object obj, const enum errorCode err) return obj.type == TYPE_ERROR && getErrorCode(obj) == err; } -inline int bothAre(const enum Type type, const Object *obj1, const Object *obj2) +inline int bothAre(const enum Type type, const Object* obj1, const Object* obj2) { return (obj1->type == type) && (obj2->type == type); } -inline int eitherIs(const enum Type type, const Object *o1, const Object *o2) +inline int eitherIs(const enum Type type, const Object* o1, const Object* o2) { return (o1->type == type) || (o2->type == type); } -inline int areSameType(const Object *obj1, const Object *obj2) +inline int areSameType(const Object* obj1, const Object* obj2) { return obj1->type == obj2->type; } @@ -786,12 +801,13 @@ inline enum errorCode getErrorCode(const Object obj) } #ifndef SIMPLE_ERRORS -inline void errorAddContext(Object *o, const char* context) + +inline void errorAddContext(Object* o, const char* context) { - //printf("o: %p\n", o); - //printf("o->error: %s\n", o->error); + // printf("o: %p\n", o); + // printf("o->error: %s\n", o->error); o->error->context = calloc(sizeof(char), RESULT_LENGTH); - //printf("context: %p\n", context); + // printf("context: %p\n", context); strncpy(o->error->context, context, RESULT_LENGTH); } @@ -803,6 +819,7 @@ inline Object errorWithContext(enum errorCode code, const char* context) } return o; } + #endif struct Error noError() @@ -814,7 +831,8 @@ struct Error noError() inline Object toBool(const Object test) { - if(test.number == 0) + if (test.number == 0) { return boolObject(0); + } return boolObject(1); } diff --git a/src/object.h b/src/object.h index 0be627c..9eb1d1d 100644 --- a/src/object.h +++ b/src/object.h @@ -3,30 +3,41 @@ #include +#ifndef STANDALONE +#include +#undef printf +#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) +#else +#ifdef DEBUG +#define printd(...) printf(__VA_ARGS__) +#else +#define printd(...) (0) +#endif +#endif + #define MAX_TOK_CNT 1024 #define MAX_ENV_ELM 100 #define RESULT_LENGTH 128 #define FOR_POINTER_IN_LIST(_list) \ - if(_list && isListy(*_list)) \ - for(Object *_element = _list->list; \ + for(Object *_element = (_list)->list; \ _element != NULL;\ _element = _element->forward) #define POINTER _element #define FOR_POINTERS_IN_LISTS(_list, _list2) \ - for(Object *_element = _list->list, *_element2 = _list2->list; \ + for(Object *_element = (_list)->list, *_element2 = (_list2)->list; \ _element != NULL && _element2 != NULL; \ _element = _element->forward, _element2 = _element2->forward) #define P1 POINTER #define P2 _element2 #ifdef PBL_PLATFORM_APLITE - #define LOW_MEM +#define LOW_MEM #endif #ifdef LOW_MEM - #define SIMPLE_ERRORS +#define SIMPLE_ERRORS #endif enum errorCode { @@ -76,24 +87,27 @@ struct Slice; struct Other; struct Error { enum errorCode code; - char* context; + char *context; }; struct Object { Type type; Object *forward; + union { int number; Object *list; char *string; + Object (*func)(Object, Object, struct Environment *); + struct Lambda *lambda; struct Other *other; - #ifdef SIMPLE_ERRORS +#ifdef SIMPLE_ERRORS enum errorCode error; - #else +#else struct Error *error; - #endif +#endif }; }; @@ -103,67 +117,110 @@ struct Lambda { }; struct Other { - void (*cleanup)(Object*); - Object (*clone)(struct Other*); + void (*cleanup)(Object *); + + Object (*clone)(struct Other *); + void *data; }; -char* stringNObj(char *dest, const Object *obj, size_t len); -char* stringObj(char *dest, const Object *obj); +char *stringNObj(char *dest, const Object *obj, size_t len); + +char *stringObj(char *dest, const Object *obj); + void printList(const Object *list); + void printType(const Object *obj); + void printObj(const Object *obj); + void _printObj(const Object *obj, int newline); + void debugObj(const Object *obj); + void printErr(const Object *obj); int isEmpty(const Object *obj); + Object *tail(const Object *listObj); + void insertIntoList(Object *dest, int ind, const Object src); + void replaceListing(Object *list, int i, const Object src); + void nf_addToList(Object *dest, Object src); + void deleteList(Object *dest); int listLength(const Object *listObj); + Object *itemAt(const Object *listObj, int n); + void copyList(Object *dest, const Object *src); void cleanObject(Object *target); + void printAndClean(Object *target); + void allocObject(Object **spot, const Object src); + void appendList(Object *dest, const Object *src); int isListy(const Object test); + int isStringy(const Object test); + int isValidType(const Object test); + int isError(const Object obj, const enum errorCode err); + int bothAre(const enum Type type, const Object *obj1, const Object *obj2); + int eitherIs(const enum Type type, const Object *obj1, const Object *obj2); + int areSameType(const Object *obj1, const Object *obj2); Object cloneList(const Object src); + Object cloneString(Object obj); + Object cloneLambda(const Object old); + Object cloneObject(const Object src); Object newObject(Type type); + Object listObject(); + Object startList(const Object start); + Object objFromSlice(const char *string, int len); + Object stringFromSlice(const char *string, int len); + Object symFromSlice(const char *string, int len); + Object boolObject(int b); + Object numberObject(int num); + Object otherObject(); + Object errorObject(enum errorCode err); + enum errorCode getErrorCode(const Object obj); + #ifdef SIMPLE_ERRORS - #define errorWithContext(code, context) errorObject(code) - #define errorAddContext(x, y) ; +#define errorWithContext(code, context) errorObject(code) +#define errorAddContext(x, y) ; #else -Object errorWithContext(enum errorCode err, const char* context); -void errorAddContext(Object *o, const char* context); + +Object errorWithContext(enum errorCode err, const char *context); + +void errorAddContext(Object *o, const char *context); + #endif + struct Error noError(); Object constructLambda(const Object *params, const Object *body); diff --git a/src/pebbleobject.c b/src/pebbleobject.c index 2439160..e2530a7 100644 --- a/src/pebbleobject.c +++ b/src/pebbleobject.c @@ -1,15 +1,13 @@ #include "pebbleobject.h" + #include "calc.h" #include "object.h" -Object pebbleOther( - enum PebbleType type, - void* data, - void (*cleanup)(Object*), - Object (*clone)(struct Other*)) +Object pebbleOther(enum PebbleType type, void* data, void (* cleanup)(Object*), + Object (* clone)(struct Other*)) { struct Object o = otherObject(); - struct PebbleObject *po = malloc(sizeof(struct PebbleObject)); + struct PebbleObject* po = malloc(sizeof(struct PebbleObject)); o.other->data = po; o.other->cleanup = cleanup; o.other->clone = clone; @@ -20,57 +18,63 @@ Object pebbleOther( enum PebbleType getPebbleType(const Object o1) { - if(o1.type == TYPE_OTHER) { - struct PebbleObject *po = o1.other->data; + if (o1.type == TYPE_OTHER) { + struct PebbleObject* po = o1.other->data; enum PebbleType t = po->type; return t; } return P_ERROR; } -struct PebbleObject* accessPebbleObject(Object obj) { - if(getPebbleType(obj) != P_ERROR) { +struct PebbleObject* accessPebbleObject(Object obj) +{ + if (getPebbleType(obj) != P_ERROR) { return obj.other->data; } return NULL; } -void custom_window_load(Window *window) { +void custom_window_load(Window* window) +{ } -void custom_window_unload(Window *window) { +void custom_window_unload(Window* window) +{ window_destroy(window); } -Object createWindow(Object o1, Object o2, struct Environment *env) { - Window *window = window_create(); - WindowHandlers wh = { - .load = custom_window_load, - .unload = custom_window_unload }; +Object createWindow(Object o1, Object o2, struct Environment* env) +{ + Window* window = window_create(); + WindowHandlers wh = {.load = custom_window_load, + .unload = custom_window_unload}; window_set_window_handlers(window, wh); return pebbleOther(WINDOW, window, NULL, NULL); } -Object deleteWindow(Object window, Object o2, struct Environment *env) { +Object deleteWindow(Object window, Object o2, struct Environment* env) +{ /* Maintain a list of layers to delete? */ - if(getPebbleType(window) == WINDOW) { + if (getPebbleType(window) == WINDOW) { window_stack_remove(accessPebbleObject(window)->window, true); return boolObject(1); } return boolObject(0); } -Object pushWindow(Object window, Object o2, struct Environment *env) { - if(getPebbleType(window) == WINDOW) { +Object pushWindow(Object window, Object o2, struct Environment* env) +{ + if (getPebbleType(window) == WINDOW) { window_stack_push(accessPebbleObject(window)->window, true); return boolObject(1); } return boolObject(0); } -Object updateTextLayer(Object textLayer, Object text, struct Environment *env) { - if(getPebbleType(textLayer) == TEXT_LAYER) { - struct PebbleObject *po = accessPebbleObject(textLayer); +Object updateTextLayer(Object textLayer, Object text, struct Environment* env) +{ + if (getPebbleType(textLayer) == TEXT_LAYER) { + struct PebbleObject* po = accessPebbleObject(textLayer); stringObj(po->textLayer->text, &text); text_layer_set_text(po->textLayer->layer, po->textLayer->text); return boolObject(1); @@ -78,49 +82,55 @@ Object updateTextLayer(Object textLayer, Object text, struct Environment *env) { return boolObject(0); } -Object addTextLayer(Object window, Object text, struct Environment *env) { - if(getPebbleType(window) != WINDOW) { +Object addTextLayer(Object window, Object text, struct Environment* env) +{ + if (getPebbleType(window) != WINDOW) { return errorObject(0); } - Layer *window_layer = window_get_root_layer(accessPebbleObject(window)->window); + Layer* window_layer = + window_get_root_layer(accessPebbleObject(window)->window); GRect bounds = layer_get_bounds(window_layer); - struct PLTextLayer *textLayer = malloc(sizeof(struct PLTextLayer)); + struct PLTextLayer* textLayer = malloc(sizeof(struct PLTextLayer)); textLayer->text = calloc(sizeof(char), 100); textLayer->layer = text_layer_create(bounds); stringObj(textLayer->text, &text); text_layer_set_text(textLayer->layer, textLayer->text); text_layer_set_font(textLayer->layer, - fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD)); + fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD)); layer_add_child(window_layer, text_layer_get_layer(textLayer->layer)); return pebbleOther(TEXT_LAYER, textLayer, NULL, NULL); } - Object subscription; -struct Environment *subscriptionEnv; +struct Environment* subscriptionEnv; -static void subscriptionHandler(struct tm *tick_time, TimeUnits changed) { +static void subscriptionHandler(struct tm* tick_time, TimeUnits changed) +{ eval(&subscription, subscriptionEnv); } -Object subscribe(Object function, Object time, struct Environment *env) { - if(function.type == TYPE_LAMBDA) { +Object subscribe(Object function, Object time, struct Environment* env) +{ + if (function.type == TYPE_LAMBDA) { subscription = cloneObject(function); subscriptionEnv = env; - int unit = time.type != TYPE_NUMBER ? MINUTE_UNIT : - time.number == 1 ? SECOND_UNIT : - time.number == 2 ? MINUTE_UNIT : - time.number == 3 ? HOUR_UNIT : - time.number == 4 ? DAY_UNIT : - time.number == 5 ? MONTH_UNIT : - time.number == 6 ? YEAR_UNIT : - MINUTE_UNIT; + int unit = time.type != TYPE_NUMBER ? MINUTE_UNIT + : time.number == 1 ? SECOND_UNIT + : time.number == 2 ? MINUTE_UNIT + : time.number == 3 ? HOUR_UNIT + : time.number == 4 + ? DAY_UNIT + : time.number == + 5 ? MONTH_UNIT + : + time.number == + 6 ? YEAR_UNIT + : MINUTE_UNIT; tick_timer_service_subscribe(unit, subscriptionHandler); return boolObject(1); } return boolObject(0); } - diff --git a/src/pebbleobject.h b/src/pebbleobject.h index cc0ee4b..cfcd65e 100644 --- a/src/pebbleobject.h +++ b/src/pebbleobject.h @@ -1,30 +1,34 @@ #include + #include "pebblisp.h" enum PebbleType { - WINDOW, - TEXT_LAYER, - P_ERROR + WINDOW, TEXT_LAYER, P_ERROR }; struct PLTextLayer { - TextLayer *layer; - char *text; + TextLayer* layer; + char* text; }; typedef struct PebbleObject PebbleObject; struct PebbleObject { enum PebbleType type; union { - Window *window; - struct PLTextLayer *textLayer; - void *ptr; + Window* window; + struct PLTextLayer* textLayer; + void* ptr; }; }; -Object createWindow(Object o1, Object o2, struct Environment *env); -Object deleteWindow(Object window, Object o2, struct Environment *env); -Object pushWindow(Object o1, Object o2, struct Environment *env); -Object addTextLayer(Object window, Object text, struct Environment *env); -Object updateTextLayer(Object textLayer, Object text, struct Environment *env); -Object subscribe(Object function, Object time, struct Environment *env); +Object createWindow(Object o1, Object o2, struct Environment* env); + +Object deleteWindow(Object window, Object o2, struct Environment* env); + +Object pushWindow(Object o1, Object o2, struct Environment* env); + +Object addTextLayer(Object window, Object text, struct Environment* env); + +Object updateTextLayer(Object textLayer, Object text, struct Environment* env); + +Object subscribe(Object function, Object time, struct Environment* env); diff --git a/src/pebblisp.c b/src/pebblisp.c index 6f157da..7529e53 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -1,14 +1,12 @@ +#pragma ide diagnostic ignored "misc-no-recursion" + #include "pebblisp.h" -#include "tokens.h" + +#include #include #include -#include -#ifndef STANDALONE -#undef printf -#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) -#include -#endif +#include "tokens.h" /** * Inserts a variable into the environment with a given name and value. @@ -21,16 +19,14 @@ * @param env The environment to add the new definition to * @return The symbol(s) defined */ -Object evalDefArgs( - const Object *symbol, - const Object *value, - struct Environment *env -) { - const char *name = symbol->string; +Object evalDefArgs(const Object* symbol, const Object* value, + struct Environment* env) +{ + const char* name = symbol->string; // Handles multi-definitions - if(bothAre(TYPE_LIST, symbol, value) - && listLength(symbol) == listLength(value)) { + if (bothAre(TYPE_LIST, symbol, value) && + listLength(symbol) == listLength(value)) { FOR_POINTERS_IN_LISTS(symbol, value) { Object finalValue = eval(P2, env); addToEnv(env, P1->string, finalValue); @@ -47,80 +43,80 @@ Object evalDefArgs( return cloneObject(*symbol); } -Object evalIfArgs(const Object *argForms, struct Environment *env) +Object evalIfArgs(const Object* argForms, struct Environment* env) { Object condition = eval(argForms, env); - Object result = condition.number ? - eval(argForms->forward, env) : - eval(argForms->forward->forward, env); + Object result = condition.number ? eval(argForms->forward, env) + : eval(argForms->forward->forward, env); cleanObject(&condition); return result; } -Object evalLambdaArgs(const Object *argForms) +Object evalLambdaArgs(const Object* argForms) { - return constructLambda( - argForms, // Params - argForms ? argForms->forward : NULL // Body + return constructLambda(argForms, // Params + argForms ? argForms->forward : NULL // Body ); } -Object evalMapArgs(const Object *argForms, struct Environment *env) +Object evalMapArgs(const Object* argForms, struct Environment* env) { - if(!argForms) { + if (!argForms) { return errorObject(NULL_MAP_ARGS); } - + Object lambda = eval(argForms, env); - const Object *inputList = argForms->forward; + const Object* inputList = argForms->forward; Object outputList = listObject(); - if(lambda.type != TYPE_LAMBDA) { + if (lambda.type != TYPE_LAMBDA) { return errorObject(BAD_TYPE); } - FOR_POINTER_IN_LIST(inputList) { - // Create a new list for each element, - // since lambda evaluation looks for a list - Object tempList = startList(cloneObject(*POINTER)); + if (inputList) { + FOR_POINTER_IN_LIST(inputList) { + // Create a new list for each element, + // since lambda evaluation looks for a list + Object tempList = startList(cloneObject(*POINTER)); - Object *params = &lambda.lambda->params; - struct Environment newEnv = envForLambda(params, &tempList, env); + Object* params = &lambda.lambda->params; + struct Environment newEnv = envForLambda(params, &tempList, env); - // Add the lambda evaluation to the list - Object lambda_output = eval(&lambda.lambda->body, &newEnv); - Object delisted = cloneObject(*lambda_output.list); - nf_addToList(&outputList, delisted); - deleteEnv(&newEnv); - cleanObject(&tempList); - cleanObject(&lambda_output); + // Add the lambda evaluation to the list + Object lambda_output = eval(&lambda.lambda->body, &newEnv); + Object delisted = cloneObject(*lambda_output.list); + nf_addToList(&outputList, delisted); + deleteEnv(&newEnv); + cleanObject(&tempList); + cleanObject(&lambda_output); + } } cleanObject(&lambda); return outputList; } -Object evalBuiltIns(const Object *first, const Object *rest, - struct Environment *env) +Object evalBuiltIns(const Object* first, const Object* rest, + struct Environment* env) { - if(first->type != TYPE_SYMBOL) { + if (first->type != TYPE_SYMBOL) { return errorObject(NOT_A_SYMBOL); } - if(strcmp(first->string, "def") == 0) { + if (strcmp(first->string, "def") == 0) { return evalDefArgs(rest, rest->forward, env); - #ifndef LOW_MEM - } else if(strcmp(first->string, "defe") == 0) { +#ifndef LOW_MEM + } else if (strcmp(first->string, "defe") == 0) { Object symbol = eval(rest, env); Object e = evalDefArgs(&symbol, rest->forward, env); cleanObject(&symbol); return e; - #endif - } else if(strcmp(first->string, "if") == 0) { +#endif + } else if (strcmp(first->string, "if") == 0) { return evalIfArgs(rest, env); - } else if(strcmp(first->string, "fn") == 0) { + } else if (strcmp(first->string, "fn") == 0) { return evalLambdaArgs(rest); - } else if(strcmp(first->string, "map") == 0) { + } else if (strcmp(first->string, "map") == 0) { return evalMapArgs(rest, env); } @@ -138,10 +134,10 @@ Object evalBuiltIns(const Object *first, const Object *rest, * @param start The Object element to start with * @param env The environment to use while evaluating */ -void evalForms(Object *destArr, const Object *start, struct Environment *env) +void evalForms(Object* destArr, const Object* start, struct Environment* env) { int i = 0; - while(start) { + while (start) { destArr[i] = eval(start, env); start = start->forward; i++; @@ -159,13 +155,10 @@ void evalForms(Object *destArr, const Object *start, struct Environment *env) * @param length Length of `list` - 1, to exclude the already-evaluated element * @param env The environment to evaluate in */ -Object listEvalFunc( - const Object *list, - const Object *function, - const int length, - struct Environment *env) +Object listEvalFunc(const Object* list, const Object* function, + const int length, struct Environment* env) { - if(length == 0) { + if (length == 0) { return function->func(boolObject(0), boolObject(0), env); } @@ -173,10 +166,9 @@ Object listEvalFunc( evalForms(rest, list->list->forward, env); Object func_result = rest[0]; - if(length == 1) { + if (length == 1) { Object oneArg = errorObject(ONLY_ONE_ARGUMENT); - func_result = function->func( - func_result, oneArg, env); + func_result = function->func(func_result, oneArg, env); // Return a partial function if more parameters are required // Otherwise, return the function result cleanObject(&rest[0]); @@ -192,7 +184,7 @@ Object listEvalFunc( } else { // With two args, will apply function once // With more than two args, apply the function repeatedly - for(int i = 1; i < length; i++) { + for (int i = 1; i < length; i++) { Object toClean = func_result; func_result = function->func(func_result, rest[i], env); cleanObject(&toClean); @@ -212,23 +204,18 @@ Object listEvalFunc( * @param remaining The first element after `lambda` * @param env The environment to evaluate in */ -Object listEvalLambda( - Object *lambda, - const Object *remaining, - struct Environment *env -) { - struct Environment newEnv = envForLambda( - &lambda->lambda->params, - remaining, - env - ); +Object listEvalLambda(Object* lambda, const Object* remaining, + struct Environment* env) +{ + struct Environment newEnv = + envForLambda(&lambda->lambda->params, remaining, env); Object ret = eval(&lambda->lambda->body, &newEnv); deleteEnv(&newEnv); cleanObject(lambda); - Object *t = tail(&ret); - if(t) { + Object* t = tail(&ret); + if (t) { Object o = cloneObject(*t); cleanObject(&ret); return o; @@ -250,20 +237,20 @@ Object listEvalLambda( * @param obj The list to be evaluated * @param env The environment to evaluate in */ -Object evalList(const Object *obj, struct Environment *env) +Object evalList(const Object* obj, struct Environment* env) { const int evalLength = listLength(obj); - if(evalLength == 0) { + if (evalLength == 0) { return cloneObject(*obj); } - Object *first_form = obj->list; + Object* first_form = obj->list; - { // Try to eval built-ins + { // Try to eval built-ins Object builtIn = evalBuiltIns(first_form, first_form->forward, env); - if(!isError(builtIn, BUILT_IN_NOT_FOUND) && + if (!isError(builtIn, BUILT_IN_NOT_FOUND) && !isError(builtIn, NOT_A_SYMBOL)) { return builtIn; } @@ -272,7 +259,7 @@ Object evalList(const Object *obj, struct Environment *env) // Evaluate the list based on the first element's type Object first_eval = eval(first_form, env); - switch(first_eval.type) { + switch (first_eval.type) { case TYPE_FUNC: // Passes evalLength - 1, because we skip the first form return listEvalFunc(obj, &first_eval, evalLength - 1, env); @@ -280,12 +267,12 @@ Object evalList(const Object *obj, struct Environment *env) case TYPE_LAMBDA: return listEvalLambda(&first_eval, first_form->forward, env); - default: { // Return list with each element evaluated + default: { // Return list with each element evaluated Object list = listObject(); int i = 0; nf_addToList(&list, first_eval); FOR_POINTER_IN_LIST(obj) { - if(i != 0) { + if (i != 0) { nf_addToList(&list, eval(POINTER, env)); } i++; @@ -295,9 +282,9 @@ Object evalList(const Object *obj, struct Environment *env) } } -Object eval(const Object *obj, struct Environment *env) +Object eval(const Object* obj, struct Environment* env) { - switch(obj->type) { + switch (obj->type) { case TYPE_FUNC: case TYPE_ERROR: case TYPE_OTHER: @@ -325,7 +312,7 @@ Object eval(const Object *obj, struct Environment *env) return errorObject(BAD_TYPE); } -Object catObjects(const Object obj1, const Object obj2, struct Environment *env) +Object catObjects(const Object obj1, const Object obj2, struct Environment* env) { Object evalObj1 = eval(&obj1, env); Object evalObj2 = eval(&obj2, env); @@ -346,25 +333,25 @@ Object catObjects(const Object obj1, const Object obj2, struct Environment *env) return o; } -Object listEquality(const Object *list1, const Object *list2) +Object listEquality(const Object* list1, const Object* list2) { FOR_POINTERS_IN_LISTS(list1, list2) { - if(P1->type != P2->type || P1->number != P2->number) { + if (P1->type != P2->type || P1->number != P2->number) { return boolObject(0); } } return boolObject(1); } -Object _basicOp(const Object *obj1, const Object *obj2, const char op, - struct Environment *env) +Object _basicOp(const Object* obj1, const Object* obj2, const char op, + struct Environment* env) { const int n1 = obj1->number; const int n2 = obj2->number; - switch(op){ + switch (op) { case '+': - if(eitherIs(TYPE_STRING, obj1, obj2)) { + if (eitherIs(TYPE_STRING, obj1, obj2)) { return catObjects(*obj1, *obj2, env); } return numberObject(n1 + n2); @@ -377,11 +364,16 @@ Object _basicOp(const Object *obj1, const Object *obj2, const char op, case '%': return numberObject(n1 % n2); + case '&': + return boolObject(n1 != 0 && n2 != 0); + case '|': + return boolObject(n1 != 0 || n2 != 0); + case '=': - if(bothAre(TYPE_STRING, obj1, obj2)) { + if (bothAre(TYPE_STRING, obj1, obj2)) { return boolObject(!strcmp(obj1->string, obj2->string)); } - if(bothAre(TYPE_LIST, obj1, obj2)) { + if (bothAre(TYPE_LIST, obj1, obj2)) { return listEquality(obj1, obj2); } return boolObject(n1 == n2 && areSameType(obj1, obj2)); @@ -394,20 +386,21 @@ Object _basicOp(const Object *obj1, const Object *obj2, const char op, return *obj1; } -Object basicOp(const Object *obj1, const Object *obj2, const char op, - struct Environment *env) +Object basicOp(const Object* obj1, const Object* obj2, const char op, + struct Environment* env) { - if(isError(*obj2, ONLY_ONE_ARGUMENT)) { + if (isError(*obj2, ONLY_ONE_ARGUMENT)) { return *obj2; } int lists = (obj1->type == TYPE_LIST) + (obj2->type == TYPE_LIST); - if(lists == 0) { + if (lists == 0) { return _basicOp(obj1, obj2, op, env); - } else if(lists == 1) { // Single operand is applied to each element in list - const Object *listObj = (obj1->type == TYPE_LIST)? obj1 : obj2; - const Object *singleObj = (obj1->type == TYPE_LIST)? obj2 : obj1; + } else if (lists == + 1) { // Single operand is applied to each element in list + const Object* listObj = (obj1->type == TYPE_LIST) ? obj1 : obj2; + const Object* singleObj = (obj1->type == TYPE_LIST) ? obj2 : obj1; Object newList = listObject(); FOR_POINTER_IN_LIST(listObj) { @@ -416,8 +409,8 @@ Object basicOp(const Object *obj1, const Object *obj2, const char op, } return newList; - } else { // 2 lists with the op applied to matching indices of both lists - if(listLength(obj1) == listLength(obj2)) { + } else { // 2 lists with the op applied to matching indices of both lists + if (listLength(obj1) == listLength(obj2)) { Object newList = listObject(); FOR_POINTERS_IN_LISTS(obj1, obj2) { const Object ev1 = eval(P1, env); @@ -431,45 +424,58 @@ Object basicOp(const Object *obj1, const Object *obj2, const char op, } } -#define BASIC_OP(_name, _char) \ -Object _name(Object obj1, Object obj2, struct Environment *env) \ - { return basicOp(&obj1, &obj2, _char, env); } +#define BASIC_OP(_name, _char) \ + Object _name(Object obj1, Object obj2, struct Environment *env) \ + { \ + return basicOp(&obj1, &obj2, _char, env); \ + } BASIC_OP(add, '+'); + BASIC_OP(sub, '-'); + BASIC_OP(mul, '*'); + BASIC_OP(dvi, '/'); + BASIC_OP(mod, '%'); + BASIC_OP(equ, '='); + BASIC_OP(gth, '>'); + BASIC_OP(lth, '<'); +BASIC_OP(and, '&'); + +BASIC_OP(or, '|'); + #undef BASIC_OP -Object filter(Object obj1, Object obj2, struct Environment *env) +Object filter(Object obj1, Object obj2, struct Environment* env) { Object filteredList = listObject(); - Object *filteringList = &obj2; + Object* filteringList = &obj2; FOR_POINTER_IN_LIST(filteringList) { Object conditional = cloneObject(obj1); - nf_addToList(&conditional, *POINTER); // cloneObject()? + nf_addToList(&conditional, *POINTER); // cloneObject()? Object result = eval(&conditional, env); cleanObject(&conditional); - if(result.number == 1) { + if (result.number == 1) { nf_addToList(&filteredList, *POINTER); } } return filteredList; } -Object append(Object list, Object newElement, struct Environment *env) +Object append(Object list, Object newElement, struct Environment* env) { Object newList = cloneObject(list); nf_addToList(&newList, cloneObject(newElement)); return newList; } -Object prepend(Object list, Object newElement, struct Environment *env) +Object prepend(Object list, Object newElement, struct Environment* env) { Object newList = listObject(); nf_addToList(&newList, cloneObject(newElement)); @@ -477,22 +483,22 @@ Object prepend(Object list, Object newElement, struct Environment *env) return newList; } -Object at(Object index, Object list, struct Environment *env) +Object at(Object index, Object list, struct Environment* env) { - const Object *found = itemAt(&list, index.number); - if(found) { + const Object* found = itemAt(&list, index.number); + if (found) { return cloneObject(*found); } else { return errorObject(INDEX_PAST_END); } } -Object rest(Object list, Object ignore, struct Environment *env) +Object rest(Object list, Object ignore, struct Environment* env) { Object ret = listObject(); - Object *l = &list; + Object* l = &list; FOR_POINTER_IN_LIST(l) { - if(POINTER == l->list) { + if (POINTER == l->list) { continue; } nf_addToList(&ret, cloneObject(*POINTER)); @@ -500,16 +506,16 @@ Object rest(Object list, Object ignore, struct Environment *env) return ret; } -Object reverse(Object _list, Object ignore, struct Environment *ignore2) +Object reverse(Object _list, Object ignore, struct Environment* ignore2) { - const Object *list = &_list; + const Object* list = &_list; Object rev = listObject(); - Object *tail = NULL; + Object* tail = NULL; FOR_POINTER_IN_LIST(list) { - Object *oldTail = tail; + Object* oldTail = tail; allocObject(&tail, cloneObject(*POINTER)); - if(oldTail) { + if (oldTail) { tail->forward = oldTail; } } @@ -518,33 +524,30 @@ Object reverse(Object _list, Object ignore, struct Environment *ignore2) return rev; } -Object isNum(Object test, Object ignore, struct Environment *ignore2) +Object isNum(Object test, Object ignore, struct Environment* ignore2) { - return test.type == TYPE_NUMBER ? - boolObject(1) : boolObject(0); + return test.type == TYPE_NUMBER ? boolObject(1) : boolObject(0); } -Object isString(Object test, Object ignore, struct Environment *ignore2) +Object isString(Object test, Object ignore, struct Environment* ignore2) { - return test.type == TYPE_STRING ? - boolObject(1) : boolObject(0); + return test.type == TYPE_STRING ? boolObject(1) : boolObject(0); } // Get the int value of a string's first character -Object charVal(Object test, Object ignore, struct Environment *ignore2) +Object charVal(Object test, Object ignore, struct Environment* ignore2) { return numberObject(test.string[0]); -// return test.type == TYPE_STRING && test.string[0] == '\0' ? -// boolObject(1) : boolObject(0); + // return test.type == TYPE_STRING && test.string[0] == '\0' ? + // boolObject(1) : boolObject(0); } -Object isErr(Object test, Object ignore, struct Environment *ignore2) +Object isErr(Object test, Object ignore, struct Environment* ignore2) { - return test.type == TYPE_ERROR ? - boolObject(1) : boolObject(0); + return test.type == TYPE_ERROR ? boolObject(1) : boolObject(0); } -Object charAt(Object string, Object at, struct Environment *ignore) +Object charAt(Object string, Object at, struct Environment* ignore) { char* c = malloc(sizeof(char) * 2); c[0] = string.string[at.number]; @@ -554,7 +557,8 @@ Object charAt(Object string, Object at, struct Environment *ignore) } #ifdef STANDALONE -Object print(Object p, Object ignore, struct Environment *env) + +Object print(Object p, Object ignore, struct Environment* env) { p = cloneObject(p); p = eval(&p, env); @@ -562,67 +566,71 @@ Object print(Object p, Object ignore, struct Environment *env) return numberObject(0); } -Object pChar(Object c, Object i1, struct Environment *i2) +Object pChar(Object c, Object i1, struct Environment* i2) { - if(c.type != TYPE_NUMBER) { + if (c.type != TYPE_NUMBER) { return errorObject(BAD_NUMBER); } printf("%c", c.number % 256); return numberObject(0); } -Object printEnvO(Object i1, Object i2, struct Environment *env) { - while(env->outer) { - env = env-> outer; +Object printEnvO(Object i1, Object i2, struct Environment* env) +{ + while (env->outer) { + env = env->outer; } printEnv(env); return numberObject(0); } + #endif -Object parseEvalO(Object text, Object ignore, struct Environment *env) +Object parseEvalO(Object text, Object ignore, struct Environment* env) { - if(text.type == TYPE_SYMBOL) { + if (text.type == TYPE_SYMBOL) { Object string = eval(&text, env); Object parsed = parseEval(string.string, env); cleanObject(&string); return parsed; - } else if(text.type != TYPE_STRING) { + } else if (text.type != TYPE_STRING) { return errorObject(CAN_ONLY_EVAL_STRINGS); } return parseEval(text.string, env); } #ifdef STANDALONE -Object takeInput(Object i1, Object i2, struct Environment *i3) + +Object takeInput(Object i1, Object i2, struct Environment* i3) { char input[256] = ""; fgets(input, 256, stdin); return stringFromSlice(input, strlen(input) - 1); } + #endif -void copySlice(char * dest, struct Slice *src) +void copySlice(char* dest, struct Slice* src) { - if(!dest || !src) { + if (!dest || !src) { return; } strncpy(dest, src->text, src->length); - dest[(int)src->length] = '\0'; + dest[(int) src->length] = '\0'; } -void debugSlice(struct Slice *s) +void debugSlice(struct Slice* s) { #ifdef DEBUG - if(!s) { + if (!s) { printf("NULL SLICE\n"); return; } printf("Debug Slice\n text:'"); - for(int i = 0; i < s->length; i++) { + for (int i = 0; i < s->length; i++) { printf("%c", s->text[i]); - if(s->text[i] == '\0') { + if (s->text[i] == '\0') { printf("NULLCHAR\n"); } } @@ -631,37 +639,37 @@ void debugSlice(struct Slice *s) #endif } -Result parse(struct Slice *slices) +Result parse(struct Slice* slices) { - struct Slice *token = slices; - if(token && token->text) { - struct Slice *rest = &slices[1]; - if(token->text[0] == '\'' && token->text[1] == '(') { + struct Slice* token = slices; + if (token && token->text) { + struct Slice* rest = &slices[1]; + if (token->text[0] == '\'' && token->text[1] == '(') { Result r = readSeq(&slices[2]); r.obj.type = TYPE_SLIST; return r; - } else if(token->text[0] == '(') { + } else if (token->text[0] == '(') { // todo check for null rest return readSeq(rest); - } else { // todo error on missing close paren - return (Result){parseAtom(token), rest}; + } else { // todo error on missing close paren + return (Result) {parseAtom(token), rest}; } } else { - return (Result){errorObject(NULL_PARSE), NULL}; + return (Result) {errorObject(NULL_PARSE), NULL}; } } -Result readSeq(struct Slice *tokens) +Result readSeq(struct Slice* tokens) { Object res = listObject(); - for(;;) { - struct Slice *next = tokens; - struct Slice *rest = next->text? &next[1] : NULL; - if(next->text[0] == ')') { - return (Result){res, rest}; + for (;;) { + struct Slice* next = tokens; + struct Slice* rest = next->text ? &next[1] : NULL; + if (next->text[0] == ')') { + return (Result) {res, rest}; } Result r = parse(tokens); - if(r.obj.type == TYPE_ERROR) { + if (r.obj.type == TYPE_ERROR) { return r; } nf_addToList(&res, cloneObject(r.obj)); @@ -670,11 +678,11 @@ Result readSeq(struct Slice *tokens) } } -Object parseDecimal(struct Slice *s) +Object parseDecimal(struct Slice* s) { int num = 0; - for(int i = 0; i < s->length; i++) { - if(!isDigit(s->text[i])) { + for (int i = 0; i < s->length; i++) { + if (!isDigit(s->text[i])) { return errorObject(BAD_NUMBER); } num *= 10; @@ -683,16 +691,16 @@ Object parseDecimal(struct Slice *s) return numberObject(num); } -Object parseHex(struct Slice *s) +Object parseHex(struct Slice* s) { int num = 0; - for(int i = 2; i < s->length; i++) { + for (int i = 2; i < s->length; i++) { const char c = s->text[i]; - if(!isHex(c)) { + if (!isHex(c)) { return errorObject(BAD_NUMBER); } num *= 16; - if(isDigit(c)) { + if (isDigit(c)) { num += c - '0'; } else /* is hex */ { num += c - 'a' + 10; @@ -701,12 +709,12 @@ Object parseHex(struct Slice *s) return numberObject(num); } -Object parseBin(struct Slice *s) +Object parseBin(struct Slice* s) { int num = 0; - for(int i = 2; i < s->length; i++) { + for (int i = 2; i < s->length; i++) { const char c = s->text[i]; - if(c != '0' && c != '1') { + if (c != '0' && c != '1') { return errorObject(BAD_NUMBER); } num *= 2; @@ -715,18 +723,18 @@ Object parseBin(struct Slice *s) return numberObject(num); } -Object parseAtom(struct Slice *s) +Object parseAtom(struct Slice* s) { const char c = s->text[0]; - if(isDigit(c)) { - if(c != '0' || s->length == 1) { + if (isDigit(c)) { + if (c != '0' || s->length == 1) { return parseDecimal(s); - #ifndef LOW_MEM - } else if(c == '0' && s->text[1] == 'x') { +#ifndef LOW_MEM + } else if (c == '0' && s->text[1] == 'x') { return parseHex(s); - } else if(c == '0' && s->text[1] == 'b') { + } else if (c == '0' && s->text[1] == 'b') { return parseBin(s); - #endif +#endif } else { return errorObject(UNSUPPORTED_NUMBER_TYPE); } @@ -741,52 +749,52 @@ Object parseAtom(struct Slice *s) } } -Object parseEval(const char *input, struct Environment *env) +Object parseEval(const char* input, struct Environment* env) { struct Error err = noError(); - struct Slice *tokens = nf_tokenize(input, &err); - if(err.context != NULL) { + struct Slice* tokens = nf_tokenize(input, &err); + if (err.context != NULL) { Object o = errorWithContext(err.code, err.context); free(err.context); return o; } - if(!tokens->text) { + if (!tokens->text) { return symFromSlice(" ", 1); } - #ifdef DEBUG +#ifdef DEBUG struct Slice *debug = tokens; printd("start slice\n"); - if(debug) { - while(debug->text) { + if (debug) { + while (debug->text) { char tok[100]; copySlice(tok, debug); printd("slice: '%s'\n", tok); debug++; } } - #endif +#endif int i = 0; int parens = 0; Object obj = numberObject(0); - struct Slice *tok = tokens; - while(tok[i].text != NULL) { - if(tok[i].text[0] == '(') { + struct Slice* tok = tokens; + while (tok[i].text != NULL) { + if (tok[i].text[0] == '(') { parens++; - } else if(tok[i].text[0] == ')') { + } else if (tok[i].text[0] == ')') { parens--; } - if(parens == 0) { + if (parens == 0) { cleanObject(&obj); Object parsed = parse(tok).obj; - if(parsed.type == TYPE_ERROR) { - obj = parsed; // TODO Check necessity + if (parsed.type == TYPE_ERROR) { + obj = parsed; // TODO Check necessity break; } - if(tok[i].text[0] == ')') { + if (tok[i].text[0] == ')') { // Skip `tok` past end of list that just closed tok = &tok[i + 1]; i = -1; @@ -806,26 +814,28 @@ Object parseEval(const char *input, struct Environment *env) } #ifdef STANDALONE -int _readFile(FILE *input, struct Environment *env) { + +int _readFile(FILE* input, struct Environment* env) +{ Object r = numberObject(0); char page[4096] = ""; - const unsigned LINE_MAX = 256; + const int LINE_MAX = 256; char line[LINE_MAX]; - if(fgets(line, LINE_MAX, input)){ - if(line[0] != '#' || line[1] != '!') { + if (fgets(line, LINE_MAX, input)) { + if (line[0] != '#' || line[1] != '!') { strncat(page, line, strlen(line) - 1); } } - while(fgets(line, LINE_MAX, input)) { + while (fgets(line, LINE_MAX, input)) { int i; - for(i = 0; i < LINE_MAX; i++) { - if(line[i] != ' ') { - if(line[i] == ';') { + for (i = 0; i < LINE_MAX; i++) { + if (line[i] != ' ') { + if (line[i] == ';') { break; } else { int j = 0; - for(j = i; j < LINE_MAX; j++) { - if(line[j] == ';' || line[j] == '\0') { + for (j = i; j < LINE_MAX; j++) { + if (line[j] == ';' || line[j] == '\0') { break; } } @@ -843,16 +853,19 @@ int _readFile(FILE *input, struct Environment *env) { fclose(input); return 0; } -int readFile(const char *filename, struct Environment *env) { - FILE *input = fopen(filename, "r"); - if(!input) { + +int readFile(const char* filename, struct Environment* env) +{ + FILE* input = fopen(filename, "r"); + if (!input) { return 1; } _readFile(input, env); return 0; } -Object loadFile(Object filename, Object _, struct Environment *env) { +Object loadFile(Object filename, Object _, struct Environment* env) +{ if (isStringy(filename)) { readFile(filename.string, env); return numberObject(0); @@ -860,23 +873,26 @@ Object loadFile(Object filename, Object _, struct Environment *env) { return numberObject(1); } -Object systemCall(Object process, Object _, struct Environment *env) { +Object systemCall(Object process, Object _, struct Environment* env) +{ if (isStringy(process)) { return numberObject(system(process.string)); } return numberObject(255); } -void repl(struct Environment *env) { +void repl(struct Environment* env) +{ if (readFile(SCRIPTDIR "/repl.pbl", env) == 1) { fprintf(stderr, "Could not read '%s'\n", SCRIPTDIR "/repl.pbl"); fprintf(stderr, "Consider installing or reinstalling pebblisp.\n"); } } -void loadArgsIntoEnv(int argc, const char* argv[], struct Environment* env) { +void loadArgsIntoEnv(int argc, const char* argv[], struct Environment* env) +{ Object args = listObject(); - for(int i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) { nf_addToList(&args, stringFromSlice(argv[i], strlen(argv[i]))); } addToEnv(env, "args", args); @@ -886,16 +902,16 @@ int main(int argc, const char* argv[]) { struct Environment env = defaultEnv(); readFile(SCRIPTDIR "/lib.pbl", &env); - if(argc >= 2) { - FILE *file = fopen(argv[1], "r"); - if(file) { + if (argc >= 2) { + FILE* file = fopen(argv[1], "r"); + if (file) { // Executing a file loadArgsIntoEnv(argc, argv, &env); _readFile(file, &env); } else { // Running arguments directly as pl code Object r = numberObject(0); - for(int i = 1; i < argc; i++) { + for (int i = 1; i < argc; i++) { r = parseEval(argv[i], &env); printAndClean(&r); } @@ -907,4 +923,5 @@ int main(int argc, const char* argv[]) } deleteEnv(&env); } -#endif + +#endif \ No newline at end of file diff --git a/src/pebblisp.h b/src/pebblisp.h index f357c31..4b097fd 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -1,76 +1,105 @@ #ifndef PEBBLISP_H #define PEBBLISP_H -#include "object.h" #include "env.h" - -#ifndef STANDALONE -#include -#define printd(...) ; -#endif - -#ifdef DEBUG -#define printd(...) printf(__VA_ARGS__) -#else -#define printd(...) ; -#endif +#include "object.h" struct Slice { - const char *text; + const char* text; char length; }; typedef struct Result { Object obj; - struct Slice *slices; + struct Slice* slices; } Result; -Object eval(const Object *obj, struct Environment *env); -Result parse(struct Slice *slices); -Result readSeq(struct Slice *slices); -Object parseAtom(struct Slice *slice); -Object parseEval(const char *input, struct Environment *env); -void evalForms(Object *destList, const Object *src, struct Environment *env); -void copySlice(char * dest, struct Slice *src); +Object eval(const Object* obj, struct Environment* env); -Object evalLambdaArgs(const Object *arg_forms); +Result parse(struct Slice* slices); + +Result readSeq(struct Slice* slices); + +Object parseAtom(struct Slice* slice); + +Object parseEval(const char* input, struct Environment* env); + +void evalForms(Object* destList, const Object* src, struct Environment* env); + +void copySlice(char* dest, struct Slice* src); + +Object evalLambdaArgs(const Object* arg_forms); // Slices -void copySlice(char * dest, struct Slice *src); -void debugSlice(struct Slice *s); +void copySlice(char* dest, struct Slice* src); + +void debugSlice(struct Slice* s); #define BASIC_OP(_name) \ -Object _name(Object obj1, Object obj2, struct Environment *env); -BASIC_OP(add); BASIC_OP(sub); -BASIC_OP(mul); BASIC_OP(dvi); -BASIC_OP(mod); BASIC_OP(equ); -BASIC_OP(gth); BASIC_OP(lth); + Object _name(Object obj1, Object obj2, struct Environment *env); + +BASIC_OP(add); + +BASIC_OP(sub); + +BASIC_OP(mul); + +BASIC_OP(dvi); + +BASIC_OP(mod); + +BASIC_OP(equ); + +BASIC_OP(gth); + +BASIC_OP(lth); + +BASIC_OP(and); + +BASIC_OP(or); #undef BASIC_OP -Object catObjects(const Object obj1, const Object obj2, struct Environment *env); -Object filter(Object obj1, Object obj2, struct Environment *env); -Object append(Object list, Object newElement, struct Environment *env); -Object prepend(Object list, Object newElement, struct Environment *env); -Object at(Object index, Object list, struct Environment *env); -Object rest(Object list, Object ignore, struct Environment *env); -Object reverse(Object _list, Object ignore, struct Environment *ignore2); +Object catObjects(const Object obj1, const Object obj2, + struct Environment* env); -Object isNum(Object test, Object ignore, struct Environment *ignore2); -Object isString(Object test, Object ignore, struct Environment *ignore2); -Object isErr(Object test, Object ignore, struct Environment *ignore2); +Object filter(Object obj1, Object obj2, struct Environment* env); -Object charAt(Object string, Object at, struct Environment *ignore); -Object charVal(Object test, Object ignore, struct Environment *ignore2); +Object append(Object list, Object newElement, struct Environment* env); -Object print(Object p, Object ignore, struct Environment *ignore2); -Object pChar(Object c, Object i1, struct Environment *i2); -Object printEnvO(Object i1, Object i2, struct Environment *env); -Object parseEvalO(Object text, Object ignore, struct Environment *env); +Object prepend(Object list, Object newElement, struct Environment* env); + +Object at(Object index, Object list, struct Environment* env); + +Object rest(Object list, Object ignore, struct Environment* env); + +Object reverse(Object _list, Object ignore, struct Environment* ignore2); + +Object isNum(Object test, Object ignore, struct Environment* ignore2); + +Object isString(Object test, Object ignore, struct Environment* ignore2); + +Object isErr(Object test, Object ignore, struct Environment* ignore2); + +Object charAt(Object string, Object at, struct Environment* ignore); + +Object charVal(Object test, Object ignore, struct Environment* ignore2); + +Object print(Object p, Object ignore, struct Environment* ignore2); + +Object pChar(Object c, Object i1, struct Environment* i2); + +Object printEnvO(Object i1, Object i2, struct Environment* env); + +Object parseEvalO(Object text, Object ignore, struct Environment* env); #ifdef STANDALONE -Object takeInput(Object i1, Object i2, struct Environment *i3); -Object systemCall(Object call, Object _, struct Environment *i3); -Object loadFile(Object filename, Object _, struct Environment *env); + +Object takeInput(Object i1, Object i2, struct Environment* i3); + +Object systemCall(Object call, Object _, struct Environment* i3); + +Object loadFile(Object filename, Object _, struct Environment* env); + #endif #endif diff --git a/src/pebcom.c b/src/pebcom.c index 1678334..66a7025 100644 --- a/src/pebcom.c +++ b/src/pebcom.c @@ -1,44 +1,49 @@ -#include #include "pebcom.h" -struct tm* getTime() { +#include + +struct tm* getTime() +{ time_t t = time(NULL); return localtime(&t); } -Object getSeconds(Object o1, Object o2, struct Environment *env) { +Object getSeconds(Object o1, Object o2, struct Environment* env) +{ return numberObject(getTime()->tm_sec); } -Object getMinutes(Object o1, Object o2, struct Environment *env) { +Object getMinutes(Object o1, Object o2, struct Environment* env) +{ return numberObject(getTime()->tm_min); } -Object getHours(Object o1, Object o2, struct Environment *env) { +Object getHours(Object o1, Object o2, struct Environment* env) +{ return numberObject(getTime()->tm_hour); } -Object getTwelveHours(Object o1, Object o2, struct Environment *env) { +Object getTwelveHours(Object o1, Object o2, struct Environment* env) +{ int hour = (getTime()->tm_hour % 12) ?: 12; return numberObject(hour); } -Object doVibe(Object patternList, Object o2, struct Environment *env) { +Object doVibe(Object patternList, Object o2, struct Environment* env) +{ int length = listLength(&patternList); uint32_t pattern[length]; - if(length > 0) { + if (length > 0) { int i = 0; - Object *pl = &patternList; + Object* pl = &patternList; FOR_POINTER_IN_LIST(pl) { - if(POINTER->type == TYPE_NUMBER) { + if (POINTER->type == TYPE_NUMBER) { pattern[i] = POINTER->number; } i++; } - vibes_enqueue_custom_pattern((VibePattern) { - .durations = pattern, - .num_segments = length - }); + vibes_enqueue_custom_pattern( + (VibePattern) {.durations = pattern, .num_segments = length}); return boolObject(1); } else { return errorObject(NOT_A_LIST); diff --git a/src/pebcom.h b/src/pebcom.h index ce43692..351a54b 100644 --- a/src/pebcom.h +++ b/src/pebcom.h @@ -1,8 +1,11 @@ #include "pebblisp.h" -Object getSeconds(Object o1, Object o2, struct Environment *env); -Object getMinutes(Object o1, Object o2, struct Environment *env); -Object getHours(Object o1, Object o2, struct Environment *env); -Object getTwelveHours(Object o1, Object o2, struct Environment *env); +Object getSeconds(Object o1, Object o2, struct Environment* env); -Object doVibe(Object patternList, Object o2, struct Environment *env); +Object getMinutes(Object o1, Object o2, struct Environment* env); + +Object getHours(Object o1, Object o2, struct Environment* env); + +Object getTwelveHours(Object o1, Object o2, struct Environment* env); + +Object doVibe(Object patternList, Object o2, struct Environment* env); diff --git a/src/tokens.c b/src/tokens.c index 07bebe4..2ed6284 100644 --- a/src/tokens.c +++ b/src/tokens.c @@ -1,19 +1,8 @@ #include "tokens.h" + #include #include -#ifdef STANDALONE -#include -#undef printd -#define printd(...) fprintf(stderr, __VA_ARGS__) -#else -#include -#undef printd -#undef printf -#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) -#define printd(...) printf(__VA_ARGS__) -#endif - #define ERR_LEN 256 /* @@ -26,44 +15,51 @@ // Is the char a standalone token? static const char singleTokens[] = "()+-*/='"; -int isSingle(const char c) { + +int isSingle(const char c) +{ int i = 0; - while(singleTokens[i] != '\0'){ - if(singleTokens[i] == c) + while (singleTokens[i] != '\0') { + if (singleTokens[i] == c) { return singleTokens[i]; + } i++; } return 0; } -int isDigit(const char c) { +int isDigit(const char c) +{ return c >= '0' && c <= '9'; } -int isHex(const char c) { +int isHex(const char c) +{ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'); } -int isWhitespace(const char c) { +int isWhitespace(const char c) +{ return c == ' ' || c == '\t' || c == '\n'; } -int notWhitespace(const char c) { +int notWhitespace(const char c) +{ return !isWhitespace(c); } // Return needs to be freed, if not null -struct Slice *nf_tokenize(const char *input, struct Error *err) +struct Slice* nf_tokenize(const char* input, struct Error* err) { - if(!input) { + if (!input) { err->context = malloc(sizeof(char) * ERR_LEN); strcpy(err->context, "no input"); return NULL; } int token_count = MAX_TOK_CNT; - struct Slice *slices = malloc(sizeof(struct Slice) * token_count); - while(slices == NULL) { + struct Slice* slices = malloc(sizeof(struct Slice) * token_count); + while (slices == NULL) { token_count /= 2; slices = malloc(sizeof(struct Slice) * token_count); } @@ -72,20 +68,20 @@ struct Slice *nf_tokenize(const char *input, struct Error *err) int slice = 0; int parens = 0; - while(input[i] != '\0') { + while (input[i] != '\0') { int l = 1; // printd("input: '%c'\n", input[i]); - if(isWhitespace(input[i]) || input[i] == ';') { + if (isWhitespace(input[i]) || input[i] == ';') { i++; continue; } - if(input[i] == '(') { + if (input[i] == '(') { parens++; } else if (input[i] == ')') { parens--; - if(parens < 0) { + if (parens < 0) { err->context = malloc(sizeof(char) * ERR_LEN + 1); err->code = MISMATCHED_PARENS; int start = i > ERR_LEN ? i - ERR_LEN : 0; @@ -97,19 +93,21 @@ struct Slice *nf_tokenize(const char *input, struct Error *err) slices[slice].text = &input[i]; - if(isSingle(input[i])) { + if (isSingle(input[i])) { i++; - } else if(input[i] == '"') { - if(input[i + 1] == '"' && input [i + 2] == '"') { + } else if (input[i] == '"') { + if (input[i + 1] == '"' && input[i + 2] == '"') { // Triple-quoted block i += 2; slices[slice].text += 2; - for(;;) { + for (;;) { i++; - if(input[i] == '"' && input[i + 1] == '"' && input[i + 2] == '"') { + if (input[i] == '"' && input[i + 1] == '"' && + input[i + 2] == '"') { break; } - if(input[i] == '\0' || input[i + 1] == '\0' || input[i + 2] == '\0') { + if (input[i] == '\0' || input[i + 1] == '\0' || + input[i + 2] == '\0') { err->context = malloc(sizeof(char) * ERR_LEN + 1); err->code = UNEXPECTED_EOF; int start = i > ERR_LEN ? i - ERR_LEN : 0; @@ -120,13 +118,14 @@ struct Slice *nf_tokenize(const char *input, struct Error *err) } } else { // Simple string - while(input[++i] != '"' && input[i] != '\0') { + while (input[++i] != '"' && input[i] != '\0') { l++; } } i++; } else { - while(!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '\0') { + while (!isWhitespace(input[++i]) && !isSingle(input[i]) && + input[i] != '\0') { l++; } } @@ -135,7 +134,7 @@ struct Slice *nf_tokenize(const char *input, struct Error *err) slice++; } - if(parens != 0){ + if (parens != 0) { err->context = malloc(sizeof(char) * ERR_LEN); err->code = MISMATCHED_PARENS; int start = i > ERR_LEN ? i - ERR_LEN : 0; diff --git a/src/tokens.h b/src/tokens.h index 1e526e6..248b0e1 100644 --- a/src/tokens.h +++ b/src/tokens.h @@ -4,8 +4,11 @@ #include "pebblisp.h" int isSingle(const char c); + int isDigit(const char c); + int isHex(const char c); -struct Slice *nf_tokenize(const char *input, struct Error *err); + +struct Slice* nf_tokenize(const char* input, struct Error* err); #endif