Broke lib-type code into array. New numparse errs

This commit is contained in:
= 2020-05-16 19:31:14 +01:00
parent c59789120c
commit 80967b9275
4 changed files with 82 additions and 34 deletions

View File

@ -142,6 +142,40 @@ void deleteEnv(struct Environment *e)
e->objects = NULL;
}
const char *codes[] = {
// Exponentiate a^b
"(def exp (fn (a b) "
"(if (= b 0)"
"1"
"(* a (exp a (- b 1)))"
")"
"))",
// Square a
"(def sq (fn (a) (exp a 2)))",
// Cube a
"(def cube (fn (a) (exp a 3)))",
// Return the larger of the two
"(def max (fn (a b) (if (> a b) a b)))",
// Return the smaller of the two
"(def min (fn (a b) (if (< a b) a b)))",
// Arbitrary recursion tester
"(def ad (fn (a) (if (> a 10) a (ad (* 10 a) ))))",
// A demo tip calculator
"(def spent (fn (a) \
(cat \"Tip: $\" \"\" \"\" (/ a 5) \".\" \
(/ (* 100 (% a 5)) 5) \
) \
))",
NULL
};
struct Environment defaultEnv()
{
struct Environment e;
@ -161,14 +195,10 @@ struct Environment defaultEnv()
addFunc("len", &len, &e);
addFunc("cat", &catObjects, &e);
parseEval("(def max (fn (a b) (if (> a b) a b)))", &e);
parseEval("(def min (fn (a b) (if (< a b) a b)))", &e);
parseEval("(def ad (fn (a) (if (> a 10) a (ad (* 10 a) ))))", &e);
parseEval("(def spent (fn (a) \
(cat \"Tip: $\" \"\" \"\" (/ a 5) \".\" \
(/ (* 100 (% a 5)) 5) \
) \
))", &e);
int i = 0;
while(codes[i]) {
parseEval(codes[i++], &e);
}
return e;
}

View File

@ -32,7 +32,9 @@ enum errorCode {
DID_NOT_FIND_SYMBOL,
BAD_TYPE,
UNEXPECTED_FORM,
LISTS_NOT_SAME_SIZE
LISTS_NOT_SAME_SIZE,
SYMBOLS_CANT_START_WITH_DIGITS,
UNSUPPORTED_NUMBER_TYPE
};
//#ifdef STANDALONE
@ -50,7 +52,9 @@ static const char *errorText[] = {
"DID_NOT_FIND_SYMBOL",
"BAD_TYPE",
"UNEXPECTED_FORM",
"LISTS_NOT_SAME_SIZE"
"LISTS_NOT_SAME_SIZE",
"SYMBOLS_CANT_START_WITH_DIGITS",
"UNSUPPORTED_NUMBER_TYPE"
};
//#endif

View File

@ -9,9 +9,9 @@
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif
Object evalDefArgs(const Object *arg_forms, struct Environment *env)
Object evalDefArgs(const Object *argForms, struct Environment *env)
{
const Object *newSymbol = arg_forms;
const Object *newSymbol = argForms;
const char *name = newSymbol->name;
const Object newValue = eval(newSymbol->forward, env);
@ -21,26 +21,26 @@ Object evalDefArgs(const Object *arg_forms, struct Environment *env)
return *newSymbol;
}
Object evalIfArgs(const Object *arg_forms, struct Environment *env)
Object evalIfArgs(const Object *argForms, struct Environment *env)
{
return eval(arg_forms, env).number?
eval(arg_forms->forward, env) :
eval(arg_forms->forward->forward, env);
return eval(argForms, env).number?
eval(argForms->forward, env) :
eval(argForms->forward->forward, env);
}
Object evalLambdaArgs(const Object *arg_forms)
Object evalLambdaArgs(const Object *argForms)
{
// params // body
return constructLambda(arg_forms, arg_forms? arg_forms->forward : NULL);
return constructLambda(argForms, argForms? argForms->forward : NULL);
}
Object evalMapArgs(const Object *arg_forms, struct Environment *env)
Object evalMapArgs(const Object *argForms, struct Environment *env)
{
if(!arg_forms)
if(!argForms)
return errorObject(NULL_MAP_ARGS);
const Object lambda = eval(arg_forms, env);
const Object *inputList = arg_forms->forward;
const Object lambda = eval(argForms, env);
const Object *inputList = argForms->forward;
if(lambda.type != TYPE_LAMBDA || inputList->type != TYPE_LIST)
return errorObject(BAD_TYPE);
@ -114,12 +114,11 @@ Object eval(const Object *obj, struct Environment *env)
Object *first_form = obj->list;
{ // Try to eval built-ins
const Object built_in =
const Object builtIn =
evalBuiltIns(first_form, first_form->forward, env);
// deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble
if(built_in.type != TYPE_ERROR) {
return built_in;
if(builtIn.type != TYPE_ERROR) {
return builtIn;
}
}
@ -138,7 +137,6 @@ Object eval(const Object *obj, struct Environment *env)
cleanObject(&rest[i]);
}
// deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble
return func_eval;
} else if (first_eval.type == TYPE_LAMBDA) {
@ -242,7 +240,7 @@ Object basicOp(const Object *obj1, const Object *obj2, const char op,
}
return newList;
} else { // 2 lists
} 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) {
@ -327,20 +325,32 @@ Result readSeq(struct Slice *tokens)
}
}
Object parseAtom(struct Slice *s)
Object parseDecimal(struct Slice *s)
{
if(isDigit(s->text[0])) {
int num = 0;
for(int i = 0; i < s->length; i++) {
if(!isDigit(s->text[i])) {
return errorObject(SYMBOLS_CANT_START_WITH_DIGITS);
}
num *= 10;
num += s->text[i] - '0';
}
return numberObject(num);
}
} else if (s->text[0] == 'T' && s->length == 1) {
Object parseAtom(struct Slice *s)
{
if(isDigit(s->text[0])) {
if(s->text[0] != '0' || s->length == 1)
return parseDecimal(s);
else {
return errorObject(UNSUPPORTED_NUMBER_TYPE);
}
} else if (s->length == 1 && (s->text[0] == 'T' || s->text[0] == 't')) {
return boolObject(1);
} else if (s->text[0] == 'F' && s->length == 1) {
} else if (s->length == 1 && (s->text[0] == 'F' || s->text[0] == 'f')) {
return boolObject(0);
} else if (s->text[0] == '"') {

View File

@ -86,6 +86,10 @@ echo""
check "EvalElems" "((* 10 10) 7)" "( 100 7 )"
check "Duplicate" "(def dupe (fn (a) (a a a))) (dupe (*10 10))" "( 100 100 100 )"
echo ""
check "Squaring" "(sq 9876)" "97535376"
check "Cubing" "(cube 81)" "531441"
check "Exponent" "(exp 9 9)" "387420489"
echo ""
if [ "$FAILS" -ne "0" ]; then
echo "$FAILS Tests Failed"