]> gitweb.ps.run Git - iftint/blobdiff - main3.c
update
[iftint] / main3.c
diff --git a/main3.c b/main3.c
index bec0d5c224f6a273a1dfbe6d08595780f6fe3edf..d6162a465451e8140e1f617b56c953de13ac8821 100644 (file)
--- a/main3.c
+++ b/main3.c
@@ -2,12 +2,15 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
+#include <assert.h>
 
 
 // Global defines
 
 #define STR_SIZE 128
 
 
 // Global defines
 
 #define STR_SIZE 128
-#define BUF_SIZE 1024*1024
+#define MEMORY_SIZE 1024*1024
+#define EDIT_QUEUE_SIZE 10
 
 // Memory
 
 
 // Memory
 
@@ -15,6 +18,8 @@ static char g_memory[1024*1024];
 static int g_memory_index = 0;
 
 void * alloc(int num, int size) {
 static int g_memory_index = 0;
 
 void * alloc(int num, int size) {
+    assert(g_memory_index + num*size < MEMORY_SIZE);
+
     void * result = g_memory + g_memory_index;
     for (int i = 0; i < num*size; i++)
         g_memory[g_memory_index+i] = 0;
     void * result = g_memory + g_memory_index;
     for (int i = 0; i < num*size; i++)
         g_memory[g_memory_index+i] = 0;
@@ -85,7 +90,7 @@ void vt100Escape(const char * str, ...) {
 
 void vt100ClearScreen() { vt100Escape("[2J"); }
 void vt100CursorHome() { vt100Escape("[H"); }
 
 void vt100ClearScreen() { vt100Escape("[2J"); }
 void vt100CursorHome() { vt100Escape("[H"); }
-void vt100CursorPos(int v, int h) { vt100Escape("[%d;%dH", v, h); }
+void vt100CursorPos(int v, int h) { vt100Escape("[%d;%df", v, h); }
 void vt100SaveCursor() { vt100Escape("7"); }
 void vt100RestoreCursor() { vt100Escape("8"); }
 void vt100EnableAlternateBuffer() { vt100Escape("[?1049h"); }
 void vt100SaveCursor() { vt100Escape("7"); }
 void vt100RestoreCursor() { vt100Escape("8"); }
 void vt100EnableAlternateBuffer() { vt100Escape("[?1049h"); }
@@ -103,8 +108,8 @@ void vt100GetScreenSize(int * v, int * h) {
 #else
     struct winsize w;
     ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
 #else
     struct winsize w;
     ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
-    *h = w.ws_row;
-    *v = w.ws_col;
+    *h = w.ws_col;
+    *v = w.ws_row;
 #endif
 }
 
 #endif
 }
 
@@ -156,14 +161,14 @@ struct Node {
     void * data;
 
     int childCount;
     void * data;
 
     int childCount;
-    Node *next, *prev, *parent, *child;
+    Node *next, *prev, *prnt, *chld;
 };
 
 Node *NodeGetChild(Node *n, unsigned int index) {
     if (index >= n->childCount)
         return NULL;
     
 };
 
 Node *NodeGetChild(Node *n, unsigned int index) {
     if (index >= n->childCount)
         return NULL;
     
-    Node *result = n->child;
+    Node *result = n->chld;
     for (int i = 0; i < index; i++)
         result = result->next;
     return result;
     for (int i = 0; i < index; i++)
         result = result->next;
     return result;
@@ -171,7 +176,7 @@ Node *NodeGetChild(Node *n, unsigned int index) {
 
 void NodeAppend(Node *n1, Node *n2) {
     if (n1->childCount == 0) {
 
 void NodeAppend(Node *n1, Node *n2) {
     if (n1->childCount == 0) {
-        n1->child = n2;
+        n1->chld = n2;
     }
     else {
         Node *lastChild = NodeGetChild(n1, n1->childCount-1);
     }
     else {
         Node *lastChild = NodeGetChild(n1, n1->childCount-1);
@@ -180,7 +185,7 @@ void NodeAppend(Node *n1, Node *n2) {
         n2->prev = lastChild;
         n2->next = NULL;
     }
         n2->prev = lastChild;
         n2->next = NULL;
     }
-    n2->parent = n1;
+    n2->prnt = n1;
     n1->childCount += 1;
 }
 
     n1->childCount += 1;
 }
 
@@ -213,10 +218,10 @@ Node *NodeRemove(Node *n1, Node *n2) {
     if (next != NULL)
         next->prev = prev;
     
     if (next != NULL)
         next->prev = prev;
     
-    n2->prev = n2->next = n2->parent = NULL;
+    n2->prev = n2->next = n2->prnt = NULL;
 
 
-    if (n2 == n1->child)
-        n1->child = next;
+    if (n2 == n1->chld)
+        n1->chld = next;
 
     n1->childCount -= 1;
     
 
     n1->childCount -= 1;
     
@@ -226,8 +231,63 @@ Node *NodeRemove(Node *n1, Node *n2) {
         return prev;
 }
 
         return prev;
 }
 
+void NodeDraw(Node *n);
 Node *g_NodeDrawSelected;
 
 Node *g_NodeDrawSelected;
 
+void Printf(Node *n, char* format, ...)
+{
+  va_list argp;
+  va_start(argp, format);
+  while (*format != '\0') {
+    if (*format == '%') {
+      format++;
+      if (*format == '%') {
+        putchar('%');
+      } else if (*format == 'n') {
+        Node *n = va_arg(argp, Node*);
+        NodeDraw(n);
+      } else if (*format == 's') {
+        char *s = va_arg(argp, char*);
+        printf("%s", s);
+        if (g_NodeDrawSelected == n && s == n->data)
+            printf("%c", ' ');
+      } else if (*format == ',' && format[1] == 'n') {
+        Node *n = va_arg(argp, Node*);
+        for (int i = 0; i < n->childCount; i++) {
+            if (i > 0) printf(", ");
+            NodeDraw(NodeGetChild(n, i));
+        }
+        format++;
+      } else if (*format == ';' && format[1] == 'n') {
+        Node *n = va_arg(argp, Node*);
+        for (int i = 0; i < n->childCount; i++) {
+            if (i == 0) printf("\n");
+            NodeDraw(NodeGetChild(n, i));
+            printf("\n");
+        }
+        format++;
+      } else {
+        fputs("Not implemented", stderr);
+      }
+    } else if (*format == '_') {
+        static bool highlighted = false;
+        // Node *n = va_arg(argp, Node*);
+        if (highlighted) {
+            vt100DisableNegative();
+            highlighted = false;
+        }
+        else if (g_NodeDrawSelected == n) {
+            vt100EnableNegative();
+            highlighted = true;
+        }
+    } else {
+      putchar(*format);
+    }
+    format++;
+  }
+  va_end(argp);
+}
+
 void NodeDraw(Node *n) {
     static int indent = 0;
     #define INDENT printf("\n"); for (int i = 0; i < indent; i++) printf("  ");
 void NodeDraw(Node *n) {
     static int indent = 0;
     #define INDENT printf("\n"); for (int i = 0; i < indent; i++) printf("  ");
@@ -235,22 +295,22 @@ void NodeDraw(Node *n) {
     #define PRINTF(...) do { if (n == g_NodeDrawSelected) vt100EnableNegative(); printf(__VA_ARGS__); vt100DisableNegative(); } while(0);
 
     switch (n->kind) {
     #define PRINTF(...) do { if (n == g_NodeDrawSelected) vt100EnableNegative(); printf(__VA_ARGS__); vt100DisableNegative(); } while(0);
 
     switch (n->kind) {
-    case NK_Namespace: { PRINTF("namespace"); printf(" %s {", n->data); indent++; for (int i = 0; i < n->childCount; i++) { INDENT NodeDraw(NodeGetChild(n, i)); } indent--; INDENT printf("}"); break; }
-    case NK_Struct:    { PRINTF("struct"); printf(" %s {", n->data); indent++; for (int i = 0; i < n->childCount; i++) { INDENT NodeDraw(NodeGetChild(n, i)); } indent--; INDENT printf("}"); break; }
-    case NK_Func:      { PRINTF("fn"); printf(" %s ", n->data); NodeDraw(NodeGetChild(n, 0)); NodeDraw(NodeGetChild(n, 1)); break; }
+    case NK_Namespace: { Printf(n, "_namespace %s {_%;n_}_\n", n->data, n); break; }
+    case NK_Struct:    { Printf(n, "_struct %s {_%;n_}_\n", n->data, n); break; }
+    case NK_Func:      { Printf(n, "_fn %s_ %n %n", n->data, NodeGetChild(n, 0), NodeGetChild(n, 1)); break; }
     case NK_VarList:
     case NK_VarList:
-    case NK_ExprList:  { PRINTF("("); for (int i = 0; i < n->childCount; i++) { if (i != 0) printf(", "); NodeDraw(NodeGetChild(n, i)); } PRINTF(")"); break; }
-    case NK_Var:       { PRINTF("[%s]", n->data); break; }
-    case NK_VarDecl:   { PRINTF("[%s : ", n->data); NodeDraw(NodeGetChild(n, 0)); printf("]"); break; }
+    case NK_ExprList:  { Printf(n, "_(_%,n_)_", n); break; }
+    case NK_Var:       { Printf(n, "_%s_", n->data); break; }
+    case NK_VarDecl:   { Printf(n, "_%s:_ %n", n->data, NodeGetChild(n, 0)); break; }
     case NK_VarType:
     case NK_VarType:
-    case NK_Type:      { PRINTF("%s", n->data); for (int i = 0; i < n->childCount; i++) { printf("%s", i == 0 ? "<" : ", "); NodeDraw(NodeGetChild(n, i)); if (i == n->childCount-1) printf(">"); } break; }
-    case NK_Body:      { PRINTF("{"); indent++; for (int i = 0; i < n->childCount; i++) { INDENT NodeDraw(NodeGetChild(n, i)); } indent--; INDENT PRINTF("}"); break; }
-    case NK_If:        { PRINTF("if"); printf(" "); NodeDraw(NodeGetChild(n, 0)); INDENT NodeDraw(NodeGetChild(n, 1)); break; }
-    case NK_While:     { PRINTF("while"); printf(" "); NodeDraw(NodeGetChild(n, 0)); INDENT NodeDraw(NodeGetChild(n, 1)); break; }
-    case NK_Num:       { PRINTF("%s", n->data); break; }
-    case NK_Str:       { PRINTF("'%s'", n->data); break; }
-    case NK_Call:      { PRINTF("!%s ", n->data); NodeDraw(NodeGetChild(n, 0)); break; }
-    case NK_Op:        { if (n->childCount <= 1) { PRINTF("%s", n->data); printf(" "); } for (int i = 0; i < n->childCount; i++) { if (i != 0) { printf(" "); PRINTF("%s", n->data); printf(" "); } NodeDraw(NodeGetChild(n, i)); } break; }
+    case NK_Type:      { Printf(n, "_%s%s%,n%s_", n->data, (n->childCount > 0 ? "<" : ""), n, (n->childCount > 0 ? ">" : "")); break; }
+    case NK_Body:      { Printf(n, "_{_%;n_}_", n); break; }
+    case NK_If:        { Printf(n, "_if_ %n %n", NodeGetChild(n, 0), NodeGetChild(n, 1)); break; }
+    case NK_While:     { Printf(n, "_while_ %n %n", NodeGetChild(n, 0), NodeGetChild(n, 1)); break; }
+    case NK_Num:       { Printf(n, "_%s_", n->data); break; }
+    case NK_Str:       { Printf(n, "_'%s'_", n->data); break; }
+    case NK_Call:      { Printf(n, "_%s_(%n)", n->data, NodeGetChild(n, 0)); break; }
+    case NK_Op:        { for (int i = 0; i < n->childCount; i++) { if (n->childCount == 0 || i != 0) { Printf(n, " _%s_ ", n->data); } NodeDraw(NodeGetChild(n, i)); } break; }
     }
 }
 
     }
 }
 
@@ -405,6 +465,9 @@ void DrawInfo(InputAction actions[NK_COUNT][IN_COUNT], NodeKind nk, InputMode mo
     int line = 2;
 
     vt100CursorPos(line++, h-30);
     int line = 2;
 
     vt100CursorPos(line++, h-30);
+    printf("%d:%d", v, h);
+    vt100CursorPos(line++, h-30);
+
     printf("%s:%s", NK_STRINGS[nk], (mode == IM_Normal ? "" : " (editing)"));
 
     for (int i = IN_L+1; i < IN_COUNT; i++) {
     printf("%s:%s", NK_STRINGS[nk], (mode == IM_Normal ? "" : " (editing)"));
 
     for (int i = IN_L+1; i < IN_COUNT; i++) {
@@ -416,10 +479,69 @@ void DrawInfo(InputAction actions[NK_COUNT][IN_COUNT], NodeKind nk, InputMode mo
     }
 }
 
     }
 }
 
+bool ValidChar(NodeKind nk, int c) {
+    const char *allow = NULL;
+    const char *block = NULL;
+    
+    switch (nk) {
+    case NK_Namespace:
+    case NK_Struct:
+    case NK_Func:
+    case NK_Var:
+    case NK_VarDecl:
+    case NK_VarType:
+    case NK_Type:
+    case NK_Str:
+    case NK_Call:
+    case NK_Op:
+        block = "";
+        break;
+       
+    case NK_Num:
+        allow = "+-.0123456789";
+        break;
+
+    case NK_VarList:
+    case NK_ExprList:
+    case NK_Body:
+    case NK_If:
+    case NK_While:
+        allow = "";
+        break;
+    }
+
+    if (allow != NULL) {
+        char a;
+        for (int i = 0; (a = allow[i]) != '\0'; i++) {
+            if (a == c) return true;
+        }
+        return false;
+    }
+    else if (block != NULL) {
+        char b;
+        for (int i = 0; (b = block[i]) != '\0'; i++) {
+            if (b == c) return false;
+        }
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+Node *PopEditQueue(Node ** q) {
+    Node *result = q[0];
+    for (int i = 0; i < EDIT_QUEUE_SIZE-1 && q[i] != NULL; i++) {
+        q[i] = q[i+1];
+    }
+    return result;
+}
+
 Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
     Node *result = NEW(Node); result->data = NEWSTR; result->kind = NK_Namespace;
 
     Node * n = result;
 Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
     Node *result = NEW(Node); result->data = NEWSTR; result->kind = NK_Namespace;
 
     Node * n = result;
+    Node * q[EDIT_QUEUE_SIZE] = {0};
 
     Input in;
     InputAction action;
 
     Input in;
     InputAction action;
@@ -443,9 +565,12 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
                 s[slen-1] = '\0';
             }
             else if (c == '\n' || c == '\r') {
                 s[slen-1] = '\0';
             }
             else if (c == '\n' || c == '\r') {
-                mode = IM_Normal;
+                if (q[0] == NULL)
+                    mode = IM_Normal;
+                else
+                    n = PopEditQueue(q);
             }
             }
-            else if (slen < STR_SIZE) {
+            else if (slen < STR_SIZE && ValidChar(n->kind, c)) {
                 s[slen++] = (char)c;
             }
         }
                 s[slen++] = (char)c;
             }
         }
@@ -461,30 +586,38 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
             #define S(NAME, PARENT, KIND) Node *NAME = NEW(Node); NAME->kind = KIND; NAME->data = NEWSTR; NodeAppend(PARENT, NAME);
 
             switch (action) {
             #define S(NAME, PARENT, KIND) Node *NAME = NEW(Node); NAME->kind = KIND; NAME->data = NEWSTR; NodeAppend(PARENT, NAME);
 
             switch (action) {
-            case IA_MoveLeft: { if (n->prev != NULL) n = n->prev; break; }
-            case IA_MoveDown: { if (n->child != NULL) n = n->child; break; }
-            case IA_MoveUp: { if (n->parent != NULL) n = n->parent; break; }
+            case IA_MoveLeft:  { if (n->prev != NULL) n = n->prev; break; }
+            case IA_MoveDown:  { if (n->chld != NULL) n = n->chld; break; }
+            case IA_MoveUp:    { if (n->prnt != NULL) n = n->prnt; break; }
             case IA_MoveRight: { if (n->next != NULL) n = n->next; break; }
             
             case IA_StartEditing: { mode = IM_Editing; break; }
             case IA_MoveRight: { if (n->next != NULL) n = n->next; break; }
             
             case IA_StartEditing: { mode = IM_Editing; break; }
-            case IA_Delete: { n = NodeRemove(n->parent, n); break; }
-
-            case IA_AddNamespace: { S(n1, n, NK_Namespace)                                            n = n1; mode = IM_Editing; break; }
-            case IA_AddStruct:    { S(n1, n, NK_Struct)                                               n = n1; mode = IM_Editing; break; }
-            case IA_AddFunc:      { S(n1, n, NK_Func)       N(n2, n1, NK_VarList)  N(n3, n1, NK_Body) n = n1; mode = IM_Editing; break; }
-            case IA_AddVar:       { S(n1, n, NK_Var)                                                  n = n1; mode = IM_Editing; break; }
-            case IA_AddVarDecl:   { S(n1, n, NK_VarDecl)    S(n2, n1, NK_VarType)                     n = n1; mode = IM_Editing; break; }
-            case IA_AddType:      { S(n1, n, NK_Type)                                                 n = n1; mode = IM_Editing; break; }
-            case IA_AddIf:        { N(n1, n, NK_If)         N(n2, n1, NK_ExprList) N(n3, n1, NK_Body) n = n2;                    break; }
-            case IA_AddWhile:     { N(n1, n, NK_While)      N(n2, n1, NK_ExprList) N(n3, n1, NK_Body) n = n2;                    break; }
-            case IA_AddNum:       { S(n1, n, NK_Num)                                                  n = n1; mode = IM_Editing; break; }
-            case IA_AddStr:       { S(n1, n, NK_Str)                                                  n = n1; mode = IM_Editing; break; }
-            case IA_AddCall:      { S(n1, n, NK_Call)       N(n2, n1, NK_ExprList)                    n = n1; mode = IM_Editing; break; }
-            case IA_AddOp:        { S(n1, n, NK_Op)                                                   n = n1; mode = IM_Editing; break; }
+            case IA_Delete:       { n = NodeRemove(n->prnt, n); break; }
+
+            case IA_AddNamespace: { S(n1, n, NK_Namespace) n=n1;    mode=IM_Editing; break; }
+            case IA_AddStruct:    { S(n1, n, NK_Struct)    n=n1;    mode=IM_Editing; break; }
+            case IA_AddFunc:      { S(n1, n, NK_Func)
+                                    N(n2, n1, NK_VarList)
+                                    N(n3, n1, NK_Body)     n=n1;    mode=IM_Editing; break; }
+            case IA_AddVar:       { S(n1, n, NK_Var)       n=n1;    mode=IM_Editing; break; }
+            case IA_AddVarDecl:   { S(n1, n, NK_VarDecl)   n=n1;
+                                    S(n2, n1, NK_VarType)  q[0]=n2; mode=IM_Editing; break; }
+            case IA_AddType:      { S(n1, n, NK_Type)      n=n1;    mode=IM_Editing; break; }
+            case IA_AddIf:        { N(n1, n, NK_If)
+                                    N(n2, n1, NK_ExprList)
+                                    N(n3, n1, NK_Body)     n=n2;                     break; }
+            case IA_AddWhile:     { N(n1, n, NK_While)
+                                    N(n2, n1, NK_ExprList)
+                                    N(n3, n1, NK_Body)     n=n2;                     break; }
+            case IA_AddNum:       { S(n1, n, NK_Num)       n=n1;    mode=IM_Editing; break; }
+            case IA_AddStr:       { S(n1, n, NK_Str)       n=n1;    mode=IM_Editing; break; }
+            case IA_AddCall:      { S(n1, n, NK_Call)
+                                    N(n2, n1, NK_ExprList) n=n1;    mode=IM_Editing; break; }
+            case IA_AddOp:        { S(n1, n, NK_Op)        n=n1;    mode=IM_Editing; break; }
             }
 
             }
 
-            #undef NA
-            #undef NS
+            #undef N
+            #undef S
         }
     }
 
         }
     }
 
@@ -495,8 +628,8 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
 void SetupInputActions(InputAction actions[NK_COUNT][IN_COUNT]) {
     for (int i = 0; i < NK_COUNT; i++) {
         actions[i][IN_H] = IA_MoveLeft;
 void SetupInputActions(InputAction actions[NK_COUNT][IN_COUNT]) {
     for (int i = 0; i < NK_COUNT; i++) {
         actions[i][IN_H] = IA_MoveLeft;
-        actions[i][IN_J] = IA_MoveUp;
-        actions[i][IN_K] = IA_MoveDown;
+        actions[i][IN_J] = IA_MoveDown;
+        actions[i][IN_K] = IA_MoveUp;
         actions[i][IN_L] = IA_MoveRight;
     }
 
         actions[i][IN_L] = IA_MoveRight;
     }
 
@@ -585,6 +718,7 @@ int main() {
     vt100ShowCursor();
 
     NodeDraw(n);
     vt100ShowCursor();
 
     NodeDraw(n);
+    printf("\n");
 
     return 0;
 }
 
     return 0;
 }