From cd36f96dfc03e3425d2d690254a8ce1b9178a751 Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Tue, 28 Feb 2023 13:19:25 -0800 Subject: floats fully implemented --- doc/precedent.1 | 5 ++++- src/eval.c | 44 +++++++++++++++++++++++++++++++++++++++----- src/parse.c | 21 +++++++++++++++++---- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/doc/precedent.1 b/doc/precedent.1 index 6b98479..0231d84 100644 --- a/doc/precedent.1 +++ b/doc/precedent.1 @@ -68,7 +68,10 @@ literals or key references. The following are examples of key references with ar \-\- If its first argument is 0, returns 1. Otherwise, returns 0. \fBsum()\fP -\-\- Evaluates all its arguments. Returns the sum. +\-\- Evaluates all its arguments and returns the sum. If any argument is a float, returns a float. Otherwise, returns an int. + +\fBsub()\fP +\-\- Evaluates all its arguments. Subtracts every argument after the first from the first. Returns the result, which is a float if any arguments were floats, or an int if all arguments were ints. \fBprint()\fP \-\- Evaluates its first argument and prints it to the terminal. diff --git a/src/eval.c b/src/eval.c index 0b28ef4..8adcf8c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -198,23 +198,56 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { } else if (hash == get_hash("sum")) { int sum = 0; + float fSum = 0; + char isFloat = 0; for (int i = 0; i < symbol->argCount; i++) { sym_t* v = eval(symbol->args[i], symbolScope); - sum += symtoi(v); + if (v->litType == INT) { + sum += symtoi(v); + } + else if (v->litType == FLOAT) { + fSum += symtof(v); + isFloat = 1; + } destroy_sym(v); } - return init_sym_int(sum); + if (!isFloat) { + return init_sym_int(sum); + } + else { + return init_sym_float(sum + fSum); + } } else if (hash == get_hash("sub")) { sym_t* v1 = eval(symbol->args[0], symbolScope); - int sum = symtoi(v1); + int sum = 0; + float fSum = 0; + char isFloat = 0; + if (v1->litType == INT) { + sum = symtoi(v1); + } + else if (v1->litType == FLOAT) { + fSum = symtof(v1); + isFloat = 1; + } destroy_sym(v1); for (int i = 1; i < symbol->argCount; i++) { sym_t* v = eval(symbol->args[i], symbolScope); - sum -= symtoi(v); + if (v->litType == INT) { + sum -= symtoi(v); + } + else if (v->litType == FLOAT) { + fSum -= symtof(v); + isFloat = 1; + } destroy_sym(v); } - return init_sym_int(sum); + if (!isFloat) { + return init_sym_int(sum); + } + else { + return init_sym_float(sum + fSum); + } } else if (hash == get_hash("print")) { sym_t* v = eval(symbol->args[0], symbolScope); @@ -222,6 +255,7 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) { printf("%d\n", symtoi(v)); } else if (v->litType == FLOAT) { + printf("%.5f\n", symtof(v)); } else if (v->litType == STRING) { char* s = symtos(v); diff --git a/src/parse.c b/src/parse.c index 18425ac..d1b0f2e 100644 --- a/src/parse.c +++ b/src/parse.c @@ -24,7 +24,7 @@ sym_t* init_sym_int(int value) { return init_sym(LITERAL, INT, vp); } sym_t* init_sym_float(float value) { - int* vp = malloc(sizeof(float)); + float* vp = malloc(sizeof(float)); *vp = value; return init_sym(LITERAL, FLOAT, vp); } @@ -93,20 +93,23 @@ symset_t* parse_symbols(char** str) { return symbolSet; } char* symbolName = calloc(30, sizeof(char)); + char isFloat = 0; int i = 0; while (1) { symbolName[i] = **str; - if (**str == ',' || **str == ';') { + if (**str == '.') { + isFloat = 1; + } + else if (**str == ',' || **str == ';') { (*str)++; symbolName[i] = '\0'; sym_t* symbol; - /* TODO: float */ /* string */ if (isalpha(symbolName[0])) { symbol = init_sym_str(symbolName); } /* int */ - else { + else if (!isFloat) { int v; if (symbolName[0] == '-') { v = atoi(symbolName + 1) * -1; @@ -116,6 +119,16 @@ symset_t* parse_symbols(char** str) { } symbol = init_sym_int(v); } + else { + float v; + if (symbolName[0] == '-') { + v = atof(symbolName + 1) * -1; + } + else { + v = atof(symbolName); + } + symbol = init_sym_float(v); + } symset_add_symbol(symbolSet, symbol); break; } -- cgit v1.3.1