about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDaniel <steew0x8@protonmail.com>2021-11-06 17:58:47 +0100
committerDaniel <steew0x8@protonmail.com>2021-11-06 17:58:47 +0100
commitfe6314692dbdbf69db8b3e8a3979c1f1d21d621c (patch)
tree91d91e912e7b9e8de7f9fb6b56c1f0fc2c4dcebe
parentbedbeb372f1d3a36b10d8737a9199c1fe4827e4f (diff)
downloadrpncalc-fe6314692dbdbf69db8b3e8a3979c1f1d21d621c.tar.gz
replaced if else chain, TODO: bsearch
-rw-r--r--cmds.c21
-rw-r--r--cmds.h3
-rw-r--r--main.c40
-rw-r--r--meson.build2
-rw-r--r--state.h7
-rw-r--r--util.c6
-rw-r--r--util.h5
7 files changed, 48 insertions, 36 deletions
diff --git a/cmds.c b/cmds.c
index 0148c7b..2a88041 100644
--- a/cmds.c
+++ b/cmds.c
@@ -4,6 +4,7 @@
 #include <math.h>
 #include <stdlib.h>
 #include <err.h>
+#include <string.h>
 
 stack fceil(stack stack) {
   stack.val[stack.count-1] = ceil(stack.val[stack.count-1]);
@@ -21,10 +22,26 @@ command CMD_LIST[] = {
   {0, 0, 0}
 };
 
-void initstate(state *s) {
+void init_state(state *s) {
   int numel = 0;
   for (int i = 0; CMD_LIST[i].name != 0; i++) numel = i;
-  char *sorted = malloc(sizeof(char *)*numel);
+  command *sorted = malloc(sizeof(command *)*numel);
   if (sorted == NULL) err(1, "could not allocate function names");
   /* todo: (merge, heap, quick) sort? */
+  for (int i = 0; CMD_LIST[i].name != 0; i++) {
+    sorted[i] = CMD_LIST[i];
+  }
+  s->sorted = sorted;
+}
+
+void exec(char *buf, state *s) {
+  /* change this to a binary tree search */
+  for (int i = 0; s->sorted[i].name != 0; i++) {
+    if (strcmp(buf, s->sorted[i].name) == 0) {
+      fprintf(s->defout, "executing function: %s\n", s->sorted[i].name);
+      s->stk = s->sorted[i].exec(s->stk);
+      return;
+    }
+  }
+  fprintf(s->defout, "error: function '%s' not found\n", buf);
 }
diff --git a/cmds.h b/cmds.h
index ba54fac..78a1c13 100644
--- a/cmds.h
+++ b/cmds.h
@@ -2,7 +2,10 @@
 #define CMDS_H
 
 #include "state.h"
+#include <stdlib.h>
 
 extern command CMD_LIST[];
+void init_state(state *s);
+void exec(char *buf, state *s);
 
 #endif
diff --git a/main.c b/main.c
index 2522e07..e81d50b 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,7 @@
 #include "util.h"
 #include <stdlib.h>
 #include <string.h>
+#include "cmds.h"
 #include <err.h>
 
 #define BUF_SIZE 50
@@ -22,8 +23,9 @@ int main() {
   s.prompt = "[%d]> ";
   stack stack = {{0}, 0};
   /* initialize value stack */
-  s.stack = stack;
+  s.stk = stack;
   s.command_count = 0;
+  init_state(&s);
   
   /* start reading from defbuf */
   char buf[BUF_SIZE];
@@ -31,49 +33,53 @@ int main() {
     fprintf(s.defout, s.prompt, s.command_count, s.last_op);
     s.last_op = 0;
     char *endptr = NULL;
-    if (s.stack.count == STACK_SIZE) err(1, "exceeded stack size");
+    if (s.stk.count == STACK_SIZE) err(1, "exceeded stk size");
     fgets(buf, BUF_SIZE, s.defbuf);
     buf[strcspn(buf, "\n")] = 0;
     double interpreted = strtod(buf, &endptr);
     if (interpreted == (double)0 && endptr == buf) { /* strtod returned the char it could not read */
       TYPE t = discriminate(buf);
       if (t == OPERATOR ) {
-	if (s.stack.count <= 1) {
+	printf("func\n");
+	if (s.stk.count <= 1) {
 	  fprintf(s.defout, "not enough arguments\n");
 	  continue;
 	}
 	char operator = buf[0];
 	if (operator == '+') {
-	  s.stack.val[s.stack.count-2] = s.stack.val[s.stack.count-1]+s.stack.val[s.stack.count-2];
-	  s.stack.val[s.stack.count--] = 0; /* lower count by 1 */
+	  s.stk.val[s.stk.count-2] = s.stk.val[s.stk.count-1]+s.stk.val[s.stk.count-2];
+	  s.stk.val[s.stk.count--] = 0; /* lower count by 1 */
 	  s.last_op = '+';
 	} else if (operator == '-') {
-	  s.stack.val[s.stack.count-2] = s.stack.val[s.stack.count-2]-s.stack.val[s.stack.count-1];
-	  s.stack.val[s.stack.count--] = 0; /* lower count by 1 */
+	  s.stk.val[s.stk.count-2] = s.stk.val[s.stk.count-2]-s.stk.val[s.stk.count-1];
+	  s.stk.val[s.stk.count--] = 0; /* lower count by 1 */
 	  s.last_op = '-';
 	} else if (operator == '*') {
-	  s.stack.val[s.stack.count-2] = s.stack.val[s.stack.count-2]*s.stack.val[s.stack.count-1];
-	  s.stack.val[s.stack.count--] = 0; /* lower count by 1 */
+	  s.stk.val[s.stk.count-2] = s.stk.val[s.stk.count-2]*s.stk.val[s.stk.count-1];
+	  s.stk.val[s.stk.count--] = 0; /* lower count by 1 */
 	  s.last_op = '*';
 	} else if (operator == '/') {
-	  s.stack.val[s.stack.count-2] = s.stack.val[s.stack.count-2]/s.stack.val[s.stack.count-1];
-	  s.stack.val[s.stack.count--] = 0; /* lower count by 1 */
+	  s.stk.val[s.stk.count-2] = s.stk.val[s.stk.count-2]/s.stk.val[s.stk.count-1];
+	  s.stk.val[s.stk.count--] = 0; /* lower count by 1 */
 	  s.last_op = '/';
-	}
+	} else;
       } else if (t == FUNCTION) {
 	if (strcmp(buf, "quit") == 0) {
 	  fprintf(s.defout, "quitting, bye!\n");
 	  exit(0);
-	} fprintf(s.defout, "unknown function %s\n", buf);
-	  continue;
+	} else exec(buf, &s);
       }
     } else { /* we found a number */
-      s.stack.val[s.stack.count++] = interpreted;
+      printf("number\n");
+      s.stk.val[s.stk.count++] = interpreted;
     }
     
     s.command_count++;
-    for (int i = 0; i < s.stack.count; i++) {
-      fprintf(s.defout,"%d → %f\n",i, s.stack.val[i]);
+    for (int i = 0; i < s.stk.count; i++) {
+      fprintf(s.defout,"%d → %f\n",i, s.stk.val[i]);
     }
   }
+  /* free stuff */
+  free (s.sorted);
 }
+
diff --git a/meson.build b/meson.build
index b5937fe..f04c60e 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('rpncalc', 'c')
-src = ['main.c', 'state.c', 'util.c']
+src = ['main.c', 'state.c', 'util.c', 'cmds.c']
 cc = meson.get_compiler('c')
 deps = cc.find_library('m', required : true)
 executable('rpncalc', src, dependencies : deps)
diff --git a/state.h b/state.h
index 54b2981..56e0f6d 100644
--- a/state.h
+++ b/state.h
@@ -22,12 +22,9 @@ typedef struct {
   FILE *defout;
   char last_op;
   char *prompt;
-  stack stack;
-
+  stack stk;
   /* btree elements */
-  
-  char **sorted_names; /* sorted function names */
-  stack *((*exec)(stack)); /* sorted function calls, same order as above */
+  command *sorted; /* sorted by function name */
 } state;
 
 #endif
diff --git a/util.c b/util.c
index 6b6cd37..1693593 100644
--- a/util.c
+++ b/util.c
@@ -10,12 +10,6 @@ const char OPERATOR_LIST[] = {
   0
 };
 
-const command COMMAND_LIST[] = {
-  {'c', "clear stack"},
-  {'p', "pop last element"},
-  {0, 0},
-};
-
 int is_operator(char *s) {
   for (int i = 0; OPERATOR_LIST[i] != 0; i++) {
     if (s[0] == OPERATOR_LIST[i]) return 1;
diff --git a/util.h b/util.h
index 97ad00e..c85d4f3 100644
--- a/util.h
+++ b/util.h
@@ -3,9 +3,4 @@
 
 typedef enum {OPERATOR, COMMAND ,DOUBLE, FUNCTION} TYPE;
 TYPE discriminate(char *s);
-typedef struct {
-  char n;
-  const char* desc;
-} command;
-  
 #endif