about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--cmds.c30
-rw-r--r--cmds.h8
-rw-r--r--main.c64
-rw-r--r--meson.build4
-rw-r--r--state.h10
-rw-r--r--util.c16
-rw-r--r--util.h8
8 files changed, 107 insertions, 37 deletions
diff --git a/.gitignore b/.gitignore
index c0df46a..b3c7d45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,4 +48,6 @@ flycheck_*.el
 # network security
 /network-security.data
 
-
+# meson build files
+build/
+.cache/
diff --git a/cmds.c b/cmds.c
new file mode 100644
index 0000000..0148c7b
--- /dev/null
+++ b/cmds.c
@@ -0,0 +1,30 @@
+#include "state.h"
+#include "cmds.h"
+#include <err.h>
+#include <math.h>
+#include <stdlib.h>
+#include <err.h>
+
+stack fceil(stack stack) {
+  stack.val[stack.count-1] = ceil(stack.val[stack.count-1]);
+  return stack;
+}
+
+stack ffloor(stack stack) {
+  stack.val[stack.count-1] = floor(stack.val[stack.count-1]);
+  return stack;
+}
+
+command CMD_LIST[] = {
+  {"ceil", &fceil, "truncate to the next integer"},
+  {"floor", &ffloor, "truncate to the previous integer"},
+  {0, 0, 0}
+};
+
+void initstate(state *s) {
+  int numel = 0;
+  for (int i = 0; CMD_LIST[i].name != 0; i++) numel = i;
+  char *sorted = malloc(sizeof(char *)*numel);
+  if (sorted == NULL) err(1, "could not allocate function names");
+  /* todo: (merge, heap, quick) sort? */
+}
diff --git a/cmds.h b/cmds.h
new file mode 100644
index 0000000..ba54fac
--- /dev/null
+++ b/cmds.h
@@ -0,0 +1,8 @@
+#ifndef CMDS_H
+#define CMDS_H
+
+#include "state.h"
+
+extern command CMD_LIST[];
+
+#endif
diff --git a/main.c b/main.c
index f72d7aa..2522e07 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,9 @@
+#include <math.h>
 #include <stdio.h>
 #include "state.h"
 #include "util.h"
 #include <stdlib.h>
+#include <string.h>
 #include <err.h>
 
 #define BUF_SIZE 50
@@ -28,35 +30,47 @@ int main() {
   while(1){
     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");
     fgets(buf, BUF_SIZE, s.defbuf);
-    TYPE t = discriminate(buf);
-    if (t == OPERATOR ) {
-      if (s.stack.count == 1) {
-	fprintf(s.defout, "not enough arguments\n");
-	continue;
+    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) {
+	  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.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.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.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.last_op = '/';
+	}
+      } 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;
       }
-      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.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.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.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.last_op = '/';
-      }
-    } else {
-      s.stack.val[s.stack.count++]=strtod(buf, NULL);
+    } else { /* we found a number */
+      s.stack.val[s.stack.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]);
diff --git a/meson.build b/meson.build
index e6012bf..b5937fe 100644
--- a/meson.build
+++ b/meson.build
@@ -1,3 +1,5 @@
 project('rpncalc', 'c')
 src = ['main.c', 'state.c', 'util.c']
-executable('rpncalc', src)
+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 8a9b2d5..54b2981 100644
--- a/state.h
+++ b/state.h
@@ -11,13 +11,23 @@ typedef struct {
 } stack;
 
 typedef struct {
+  char *name;
+  stack (*exec)(stack);
+  char *description;
+} command;
+
+typedef struct {
   int command_count;
   FILE *defbuf;
   FILE *defout;
   char last_op;
   char *prompt;
   stack stack;
+
+  /* btree elements */
   
+  char **sorted_names; /* sorted function names */
+  stack *((*exec)(stack)); /* sorted function calls, same order as above */
 } state;
 
 #endif
diff --git a/util.c b/util.c
index c4dd940..6b6cd37 100644
--- a/util.c
+++ b/util.c
@@ -1,7 +1,8 @@
 #include "util.h"
 #include <math.h>
+#include <string.h>
 
-char OPERATOR_LIST[] = {
+const char OPERATOR_LIST[] = {
   '+',
   '-',
   '*',
@@ -9,12 +10,11 @@ char OPERATOR_LIST[] = {
   0
 };
 
-int is_decimal(char *s) {
-  for (int i = 0; s[i] != 0; i++) {
-    if (s[i] == ',' || s[i] == '.') return 1;
-  }
-  return 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++) {
@@ -26,5 +26,5 @@ int is_operator(char *s) {
 TYPE discriminate(char *s) {
   if (is_operator(s)) {
     return OPERATOR;
-  } else return DOUBLE;
+  } else return FUNCTION;
 }
diff --git a/util.h b/util.h
index 5f948d9..97ad00e 100644
--- a/util.h
+++ b/util.h
@@ -1,7 +1,11 @@
 #ifndef UTIL_H
 #define UTIL_H
 
-typedef enum {OPERATOR, DOUBLE, FUNCTION} TYPE;
+typedef enum {OPERATOR, COMMAND ,DOUBLE, FUNCTION} TYPE;
 TYPE discriminate(char *s);
-
+typedef struct {
+  char n;
+  const char* desc;
+} command;
+  
 #endif