From: Patrick Date: Sun, 24 Sep 2023 00:13:16 +0000 (+0200) Subject: proof of concept X-Git-Url: https://gitweb.ps.run/iftint/commitdiff_plain/3f196f89f7864f818cfc782b0db81c639156aa84 proof of concept --- diff --git a/main2.c b/main2.c index aeb0c55..c8b9023 100644 --- a/main2.c +++ b/main2.c @@ -139,6 +139,7 @@ typedef enum { JSONNodeKind_Int, JSONNodeKind_Str, JSONNodeKind_Obj, + JSONNodeKind_Key, JSONNodeKind_Arr, JSONNodeKind_COUNT } JSONNodeKind; @@ -244,7 +245,6 @@ JSONNodePrint(JSONNode * node, JSONNode * currNode) { while (ptr != NULL) { Indent(indent); JSONNodePrint(ptr, currNode); - printf(": "); JSONNodePrint(ptr->firstChild, currNode); if (ptr->next != NULL) printf(","); @@ -256,6 +256,11 @@ JSONNodePrint(JSONNode * node, JSONNode * currNode) { printf("}"); break; } + case JSONNodeKind_Key: { + char * str = (char *)node->data; + printf("\"%s\": ", str == NULL ? "" : str); + break; + } case JSONNodeKind_Arr: { printf("[\n"); JSONNode * ptr = node->firstChild; @@ -312,102 +317,126 @@ typedef bool(*CharPredicateFunc)(char, int); bool predStr(char c, int i) { return c >= 'a' && c <= 'z'; } bool predInt(char c, int i) { return c >= '0' && c <= '9'; } +void +GetInput(JSONNode * node, char c) { + if (node->data == (size_t)NULL) { + node->data = (size_t)NEWARR(char, 16); + } + + char * str = (char *)node->data; + int strLen = strlen(str); + + if (isBackspace(c)) { + str[strLen-1] = '\0'; + } + else if (strLen < 16 - 1) { + str[strLen] = c; + str[strLen+1] = '\0'; + } +} + JSONNode * GetNode() { JSONNode * result = NULL; JSONNode * node = NULL; int c; - int strLen = 0; bool editingNode = false; while (true) { - c = GetChar(); + Draw(); + c = getch(); if (c == KEY_CTRL_C) break; - /* - - - editing - - primitive -> input - - obj/arr -> new node inside - - not editing - - hjkl -> movement - - isoa - - parent=obj -> new key/value node after - - parent=arr -> new node after - - else -> nothing - */ - - if (isNewline(c)) { + if (node == NULL) { + /**/ if (c == 'i') { node = JSONNodeNew(JSONNodeKind_Int); editingNode = true; } + else if (c == 's') { node = JSONNodeNew(JSONNodeKind_Str); editingNode = true; } + else if (c == 'o') { node = JSONNodeNew(JSONNodeKind_Obj); editingNode = true; } + else if (c == 'a') { node = JSONNodeNew(JSONNodeKind_Arr); editingNode = true; } + g_DrawNode = g_CurrNode = result = node; + } + else if (node->kind ==JSONNodeKind_Int) { if (editingNode) { - editingNode = false; - if (node->parent != NULL && node->parent->kind == JSONNodeKind_Obj && node->firstChild != NULL) { - node = node->firstChild; - editingNode = true; - } - else if (node->parent != NULL && node->parent->kind == JSONNodeKind_Str && node->parent->parent != NULL) { - node = node->parent->parent; - editingNode = true; - } + GetInput(node, c); } else { - if (node->parent != NULL) - node = node->parent; + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } + + g_CurrNode = node; } + } + else if (node->kind ==JSONNodeKind_Str) { + if (editingNode) { + GetInput(node, c); + } + else { + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } - g_CurrNode = node; - - continue; + g_CurrNode = node; + } } + else if (node->kind ==JSONNodeKind_Obj) { + if (editingNode) { + GetInput(node, c); + } + else { + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } - if (editingNode) { - if (JSONNodeEditable(node)) { - if (node->data == (size_t)NULL) { - node->data = (size_t)NEWARR(char, 16); - strLen = 0; - } - - char * str = (char *)node->data; - - if (isBackspace(c)) { - str[strLen-1] = '\0'; - strLen--; - } - else if (strLen < 16 - 1) { - str[strLen] = c; - str[strLen+1] = '\0'; - strLen++; - } + g_CurrNode = node; + } + } + else if (node->kind ==JSONNodeKind_Key) { + if (editingNode) { + GetInput(node, c); } else { - if (node->kind == JSONNodeKind_Obj) { - /**/ if (c == 'i') { node = JSONNodePush(node, JSONNodePush(JSONNodeNew(JSONNodeKind_Str), JSONNodeNew(JSONNodeKind_Int))->parent); } - else if (c == 's') { node = JSONNodePush(node, JSONNodePush(JSONNodeNew(JSONNodeKind_Str), JSONNodeNew(JSONNodeKind_Str))->parent); } - else if (c == 'o') { node = JSONNodePush(node, JSONNodePush(JSONNodeNew(JSONNodeKind_Str), JSONNodeNew(JSONNodeKind_Obj))->parent); } - else if (c == 'a') { node = JSONNodePush(node, JSONNodePush(JSONNodeNew(JSONNodeKind_Str), JSONNodeNew(JSONNodeKind_Arr))->parent); } - } - else if (node->kind == JSONNodeKind_Arr) { - /**/ if (c == 'i') { node = JSONNodePush(node, JSONNodeNew(JSONNodeKind_Int)); } - else if (c == 's') { node = JSONNodePush(node, JSONNodeNew(JSONNodeKind_Str)); } - else if (c == 'o') { node = JSONNodePush(node, JSONNodeNew(JSONNodeKind_Obj)); } - else if (c == 'a') { node = JSONNodePush(node, JSONNodeNew(JSONNodeKind_Arr)); } - } + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } + g_CurrNode = node; } } - else { - if (node == NULL) { - /**/ if (c == 'i') { node = JSONNodeNew(JSONNodeKind_Int); editingNode = true; } - else if (c == 's') { node = JSONNodeNew(JSONNodeKind_Str); editingNode = true; } - else if (c == 'o') { node = JSONNodeNew(JSONNodeKind_Obj); editingNode = true; } - else if (c == 'a') { node = JSONNodeNew(JSONNodeKind_Arr); editingNode = true; } - g_DrawNode = g_CurrNode = result = node; + else if (node->kind ==JSONNodeKind_Arr) { + if (editingNode) { + GetInput(node, c); } - // else if (node->kind == JSONNodeKind_Str && node->parent != NULL && node->parent->kind == JSONNodeKind_Obj) { - - // } else { /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } @@ -417,7 +446,7 @@ GetNode() { else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } - else if (c == ' ') { editingNode = true; if (JSONNodeEditable(node) && (void *)node->data != NULL) strLen = strlen((char *)node->data); } + else if (c == ' ') { editingNode = true; } else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } g_CurrNode = node; diff --git a/main3.c b/main3.c index b7f1344..4209d9c 100644 --- a/main3.c +++ b/main3.c @@ -107,14 +107,34 @@ void vt100GetScreenSize(int * v, int * h) { // Node -typedef enum { - NK_Nul, - NK_Arr, +typedef enum NodeKind { + NK_Func, + NK_ArgList, + NK_ExprList, + NK_Var, + NK_Body, + NK_If, + NK_Num, NK_Str, + NK_Call, + NK_Op, NK_COUNT } NodeKind; +const char *NK_STRINGS[NK_COUNT] = { + "NK_Func", + "NK_ArgList", + "NK_ExprList", + "NK_Var", + "NK_Body", + "NK_If", + "NK_Num", + "NK_Str", + "NK_Call", + "NK_Op", +}; + typedef struct Node Node; struct Node { NodeKind kind; @@ -193,18 +213,25 @@ Node *NodeRemove(Node *n1, Node *n2) { void NodeDraw(Node *n, Node *selected) { static int indent = 0; - for (int i = 0; i < indent; i++) - printf(" "); + #define INDENT for (int i = 0; i < indent; i++) printf(" "); + vt100DisableNegative(); if (n == selected) vt100EnableNegative(); 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_Func: { printf("fn %s ", n->data); NodeDraw(NodeGetChild(n, 0), selected); printf("\n"); INDENT NodeDraw(NodeGetChild(n, 1), selected); break; } + case NK_ExprList: + case NK_ArgList: { printf("("); for (int i = 0; i < n->childCount; i++) { if (i != 0) printf(" "); NodeDraw(NodeGetChild(n, i), selected); } printf(")"); break; } + case NK_Var: { printf("var %s", n->data); break; } + case NK_Body: { printf("{\n"); indent++; for (int i = 0; i < n->childCount; i++) { INDENT NodeDraw(NodeGetChild(n, i), selected); printf("\n"); } indent--; INDENT printf("}\n"); break; } + case NK_If: { printf("if "); NodeDraw(NodeGetChild(n, 0), selected); printf("\n"); INDENT NodeDraw(NodeGetChild(n, 1), selected); break; } + case NK_Num: { printf("%s", n->data); break; } + case NK_Str: { printf("'%s'", n->data); break; } + case NK_Call: { printf("call %s ", n->data); NodeDraw(NodeGetChild(n, 0), selected); break; } + case NK_Op: { if (n->childCount <= 1) printf("%s ", n->data); for (int i = 0; i < n->childCount; i++) { if (i != 0) printf(" %s ", n->data); NodeDraw(NodeGetChild(n, i), selected); } break; } } - if (n == selected) vt100DisableNegative(); + vt100DisableNegative(); } // Input @@ -216,8 +243,7 @@ void NodeDraw(Node *n, Node *selected) { typedef enum Input { IN_None, - IN_A, - IN_S, + IN_SPACE, IN_D, IN_H, @@ -225,21 +251,48 @@ typedef enum Input { IN_K, IN_L, - IN_SPACE, + IN_F, + IN_V, + IN_I, + IN_N, + IN_S, + IN_C, + IN_O, IN_Quit, IN_COUNT } Input; +const char *IN_STRINGS[IN_COUNT] = { + "IN_None", + + "IN_SPACE", + "IN_D", + + "IN_H", + "IN_J", + "IN_K", + "IN_L", + + "IN_F", + "IN_V", + "IN_I", + "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 ' ': return IN_SPACE; case 'd': return IN_D; case 'h': return IN_H; @@ -247,7 +300,13 @@ Input InputGet() { case 'k': return IN_K; case 'l': return IN_L; - case ' ': return IN_SPACE; + case 'f': return IN_F; + case 'v': return IN_V; + case 'i': return IN_I; + 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,22 +315,66 @@ 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_AddFunc, + IA_AddVar, + IA_AddIf, + IA_AddNum, + IA_AddStr, + IA_AddCall, + IA_AddOp, + IA_COUNT } InputAction; +const char *IA_STRINGS[IA_COUNT] = { + "IA_None", + + "IA_StartEditing", + "IA_Delete", + + "IA_MoveLeft", + "IA_MoveUp", + "IA_MoveDown", + "IA_MoveRight", + + "IA_AddFunc", + "IA_AddVar", + "IA_AddIf", + "IA_AddNum", + "IA_AddStr", + "IA_AddCall", + "IA_AddOp", +}; + +void DrawInfo(InputAction actions[NK_COUNT][IN_COUNT], NodeKind nk) { + int v, h; + vt100GetScreenSize(&v, &h); + + int line = 2; + + vt100CursorPos(line++, h-30); + printf("%s:", NK_STRINGS[nk]); + + for (int i = 0; i < IN_COUNT; i++) { + InputAction action = actions[nk][i]; + if (action != IA_None) { + vt100CursorPos(line++, h-30); + 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->kind = NK_Body; Node * n = result; @@ -287,6 +390,7 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) { vt100ClearScreen(); vt100CursorHome(); NodeDraw(result, n); + DrawInfo(actions, n->kind); if (mode == Mode_Editing) { int c = getch(); @@ -311,11 +415,10 @@ 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 NA(NAME, PARENT, KIND) Node *NAME = NEW(Node); NAME->kind = KIND; NodeAppend(PARENT, NAME); + #define NS(NAME, PARENT, KIND) Node *NAME = NEW(Node); NAME->kind = KIND; NAME->data = NEWARR(char, STR_SIZE); 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; } @@ -323,9 +426,18 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) { 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_AddFunc: { NS(n1, n, NK_Func) NA(n2, n1, NK_ArgList) NA(n3, n1, NK_Body) n = n1; mode = Mode_Editing; break; } + case IA_AddVar: { NS(n1, n, NK_Var) n = n1; mode = Mode_Editing; break; } + case IA_AddIf: { NA(n1, n, NK_If) NA(n2, n1, NK_ExprList) NA(n3, n1, NK_Body) n = n1; break; } + case IA_AddNum: { NS(n1, n, NK_Num) n = n1; mode = Mode_Editing; break; } + case IA_AddStr: { NS(n1, n, NK_Str) n = n1; mode = Mode_Editing; break; } + case IA_AddCall: { NS(n1, n, NK_Call) NA(n2, n1, NK_ExprList) n = n1; mode = Mode_Editing; break; } + case IA_AddOp: { NS(n1, n, NK_Op) n = n1; mode = Mode_Editing; break; } } - #undef NODE_APPEND + #undef NA + #undef NS } } @@ -335,22 +447,54 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) { int main() { // Setup - InputAction actions[NK_COUNT][IN_COUNT]; - - 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_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; + static 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_Func][IN_D] = IA_Delete; + actions[NK_Func][IN_SPACE] = IA_StartEditing; + + actions[NK_ArgList][IN_V] = IA_AddVar; + + actions[NK_ExprList][IN_V] = IA_AddVar; + actions[NK_ExprList][IN_I] = IA_AddIf; + 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_Body][IN_F] = IA_AddFunc; + actions[NK_Body][IN_V] = IA_AddVar; + actions[NK_Body][IN_I] = IA_AddIf; + 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_Num][IN_D] = IA_Delete; + actions[NK_Num][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_N] = IA_AddNum; + actions[NK_Op][IN_S] = IA_AddStr; + actions[NK_Op][IN_C] = IA_AddCall; + actions[NK_Op][IN_O] = IA_AddOp; // Main vt100EnableAlternateBuffer();