static void makeTables(sqlite3 *db) { size_t i; evlog(LOG_SOMETIMES, "Creating tables."); for (i=0; i < (sizeof(createStatements)/sizeof(createStatements[0])); ++i) { runStatement(db, createStatements[i], "Table creation"); } }
static bool runFunctionCall(ASTNode* node, MemoryStack* stack, Scope* scope, RuntimeError* error, Value* result) { assert(node->nodeType == AST_FUNCTION_CALL); bool stillWorking = true; // TODO: change this to temporary memory? Scope identifierScope = makeScope(nullptr); FunctionIdentifier identifier = {}; if (calcFunctionIdentifier(scope, &identifierScope, stack, error, node, &identifier)) { Function* funcToCall = getFunction(scope, identifier); if (funcToCall) { Scope functionScope = makeScope(scope); ListIterator<ASTNode> iterator = makeIterator(&node->functionCall.arguments); ListIterator<Argument> iterator2 = makeIterator(&funcToCall->identifier.arguments); while (stillWorking && hasNext(&iterator)) { ASTNode* node = getNext(&iterator); Argument* argFunctionRecieves = getNext(&iterator2); Variable* var = defineAVariable(argFunctionRecieves->identifier, argFunctionRecieves->type, stack, &functionScope); stillWorking = runExpression(node, stack, scope, error, &var->value); } if (stillWorking) { assert(!hasNext(&iterator) && !hasNext(&iterator2)); if (funcToCall->type == FT_INTERNAL) stillWorking = runStatement(funcToCall->body, stack, &functionScope, error); else funcToCall->func(funcToCall->identifier.name, &functionScope.variables, result); // TODO: externals error checking? } scopeFreeMemory(&functionScope, stack); } else { *error = RuntimeError{ RET_UNDEFINED_FUNCTION, identifier.name, node->functionCall.lineNumber }; stillWorking = false; } } else stillWorking = false; scopeFreeMemory(&identifierScope, stack); return stillWorking; }
static bool runStatements(LinkedList<ASTNode>* statements, MemoryStack* stack, Scope* scope, RuntimeError* error) { bool stillWorking = true; ListIterator<ASTNode> iterator = makeIterator(statements); while (stillWorking && hasNext(&iterator)) { stillWorking = runStatement(getNext(&iterator), stack, scope, error); } return stillWorking; }
LRESULT ConsoleDialog::run_inputWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_KEYDOWN: switch(wParam) { case VK_UP: historyPrevious(); return FALSE; case VK_DOWN: historyNext(); return FALSE; default: return CallWindowProc(m_originalInputWndProc, hWnd, message, wParam, lParam); } case WM_KEYUP: switch(wParam) { case VK_RETURN: runStatement(); return FALSE; case VK_ESCAPE: historyEnd(); return FALSE; default: return CallWindowProc(m_originalInputWndProc, hWnd, message, wParam, lParam); } default: return CallWindowProc(m_originalInputWndProc, hWnd, message, wParam, lParam); } }
BOOL CALLBACK ConsoleDialog::run_dlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { SetParent(m_scintilla, hWnd); ShowWindow(m_scintilla, SW_SHOW); m_hInput = ::GetDlgItem(_hSelf, IDC_INPUT); HFONT hCourier = CreateFont(14,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, FIXED_PITCH, _T("Courier New")); if (hCourier != NULL) { SendMessage(m_hInput, WM_SETFONT, reinterpret_cast<WPARAM>(hCourier), TRUE); SendMessage(::GetDlgItem(_hSelf, IDC_PROMPT), WM_SETFONT, reinterpret_cast<WPARAM>(hCourier), TRUE); } // Subclass the Input box ::SetWindowLongPtr(::GetDlgItem(_hSelf, IDC_INPUT), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); m_originalInputWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(::GetDlgItem(_hSelf, IDC_INPUT), GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(ConsoleDialog::inputWndProc))); return TRUE; } case WM_SIZE: MoveWindow(m_scintilla, 0, 0, LOWORD(lParam), HIWORD(lParam)-30, TRUE); MoveWindow(::GetDlgItem(_hSelf, IDC_PROMPT), 0, HIWORD(lParam)-25, 30, 25, TRUE); MoveWindow(m_hInput, 30, HIWORD(lParam)-30, LOWORD(lParam) - 85, 25, TRUE); MoveWindow(::GetDlgItem(_hSelf, IDC_RUN), LOWORD(lParam) - 50, HIWORD(lParam) - 30, 50, 25, TRUE); // ::SendMessage(m_scintilla, WM_SIZE, 0, MAKEWORD(LOWORD(lParam) - 10, HIWORD(lParam) - 30)); return FALSE; case WM_CONTEXTMENU: { MENUITEMINFO mi; mi.cbSize = sizeof(mi); mi.fMask = MIIM_STATE; if (0 == (callScintilla(SCI_GETSELECTIONSTART) - callScintilla(SCI_GETSELECTIONEND))) { mi.fState = MFS_DISABLED; } else { mi.fState = MFS_ENABLED; } SetMenuItemInfo(m_hContext, 2, FALSE, &mi); // Thanks MS for corrupting the value of BOOL. :-/ // From the documentation (http://msdn.microsoft.com/en-us/library/ms648002.aspx): // // If you specify TPM_RETURNCMD in the uFlags parameter, the return value is the menu-item // identifier of the item that the user selected. If the user cancels the menu without making // a selection, or if an error occurs, then the return value is zero. INT cmdID = (INT)TrackPopupMenu(m_hContext, TPM_RETURNCMD, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, _hSelf, NULL); switch(cmdID) { case 1: // Select All callScintilla(SCI_SELECTALL); break; case 2: // Copy callScintilla(SCI_COPY); break; case 3: // Clear clearText(); break; default: break; } } break; case WM_COMMAND: if (LOWORD(wParam) == IDC_RUN) { if (m_runButtonIsRun) { runStatement(); } else { assert(m_console != NULL); if (m_console) { m_console->stopStatement(); } } //MessageBox(NULL, _T("Command") , _T("Python Command"), 0); return FALSE; } break; case WM_NOTIFY: { LPNMHDR nmhdr = reinterpret_cast<LPNMHDR>(lParam); if (m_scintilla == nmhdr->hwndFrom) { switch(nmhdr->code) { case SCN_STYLENEEDED: onStyleNeeded(reinterpret_cast<SCNotification*>(lParam)); return FALSE; case SCN_HOTSPOTCLICK: onHotspotClick(reinterpret_cast<SCNotification*>(lParam)); return FALSE; default: break; } } break; } default: break; } return DockingDlgInterface::run_dlgProc(message, wParam, lParam); }
static int64 readLog(FILE *input, sqlite3 *db) { int64 eventCount = 0; /* declare statements for every event type */ EVENT_LIST(EVENT_TYPE_DECLARE_STATEMENT, X); /* prepare statements for every event type */ EVENT_LIST(EVENT_TYPE_PREPARE_STATEMENT, X); runStatement(db, "BEGIN", "Transaction start"); while (TRUE) { /* loop for each event */ char line[MAX_LOG_LINE_LENGTH]; char *p; char *q; int last_index=0; sqlite3_stmt *statement = NULL; int res; int64 clock_field; long code; p = fgets(line, MAX_LOG_LINE_LENGTH, input); if (!p) { if (feof(input)) break; else error("Couldn't read line after event %llu", eventCount); } eventCount++; clock_field = strtoll(p, &q, 16); if (q == p) error("event %llu clock field not a hex integer: %s", eventCount, p); if (*q != ' ') error("event %llu code field not preceded by ' ': %s", eventCount, q); while(*q == ' ') ++q; p = q; code = strtol(p, &q, 16); if (q == p) error("event %llu code field not an integer: %s", eventCount, p); p = q; /* Write event to SQLite. */ switch (code) { /* this macro sets statement and last_index */ EVENT_LIST(EVENT_TYPE_WRITE_SQL, X); default: error("Event %llu has Unknown event code %d", eventCount, code); } /* bind the fields we store for every event */ \ res = sqlite3_bind_int64(statement, last_index+1, logSerial); if (res != SQLITE_OK) sqlite_error(res, db, "Event %llu bind of log_serial failed.", eventCount); res = sqlite3_bind_int64(statement, last_index+2, clock_field); if (res != SQLITE_OK) sqlite_error(res, db, "Event %llu bind of clock failed.", eventCount); res = sqlite3_step(statement); if (res != SQLITE_DONE) sqlite_error(res, db, "insert of event %llu failed.", eventCount); res = sqlite3_reset(statement); if (res != SQLITE_OK) sqlite_error(res, db, "Couldn't reset insert statement of event %llu", eventCount); if (progress) { if ((eventCount % SMALL_TICK) == 0) { printf("."); fflush(stdout); if (((eventCount / SMALL_TICK) % BIG_TICK) == 0) { printf("\n"); fflush(stdout); evlog(LOG_SOMETIMES, "%lu events.", (unsigned long)eventCount); } } } } if (progress) { printf("\n"); fflush(stdout); } runStatement(db, "COMMIT", "Transaction finish"); logFileCompleted(db, eventCount); /* finalize all the statements */ EVENT_LIST(EVENT_TYPE_FINALIZE_STATEMENT, X); return eventCount; }
bool run(ASTNode* mainNode, RuntimeError* error, ExternalFunctions externals, char** libsToLoad, int libsCount) { assert(mainNode->nodeType == AST_MAIN); getValueFunc = getGetValueFuncPtr(); MemoryStack stack = makeMemoryStack(MEGABYTE(16)); Array<HINSTANCE> libraries = makeArray<HINSTANCE>(KILOBYTE(1)); Scope scalarTypesScope = makeScope(nullptr); Scope globalScope = makeScope(&scalarTypesScope); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s64"), {}, 8 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u64"), {}, 8 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f64"), {}, 8 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s32"), {}, 4 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u32"), {}, 4 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f32"), {}, 4 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s16"), {}, 2 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u16"), {}, 2 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s8"), {}, 1 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u8"), {}, 1 }); ExternalArgumentDefinition binarys32Args[] = { { "a", "s32" }, { "b", "s32" } }; ExternalArgumentDefinition binaryf32Args[] = { { "a", "f32" }, { "b", "f32" } }; ExternalDefinition buildInExternals[] = { { &scalarS32FuncsHandler, "opAdd", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opSub", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opEqualsOrLess", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opEqualsOrsGreater", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opLess", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opGreater", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opEquals", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opNot", "s32", binarys32Args, ArrayCount(binarys32Args) }, }; loadExternals(&scalarTypesScope, &stack, ExternalFunctions{ buildInExternals, ArrayCount(buildInExternals) }); loadExternals(&scalarTypesScope, &stack, externals); loadLibrariries(&libraries, &scalarTypesScope, &stack, libsToLoad, libsCount); bool stillWorking = true; // load all global function and type definitions ListIterator<ASTNode> iterator = makeIterator(&mainNode->main.statements); while (stillWorking && hasNext(&iterator)) { ASTNode* statement = getNext(&iterator); if (statement->nodeType == AST_STATEMENT_FUNCTION_DEFINITION || statement->nodeType == AST_STATEMENT_TYPE_DEFINITION) stillWorking = runStatement(statement, &stack, &globalScope, error); else { // TODO: illigal statement exception? Or do this on parsing stage? } } if (stillWorking) { FunctionIdentifier mainIdentifier = {}; mainIdentifier.name = makeSlice("main"); Function* func = getFunction(&globalScope, mainIdentifier); if (func != nullptr) stillWorking = runStatement(func->body, &stack, &globalScope, error); else { stillWorking = false; *error = RuntimeError{ RET_UNDEFINED_FUNCTION, mainIdentifier.name, 0 }; } } scopeFreeMemory(&globalScope, &stack); scopeFreeMemory(&scalarTypesScope, &stack); freeAllLibraries(&libraries); freeArray(&libraries); freeMemoryStack(&stack); return stillWorking; }
BOOL CALLBACK ConsoleDialog::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: SetParent((HWND)m_sciOutput.GetID(), _hSelf); ShowWindow((HWND)m_sciOutput.GetID(), SW_SHOW); SetParent((HWND)m_sciInput.GetID(), _hSelf); ShowWindow((HWND)m_sciInput.GetID(), SW_SHOW); // Subclass some stuff SetWindowSubclass((HWND)m_sciInput.GetID(), ConsoleDialog::inputWndProc, 0, reinterpret_cast<DWORD_PTR>(this)); SetWindowSubclass((HWND)m_sciOutput.GetID(), ConsoleDialog::scintillaWndProc, 0, reinterpret_cast<DWORD_PTR>(this)); return FALSE; case WM_SIZE: { RECT rect = { 0, 0, LOWORD(lParam), HIWORD(lParam) }; int h = min(m_sciInput.Call(SCI_GETLINECOUNT), 8) * m_sciInput.Call(SCI_TEXTHEIGHT, 1); MoveWindow((HWND)m_sciOutput.GetID(), 0, 0, rect.right, rect.bottom - h - 14, TRUE); MoveWindow((HWND)m_sciInput.GetID(), 0, rect.bottom - h - 14, rect.right - 50, h + 9, TRUE); m_sciOutput.Call(SCI_DOCUMENTEND); MoveWindow(::GetDlgItem(_hSelf, IDC_RUN), rect.right - 50, rect.bottom - 30, 50, 25, TRUE); return FALSE; } case WM_CONTEXTMENU: { MENUITEMINFO mi; mi.cbSize = sizeof(mi); mi.fMask = MIIM_STATE; mi.fState = m_sciOutput.Call(SCI_GETSELECTIONEMPTY) ? MFS_DISABLED : MFS_ENABLED; SetMenuItemInfo(m_hContext, 2, FALSE, &mi); // Thanks MS for corrupting the value of BOOL. :-/ // From the documentation (http://msdn.microsoft.com/en-us/library/ms648002.aspx): // // If you specify TPM_RETURNCMD in the uFlags parameter, the return value is the menu-item // identifier of the item that the user selected. If the user cancels the menu without making // a selection, or if an error occurs, then the return value is zero. INT cmdID = (INT)TrackPopupMenu(m_hContext, TPM_RETURNCMD, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, _hSelf, NULL); switch (cmdID) { case 1: // Select All m_sciOutput.Call(SCI_SELECTALL); break; case 2: // Copy m_sciOutput.Call(SCI_COPY); break; case 3: // Clear clearText(); break; default: break; } } break; case WM_COMMAND: if (LOWORD(wParam) == IDC_RUN) { runStatement(); giveInputFocus(); return FALSE; } break; case WM_NOTIFY: { LPNMHDR nmhdr = reinterpret_cast<LPNMHDR>(lParam); if (m_sciInput.GetID() == nmhdr->hwndFrom) { SCNotification* scn = reinterpret_cast<SCNotification*>(lParam); m_console->processNotification(scn); switch (nmhdr->code) { case SCN_MODIFIED: { SCNotification* scn = reinterpret_cast<SCNotification*>(lParam); if ((scn->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT))) { if (scn->linesAdded != 0) { RECT rect; GetClientRect(_hSelf, &rect); int h = min(m_sciInput.Call(SCI_GETLINECOUNT), 8) * m_sciInput.Call(SCI_TEXTHEIGHT, 1); MoveWindow((HWND)m_sciOutput.GetID(), 0, 0, rect.right, rect.bottom - h - 14, TRUE); MoveWindow((HWND)m_sciInput.GetID(), 0, rect.bottom - h - 14, rect.right - 50, h + 9, TRUE); m_sciOutput.Call(SCI_DOCUMENTEND); } // Not the most efficient way but by far the easiest to do it here int startLine = 0; int endLine = m_sciInput.Call(SCI_GETLINECOUNT); for (int i = startLine; i < endLine; ++i) { m_sciInput.CallString(SCI_MARGINSETTEXT, i, ">"); m_sciInput.Call(SCI_MARGINSETSTYLE, i, STYLE_LINENUMBER); } } break; } } } break; } default: break; } return FALSE; }
static bool runStatement(ASTNode* node, MemoryStack* stack, Scope* scope, RuntimeError* error) { switch (node->nodeType) { case AST_STATEMENT_TYPE_DEFINITION: { if (getTypeDefinition(scope, node->typeDefinition.identifier, false)) { *error = RuntimeError{ RET_TYPE_ALREADY_DEFINED, node->typeDefinition.identifier, node->typeDefinition.lineNumber }; return false; } else { TypeDefinition* typeDef = scopePushToList(scope, stack, &scope->types); typeDef->identifier = node->typeDefinition.identifier; typeDef->members = {}; ListIterator<ASTNode> iterator = makeIterator(&node->typeDefinition.definitions); int currOffsetInBytes = 0; while (hasNext(&iterator)) { ASTNode* node = getNext(&iterator); StructMember* member = scopePushToList(scope, stack, &typeDef->members); member->identifier = node->variableDeclaration.identifier; member->type = makeType(scope, node->variableDeclaration.typeIdentifier); member->offsetInBytes = currOffsetInBytes; currOffsetInBytes += member->type.definition->totalSizeInBytes; } typeDef->totalSizeInBytes = currOffsetInBytes; return true; } } break; case AST_STATEMENT_VARIABLE_DECLARATION: { if (getVariable(scope, node->variableDeclaration.identifier, false)) { *error = RuntimeError{ RET_VARIABLE_ALREADY_DEFINED, node->variableDeclaration.identifier, node->variableDeclaration.lineNumber }; return false; } else { Variable* var = defineAVariable( node->variableDeclaration.identifier, makeType(scope, node->variableDeclaration.typeIdentifier), stack, scope); if (node->variableDeclaration.expression) return runExpression(node->variableDeclaration.expression, stack, scope, error, &var->value); else return true; // TODO: set default value } } break; case AST_STATEMENT_FUNCTION_DEFINITION: { Function func; func.type = FT_INTERNAL; func.identifier.name = node->functionDefinition.identifier; func.identifier.arguments = {}; bool stillWorking = true; if (!node->functionDefinition.returnType) func.returnType = Type{ nullptr, 0 }; else { func.returnType = makeType(scope, node->functionDefinition.returnType); if (!func.returnType.definition) { *error = RuntimeError{ RET_UNDEFINED_TYPE, node->functionDefinition.returnType->typeIdentifier.name, node->functionDefinition.lineNumber }; stillWorking = false; } } ListIterator<ASTNode> args = makeIterator(&node->functionDefinition.arguments); while (stillWorking && hasNext(&args)) { ASTNode* arg = getNext(&args); Argument* argument = scopePushToList(scope, stack, &func.identifier.arguments); argument->identifier = arg->variableDeclaration.identifier; argument->type = makeType(scope, arg->variableDeclaration.typeIdentifier); if (!argument->type.definition) { *error = RuntimeError{ RET_UNDEFINED_TYPE, arg->variableDeclaration.typeIdentifier->typeIdentifier.name, arg->variableDeclaration.lineNumber }; stillWorking = false; } } func.body = node->functionDefinition.body; Function* hasFunc = getFunction(scope, func.identifier, false); if (hasFunc) { *error = RuntimeError{ RET_FUNCTION_ALREADY_DEFINED, node->functionDefinition.identifier, node->functionDefinition.lineNumber }; stillWorking = false; } else { *scopePushToList(scope, stack, &scope->functions) = func; } return stillWorking; } break; case AST_STATEMENT_IF: { Scope ifScope = makeScope(scope); Value conditionResult = pushValue(&ifScope, stack, Type{ getTypeDefinition(scope, makeSlice("s32")), false }); bool stillWorking = runExpression(node->ifStatement.condition, stack, scope, error, &conditionResult); if (stillWorking) { if (*(int*)conditionResult.memory != 0) { stillWorking = runStatement(node->ifStatement.ifCase, stack, &ifScope, error); } else if (node->ifStatement.elseCase != nullptr) { stillWorking = runStatement(node->ifStatement.elseCase, stack, &ifScope, error); } } scopeFreeMemory(&ifScope, stack); return stillWorking; } break; case AST_STATEMENT_WHILE: { Scope whileScope = makeScope(scope); Value conditionResult = pushValue(&whileScope, stack, Type{ getTypeDefinition(scope, makeSlice("s32")), false }); bool stillWorking = runExpression(node->whileStatement.condition, stack, scope, error, &conditionResult); if (stillWorking) { while (*(int*)conditionResult.memory != 0) { if (!(stillWorking = runStatement(node->whileStatement.body, stack, &whileScope, error))) break; if (!(stillWorking = runExpression(node->whileStatement.condition, stack, scope, error, &conditionResult))) break; } } scopeFreeMemory(&whileScope, stack); return stillWorking; } break; case AST_STATEMENT_ASSIGNMENT: { Value value; if (getValue(scope, node->assignment.lValue, error, &value)) { return runExpression(node->assignment.expression, stack, scope, error, &value); } else return false; } break; case AST_STATEMENTS_BLOCK: { Scope blockScope = makeScope(scope); bool result = runStatements(&node->statementsBlock.statements, stack, &blockScope, error); scopeFreeMemory(&blockScope, stack); return result; } break; case AST_FUNCTION_CALL: { return runFunctionCall(node, stack, scope, error, nullptr); } break; default: { assert(!"this is not a statement!"); return false; } break; } }