X-Git-Url: https://gitweb.ps.run/iftint/blobdiff_plain/2acf9a06e0a4952223418d73c82bc11baf2b47f1..d855fc21ed7a065f8b0d6f2607fef09b4c6865e1:/main3.c diff --git a/main3.c b/main3.c index 40e6966..c3da7f6 100644 --- a/main3.c +++ b/main3.c @@ -24,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 @@ -84,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"); } @@ -116,6 +117,8 @@ typedef enum NodeKind { NK_VarList, NK_ExprList, NK_Var, + NK_VarDecl, + NK_VarType, NK_Type, NK_Body, NK_If, @@ -135,6 +138,8 @@ const char *NK_STRINGS[NK_COUNT] = { "NK_VarList", "NK_ExprList", "NK_Var", + "NK_VarDecl", + "NK_VarType", "NK_Type", "NK_Body", "NK_If", @@ -221,31 +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; - #define INDENT for (int i = 0; i < indent; i++) printf(" "); - - vt100DisableNegative(); - 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_Namespace: { break; } - case NK_Struct: { 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_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), selected); } printf(")"); break; } - case NK_Var: { printf("[%s : ", n->data); NodeDraw(NodeGetChild(n, 0), selected); printf(); break; } - case NK_Type: { 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_While: { printf("while "); 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; } + 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; } } - - vt100DisableNegative(); } // Input @@ -257,17 +263,20 @@ void NodeDraw(Node *n, Node *selected) { typedef enum Input { IN_None, - IN_SPACE, - 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, @@ -281,17 +290,20 @@ typedef enum Input { const char *IN_STRINGS[IN_COUNT] = { "IN_None", - "IN_SPACE", - "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", @@ -306,17 +318,19 @@ 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; 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; @@ -330,17 +344,22 @@ 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, IA_AddVar, + IA_AddVarDecl, + IA_AddType, IA_AddIf, + IA_AddWhile, IA_AddNum, IA_AddStr, IA_AddCall, @@ -352,61 +371,70 @@ 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", "IA_AddVar", + "IA_AddVarDecl", + "IA_AddType", "IA_AddIf", + "IA_AddWhile", "IA_AddNum", "IA_AddStr", "IA_AddCall", "IA_AddOp", }; -void DrawInfo(InputAction actions[NK_COUNT][IN_COUNT], NodeKind nk) { +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-30); - printf("%s:", NK_STRINGS[nk]); + vt100CursorPos(line++, h-10); + 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); + 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_Body; + 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); - DrawInfo(actions, n->kind); + 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); @@ -415,13 +443,13 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) { s[slen-1] = '\0'; } else if (c == '\n' || c == '\r') { - mode = Mode_Normal; + 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) @@ -429,25 +457,30 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) { action = actions[n->kind][in]; - #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); + #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_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_AddFunc: { NS(n1, n, NK_Func) NA(n2, n1, NK_VarList) 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; } + 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 NA @@ -459,10 +492,7 @@ 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; @@ -470,13 +500,25 @@ int main() { actions[i][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_AddVar; + 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; @@ -485,9 +527,20 @@ int main() { 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_AddVar; + 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; @@ -495,6 +548,8 @@ int main() { 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; @@ -508,10 +563,17 @@ int main() { 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(); @@ -522,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; }