Broke lib-type code into array. New numparse errs
This commit is contained in:
parent
c59789120c
commit
80967b9275
46
src/env.c
46
src/env.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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] == '"') {
|
||||
|
|
|
@ -82,10 +82,14 @@ check "CatNums" "(cat \"There are \" (+ 2 3) \" kitties\")" "There are 5 kitties
|
|||
check "ImplicitCat" "(+ \"There are \" (* 5 4) \" bonks\")" "There are 20 bonks"
|
||||
# Not recommended
|
||||
check "CatAssocLeft" "(+ 10 20 \" rascals\")" "30 rascals"
|
||||
echo""
|
||||
echo ""
|
||||
check "EvalElems" "((* 10 10) 7)" "( 100 7 )"
|
||||
check "Duplicate" "(def dupe (fn (a) (a a a))) (dupe (*10 10))" "( 100 100 100 )"
|
||||
echo""
|
||||
echo ""
|
||||
check "Squaring" "(sq 9876)" "97535376"
|
||||
check "Cubing" "(cube 81)" "531441"
|
||||
check "Exponent" "(exp 9 9)" "387420489"
|
||||
echo ""
|
||||
|
||||
if [ "$FAILS" -ne "0" ]; then
|
||||
echo "[1;31m$FAILS Tests Failed[0m"
|
||||
|
|
Loading…
Reference in New Issue