Finally some consistent styling.

Centralized printf/printd defines in object.h
Removed null/isList checking from FOR_POINTER_IN_LIST
This commit is contained in:
Sage Vaillancourt 2022-01-07 16:55:03 -05:00 committed by Sage Vaillancourt
parent 8d22bf575c
commit e2c977e95a
14 changed files with 892 additions and 708 deletions

View File

@ -141,18 +141,20 @@ static void adjustFont()
int i = 0; int i = 0;
int size = 0; int size = 0;
while (displayed_code[i++]) { while (displayed_code[i++]) {
if(displayed_code[i] == '\n') if (displayed_code[i] == '\n') {
size += 10; size += 10;
}
size++; size++;
} }
// Use various system fonts for most text // Use various system fonts for most text
if (size <= 100) { if (size <= 100) {
int f = size < 50 ? smallestFont - 3 : const char* f = fonts[
size < 50 ? smallestFont - 3 :
size < 80 ? smallestFont - 2 : size < 80 ? smallestFont - 2 :
size < 100 ? smallestFont - 1 : size < 100 ? smallestFont - 1 :
smallestFont; smallestFont
text_layer_set_font(s_input_text_layer, ];
fonts_get_system_font(fonts[f])); text_layer_set_font(s_input_text_layer, fonts_get_system_font(f));
} else { } else {
// Use custom extra small font for lots of text // Use custom extra small font for lots of text
text_layer_set_font(s_input_text_layer, tiny_font); text_layer_set_font(s_input_text_layer, tiny_font);
@ -220,9 +222,11 @@ static void calculate()
stringNObj(temp, &obj, RESULT_LENGTH); stringNObj(temp, &obj, RESULT_LENGTH);
if (obj.type == TYPE_ERROR) { if (obj.type == TYPE_ERROR) {
text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); text_layer_set_font(s_result_text_layer,
fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD));
} else { } 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); snprintf(result_text, RESULT_LENGTH, RESULT_PREFIX "%s", temp);
text_layer_set_text(s_result_text_layer, result_text); text_layer_set_text(s_result_text_layer, result_text);
@ -301,16 +305,20 @@ static void code_window_load(Window *window)
// Input text layer setup // Input text layer setup
s_input_text_layer = text_layer_create(bounds); s_input_text_layer = text_layer_create(bounds);
text_layer_set_text(s_input_text_layer, getToken(1)); 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)); text_layer_set_font(s_input_text_layer,
layer_add_child(window_get_root_layer(s_code_window), text_layer_get_layer(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 // Result text layer setup
GRect result_bounds = GRect(6, 148, 132, 132); GRect result_bounds = GRect(6, 148, 132, 132);
s_result_text_layer = text_layer_create(result_bounds); s_result_text_layer = text_layer_create(result_bounds);
text_layer_set_text(s_result_text_layer, result_text); 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); 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' // Push the window, setting the window animation to 'true'
window_stack_push(s_code_window, true); window_stack_push(s_code_window, true);
@ -329,13 +337,16 @@ static void code_window_load(Window *window)
#endif #endif
} }
void debug_result(const char* d) { void debug_result(const char* d)
{
snprintf(result_text, RESULT_LENGTH, "%s", d); snprintf(result_text, RESULT_LENGTH, "%s", d);
text_layer_set_text(s_result_text_layer, result_text); text_layer_set_text(s_result_text_layer, result_text);
psleep(300); 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; int n = script_num.number - 1;
if (persist_exists(n)) { if (persist_exists(n)) {
char* code = malloc(sizeof(char) * SMAX_LENGTH); char* code = malloc(sizeof(char) * SMAX_LENGTH);
@ -374,8 +385,8 @@ void code_window_push()
/** Menu Window **/ /** Menu Window **/
static void select_callback(struct MenuLayer *menu_layer, static void select_callback(MenuLayer* menu_layer, MenuIndex* cell_index,
MenuIndex *cell_index, void *context) void* context)
{ {
current_script_num = cell_index->row; current_script_num = cell_index->row;
code_window_push(); code_window_push();
@ -397,7 +408,7 @@ static void draw_row_callback(GContext *ctx, const Layer *cell_layer,
menu_cell_basic_draw(ctx, cell_layer, s_buff, NULL, NULL); menu_cell_basic_draw(ctx, cell_layer, s_buff, NULL, NULL);
} }
static int16_t get_cell_height_callback(struct MenuLayer *menu_layer, static int16_t get_cell_height_callback(MenuLayer* menu_layer,
MenuIndex* cell_index, void* context) MenuIndex* cell_index, void* context)
{ {
return CELL_HEIGHT; return CELL_HEIGHT;
@ -412,8 +423,11 @@ static void script_menu_load(Window *window)
menu_layer_set_click_config_onto_window(s_script_select_layer, window); menu_layer_set_click_config_onto_window(s_script_select_layer, window);
#if defined(PBL_COLOR) #if defined(PBL_COLOR)
menu_layer_set_normal_colors(s_script_select_layer, GColorBlack, GColorWhite); menu_layer_set_normal_colors(s_script_select_layer,
menu_layer_set_highlight_colors(s_script_select_layer, GColorDukeBlue, GColorWhite); GColorBlack, GColorWhite);
menu_layer_set_highlight_colors(s_script_select_layer,
GColorDukeBlue, GColorWhite);
#endif #endif
menu_layer_set_callbacks(s_script_select_layer, NULL, (MenuLayerCallbacks) { menu_layer_set_callbacks(s_script_select_layer, NULL, (MenuLayerCallbacks) {
@ -422,6 +436,7 @@ static void script_menu_load(Window *window)
.get_cell_height = get_cell_height_callback, .get_cell_height = get_cell_height_callback,
.select_click = select_callback, .select_click = select_callback,
}); });
layer_add_child(window_layer, menu_layer_get_layer(s_script_select_layer)); layer_add_child(window_layer, menu_layer_get_layer(s_script_select_layer));
} }
@ -461,7 +476,8 @@ Object add_window(Object obj1, Object _, struct Environment *env)
s_custom_window = window_create(); s_custom_window = window_create();
WindowHandlers wh = { WindowHandlers wh = {
.load = custom_load, .load = custom_load,
.unload = custom_unload }; .unload = custom_unload
};
window_set_window_handlers(s_custom_window, wh); window_set_window_handlers(s_custom_window, wh);
} }
@ -470,7 +486,8 @@ Object add_window(Object obj1, Object _, struct Environment *env)
return numberObject(1); return numberObject(1);
} }
static void inbox_received_callback(DictionaryIterator *iter, void *context) { static void inbox_received_callback(DictionaryIterator* iter, void* context)
{
Tuple* script_tuple = dict_find(iter, MESSAGE_KEY_ScriptText); Tuple* script_tuple = dict_find(iter, MESSAGE_KEY_ScriptText);
if (script_tuple) { if (script_tuple) {
if (!s_code_window) { if (!s_code_window) {

View File

@ -1,19 +1,16 @@
#include "env.h" #include "env.h"
#include "pebblisp.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#ifndef STANDALONE #include "pebblisp.h"
#include <pebble.h>
#undef printf
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif
Object fetchFromEnvironment(const char* name, struct Environment* env) Object fetchFromEnvironment(const char* name, struct Environment* env)
{ {
if(!env) if (!env) {
return errorObject(NULL_ENV); return errorObject(NULL_ENV);
}
if (env->size == 0) { if (env->size == 0) {
if (env->outer) { if (env->outer) {
@ -50,15 +47,14 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms,
{ {
int paramCount = listLength(params); int paramCount = listLength(params);
struct Environment env = { struct Environment env = {.outer = outer,
.outer = outer,
.strings = NULL, .strings = NULL,
.objects = NULL, .objects = NULL,
.size = paramCount .size = paramCount};
};
if(paramCount == 0) if (paramCount == 0) {
return env; return env;
}
env.strings = calloc(sizeof(char*), paramCount + 1); env.strings = calloc(sizeof(char*), paramCount + 1);
env.objects = malloc(sizeof(Object) * (paramCount + 1)); env.objects = malloc(sizeof(Object) * (paramCount + 1));
@ -119,7 +115,8 @@ void addToEnv(struct Environment *env, const char *name, const Object obj)
// Add *new* item to env only if we're in the local scope // 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) { 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)); strncpy(temp_env->strings[i], name, strlen(name));
temp_env->objects[i] = cloneObject(obj); temp_env->objects[i] = cloneObject(obj);
return; return;
@ -170,7 +167,8 @@ void printEnv(struct Environment *env)
} }
} }
void addFunc(const char *name, Object (*func)(Object, Object, struct Environment*), void addFunc(const char* name,
Object (* func)(Object, Object, struct Environment*),
struct Environment* env) struct Environment* env)
{ {
Object o = newObject(TYPE_FUNC); Object o = newObject(TYPE_FUNC);
@ -197,6 +195,7 @@ void deleteEnv(struct Environment *e)
struct symFunc { struct symFunc {
const char* sym; const char* sym;
Object (* func)(Object, Object, struct Environment*); Object (* func)(Object, Object, struct Environment*);
}; };
@ -214,20 +213,36 @@ struct Environment defaultEnv()
}; };
struct symFunc symFuncs[] = { struct symFunc symFuncs[] = {
{"+", &add}, {"-", &sub}, {"*", &mul}, {"/", &dvi}, {"%", &mod}, {"+", &add},
{"=", &equ}, {">", &gth}, {"<", &lth}, {"-", &sub},
{"cat", &catObjects}, {"fil", &filter}, {"len", &len}, {"*", &mul},
{"ap", &append}, {"pre", &prepend}, {"/", &dvi},
{"at", &at}, {"rest", &rest}, {"%", &mod},
{"=", &equ},
{">", &gth},
{"<", &lth},
{"&", &and},
{"|", &or},
{"cat", &catObjects},
{"fil", &filter},
{"len", &len},
{"ap", &append},
{"pre", &prepend},
{"at", &at},
{"rest", &rest},
{"chat", &charAt}, {"chat", &charAt},
#ifndef LOW_MEM #ifndef LOW_MEM
{"rev", &reverse}, {"rev", &reverse},
#endif #endif
{"isnum", &isNum}, {"isstr", &isString}, {"iserr", &isErr}, {"isnum", &isNum},
{"isstr", &isString},
{"iserr", &isErr},
{"char", &charVal}, {"char", &charVal},
{"eval", &parseEvalO}, {"eval", &parseEvalO},
#ifdef STANDALONE #ifdef STANDALONE
{"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO}, {"prn", &print},
{"pch", &pChar},
{"penv", &printEnvO},
{"sys", &systemCall}, {"sys", &systemCall},
{"loadfile", &loadFile}, {"loadfile", &loadFile},
{"inp", &takeInput}, {"inp", &takeInput},

View File

@ -8,17 +8,24 @@ struct Environment {
char** strings; char** strings;
Object* objects; Object* objects;
struct Environment* outer; struct Environment* outer;
char size; int size;
}; };
Object fetchFromEnvironment(const char* name, struct Environment* env); Object fetchFromEnvironment(const char* name, struct Environment* env);
struct Environment envForLambda(const Object* params, const Object* arg_forms, struct Environment envForLambda(const Object* params, const Object* arg_forms,
struct Environment* outer); struct Environment* outer);
void addToEnv(struct Environment* env, const char* name, const Object obj); void addToEnv(struct Environment* env, const char* name, const Object obj);
void printEnv(struct Environment* env); void printEnv(struct Environment* env);
void addFunc(const char *name, Object (*func)(Object, Object, struct Environment*),
void addFunc(const char* name,
Object (* func)(Object, Object, struct Environment*),
struct Environment* env); struct Environment* env);
void deleteEnv(struct Environment* e); void deleteEnv(struct Environment* e);
struct Environment defaultEnv(); struct Environment defaultEnv();
#endif #endif

View File

@ -1,20 +1,7 @@
#include "object.h" #include "object.h"
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#ifdef DEBUG
#define printd(...) printf(__VA_ARGS__)
#else
#define printd(...) ;
#endif
#ifndef STANDALONE
#include <pebble.h>
#undef printf
#undef printd
#define printf(...) ;
#define printd(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif
/** /**
* Returns the length of a given list Object * Returns the length of a given list Object
@ -23,11 +10,14 @@
*/ */
int listLength(const Object* listObj) int listLength(const Object* listObj)
{ {
if(!listObj || !isListy(*listObj)) if (!listObj || !isListy(*listObj)) {
return -1; return -1;
}
int len = 0; int len = 0;
FOR_POINTER_IN_LIST(listObj) { len++; } FOR_POINTER_IN_LIST(listObj) {
len++;
}
return len; return len;
} }
@ -48,15 +38,18 @@ Object len(Object obj1, Object o_ignore, struct Environment *e_ignore)
*/ */
Object* itemAt(const Object* listObj, int n) Object* itemAt(const Object* listObj, int n)
{ {
if(!listObj || !isListy(*listObj)) if (!listObj || !isListy(*listObj)) {
return NULL; return NULL;
}
FOR_POINTER_IN_LIST(listObj) { FOR_POINTER_IN_LIST(listObj) {
if(POINTER == NULL) if (POINTER == NULL) {
return NULL; return NULL;
if(n-- == 0) }
if (n-- == 0) {
return POINTER; return POINTER;
} }
}
return NULL; return NULL;
} }
@ -67,8 +60,9 @@ Object *itemAt(const Object *listObj, int n)
*/ */
Object* tail(const Object* listObj) Object* tail(const Object* listObj)
{ {
if(!listObj || !isListy(*listObj)) if (!listObj || !isListy(*listObj)) {
return NULL; return NULL;
}
Object* tail = NULL; Object* tail = NULL;
FOR_POINTER_IN_LIST(listObj) { FOR_POINTER_IN_LIST(listObj) {
@ -88,8 +82,9 @@ Object *tail(const Object *listObj)
*/ */
inline int isEmpty(const Object* obj) inline int isEmpty(const Object* obj)
{ {
if(obj == NULL) if (obj == NULL) {
return 0; return 0;
}
switch (obj->type) { switch (obj->type) {
case TYPE_NUMBER: case TYPE_NUMBER:
@ -140,8 +135,9 @@ void allocObject(Object **spot, const Object src)
*/ */
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; return;
}
// Merely append, when possible // Merely append, when possible
if (ind >= listLength(dest)) { if (ind >= listLength(dest)) {
@ -169,8 +165,9 @@ void insertIntoList(Object *dest, int ind, const Object src)
*/ */
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; return;
}
Object* replace = itemAt(list, i); Object* replace = itemAt(list, i);
Object* oldForward = replace->forward; Object* oldForward = replace->forward;
cleanObject(replace); cleanObject(replace);
@ -186,8 +183,9 @@ void replaceListing(Object *list, int i, const Object src)
*/ */
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; return;
}
if (isEmpty(dest)) { if (isEmpty(dest)) {
allocObject(&dest->list, src); allocObject(&dest->list, src);
@ -198,8 +196,7 @@ void nf_addToList(Object *dest, const Object src)
} }
#ifndef SIMPLE_ERRORS #ifndef SIMPLE_ERRORS
static const char *errorText[] = { static const char* errorText[] = {"MISMATCHED_PARENS",
"MISMATCHED_PARENS",
"BAD_LIST_OF_SYMBOL_STRINGS", "BAD_LIST_OF_SYMBOL_STRINGS",
"TYPE_LIST_NOT_CAUGHT", "TYPE_LIST_NOT_CAUGHT",
"NULL_ENV", "NULL_ENV",
@ -222,8 +219,7 @@ static const char *errorText[] = {
"NO_CLONE_SPECIFIED", "NO_CLONE_SPECIFIED",
"CAN_ONLY_EVAL_STRINGS", "CAN_ONLY_EVAL_STRINGS",
"UNEXPECTED_EOF", "UNEXPECTED_EOF",
"INDEX_PAST_END" "INDEX_PAST_END"};
};
#endif #endif
/** /**
@ -235,8 +231,9 @@ static const char *errorText[] = {
*/ */
void stringList(char* dest, const Object* obj) void stringList(char* dest, const Object* obj)
{ {
if(!dest || !isListy(*obj)) if (!dest || !isListy(*obj)) {
return; return;
}
dest[0] = '('; dest[0] = '(';
dest[1] = '\0'; dest[1] = '\0';
@ -266,9 +263,11 @@ void stringList(char *dest, const Object *obj)
* @param dest The string to copy the list text into * @param dest The string to copy the list text into
* @param obj The list Object to make a string from * @param obj The list Object to make a string from
*/ */
char* stringNObj(char *dest, const Object *obj, const size_t len) { char* stringNObj(char* dest, const Object* obj, const size_t len)
if(!dest || !obj) {
if (!dest || !obj) {
return NULL; return NULL;
}
switch (obj->type) { switch (obj->type) {
case TYPE_NUMBER: case TYPE_NUMBER:
@ -293,8 +292,8 @@ char* stringNObj(char *dest, const Object *obj, const size_t len) {
snprintf(dest, len, "E[%d]", (int)code); snprintf(dest, len, "E[%d]", (int)code);
#else #else
if (obj->error->context && obj->error->context[0] != '\0') { if (obj->error->context && obj->error->context[0] != '\0') {
snprintf(dest, len, "'%s': %s", snprintf(dest, len, "'%s': %s", errorText[code],
errorText[code], obj->error->context); obj->error->context);
} else { } else {
snprintf(dest, len, "%s", errorText[code]); snprintf(dest, len, "%s", errorText[code]);
} }
@ -310,13 +309,15 @@ char* stringNObj(char *dest, const Object *obj, const size_t len) {
break; break;
} }
if(!isValidType(*obj)) if (!isValidType(*obj)) {
snprintf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number); snprintf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number);
}
return dest; return dest;
} }
char* stringObj(char *dest, const Object *obj) { char* stringObj(char* dest, const Object* obj)
{
return stringNObj(dest, obj, RESULT_LENGTH); return stringNObj(dest, obj, RESULT_LENGTH);
} }
@ -333,6 +334,7 @@ void debugObj(const Object *obj)
} }
#if defined(DEBUG) || defined(STANDALONE) #if defined(DEBUG) || defined(STANDALONE)
void printType(const Object* obj) void printType(const Object* obj)
{ {
switch (obj->type) { switch (obj->type) {
@ -367,11 +369,13 @@ void printType(const Object *obj)
return; return;
} }
if(!isValidType(*obj)) if (!isValidType(*obj)) {
printf("UNKNOWN TYPE (%d)", obj->type); printf("UNKNOWN TYPE (%d)", obj->type);
} }
}
void nestedPrintList(const Object* list, int newline);
void _printList(const Object *list, int newline);
void _printObj(const Object* obj, int newline) void _printObj(const Object* obj, int newline)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -387,11 +391,12 @@ void _printObj(const Object *obj, int newline)
char temp[100] = ""; char temp[100] = "";
stringObj(temp, obj); stringObj(temp, obj);
if(newline) if (newline) {
printf("%s\n", temp); printf("%s\n", temp);
else } else {
printf("%s", temp); printf("%s", temp);
} }
}
/** /**
* Prints the given Object and a newline. * Prints the given Object and a newline.
@ -404,18 +409,21 @@ inline void printObj(const Object *obj)
_printObj(obj, 1); _printObj(obj, 1);
} }
void _printList(const Object *list, int newline) void nestedPrintList(const Object* list, int newline)
{ {
printf("("); printf("(");
if (list && isListy(*list)) {
FOR_POINTER_IN_LIST(list) { FOR_POINTER_IN_LIST(list) {
printf(" "); printf(" ");
_printObj(POINTER, 0); _printObj(POINTER, 0);
} }
}
printf(" )"); printf(" )");
if(newline) if (newline) {
printf("\n"); printf("\n");
} }
}
/** /**
* Prints each Object in a given list, surrounded by parentheses * Prints each Object in a given list, surrounded by parentheses
@ -423,8 +431,9 @@ void _printList(const Object *list, int newline)
*/ */
void printList(const Object* list) void printList(const Object* list)
{ {
_printList(list, 1); nestedPrintList(list, 1);
} }
#endif #endif
/** /**
@ -439,8 +448,9 @@ void printList(const Object *list)
*/ */
void cleanObject(Object* target) void cleanObject(Object* target)
{ {
if(target == NULL) if (target == NULL) {
return; return;
}
switch (target->type) { switch (target->type) {
case TYPE_STRING: case TYPE_STRING:
@ -483,11 +493,13 @@ void cleanObject(Object *target)
* @param target The object to print and clean * @param target The object to print and clean
*/ */
#ifdef STANDALONE #ifdef STANDALONE
void printAndClean(Object* target) void printAndClean(Object* target)
{ {
printObj(target); printObj(target);
cleanObject(target); cleanObject(target);
} }
#endif #endif
/** /**
@ -498,8 +510,9 @@ void printAndClean(Object *target)
*/ */
void deleteList(Object* dest) void deleteList(Object* dest)
{ {
if(!dest) if (!dest) {
return; return;
}
if (!isListy(*dest)) { if (!isListy(*dest)) {
printf("Tried to delete something other than a list\n"); printf("Tried to delete something other than a list\n");
@ -527,8 +540,9 @@ void _copyList(Object *dest, const Object *src, int delete)
return; return;
} }
if(delete) if (delete) {
deleteList(dest); deleteList(dest);
}
FOR_POINTER_IN_LIST(src) { FOR_POINTER_IN_LIST(src) {
if (isListy(*POINTER)) { if (isListy(*POINTER)) {
@ -654,10 +668,9 @@ inline Object cloneList(const Object src)
return list; return list;
} }
inline Object cloneOther(const Object src) { inline Object cloneOther(const Object src)
return src.other->clone? {
src.other->clone(src.other) : return src.other->clone ? src.other->clone(src.other) : src;
src;
} }
inline Object cloneObject(const Object src) inline Object cloneObject(const Object src)
@ -677,7 +690,7 @@ inline Object cloneObject(const Object src)
case TYPE_NUMBER: case TYPE_NUMBER:
case TYPE_FUNC: case TYPE_FUNC:
case TYPE_OTHER: case TYPE_OTHER:
; // Fall through to plain return return src;
} }
return src; return src;
@ -720,11 +733,13 @@ inline Object symFromSlice(const char *string, int len)
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); 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); return errorObject(LAMBDA_ARGS_NOT_LIST);
}
Object o = newObject(TYPE_LAMBDA); Object o = newObject(TYPE_LAMBDA);
o.lambda = malloc(sizeof(struct Lambda)); o.lambda = malloc(sizeof(struct Lambda));
@ -786,6 +801,7 @@ inline enum errorCode getErrorCode(const Object obj)
} }
#ifndef SIMPLE_ERRORS #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: %p\n", o);
@ -803,6 +819,7 @@ inline Object errorWithContext(enum errorCode code, const char* context)
} }
return o; return o;
} }
#endif #endif
struct Error noError() struct Error noError()
@ -814,7 +831,8 @@ struct Error noError()
inline Object toBool(const Object test) inline Object toBool(const Object test)
{ {
if(test.number == 0) if (test.number == 0) {
return boolObject(0); return boolObject(0);
}
return boolObject(1); return boolObject(1);
} }

View File

@ -3,19 +3,30 @@
#include <stdlib.h> #include <stdlib.h>
#ifndef STANDALONE
#include <pebble.h>
#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_TOK_CNT 1024
#define MAX_ENV_ELM 100 #define MAX_ENV_ELM 100
#define RESULT_LENGTH 128 #define RESULT_LENGTH 128
#define FOR_POINTER_IN_LIST(_list) \ #define FOR_POINTER_IN_LIST(_list) \
if(_list && isListy(*_list)) \ for(Object *_element = (_list)->list; \
for(Object *_element = _list->list; \
_element != NULL;\ _element != NULL;\
_element = _element->forward) _element = _element->forward)
#define POINTER _element #define POINTER _element
#define FOR_POINTERS_IN_LISTS(_list, _list2) \ #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 != NULL && _element2 != NULL; \
_element = _element->forward, _element2 = _element2->forward) _element = _element->forward, _element2 = _element2->forward)
#define P1 POINTER #define P1 POINTER
@ -82,11 +93,14 @@ struct Error {
struct Object { struct Object {
Type type; Type type;
Object *forward; Object *forward;
union { union {
int number; int number;
Object *list; Object *list;
char *string; char *string;
Object (*func)(Object, Object, struct Environment *); Object (*func)(Object, Object, struct Environment *);
struct Lambda *lambda; struct Lambda *lambda;
struct Other *other; struct Other *other;
#ifdef SIMPLE_ERRORS #ifdef SIMPLE_ERRORS
@ -104,66 +118,109 @@ struct Lambda {
struct Other { struct Other {
void (*cleanup)(Object *); void (*cleanup)(Object *);
Object (*clone)(struct Other *); Object (*clone)(struct Other *);
void *data; void *data;
}; };
char *stringNObj(char *dest, const Object *obj, size_t len); char *stringNObj(char *dest, const Object *obj, size_t len);
char *stringObj(char *dest, const Object *obj); char *stringObj(char *dest, const Object *obj);
void printList(const Object *list); void printList(const Object *list);
void printType(const Object *obj); void printType(const Object *obj);
void printObj(const Object *obj); void printObj(const Object *obj);
void _printObj(const Object *obj, int newline); void _printObj(const Object *obj, int newline);
void debugObj(const Object *obj); void debugObj(const Object *obj);
void printErr(const Object *obj); void printErr(const Object *obj);
int isEmpty(const Object *obj); int isEmpty(const Object *obj);
Object *tail(const Object *listObj); Object *tail(const Object *listObj);
void insertIntoList(Object *dest, int ind, const Object src); void insertIntoList(Object *dest, int ind, const Object src);
void replaceListing(Object *list, int i, const Object src); void replaceListing(Object *list, int i, const Object src);
void nf_addToList(Object *dest, Object src); void nf_addToList(Object *dest, Object src);
void deleteList(Object *dest); void deleteList(Object *dest);
int listLength(const Object *listObj); int listLength(const Object *listObj);
Object *itemAt(const Object *listObj, int n); Object *itemAt(const Object *listObj, int n);
void copyList(Object *dest, const Object *src); void copyList(Object *dest, const Object *src);
void cleanObject(Object *target); void cleanObject(Object *target);
void printAndClean(Object *target); void printAndClean(Object *target);
void allocObject(Object **spot, const Object src); void allocObject(Object **spot, const Object src);
void appendList(Object *dest, const Object *src); void appendList(Object *dest, const Object *src);
int isListy(const Object test); int isListy(const Object test);
int isStringy(const Object test); int isStringy(const Object test);
int isValidType(const Object test); int isValidType(const Object test);
int isError(const Object obj, const enum errorCode err); int isError(const Object obj, const enum errorCode err);
int bothAre(const enum Type type, const Object *obj1, const Object *obj2); 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 eitherIs(const enum Type type, const Object *obj1, const Object *obj2);
int areSameType(const Object *obj1, const Object *obj2); int areSameType(const Object *obj1, const Object *obj2);
Object cloneList(const Object src); Object cloneList(const Object src);
Object cloneString(Object obj); Object cloneString(Object obj);
Object cloneLambda(const Object old); Object cloneLambda(const Object old);
Object cloneObject(const Object src); Object cloneObject(const Object src);
Object newObject(Type type); Object newObject(Type type);
Object listObject(); Object listObject();
Object startList(const Object start); Object startList(const Object start);
Object objFromSlice(const char *string, int len); Object objFromSlice(const char *string, int len);
Object stringFromSlice(const char *string, int len); Object stringFromSlice(const char *string, int len);
Object symFromSlice(const char *string, int len); Object symFromSlice(const char *string, int len);
Object boolObject(int b); Object boolObject(int b);
Object numberObject(int num); Object numberObject(int num);
Object otherObject(); Object otherObject();
Object errorObject(enum errorCode err); Object errorObject(enum errorCode err);
enum errorCode getErrorCode(const Object obj); enum errorCode getErrorCode(const Object obj);
#ifdef SIMPLE_ERRORS #ifdef SIMPLE_ERRORS
#define errorWithContext(code, context) errorObject(code) #define errorWithContext(code, context) errorObject(code)
#define errorAddContext(x, y) ; #define errorAddContext(x, y) ;
#else #else
Object errorWithContext(enum errorCode err, const char *context); Object errorWithContext(enum errorCode err, const char *context);
void errorAddContext(Object *o, const char *context); void errorAddContext(Object *o, const char *context);
#endif #endif
struct Error noError(); struct Error noError();
Object constructLambda(const Object *params, const Object *body); Object constructLambda(const Object *params, const Object *body);

View File

@ -1,11 +1,9 @@
#include "pebbleobject.h" #include "pebbleobject.h"
#include "calc.h" #include "calc.h"
#include "object.h" #include "object.h"
Object pebbleOther( Object pebbleOther(enum PebbleType type, void* data, void (* cleanup)(Object*),
enum PebbleType type,
void* data,
void (*cleanup)(Object*),
Object (* clone)(struct Other*)) Object (* clone)(struct Other*))
{ {
struct Object o = otherObject(); struct Object o = otherObject();
@ -28,30 +26,34 @@ enum PebbleType getPebbleType(const Object o1)
return P_ERROR; return P_ERROR;
} }
struct PebbleObject* accessPebbleObject(Object obj) { struct PebbleObject* accessPebbleObject(Object obj)
{
if (getPebbleType(obj) != P_ERROR) { if (getPebbleType(obj) != P_ERROR) {
return obj.other->data; return obj.other->data;
} }
return NULL; 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); window_destroy(window);
} }
Object createWindow(Object o1, Object o2, struct Environment *env) { Object createWindow(Object o1, Object o2, struct Environment* env)
{
Window* window = window_create(); Window* window = window_create();
WindowHandlers wh = { WindowHandlers wh = {.load = custom_window_load,
.load = custom_window_load,
.unload = custom_window_unload}; .unload = custom_window_unload};
window_set_window_handlers(window, wh); window_set_window_handlers(window, wh);
return pebbleOther(WINDOW, window, NULL, NULL); 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? */ /* Maintain a list of layers to delete? */
if (getPebbleType(window) == WINDOW) { if (getPebbleType(window) == WINDOW) {
window_stack_remove(accessPebbleObject(window)->window, true); window_stack_remove(accessPebbleObject(window)->window, true);
@ -60,7 +62,8 @@ Object deleteWindow(Object window, Object o2, struct Environment *env) {
return boolObject(0); return boolObject(0);
} }
Object pushWindow(Object window, Object o2, struct Environment *env) { Object pushWindow(Object window, Object o2, struct Environment* env)
{
if (getPebbleType(window) == WINDOW) { if (getPebbleType(window) == WINDOW) {
window_stack_push(accessPebbleObject(window)->window, true); window_stack_push(accessPebbleObject(window)->window, true);
return boolObject(1); return boolObject(1);
@ -68,7 +71,8 @@ Object pushWindow(Object window, Object o2, struct Environment *env) {
return boolObject(0); return boolObject(0);
} }
Object updateTextLayer(Object textLayer, Object text, struct Environment *env) { Object updateTextLayer(Object textLayer, Object text, struct Environment* env)
{
if (getPebbleType(textLayer) == TEXT_LAYER) { if (getPebbleType(textLayer) == TEXT_LAYER) {
struct PebbleObject* po = accessPebbleObject(textLayer); struct PebbleObject* po = accessPebbleObject(textLayer);
stringObj(po->textLayer->text, &text); stringObj(po->textLayer->text, &text);
@ -78,11 +82,13 @@ Object updateTextLayer(Object textLayer, Object text, struct Environment *env) {
return boolObject(0); return boolObject(0);
} }
Object addTextLayer(Object window, Object text, struct Environment *env) { Object addTextLayer(Object window, Object text, struct Environment* env)
{
if (getPebbleType(window) != WINDOW) { if (getPebbleType(window) != WINDOW) {
return errorObject(0); 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); GRect bounds = layer_get_bounds(window_layer);
struct PLTextLayer* textLayer = malloc(sizeof(struct PLTextLayer)); struct PLTextLayer* textLayer = malloc(sizeof(struct PLTextLayer));
@ -98,29 +104,33 @@ Object addTextLayer(Object window, Object text, struct Environment *env) {
return pebbleOther(TEXT_LAYER, textLayer, NULL, NULL); return pebbleOther(TEXT_LAYER, textLayer, NULL, NULL);
} }
Object subscription; 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); eval(&subscription, subscriptionEnv);
} }
Object subscribe(Object function, Object time, struct Environment *env) { Object subscribe(Object function, Object time, struct Environment* env)
{
if (function.type == TYPE_LAMBDA) { if (function.type == TYPE_LAMBDA) {
subscription = cloneObject(function); subscription = cloneObject(function);
subscriptionEnv = env; subscriptionEnv = env;
int unit = time.type != TYPE_NUMBER ? MINUTE_UNIT : int unit = time.type != TYPE_NUMBER ? MINUTE_UNIT
time.number == 1 ? SECOND_UNIT : : time.number == 1 ? SECOND_UNIT
time.number == 2 ? MINUTE_UNIT : : time.number == 2 ? MINUTE_UNIT
time.number == 3 ? HOUR_UNIT : : time.number == 3 ? HOUR_UNIT
time.number == 4 ? DAY_UNIT : : time.number == 4
time.number == 5 ? MONTH_UNIT : ? DAY_UNIT
time.number == 6 ? YEAR_UNIT : : time.number ==
MINUTE_UNIT; 5 ? MONTH_UNIT
:
time.number ==
6 ? YEAR_UNIT
: MINUTE_UNIT;
tick_timer_service_subscribe(unit, subscriptionHandler); tick_timer_service_subscribe(unit, subscriptionHandler);
return boolObject(1); return boolObject(1);
} }
return boolObject(0); return boolObject(0);
} }

View File

@ -1,10 +1,9 @@
#include <pebble.h> #include <pebble.h>
#include "pebblisp.h" #include "pebblisp.h"
enum PebbleType { enum PebbleType {
WINDOW, WINDOW, TEXT_LAYER, P_ERROR
TEXT_LAYER,
P_ERROR
}; };
struct PLTextLayer { struct PLTextLayer {
@ -23,8 +22,13 @@ struct PebbleObject {
}; };
Object createWindow(Object o1, Object o2, struct Environment* env); Object createWindow(Object o1, Object o2, struct Environment* env);
Object deleteWindow(Object window, Object o2, struct Environment* env); Object deleteWindow(Object window, Object o2, struct Environment* env);
Object pushWindow(Object o1, Object o2, struct Environment* env); Object pushWindow(Object o1, Object o2, struct Environment* env);
Object addTextLayer(Object window, Object text, struct Environment* env); Object addTextLayer(Object window, Object text, struct Environment* env);
Object updateTextLayer(Object textLayer, Object text, struct Environment* env); Object updateTextLayer(Object textLayer, Object text, struct Environment* env);
Object subscribe(Object function, Object time, struct Environment* env); Object subscribe(Object function, Object time, struct Environment* env);

View File

@ -1,14 +1,12 @@
#pragma ide diagnostic ignored "misc-no-recursion"
#include "pebblisp.h" #include "pebblisp.h"
#include "tokens.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#ifndef STANDALONE #include "tokens.h"
#undef printf
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#include <pebble.h>
#endif
/** /**
* Inserts a variable into the environment with a given name and value. * 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 * @param env The environment to add the new definition to
* @return The symbol(s) defined * @return The symbol(s) defined
*/ */
Object evalDefArgs( Object evalDefArgs(const Object* symbol, const Object* value,
const Object *symbol, struct Environment* env)
const Object *value, {
struct Environment *env
) {
const char* name = symbol->string; const char* name = symbol->string;
// Handles multi-definitions // Handles multi-definitions
if(bothAre(TYPE_LIST, symbol, value) if (bothAre(TYPE_LIST, symbol, value) &&
&& listLength(symbol) == listLength(value)) { listLength(symbol) == listLength(value)) {
FOR_POINTERS_IN_LISTS(symbol, value) { FOR_POINTERS_IN_LISTS(symbol, value) {
Object finalValue = eval(P2, env); Object finalValue = eval(P2, env);
addToEnv(env, P1->string, finalValue); addToEnv(env, P1->string, finalValue);
@ -50,17 +46,15 @@ Object evalDefArgs(
Object evalIfArgs(const Object* argForms, struct Environment* env) Object evalIfArgs(const Object* argForms, struct Environment* env)
{ {
Object condition = eval(argForms, env); Object condition = eval(argForms, env);
Object result = condition.number ? Object result = condition.number ? eval(argForms->forward, env)
eval(argForms->forward, env) : : eval(argForms->forward->forward, env);
eval(argForms->forward->forward, env);
cleanObject(&condition); cleanObject(&condition);
return result; return result;
} }
Object evalLambdaArgs(const Object* argForms) Object evalLambdaArgs(const Object* argForms)
{ {
return constructLambda( return constructLambda(argForms, // Params
argForms, // Params
argForms ? argForms->forward : NULL // Body argForms ? argForms->forward : NULL // Body
); );
} }
@ -79,6 +73,7 @@ Object evalMapArgs(const Object *argForms, struct Environment *env)
return errorObject(BAD_TYPE); return errorObject(BAD_TYPE);
} }
if (inputList) {
FOR_POINTER_IN_LIST(inputList) { FOR_POINTER_IN_LIST(inputList) {
// Create a new list for each element, // Create a new list for each element,
// since lambda evaluation looks for a list // since lambda evaluation looks for a list
@ -95,6 +90,7 @@ Object evalMapArgs(const Object *argForms, struct Environment *env)
cleanObject(&tempList); cleanObject(&tempList);
cleanObject(&lambda_output); cleanObject(&lambda_output);
} }
}
cleanObject(&lambda); cleanObject(&lambda);
return outputList; return outputList;
@ -159,11 +155,8 @@ void evalForms(Object *destArr, const Object *start, struct Environment *env)
* @param length Length of `list` - 1, to exclude the already-evaluated element * @param length Length of `list` - 1, to exclude the already-evaluated element
* @param env The environment to evaluate in * @param env The environment to evaluate in
*/ */
Object listEvalFunc( Object listEvalFunc(const Object* list, const Object* function,
const Object *list, const int length, struct Environment* env)
const Object *function,
const int length,
struct Environment *env)
{ {
if (length == 0) { if (length == 0) {
return function->func(boolObject(0), boolObject(0), env); return function->func(boolObject(0), boolObject(0), env);
@ -175,8 +168,7 @@ Object listEvalFunc(
Object func_result = rest[0]; Object func_result = rest[0];
if (length == 1) { if (length == 1) {
Object oneArg = errorObject(ONLY_ONE_ARGUMENT); Object oneArg = errorObject(ONLY_ONE_ARGUMENT);
func_result = function->func( func_result = function->func(func_result, oneArg, env);
func_result, oneArg, env);
// Return a partial function if more parameters are required // Return a partial function if more parameters are required
// Otherwise, return the function result // Otherwise, return the function result
cleanObject(&rest[0]); cleanObject(&rest[0]);
@ -212,16 +204,11 @@ Object listEvalFunc(
* @param remaining The first element after `lambda` * @param remaining The first element after `lambda`
* @param env The environment to evaluate in * @param env The environment to evaluate in
*/ */
Object listEvalLambda( Object listEvalLambda(Object* lambda, const Object* remaining,
Object *lambda, struct Environment* env)
const Object *remaining, {
struct Environment *env struct Environment newEnv =
) { envForLambda(&lambda->lambda->params, remaining, env);
struct Environment newEnv = envForLambda(
&lambda->lambda->params,
remaining,
env
);
Object ret = eval(&lambda->lambda->body, &newEnv); Object ret = eval(&lambda->lambda->body, &newEnv);
deleteEnv(&newEnv); deleteEnv(&newEnv);
@ -377,6 +364,11 @@ Object _basicOp(const Object *obj1, const Object *obj2, const char op,
case '%': case '%':
return numberObject(n1 % n2); return numberObject(n1 % n2);
case '&':
return boolObject(n1 != 0 && n2 != 0);
case '|':
return boolObject(n1 != 0 || n2 != 0);
case '=': case '=':
if (bothAre(TYPE_STRING, obj1, obj2)) { if (bothAre(TYPE_STRING, obj1, obj2)) {
return boolObject(!strcmp(obj1->string, obj2->string)); return boolObject(!strcmp(obj1->string, obj2->string));
@ -405,7 +397,8 @@ Object basicOp(const Object *obj1, const Object *obj2, const char op,
if (lists == 0) { if (lists == 0) {
return _basicOp(obj1, obj2, op, env); return _basicOp(obj1, obj2, op, env);
} else if(lists == 1) { // Single operand is applied to each element in list } else if (lists ==
1) { // Single operand is applied to each element in list
const Object* listObj = (obj1->type == TYPE_LIST) ? obj1 : obj2; const Object* listObj = (obj1->type == TYPE_LIST) ? obj1 : obj2;
const Object* singleObj = (obj1->type == TYPE_LIST) ? obj2 : obj1; const Object* singleObj = (obj1->type == TYPE_LIST) ? obj2 : obj1;
@ -433,17 +426,30 @@ Object basicOp(const Object *obj1, const Object *obj2, const char op,
#define BASIC_OP(_name, _char) \ #define BASIC_OP(_name, _char) \
Object _name(Object obj1, Object obj2, struct Environment *env) \ Object _name(Object obj1, Object obj2, struct Environment *env) \
{ return basicOp(&obj1, &obj2, _char, env); } { \
return basicOp(&obj1, &obj2, _char, env); \
}
BASIC_OP(add, '+'); BASIC_OP(add, '+');
BASIC_OP(sub, '-'); BASIC_OP(sub, '-');
BASIC_OP(mul, '*'); BASIC_OP(mul, '*');
BASIC_OP(dvi, '/'); BASIC_OP(dvi, '/');
BASIC_OP(mod, '%'); BASIC_OP(mod, '%');
BASIC_OP(equ, '='); BASIC_OP(equ, '=');
BASIC_OP(gth, '>'); BASIC_OP(gth, '>');
BASIC_OP(lth, '<'); BASIC_OP(lth, '<');
BASIC_OP(and, '&');
BASIC_OP(or, '|');
#undef BASIC_OP #undef BASIC_OP
Object filter(Object obj1, Object obj2, struct Environment* env) Object filter(Object obj1, Object obj2, struct Environment* env)
@ -520,14 +526,12 @@ Object reverse(Object _list, Object ignore, struct Environment *ignore2)
Object isNum(Object test, Object ignore, struct Environment* ignore2) Object isNum(Object test, Object ignore, struct Environment* ignore2)
{ {
return test.type == TYPE_NUMBER ? return test.type == TYPE_NUMBER ? boolObject(1) : boolObject(0);
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 ? return test.type == TYPE_STRING ? boolObject(1) : boolObject(0);
boolObject(1) : boolObject(0);
} }
// Get the int value of a string's first character // Get the int value of a string's first character
@ -540,8 +544,7 @@ Object charVal(Object test, Object ignore, struct Environment *ignore2)
Object isErr(Object test, Object ignore, struct Environment* ignore2) Object isErr(Object test, Object ignore, struct Environment* ignore2)
{ {
return test.type == TYPE_ERROR ? return test.type == TYPE_ERROR ? boolObject(1) : boolObject(0);
boolObject(1) : boolObject(0);
} }
Object charAt(Object string, Object at, struct Environment* ignore) Object charAt(Object string, Object at, struct Environment* ignore)
@ -554,6 +557,7 @@ Object charAt(Object string, Object at, struct Environment *ignore)
} }
#ifdef STANDALONE #ifdef STANDALONE
Object print(Object p, Object ignore, struct Environment* env) Object print(Object p, Object ignore, struct Environment* env)
{ {
p = cloneObject(p); p = cloneObject(p);
@ -571,7 +575,8 @@ Object pChar(Object c, Object i1, struct Environment *i2)
return numberObject(0); return numberObject(0);
} }
Object printEnvO(Object i1, Object i2, struct Environment *env) { Object printEnvO(Object i1, Object i2, struct Environment* env)
{
while (env->outer) { while (env->outer) {
env = env->outer; env = env->outer;
} }
@ -579,6 +584,7 @@ Object printEnvO(Object i1, Object i2, struct Environment *env) {
printEnv(env); printEnv(env);
return numberObject(0); return numberObject(0);
} }
#endif #endif
Object parseEvalO(Object text, Object ignore, struct Environment* env) Object parseEvalO(Object text, Object ignore, struct Environment* env)
@ -595,12 +601,14 @@ Object parseEvalO(Object text, Object ignore, struct Environment *env)
} }
#ifdef STANDALONE #ifdef STANDALONE
Object takeInput(Object i1, Object i2, struct Environment* i3) Object takeInput(Object i1, Object i2, struct Environment* i3)
{ {
char input[256] = ""; char input[256] = "";
fgets(input, 256, stdin); fgets(input, 256, stdin);
return stringFromSlice(input, strlen(input) - 1); return stringFromSlice(input, strlen(input) - 1);
} }
#endif #endif
void copySlice(char* dest, struct Slice* src) void copySlice(char* dest, struct Slice* src)
@ -806,10 +814,12 @@ Object parseEval(const char *input, struct Environment *env)
} }
#ifdef STANDALONE #ifdef STANDALONE
int _readFile(FILE *input, struct Environment *env) {
int _readFile(FILE* input, struct Environment* env)
{
Object r = numberObject(0); Object r = numberObject(0);
char page[4096] = ""; char page[4096] = "";
const unsigned LINE_MAX = 256; const int LINE_MAX = 256;
char line[LINE_MAX]; char line[LINE_MAX];
if (fgets(line, LINE_MAX, input)) { if (fgets(line, LINE_MAX, input)) {
if (line[0] != '#' || line[1] != '!') { if (line[0] != '#' || line[1] != '!') {
@ -843,7 +853,9 @@ int _readFile(FILE *input, struct Environment *env) {
fclose(input); fclose(input);
return 0; return 0;
} }
int readFile(const char *filename, struct Environment *env) {
int readFile(const char* filename, struct Environment* env)
{
FILE* input = fopen(filename, "r"); FILE* input = fopen(filename, "r");
if (!input) { if (!input) {
return 1; return 1;
@ -852,7 +864,8 @@ int readFile(const char *filename, struct Environment *env) {
return 0; return 0;
} }
Object loadFile(Object filename, Object _, struct Environment *env) { Object loadFile(Object filename, Object _, struct Environment* env)
{
if (isStringy(filename)) { if (isStringy(filename)) {
readFile(filename.string, env); readFile(filename.string, env);
return numberObject(0); return numberObject(0);
@ -860,21 +873,24 @@ Object loadFile(Object filename, Object _, struct Environment *env) {
return numberObject(1); return numberObject(1);
} }
Object systemCall(Object process, Object _, struct Environment *env) { Object systemCall(Object process, Object _, struct Environment* env)
{
if (isStringy(process)) { if (isStringy(process)) {
return numberObject(system(process.string)); return numberObject(system(process.string));
} }
return numberObject(255); return numberObject(255);
} }
void repl(struct Environment *env) { void repl(struct Environment* env)
{
if (readFile(SCRIPTDIR "/repl.pbl", env) == 1) { if (readFile(SCRIPTDIR "/repl.pbl", env) == 1) {
fprintf(stderr, "Could not read '%s'\n", SCRIPTDIR "/repl.pbl"); fprintf(stderr, "Could not read '%s'\n", SCRIPTDIR "/repl.pbl");
fprintf(stderr, "Consider installing or reinstalling pebblisp.\n"); 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(); 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]))); nf_addToList(&args, stringFromSlice(argv[i], strlen(argv[i])));
@ -907,4 +923,5 @@ int main(int argc, const char* argv[])
} }
deleteEnv(&env); deleteEnv(&env);
} }
#endif #endif

View File

@ -1,19 +1,8 @@
#ifndef PEBBLISP_H #ifndef PEBBLISP_H
#define PEBBLISP_H #define PEBBLISP_H
#include "object.h"
#include "env.h" #include "env.h"
#include "object.h"
#ifndef STANDALONE
#include <pebble.h>
#define printd(...) ;
#endif
#ifdef DEBUG
#define printd(...) printf(__VA_ARGS__)
#else
#define printd(...) ;
#endif
struct Slice { struct Slice {
const char* text; const char* text;
@ -26,51 +15,91 @@ typedef struct Result {
} Result; } Result;
Object eval(const Object* obj, struct Environment* env); Object eval(const Object* obj, struct Environment* env);
Result parse(struct Slice* slices); Result parse(struct Slice* slices);
Result readSeq(struct Slice* slices); Result readSeq(struct Slice* slices);
Object parseAtom(struct Slice* slice); Object parseAtom(struct Slice* slice);
Object parseEval(const char* input, struct Environment* env); Object parseEval(const char* input, struct Environment* env);
void evalForms(Object* destList, const Object* src, struct Environment* env); void evalForms(Object* destList, const Object* src, struct Environment* env);
void copySlice(char* dest, struct Slice* src); void copySlice(char* dest, struct Slice* src);
Object evalLambdaArgs(const Object* arg_forms); Object evalLambdaArgs(const Object* arg_forms);
// Slices // Slices
void copySlice(char* dest, struct Slice* src); void copySlice(char* dest, struct Slice* src);
void debugSlice(struct Slice* s); void debugSlice(struct Slice* s);
#define BASIC_OP(_name) \ #define BASIC_OP(_name) \
Object _name(Object obj1, Object obj2, struct Environment *env); Object _name(Object obj1, Object obj2, struct Environment *env);
BASIC_OP(add); BASIC_OP(sub);
BASIC_OP(mul); BASIC_OP(dvi); BASIC_OP(add);
BASIC_OP(mod); BASIC_OP(equ);
BASIC_OP(gth); BASIC_OP(lth); 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 #undef BASIC_OP
Object catObjects(const Object obj1, const Object obj2, struct Environment *env); Object catObjects(const Object obj1, const Object obj2,
struct Environment* env);
Object filter(Object obj1, Object obj2, struct Environment* env); Object filter(Object obj1, Object obj2, struct Environment* env);
Object append(Object list, Object newElement, struct Environment* env); Object append(Object list, Object newElement, struct Environment* env);
Object prepend(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 at(Object index, Object list, struct Environment* env);
Object rest(Object list, Object ignore, struct Environment* env); Object rest(Object list, Object ignore, struct Environment* env);
Object reverse(Object _list, Object ignore, struct Environment* ignore2); Object reverse(Object _list, Object ignore, struct Environment* ignore2);
Object isNum(Object test, Object ignore, struct Environment* ignore2); Object isNum(Object test, Object ignore, struct Environment* ignore2);
Object isString(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 isErr(Object test, Object ignore, struct Environment* ignore2);
Object charAt(Object string, Object at, struct Environment* ignore); Object charAt(Object string, Object at, struct Environment* ignore);
Object charVal(Object test, Object ignore, struct Environment* ignore2); Object charVal(Object test, Object ignore, struct Environment* ignore2);
Object print(Object p, Object ignore, struct Environment* ignore2); Object print(Object p, Object ignore, struct Environment* ignore2);
Object pChar(Object c, Object i1, struct Environment* i2); Object pChar(Object c, Object i1, struct Environment* i2);
Object printEnvO(Object i1, Object i2, struct Environment* env); Object printEnvO(Object i1, Object i2, struct Environment* env);
Object parseEvalO(Object text, Object ignore, struct Environment* env); Object parseEvalO(Object text, Object ignore, struct Environment* env);
#ifdef STANDALONE #ifdef STANDALONE
Object takeInput(Object i1, Object i2, struct Environment* i3); Object takeInput(Object i1, Object i2, struct Environment* i3);
Object systemCall(Object call, Object _, struct Environment* i3); Object systemCall(Object call, Object _, struct Environment* i3);
Object loadFile(Object filename, Object _, struct Environment* env); Object loadFile(Object filename, Object _, struct Environment* env);
#endif #endif
#endif #endif

View File

@ -1,29 +1,36 @@
#include <pebble.h>
#include "pebcom.h" #include "pebcom.h"
struct tm* getTime() { #include <pebble.h>
struct tm* getTime()
{
time_t t = time(NULL); time_t t = time(NULL);
return localtime(&t); 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); 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); 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); 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; int hour = (getTime()->tm_hour % 12) ?: 12;
return numberObject(hour); 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); int length = listLength(&patternList);
uint32_t pattern[length]; uint32_t pattern[length];
if (length > 0) { if (length > 0) {
@ -35,10 +42,8 @@ Object doVibe(Object patternList, Object o2, struct Environment *env) {
} }
i++; i++;
} }
vibes_enqueue_custom_pattern((VibePattern) { vibes_enqueue_custom_pattern(
.durations = pattern, (VibePattern) {.durations = pattern, .num_segments = length});
.num_segments = length
});
return boolObject(1); return boolObject(1);
} else { } else {
return errorObject(NOT_A_LIST); return errorObject(NOT_A_LIST);

View File

@ -1,8 +1,11 @@
#include "pebblisp.h" #include "pebblisp.h"
Object getSeconds(Object o1, Object o2, struct Environment* env); Object getSeconds(Object o1, Object o2, struct Environment* env);
Object getMinutes(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 getHours(Object o1, Object o2, struct Environment* env);
Object getTwelveHours(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); Object doVibe(Object patternList, Object o2, struct Environment* env);

View File

@ -1,19 +1,8 @@
#include "tokens.h" #include "tokens.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef STANDALONE
#include <stdio.h>
#undef printd
#define printd(...) fprintf(stderr, __VA_ARGS__)
#else
#include <pebble.h>
#undef printd
#undef printf
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#define printd(...) printf(__VA_ARGS__)
#endif
#define ERR_LEN 256 #define ERR_LEN 256
/* /*
@ -26,29 +15,36 @@
// Is the char a standalone token? // Is the char a standalone token?
static const char singleTokens[] = "()+-*/='"; static const char singleTokens[] = "()+-*/='";
int isSingle(const char c) {
int isSingle(const char c)
{
int i = 0; int i = 0;
while (singleTokens[i] != '\0') { while (singleTokens[i] != '\0') {
if(singleTokens[i] == c) if (singleTokens[i] == c) {
return singleTokens[i]; return singleTokens[i];
}
i++; i++;
} }
return 0; return 0;
} }
int isDigit(const char c) { int isDigit(const char c)
{
return c >= '0' && c <= '9'; return c >= '0' && c <= '9';
} }
int isHex(const char c) { int isHex(const char c)
{
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'); 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'; return c == ' ' || c == '\t' || c == '\n';
} }
int notWhitespace(const char c) { int notWhitespace(const char c)
{
return !isWhitespace(c); return !isWhitespace(c);
} }
@ -106,10 +102,12 @@ struct Slice *nf_tokenize(const char *input, struct Error *err)
slices[slice].text += 2; slices[slice].text += 2;
for (;;) { for (;;) {
i++; i++;
if(input[i] == '"' && input[i + 1] == '"' && input[i + 2] == '"') { if (input[i] == '"' && input[i + 1] == '"' &&
input[i + 2] == '"') {
break; 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->context = malloc(sizeof(char) * ERR_LEN + 1);
err->code = UNEXPECTED_EOF; err->code = UNEXPECTED_EOF;
int start = i > ERR_LEN ? i - ERR_LEN : 0; int start = i > ERR_LEN ? i - ERR_LEN : 0;
@ -126,7 +124,8 @@ struct Slice *nf_tokenize(const char *input, struct Error *err)
} }
i++; i++;
} else { } else {
while(!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '\0') { while (!isWhitespace(input[++i]) && !isSingle(input[i]) &&
input[i] != '\0') {
l++; l++;
} }
} }

View File

@ -4,8 +4,11 @@
#include "pebblisp.h" #include "pebblisp.h"
int isSingle(const char c); int isSingle(const char c);
int isDigit(const char c); int isDigit(const char c);
int isHex(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 #endif