]> gitweb.ps.run Git - iftint/blobdiff - main3.c
space in func dexl
[iftint] / main3.c
diff --git a/main3.c b/main3.c
index b7f13443ff858d0faccd9bc955f5a57a15f584d4..c3da7f67baebf922971c597e729ee1bb8537d975 100644 (file)
--- a/main3.c
+++ b/main3.c
@@ -1,6 +1,8 @@
-#include<stdint.h>
-#include<stdbool.h>
-#include<stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdarg.h>
+
 
 // Global defines
 
@@ -22,6 +24,7 @@ void * alloc(int num, int size) {
 
 #define NEW(TYPE) ((TYPE *)alloc(1, sizeof(TYPE)))
 #define NEWARR(TYPE, NUM) ((TYPE *)alloc(NUM, sizeof(TYPE)))
+#define NEWSTR NEWARR(char, STR_SIZE)
 
 // getch
 
@@ -82,7 +85,7 @@ void vt100Escape(const char * str, ...) {
 
 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"); }
@@ -107,14 +110,46 @@ void vt100GetScreenSize(int * v, int * h) {
 
 // Node
 
-typedef enum {
-    NK_Nul,
-    NK_Arr,
+typedef enum NodeKind {
+    NK_Namespace,
+    NK_Struct,
+    NK_Func,
+    NK_VarList,
+    NK_ExprList,
+    NK_Var,
+    NK_VarDecl,
+    NK_VarType,
+    NK_Type,
+    NK_Body,
+    NK_If,
+    NK_While,
+    NK_Num,
     NK_Str,
+    NK_Call,
+    NK_Op,
 
     NK_COUNT
 } NodeKind;
 
+const char *NK_STRINGS[NK_COUNT] = {
+    "NK_Namespace",
+    "NK_Struct",
+    "NK_Func",
+    "NK_VarList",
+    "NK_ExprList",
+    "NK_Var",
+    "NK_VarDecl",
+    "NK_VarType",
+    "NK_Type",
+    "NK_Body",
+    "NK_If",
+    "NK_While",
+    "NK_Num",
+    "NK_Str",
+    "NK_Call",
+    "NK_Op",
+};
+
 typedef struct Node Node;
 struct Node {
     NodeKind kind;
@@ -191,20 +226,32 @@ Node *NodeRemove(Node *n1, Node *n2) {
         return prev;
 }
 
-void NodeDraw(Node *n, Node *selected) {
+Node *g_NodeDrawSelected;
+
+void NodeDraw(Node *n) {
     static int indent = 0;
-    for (int i = 0; i < indent; i++)
-        printf("  ");
-    
-    if (n == selected) vt100EnableNegative();
+    #define INDENT printf("\n"); for (int i = 0; i < indent; i++) printf("  ");
     
+    #define PRINTF(...) do { if (n == g_NodeDrawSelected) vt100EnableNegative(); printf(__VA_ARGS__); vt100DisableNegative(); } while(0);
+
     switch (n->kind) {
-    case NK_Nul: printf("null\n"); break;
-    case NK_Arr: printf("(%d) [\n", n->childCount); for (int i = 0; i < n->childCount; i++) NodeDraw(NodeGetChild(n, i), selected); printf("]\n"); break;
-    case NK_Str: printf("'%.16s'\n", (char *)n->data); break;
+    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)); printf(" "); NodeDraw(NodeGetChild(n, 1)); break; }
+    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_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; }
     }
-
-    if (n == selected) vt100DisableNegative();
 }
 
 // Input
@@ -216,38 +263,78 @@ void NodeDraw(Node *n, Node *selected) {
 typedef enum Input {
     IN_None,
 
-    IN_A,
-    IN_S,
-    IN_D,
-
     IN_H,
     IN_J,
     IN_K,
     IN_L,
 
     IN_SPACE,
+    IN_D,
+    IN_A,
+
+    IN_F,
+    IN_V,
+    IN_T,
+    IN_I,
+    IN_W,
+    IN_N,
+    IN_S,
+    IN_C,
+    IN_O,
 
     IN_Quit,
 
     IN_COUNT
 } Input;
 
+const char *IN_STRINGS[IN_COUNT] = {
+    "IN_None",
+
+    "IN_H",
+    "IN_J",
+    "IN_K",
+    "IN_L",
+
+    "IN_SPACE",
+    "IN_D",
+    "IN_A",
+
+    "IN_F",
+    "IN_V",
+    "IN_T",
+    "IN_I",
+    "IN_W",
+    "IN_N",
+    "IN_S",
+    "IN_C",
+    "IN_O",
+
+    "IN_Quit",
+};
+
 Input InputGet() {
     int c;
 
     while (true) {
         c = getch();
         switch (c) {
-            case 'a': return IN_A;
-            case 's': return IN_S;
-            case 'd': return IN_D;
-            
             case 'h': return IN_H;
             case 'j': return IN_J;
             case 'k': return IN_K;
             case 'l': return IN_L;
 
             case ' ': return IN_SPACE;
+            case 'd': return IN_D;
+            
+            case 'f': return IN_F;
+            case 'v': return IN_V;
+            case 't': return IN_T;
+            case 'i': return IN_I;
+            case 'w': return IN_W;
+            case 'n': return IN_N;
+            case 's': return IN_S;
+            case 'c': return IN_C;
+            case 'o': return IN_O;
 
             case 'q': return IN_Quit;
         }
@@ -256,39 +343,98 @@ Input InputGet() {
 
 typedef enum InputAction {
     IA_None,
-    IA_AppendArray,
-    IA_AppendString,
-    IA_StartEditing,
-    IA_Delete,
 
     IA_MoveLeft,
-    IA_MoveDown,
     IA_MoveUp,
+    IA_MoveDown,
     IA_MoveRight,
 
+    IA_StartEditing,
+    IA_Delete,
+
+    IA_AddNamespace,
+    IA_AddStruct,
+    IA_AddFunc,
+    IA_AddVar,
+    IA_AddVarDecl,
+    IA_AddType,
+    IA_AddIf,
+    IA_AddWhile,
+    IA_AddNum,
+    IA_AddStr,
+    IA_AddCall,
+    IA_AddOp,
+
     IA_COUNT
 } InputAction;
 
+const char *IA_STRINGS[IA_COUNT] = {
+    "IA_None",
+
+    "IA_MoveLeft",
+    "IA_MoveUp",
+    "IA_MoveDown",
+    "IA_MoveRight",
+
+    "IA_StartEditing",
+    "IA_Delete",
+
+    "IA_AddNamespace",
+    "IA_AddStruct",
+    "IA_AddFunc",
+    "IA_AddVar",
+    "IA_AddVarDecl",
+    "IA_AddType",
+    "IA_AddIf",
+    "IA_AddWhile",
+    "IA_AddNum",
+    "IA_AddStr",
+    "IA_AddCall",
+    "IA_AddOp",
+};
+
+typedef enum InputMode {
+    IM_Normal,
+    IM_Editing,
+} InputMode;
+
+void DrawInfo(InputAction actions[NK_COUNT][IN_COUNT], NodeKind nk, InputMode mode) {
+    int v, h;
+    vt100GetScreenSize(&v, &h);
+
+    int line = 2;
+
+    vt100CursorPos(line++, h-10);
+    printf("%s:%s", NK_STRINGS[nk], (mode == IM_Normal ? "" : " (editing)"));
+
+    for (int i = IN_L+1; i < IN_COUNT; i++) {
+        InputAction action = actions[nk][i];
+        if (action != IA_None) {
+            vt100CursorPos(line++, h-10);
+            printf("%s %s", IN_STRINGS[i], IA_STRINGS[action]);
+        }
+    }
+}
+
 Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
-    Node * result = NEW(Node);
-    result->kind = NK_Arr;
+    Node *result = NEW(Node); result->data = NEWSTR; result->kind = NK_Namespace;
 
     Node * n = result;
 
     Input in;
     InputAction action;
 
-    enum {
-        Mode_Normal,
-        Mode_Editing,
-    } mode = Mode_Normal;
+    InputMode mode = IM_Normal;
 
     while (true) {
         vt100ClearScreen();
         vt100CursorHome();
-        NodeDraw(result, n);
+        g_NodeDrawSelected = n;
+        NodeDraw(result);
+        g_NodeDrawSelected = NULL;
+        DrawInfo(actions, n->kind, mode);
 
-        if (mode == Mode_Editing) {
+        if (mode == IM_Editing) {
             int c = getch();
             char *s = (char*)n->data;
             int slen = strlen(s);
@@ -296,14 +442,14 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
             if (c == KEY_BACKSPACE1 || c == KEY_BACKSPACE2) {
                 s[slen-1] = '\0';
             }
-            else if (c == 13) {
-                mode = Mode_Normal;
+            else if (c == '\n' || c == '\r') {
+                mode = IM_Normal;
             }
             else if (slen < STR_SIZE) {
                 s[slen++] = (char)c;
             }
         }
-        else if (mode == Mode_Normal) {
+        else if (mode == IM_Normal) {
             in = InputGet();
 
             if (in == IN_Quit)
@@ -311,21 +457,34 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
 
             action = actions[n->kind][in];
 
-            #define NODE_APPEND(KIND, DATA) Node *newNode = NEW(Node); newNode->kind = KIND; newNode->data = DATA; NodeAppend(n, newNode); n = newNode;
+            #define N(NAME, PARENT, KIND) Node *NAME = NEW(Node); NAME->kind = KIND; NodeAppend(PARENT, NAME);
+            #define S(NAME, PARENT, KIND) Node *NAME = NEW(Node); NAME->kind = KIND; NAME->data = NEWSTR; NodeAppend(PARENT, NAME);
 
             switch (action) {
-            case IA_AppendArray: { NODE_APPEND(NK_Arr, 0); break; }
-            case IA_AppendString: { NODE_APPEND(NK_Str, NEWARR(char, STR_SIZE)); mode = Mode_Editing; break; }
-            case IA_StartEditing: { mode = Mode_Editing; break; }
-            case IA_Delete: { n = NodeRemove(n->parent, n); break; }
-
             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_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; }
             }
 
-            #undef NODE_APPEND
+            #undef NA
+            #undef NS
         }
     }
 
@@ -333,24 +492,88 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) {
 }
 
 
-int main() {
-    // Setup
-    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;
+        actions[i][IN_J] = IA_MoveUp;
+        actions[i][IN_K] = IA_MoveDown;
+        actions[i][IN_L] = IA_MoveRight;
+    }
 
-    actions[NK_Arr][IN_A] = IA_AppendArray;
-    actions[NK_Arr][IN_S] = IA_AppendString;
-    actions[NK_Arr][IN_D] = IA_Delete;
-    actions[NK_Arr][IN_H] = IA_MoveLeft;
-    actions[NK_Arr][IN_J] = IA_MoveDown;
-    actions[NK_Arr][IN_K] = IA_MoveUp;
-    actions[NK_Arr][IN_L] = IA_MoveRight;
+    actions[NK_Namespace][IN_D] = IA_Delete;
+    actions[NK_Namespace][IN_SPACE] = IA_StartEditing;
+    actions[NK_Namespace][IN_N] = IA_AddNamespace;
+    actions[NK_Namespace][IN_S] = IA_AddStruct;
+    actions[NK_Namespace][IN_F] = IA_AddFunc;
+    
+    actions[NK_Struct][IN_D] = IA_Delete;
+    actions[NK_Struct][IN_SPACE] = IA_StartEditing;
+    actions[NK_Struct][IN_V] = IA_AddVarDecl;
+    actions[NK_Struct][IN_F] = IA_AddFunc;
+
+    actions[NK_Func][IN_D] = IA_Delete;
+    actions[NK_Func][IN_SPACE] = IA_StartEditing;
+
+    actions[NK_VarList][IN_V] = IA_AddVarDecl;
+    
+    actions[NK_ExprList][IN_V] = IA_AddVar;
+    actions[NK_ExprList][IN_I] = IA_AddIf;
+    actions[NK_ExprList][IN_W] = IA_AddWhile;
+    actions[NK_ExprList][IN_N] = IA_AddNum;
+    actions[NK_ExprList][IN_S] = IA_AddStr;
+    actions[NK_ExprList][IN_C] = IA_AddCall;
+    actions[NK_ExprList][IN_O] = IA_AddOp;
+
+    actions[NK_Var][IN_D] = IA_Delete;
+    actions[NK_Var][IN_SPACE] = IA_StartEditing;
+
+    actions[NK_VarDecl][IN_D] = IA_Delete;
+    actions[NK_VarDecl][IN_SPACE] = IA_StartEditing;
+
+    actions[NK_VarType][IN_SPACE] = IA_StartEditing;
+    actions[NK_VarType][IN_T] = IA_AddType;
+
+    actions[NK_Type][IN_D] = IA_Delete;
+    actions[NK_Type][IN_SPACE] = IA_StartEditing;
+    actions[NK_Type][IN_T] = IA_AddType;
+
+    actions[NK_Body][IN_F] = IA_AddFunc;
+    actions[NK_Body][IN_V] = IA_AddVarDecl;
+    actions[NK_Body][IN_I] = IA_AddIf;
+    actions[NK_Body][IN_W] = IA_AddWhile;
+    actions[NK_Body][IN_N] = IA_AddNum;
+    actions[NK_Body][IN_S] = IA_AddStr;
+    actions[NK_Body][IN_C] = IA_AddCall;
+    actions[NK_Body][IN_O] = IA_AddOp;
+
+    actions[NK_If][IN_D] = IA_Delete;
+
+    actions[NK_While][IN_D] = IA_Delete;
+
+    actions[NK_Num][IN_D] = IA_Delete;
+    actions[NK_Num][IN_SPACE] = IA_StartEditing;
 
-    actions[NK_Str][IN_SPACE] = IA_StartEditing;
     actions[NK_Str][IN_D] = IA_Delete;
-    actions[NK_Str][IN_H] = IA_MoveLeft;
-    actions[NK_Str][IN_J] = IA_MoveDown;
-    actions[NK_Str][IN_K] = IA_MoveUp;
-    actions[NK_Str][IN_L] = IA_MoveRight;
+    actions[NK_Str][IN_SPACE] = IA_StartEditing;
+
+    actions[NK_Call][IN_D] = IA_Delete;
+    actions[NK_Call][IN_SPACE] = IA_StartEditing;
+
+    actions[NK_Op][IN_D] = IA_Delete;
+    actions[NK_Op][IN_SPACE] = IA_StartEditing;
+    actions[NK_Op][IN_V] = IA_AddVar;
+    actions[NK_Op][IN_I] = IA_AddIf;
+    actions[NK_Op][IN_W] = IA_AddWhile;
+    actions[NK_Op][IN_N] = IA_AddNum;
+    actions[NK_Op][IN_S] = IA_AddStr;
+    actions[NK_Op][IN_C] = IA_AddCall;
+    actions[NK_Op][IN_O] = IA_AddOp;
+}
+
+int main() {
+    // Setup
+    static InputAction actions[NK_COUNT][IN_COUNT];
+    SetupInputActions(actions);
 
     // Main
     vt100EnableAlternateBuffer();
@@ -361,11 +584,8 @@ int main() {
     vt100DisableAlternateBuffer();
     vt100ShowCursor();
 
-    int v, h;
-    vt100GetScreenSize(&v, &h);
-    printf("Screen Size: %d | %d\n", v, h);
-
-    NodeDraw(n, NULL);
+    NodeDraw(n);
+    printf("\n");
 
     return 0;
 }