X-Git-Url: https://gitweb.ps.run/iftint/blobdiff_plain/609c5afa7ef670d6cf39a50e001079f1747ac261..ced3cb7cb9c341c5dfbcf189c575cd07f131e136:/main3.c diff --git a/main3.c b/main3.c index 2b0be3b..d6162a4 100644 --- a/main3.c +++ b/main3.c @@ -2,12 +2,15 @@ #include #include #include +#include +#include // Global defines #define STR_SIZE 128 -#define BUF_SIZE 1024*1024 +#define MEMORY_SIZE 1024*1024 +#define EDIT_QUEUE_SIZE 10 // Memory @@ -15,6 +18,8 @@ static char g_memory[1024*1024]; 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; @@ -85,7 +90,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"); } @@ -103,8 +108,8 @@ void vt100GetScreenSize(int * v, int * h) { #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 } @@ -156,14 +161,14 @@ struct Node { 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 *result = n->child; + Node *result = n->chld; 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) { - n1->child = n2; + n1->chld = n2; } 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->parent = n1; + n2->prnt = n1; n1->childCount += 1; } @@ -213,10 +218,10 @@ Node *NodeRemove(Node *n1, Node *n2) { 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; @@ -226,8 +231,63 @@ Node *NodeRemove(Node *n1, Node *n2) { return prev; } +void NodeDraw(Node *n); 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(" "); @@ -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) { - 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("}\n"); 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("}\n"); break; } - case NK_Func: { PRINTF("fn"); printf(" %s ", n->data); NodeDraw(NodeGetChild(n, 0)); INDENT 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_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_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("}\n"); 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; } } } @@ -263,15 +323,15 @@ void NodeDraw(Node *n) { typedef enum Input { IN_None, - IN_SPACE, - IN_D, - IN_A, - IN_H, IN_J, IN_K, IN_L, + IN_SPACE, + IN_D, + IN_A, + IN_F, IN_V, IN_T, @@ -290,15 +350,15 @@ typedef enum Input { const char *IN_STRINGS[IN_COUNT] = { "IN_None", - "IN_SPACE", - "IN_D", - "IN_A", - "IN_H", "IN_J", "IN_K", "IN_L", + "IN_SPACE", + "IN_D", + "IN_A", + "IN_F", "IN_V", "IN_T", @@ -318,14 +378,14 @@ Input InputGet() { while (true) { c = getch(); switch (c) { - case ' ': return IN_SPACE; - 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; @@ -344,14 +404,14 @@ Input InputGet() { typedef enum InputAction { IA_None, - IA_StartEditing, - IA_Delete, - IA_MoveLeft, IA_MoveUp, IA_MoveDown, IA_MoveRight, + IA_StartEditing, + IA_Delete, + IA_AddNamespace, IA_AddStruct, IA_AddFunc, @@ -371,14 +431,14 @@ typedef enum InputAction { const char *IA_STRINGS[IA_COUNT] = { "IA_None", - "IA_StartEditing", - "IA_Delete", - "IA_MoveLeft", "IA_MoveUp", "IA_MoveDown", "IA_MoveRight", + "IA_StartEditing", + "IA_Delete", + "IA_AddNamespace", "IA_AddStruct", "IA_AddFunc", @@ -405,9 +465,12 @@ void DrawInfo(InputAction actions[NK_COUNT][IN_COUNT], NodeKind nk, InputMode mo 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 = 0; i < IN_COUNT; i++) { + for (int i = IN_L+1; i < IN_COUNT; i++) { InputAction action = actions[nk][i]; if (action != IA_None) { vt100CursorPos(line++, h-30); @@ -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 * q[EDIT_QUEUE_SIZE] = {0}; 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') { - 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; } } @@ -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) { - case IA_StartEditing: { mode = IM_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_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_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_StartEditing: { 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 } } @@ -492,14 +625,11 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) { } -int main() { - // Setup - static 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_J] = IA_MoveDown; + actions[i][IN_K] = IA_MoveUp; actions[i][IN_L] = IA_MoveRight; } @@ -571,6 +701,12 @@ int main() { 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(); @@ -581,11 +717,8 @@ int main() { vt100DisableAlternateBuffer(); vt100ShowCursor(); - int v, h; - vt100GetScreenSize(&v, &h); - printf("Screen Size: %d | %d\n", v, h); - NodeDraw(n); + printf("\n"); return 0; }