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;
|
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 defaultEnv()
|
||||||
{
|
{
|
||||||
struct Environment e;
|
struct Environment e;
|
||||||
|
@ -161,14 +195,10 @@ struct Environment defaultEnv()
|
||||||
addFunc("len", &len, &e);
|
addFunc("len", &len, &e);
|
||||||
addFunc("cat", &catObjects, &e);
|
addFunc("cat", &catObjects, &e);
|
||||||
|
|
||||||
parseEval("(def max (fn (a b) (if (> a b) a b)))", &e);
|
int i = 0;
|
||||||
parseEval("(def min (fn (a b) (if (< a b) a b)))", &e);
|
while(codes[i]) {
|
||||||
parseEval("(def ad (fn (a) (if (> a 10) a (ad (* 10 a) ))))", &e);
|
parseEval(codes[i++], &e);
|
||||||
parseEval("(def spent (fn (a) \
|
}
|
||||||
(cat \"Tip: $\" \"\" \"\" (/ a 5) \".\" \
|
|
||||||
(/ (* 100 (% a 5)) 5) \
|
|
||||||
) \
|
|
||||||
))", &e);
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,9 @@ enum errorCode {
|
||||||
DID_NOT_FIND_SYMBOL,
|
DID_NOT_FIND_SYMBOL,
|
||||||
BAD_TYPE,
|
BAD_TYPE,
|
||||||
UNEXPECTED_FORM,
|
UNEXPECTED_FORM,
|
||||||
LISTS_NOT_SAME_SIZE
|
LISTS_NOT_SAME_SIZE,
|
||||||
|
SYMBOLS_CANT_START_WITH_DIGITS,
|
||||||
|
UNSUPPORTED_NUMBER_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
//#ifdef STANDALONE
|
//#ifdef STANDALONE
|
||||||
|
@ -50,7 +52,9 @@ static const char *errorText[] = {
|
||||||
"DID_NOT_FIND_SYMBOL",
|
"DID_NOT_FIND_SYMBOL",
|
||||||
"BAD_TYPE",
|
"BAD_TYPE",
|
||||||
"UNEXPECTED_FORM",
|
"UNEXPECTED_FORM",
|
||||||
"LISTS_NOT_SAME_SIZE"
|
"LISTS_NOT_SAME_SIZE",
|
||||||
|
"SYMBOLS_CANT_START_WITH_DIGITS",
|
||||||
|
"UNSUPPORTED_NUMBER_TYPE"
|
||||||
};
|
};
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||||
#endif
|
#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 char *name = newSymbol->name;
|
||||||
|
|
||||||
const Object newValue = eval(newSymbol->forward, env);
|
const Object newValue = eval(newSymbol->forward, env);
|
||||||
|
@ -21,26 +21,26 @@ Object evalDefArgs(const Object *arg_forms, struct Environment *env)
|
||||||
return *newSymbol;
|
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?
|
return eval(argForms, env).number?
|
||||||
eval(arg_forms->forward, env) :
|
eval(argForms->forward, env) :
|
||||||
eval(arg_forms->forward->forward, env);
|
eval(argForms->forward->forward, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object evalLambdaArgs(const Object *arg_forms)
|
Object evalLambdaArgs(const Object *argForms)
|
||||||
{
|
{
|
||||||
// params // body
|
// 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);
|
return errorObject(NULL_MAP_ARGS);
|
||||||
|
|
||||||
const Object lambda = eval(arg_forms, env);
|
const Object lambda = eval(argForms, env);
|
||||||
const Object *inputList = arg_forms->forward;
|
const Object *inputList = argForms->forward;
|
||||||
|
|
||||||
if(lambda.type != TYPE_LAMBDA || inputList->type != TYPE_LIST)
|
if(lambda.type != TYPE_LAMBDA || inputList->type != TYPE_LIST)
|
||||||
return errorObject(BAD_TYPE);
|
return errorObject(BAD_TYPE);
|
||||||
|
@ -114,12 +114,11 @@ Object eval(const Object *obj, struct Environment *env)
|
||||||
Object *first_form = obj->list;
|
Object *first_form = obj->list;
|
||||||
|
|
||||||
{ // Try to eval built-ins
|
{ // Try to eval built-ins
|
||||||
const Object built_in =
|
const Object builtIn =
|
||||||
evalBuiltIns(first_form, first_form->forward, env);
|
evalBuiltIns(first_form, first_form->forward, env);
|
||||||
|
|
||||||
// deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble
|
if(builtIn.type != TYPE_ERROR) {
|
||||||
if(built_in.type != TYPE_ERROR) {
|
return builtIn;
|
||||||
return built_in;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +137,6 @@ Object eval(const Object *obj, struct Environment *env)
|
||||||
cleanObject(&rest[i]);
|
cleanObject(&rest[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble
|
|
||||||
return func_eval;
|
return func_eval;
|
||||||
|
|
||||||
} else if (first_eval.type == TYPE_LAMBDA) {
|
} else if (first_eval.type == TYPE_LAMBDA) {
|
||||||
|
@ -242,7 +240,7 @@ Object basicOp(const Object *obj1, const Object *obj2, const char op,
|
||||||
}
|
}
|
||||||
return newList;
|
return newList;
|
||||||
|
|
||||||
} else { // 2 lists
|
} else { // 2 lists with the op applied to matching indices of both lists
|
||||||
if(listLength(obj1) == listLength(obj2)) {
|
if(listLength(obj1) == listLength(obj2)) {
|
||||||
Object newList = listObject();
|
Object newList = listObject();
|
||||||
FOR_POINTERS_IN_LISTS(obj1, obj2) {
|
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;
|
int num = 0;
|
||||||
for(int i = 0; i < s->length; i++) {
|
for(int i = 0; i < s->length; i++) {
|
||||||
|
if(!isDigit(s->text[i])) {
|
||||||
|
return errorObject(SYMBOLS_CANT_START_WITH_DIGITS);
|
||||||
|
}
|
||||||
num *= 10;
|
num *= 10;
|
||||||
num += s->text[i] - '0';
|
num += s->text[i] - '0';
|
||||||
}
|
}
|
||||||
return numberObject(num);
|
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);
|
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);
|
return boolObject(0);
|
||||||
|
|
||||||
} else if (s->text[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"
|
check "ImplicitCat" "(+ \"There are \" (* 5 4) \" bonks\")" "There are 20 bonks"
|
||||||
# Not recommended
|
# Not recommended
|
||||||
check "CatAssocLeft" "(+ 10 20 \" rascals\")" "30 rascals"
|
check "CatAssocLeft" "(+ 10 20 \" rascals\")" "30 rascals"
|
||||||
echo""
|
echo ""
|
||||||
check "EvalElems" "((* 10 10) 7)" "( 100 7 )"
|
check "EvalElems" "((* 10 10) 7)" "( 100 7 )"
|
||||||
check "Duplicate" "(def dupe (fn (a) (a a a))) (dupe (*10 10))" "( 100 100 100 )"
|
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
|
if [ "$FAILS" -ne "0" ]; then
|
||||||
echo "[1;31m$FAILS Tests Failed[0m"
|
echo "[1;31m$FAILS Tests Failed[0m"
|
||||||
|
|
Loading…
Reference in New Issue