OSDN Git Service

Expression is a list-of-lists now.
authorSimon Forman <sforman@hushmail.com>
Sat, 4 Feb 2023 21:38:28 +0000 (13:38 -0800)
committerSimon Forman <sforman@hushmail.com>
Sat, 4 Feb 2023 21:38:28 +0000 (13:38 -0800)
That way we don't have to concatinate quotes onto it all the time.
Instead we amortize in the next_term() function.

implementations/C/joy.c
implementations/C/keywords.c

index 93e417e..d49ab2d 100644 (file)
@@ -334,6 +334,75 @@ pop_int(JoyListPtr stack) {
 
 
 JoyList
+pop_list(JoyListPtr stack)
+{
+       JoyList node;
+       node = pop_any(stack);
+       switch (node->head->kind) {
+       case joyList:
+               return node;
+       default:
+               printf("Not a list.\n");
+               exit(1);
+       }
+}
+
+
+JoyList
+pop_list_node(JoyListPtr stack)
+{
+       return pop_list(stack)->head->value.el;
+}
+
+
+void
+push_quote(JoyList el, JoyListPtr expression)
+{
+       JoyList node;
+
+       if (!el) return;
+       node = newJoyList;
+       node->head = newJoyType;
+       node->head->kind = joyList;
+       node->head->value.el = el;
+       node->tail = *expression;
+       *expression = node;
+}
+
+
+/*
+Return the next term from the expression and the new expression.
+
+(item, quote), expression = expression
+return item, push_quote(quote, expression)
+
+*/
+JoyTypePtr
+next_term(JoyListPtr expression)
+{
+       JoyList quote;
+       JoyTypePtr term;
+       if (!(*expression)) {
+               printf("Do not call next_term on an empty expression.\n");
+               exit(1);
+       }
+       quote = pop_list_node(expression);
+       if (!quote) {
+               printf("How did an empty list get onto the expression!?\n");
+               exit(1);
+       }
+       term = quote->head;
+       quote = quote->tail;
+       if (quote) {
+               push_quote(quote, expression);
+       }
+               print_list(*expression);
+               printf(" <--\n");
+       return term;
+}
+
+
+JoyList
 newIntNode(void) {
        JoyList node = newJoyList;
        node->head = newJoyType;
@@ -426,10 +495,13 @@ joy(JoyListPtr stack, JoyListPtr expression)
        char *sym;
        JoyTypePtr term;
        const struct dict_entry *interned;
+       JoyList e = EMPTY_LIST;
+       JoyListPtr ePtr = &e;
+       push_quote(*expression, ePtr);
+       expression = ePtr;
 
        while (*expression) {
-               term = (*expression)->head;
-               *expression = (*expression)->tail;
+               term = next_term(expression);
                switch (term->kind) {
                case joyInt:
                case joyTrue:
index 9e887aa..6a5626e 100644 (file)
@@ -1,6 +1,6 @@
 /* ANSI-C code produced by gperf version 3.1 */
 /* Command-line: gperf --output-file=keywords.c --readonly-tables --enum --includes --hash-function-name=keyword_hash KEYWORDS.txt  */
-/* Computed positions: -k'1-2' */
+/* Computed positions: -k'1' */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
       && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -35,7 +35,7 @@
 #line 7 "KEYWORDS.txt"
 struct dict_entry;
 #include <string.h>
-/* maximum key range = 22, duplicates = 0 */
+/* maximum key range = 16, duplicates = 0 */
 
 #ifdef __GNUC__
 __inline
@@ -49,45 +49,34 @@ keyword_hash (register const char *str, register size_t len)
 {
   static const unsigned char asso_values[] =
     {
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 15, 23, 23, 23,  2, 23, 23,
-      23, 23, 13,  3, 23, 14, 23,  9, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      10,  5,  0, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23,  5,  0,
-      23, 23, 23, 23, 23, 23, 23, 23,  0, 23,
-      23,  0, 23, 23,  5, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-      23, 23, 23, 23, 23, 23
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 14, 17, 17,
+      17, 17,  9, 15, 17, 10, 17,  0, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17,  0,  0,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+      17, 17, 17, 17, 17, 17
     };
-  register unsigned int hval = len;
-
-  switch (hval)
-    {
-      default:
-        hval += asso_values[(unsigned char)str[1]];
-      /*FALLTHROUGH*/
-      case 1:
-        hval += asso_values[(unsigned char)str[0]];
-        break;
-    }
-  return hval;
+  return len + asso_values[(unsigned char)str[0]];
 }
 
 const struct dict_entry *
@@ -95,50 +84,37 @@ in_word_set (register const char *str, register size_t len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 15,
+      TOTAL_KEYWORDS = 9,
       MIN_WORD_LENGTH = 1,
       MAX_WORD_LENGTH = 6,
       MIN_HASH_VALUE = 1,
-      MAX_HASH_VALUE = 22
+      MAX_HASH_VALUE = 16
     };
 
   static const struct dict_entry wordlist[] =
     {
       {""},
-#line 19 "KEYWORDS.txt"
-      {">", gt},
-      {""},
-#line 10 "KEYWORDS.txt"
-      {"%", mod},
-#line 12 "KEYWORDS.txt"
-      {"+", add},
-#line 23 "KEYWORDS.txt"
-      {"clear", clear},
-#line 18 "KEYWORDS.txt"
-      {"=", eq},
-#line 20 "KEYWORDS.txt"
-      {">=", ge},
+#line 13 "KEYWORDS.txt"
+      {"/", div_joyfunc},
       {""},
-#line 21 "KEYWORDS.txt"
-      {"bool", truthy},
+#line 17 "KEYWORDS.txt"
+      {"cmp", cmp_joyfunc},
 #line 14 "KEYWORDS.txt"
-      {"/", div_joyfunc},
+      {"bool", truthy},
+#line 16 "KEYWORDS.txt"
+      {"clear", clear},
 #line 15 "KEYWORDS.txt"
-      {"<", lt},
-#line 17 "KEYWORDS.txt"
-      {"<>", neq},
-      {""},
-#line 11 "KEYWORDS.txt"
+      {"branch", branch},
+      {""}, {""}, {""},
+#line 10 "KEYWORDS.txt"
       {"*", mul},
-#line 13 "KEYWORDS.txt"
+#line 12 "KEYWORDS.txt"
       {"-", sub},
-#line 22 "KEYWORDS.txt"
-      {"branch", branch},
-#line 16 "KEYWORDS.txt"
-      {"<=", le},
-      {""}, {""}, {""}, {""},
+      {""}, {""}, {""},
 #line 9 "KEYWORDS.txt"
-      {"!=", neq}
+      {"%", mod},
+#line 11 "KEYWORDS.txt"
+      {"+", add}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)