X-Git-Url: https://gitweb.ps.run/iftint/blobdiff_plain/e12b94087df67d7834b17cc37eaa25586b59c3e3..refs/heads/Printf:/main3.c?ds=sidebyside diff --git a/main3.c b/main3.c index b7f1344..a21f54b 100644 --- a/main3.c +++ b/main3.c @@ -1,6 +1,8 @@ -#include -#include -#include +#include +#include +#include +#include + // 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 @@ -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,102 @@ Node *NodeRemove(Node *n1, Node *n2) { return prev; } -void NodeDraw(Node *n, Node *selected) { +void NodeDraw(Node *n); +Node *g_NodeDrawSelected; + +void Printf(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); + } else if (*format == ',' && format[1] == 'n') { + Node *n = va_arg(argp, Node*); + for (int i = 0; i < n->childCount; i++) { + if (n > 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 (n > 0) printf("\n"); + NodeDraw(NodeGetChild(n, i)); + } + format++; + } else { + fputs("Not implemented", stdout); + } + } else if (*format == '_') { + static bool highlighted = false; + 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; - 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_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_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("}\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; } + // } + 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_ %s {%;n}\n", n->data, n); break; } + case NK_Struct: { Printf("_struct_ %s {%;n}\n", n->data, n); break; } + case NK_Func: { Printf("_fn_ %s %n %n", n->data, NodeGetChild(n, 0), NodeGetChild(n, 1)); break; } + case NK_VarList: + case NK_ExprList: { Printf("_(_%,n_)_", n); break; } + case NK_Var: { Printf("_[_%s_]_", n->data); break; } + case NK_VarDecl: { Printf("_[_%s : %n_]_", n->data, NodeGetChild(n, 0)); break; } + case NK_VarType: + case NK_Type: { Printf("%s%s%,n%s", n->data, (n->childCount > 0 ? "<" : ""), n, (n->childCount > 0 ? "<" : "")); break; } + case NK_Body: { Printf("_{_%;n_}_"); break; } + case NK_If: { Printf("_if_ %n %n", NodeGetChild(n, 0), NodeGetChild(n, 1)); break; } + case NK_While: { Printf("_while_ %n %n", NodeGetChild(n, 0), 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", n->data, NodeGetChild(n, 0)); 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)); } break; } } - - if (n == selected) vt100DisableNegative(); } // Input @@ -216,30 +333,62 @@ void NodeDraw(Node *n, Node *selected) { typedef enum Input { IN_None, - IN_A, - IN_S, + IN_SPACE, IN_D, + IN_A, IN_H, IN_J, IN_K, IN_L, - IN_SPACE, + 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_SPACE", + "IN_D", + "IN_A", + + "IN_H", + "IN_J", + "IN_K", + "IN_L", + + "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 ' ': return IN_SPACE; case 'd': return IN_D; case 'h': return IN_H; @@ -247,7 +396,15 @@ 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 '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 +413,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_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_StartEditing", + "IA_Delete", + + "IA_MoveLeft", + "IA_MoveUp", + "IA_MoveDown", + "IA_MoveRight", + + "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-30); + printf("%s:%s", NK_STRINGS[nk], (mode == IM_Normal ? "" : " (editing)")); + + 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->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 +512,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 +527,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_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_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; } } - #undef NODE_APPEND + #undef NA + #undef NS } } @@ -335,22 +564,83 @@ Node *GetNode(InputAction actions[NK_COUNT][IN_COUNT]) { int main() { // Setup - InputAction actions[NK_COUNT][IN_COUNT]; + static 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; + 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_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; // Main vt100EnableAlternateBuffer(); @@ -365,7 +655,7 @@ int main() { vt100GetScreenSize(&v, &h); printf("Screen Size: %d | %d\n", v, h); - NodeDraw(n, NULL); + NodeDraw(n); return 0; }