CString CreateDataFieldFromItemList (const TArray<CItem> &List) // CreateDataFieldFromItemList // // Creates a data field string from a list of items { int i; CCodeChain &CC = g_pUniverse->GetCC(); CMemoryWriteStream Output(10000); if (Output.Create() != NOERROR) return NULL_STR; Output.Write("='(", 3); for (i = 0; i < List.GetCount(); i++) { ICCItem *pItem = List[i].WriteToCCItem(CC); if (pItem->IsError()) { pItem->Discard(&CC); return NULL_STR; } CString sItem = pItem->Print(&CC); Output.Write(sItem.GetASCIIZPointer(), sItem.GetLength()); Output.Write(" ", 1); pItem->Discard(&CC); } Output.Write(")", 1); Output.Close(); return CString(Output.GetPointer(), Output.GetLength()); }
ICCItem *CCPrimitive::Execute (CEvalContext *pCtx, ICCItem *pArgs) // Execute // // Executes the function and returns a result { bool bCustomArgEval = ((m_dwFlags & PPFLAG_CUSTOM_ARG_EVAL) ? true : false); // Evaluate args, if necessary ICCItem *pEvalArgs; if (!bCustomArgEval) { pEvalArgs = pCtx->pCC->EvaluateArgs(pCtx, pArgs, m_sArgPattern); if (pEvalArgs->IsError()) return pEvalArgs; } else pEvalArgs = pArgs; // Invoke the function ICCItem *pResult; bool bReportError = false; try { pResult = m_pfFunction(pCtx, pEvalArgs, m_dwData); } catch (...) { bReportError = true; } // Report error if (bReportError) { CString sArgs; try { sArgs = pEvalArgs->Print(pCtx->pCC); } catch (...) { sArgs = CONSTLIT("[invalid arg item]"); } CString sError = strPatternSubst(CONSTLIT("Exception in %s; arg = %s"), m_sName, sArgs); pResult = pCtx->pCC->CreateError(sError, pEvalArgs); kernelDebugLogMessage(sError.GetASCIIZPointer()); } // Done if (!bCustomArgEval) pEvalArgs->Discard(pCtx->pCC); return pResult; }
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList) { int i, j; if (ItemList.GetCount() == 0) return; // Output each row for (i = 0; i < ItemList.GetCount(); i++) { CItemType *pType = ItemList[i]; for (j = 0; j < Ctx.Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Ctx.Cols[j]; // Get the field value CString sValue; CItem Item(pType, 1); CItemCtx ItemCtx(Item); CCodeChainCtx CCCtx; ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField); if (pResult->IsNil()) sValue = NULL_STR; else sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); pResult->Discard(&g_pUniverse->GetCC()); // Format the value if (strEquals(sField, FIELD_AVERAGE_DAMAGE) || strEquals(sField, FIELD_POWER_PER_SHOT)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_POWER)) printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID()); double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0); printf("%.2f", rCount); } else printf(sValue.GetASCIIZPointer()); } printf("\n"); } }
CString CCSymbolTable::Print (CCodeChain *pCC, DWORD dwFlags) // Print // // Render as text { int i; CMemoryWriteStream Stream; if (Stream.Create() != NOERROR) return CONSTLIT("ERROR-OUT-OF-MEMORY"); // Open paren Stream.Write("{ ", 2); // Write items for (i = 0; i < m_Symbols.GetCount(); i++) { CString sKey = CCString::Print(m_Symbols.GetKey(i)); Stream.Write(sKey.GetASCIIZPointer(), sKey.GetLength()); Stream.Write(":", 1); ICCItem *pValue = dynamic_cast<ICCItem *>(m_Symbols.GetValue(i)); CString sValue = pValue->Print(pCC); Stream.Write(sValue.GetASCIIZPointer(), sValue.GetLength()); Stream.Write(" ", 1); } // Close paren Stream.Write("}", 1); return CString(Stream.GetPointer(), Stream.GetLength()); }
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList) { int i, j; if (ItemList.GetCount() == 0) return; // Output each row for (i = 0; i < ItemList.GetCount(); i++) { CItemType *pType = ItemList[i]; CItem Item(pType, 1); CItemCtx ItemCtx(Item); for (j = 0; j < Ctx.Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Ctx.Cols[j]; // Handle some special fields if (strEquals(sField, FIELD_BENCHMARK)) { CWeaponBenchmarkCtx::SStats Stats; if (!Ctx.WeaponBenchmarks.GetStats(pType, Stats)) { printf("\t\t\t\t"); } else { CString sBestArmor; if (Stats.pBestArmor) { CItem BestArmor(Stats.pBestArmor, 1); sBestArmor = BestArmor.GetNounPhrase(nounShort); } CString sWorstArmor; if (Stats.pWorstArmor) { CItem WorstArmor(Stats.pWorstArmor, 1); sWorstArmor = WorstArmor.GetNounPhrase(nounShort); } printf("%d\t%s\t%d\t%s\t%d", Stats.iAverageTime, (LPSTR)sBestArmor, Stats.iBestTime, (LPSTR)sWorstArmor, Stats.iWorstTime); } } else if (strEquals(sField, FIELD_BALANCE_STATS)) { CDeviceClass *pDevice = pType->GetDeviceClass(); CWeaponClass *pWeapon = NULL; if (pDevice) pWeapon = pDevice->AsWeaponClass(); else if (pType->IsMissile() && ItemCtx.ResolveVariant()) { pDevice = ItemCtx.GetVariantDevice(); pWeapon = pDevice->AsWeaponClass(); } if (pWeapon) { CWeaponClass::SBalance Balance; pWeapon->CalcBalance(ItemCtx, Balance); printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f", Balance.rBalance, Balance.rBalance - Balance.rCost, Balance.rDamage, Balance.rDamageType, Balance.rAmmo, Balance.rOmni, Balance.rTracking, Balance.rRange, Balance.rSpeed, Balance.rWMD, Balance.rRadiation, Balance.rMining, Balance.rShatter, Balance.rDeviceDisrupt, Balance.rDeviceDamage, Balance.rDisintegration, Balance.rShieldPenetrate, Balance.rArmor, Balance.rShield, Balance.rProjectileHP, Balance.rPower, Balance.rCost, Balance.rSlots, Balance.rExternal, Balance.rLinkedFire, Balance.rRecoil ); } else printf("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); } // Get the field value else { CString sValue; CCodeChainCtx CCCtx; ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField); if (pResult->IsNil()) sValue = NULL_STR; else sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); pResult->Discard(&g_pUniverse->GetCC()); // Format the value if (strEquals(sField, FIELD_POWER_PER_SHOT)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_POWER)) printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID()); double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0); printf("%.2f", rCount); } else printf(sValue.GetASCIIZPointer()); } } printf("\n"); } }
void Run (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i; CCodeChain &CC = g_pUniverse->GetCC(); bool bNoLogo = pCmdLine->GetAttributeBool(NO_LOGO_SWITCH); // Prepare the universe CTopologyNode *pNode = g_pUniverse->GetFirstTopologyNode(); if (pNode == NULL) { printf("ERROR: No topology node found.\n"); return; } CSystem *pSystem; if (error = g_pUniverse->CreateStarSystem(pNode, &pSystem)) { printf("ERROR: Unable to create star system.\n"); return; } // Set the POV CSpaceObject *pPOV = pSystem->GetObject(0); g_pUniverse->SetPOV(pPOV); pSystem->SetPOVLRS(pPOV); // Prepare system g_pUniverse->UpdateExtended(); g_pUniverse->GarbageCollectLibraryBitmaps(); CString sCommand = pCmdLine->GetAttribute(RUN_SWITCH); CString sRunFile = pCmdLine->GetAttribute(RUN_FILE_SWITCH); // If this is a run file, then we parse it and run it if (!sRunFile.IsBlank() && !strEquals(sRunFile, CONSTLIT("true"))) { TArray<CString> Files; ParseStringList(sRunFile, PSL_FLAG_ALLOW_WHITESPACE, &Files); for (i = 0; i < Files.GetCount(); i++) RunFile(Files[i], bNoLogo); } // If we have a command, invoke it else if (!sCommand.IsBlank() && !strEquals(sCommand, CONSTLIT("True"))) { CCodeChainCtx Ctx; ICCItem *pCode = Ctx.Link(sCommand, 0, NULL); ICCItem *pResult = Ctx.Run(pCode); CString sOutput; if (pResult->IsIdentifier()) sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); else sOutput = CC.Unlink(pResult); Ctx.Discard(pResult); Ctx.Discard(pCode); // Output result printf("%s\n", sOutput.GetASCIIZPointer()); } // Otherwise, we enter a command loop else { // Welcome if (!bNoLogo) { printf("(help) for function help.\n"); printf("\\q to quit.\n\n"); } // Loop while (true) { char szBuffer[1024]; if (!bNoLogo) printf(": "); gets_s(szBuffer, sizeof(szBuffer)-1); CString sCommand(szBuffer); // Escape codes if (*sCommand.GetASCIIZPointer() == '\\') { // Quit command if (strStartsWith(sCommand, CONSTLIT("\\q"))) break; else if (strStartsWith(sCommand, CONSTLIT("\\?")) || strStartsWith(sCommand, CONSTLIT("\\h"))) { printf("TLisp Shell\n\n"); printf("\\h Show this help\n"); printf("\\q Quit\n"); printf("\n(help) for function help.\n"); } } // Null command else if (sCommand.IsBlank()) NULL; // Command else { CCodeChainCtx Ctx; ICCItem *pCode = Ctx.Link(sCommand, 0, NULL); ICCItem *pResult = Ctx.Run(pCode); CString sOutput; if (pResult->IsIdentifier()) sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); else sOutput = CC.Unlink(pResult); Ctx.Discard(pResult); Ctx.Discard(pCode); // Output result printf("%s\n", sOutput.GetASCIIZPointer()); } } } }
void RunFile (const CString &sFilespec, bool bNoLogo) { ALERROR error; CCodeChain &CC = g_pUniverse->GetCC(); CCodeChainCtx Ctx; // Verify the file CString sRunFile = sFilespec; if (!strEndsWith(sRunFile, CONSTLIT(".")) && pathGetExtension(sRunFile).IsBlank()) sRunFile.Append(CONSTLIT(".tlisp")); // Open the file CFileReadBlock InputFile(sRunFile); if (error = InputFile.Open()) { printf("error : Unable to open file '%s'.\n", sRunFile.GetASCIIZPointer()); return; } if (!bNoLogo) printf("%s\n", sRunFile.GetASCIIZPointer()); // Parse CString sInputFile(InputFile.GetPointer(0), InputFile.GetLength(), TRUE); CString sOutput; int iOffset = 0; while (true) { int iCharCount; ICCItem *pCode = Ctx.Link(sInputFile, iOffset, &iCharCount); if (pCode->IsNil()) break; else if (pCode->IsError()) { printf("error : %s\n", pCode->GetStringValue().GetASCIIZPointer()); Ctx.Discard(pCode); return; } iOffset += iCharCount; // Execute ICCItem *pResult = Ctx.Run(pCode); // Compose output if (pResult->IsIdentifier()) sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); else sOutput = CC.Unlink(pResult); // Free Ctx.Discard(pResult); Ctx.Discard(pCode); } // Output result printf("%s\n", sOutput.GetASCIIZPointer()); }
void GenerateShipTable (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j; // Some options bool bAllClasses = (pCmdLine->GetAttributeBool(CONSTLIT("allClasses")) || pCmdLine->GetAttributeBool(CONSTLIT("all"))); // Get the criteria from the command line. Always append 's' because we // want ship classes. CString sCriteria = strPatternSubst(CONSTLIT("%s s"), pCmdLine->GetAttribute(CONSTLIT("criteria"))); CDesignTypeCriteria Criteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } // Generate a list of columns to display TArray<CString> Cols; Cols.Insert(FIELD_LEVEL); Cols.Insert(FIELD_NAME); for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (strEquals(sAttrib, FIELD_BALANCE)) { Cols.Insert(CONSTLIT("balanceType")); Cols.Insert(CONSTLIT("combatStrength")); Cols.Insert(CONSTLIT("damage")); Cols.Insert(CONSTLIT("defenseStrength")); } else if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, CONSTLIT("shiptable"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols[j].GetASCIIZPointer()); } printf("\n"); // Generate a table CSymbolTable Table(FALSE, TRUE); // Loop over all items that match and add them to // a sorted table. for (i = 0; i < Universe.GetShipClassCount(); i++) { CShipClass *pClass = Universe.GetShipClass(i); // Only include generic classes unless otherwise specified if (!bAllClasses && !pClass->HasLiteralAttribute(CONSTLIT("genericClass"))) continue; if (!pClass->MatchesCriteria(Criteria)) continue; // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%04d%s%d", pClass->GetLevel(), pClass->GetNounPhrase(0).GetASCIIZPointer(), pClass->GetUNID()); Table.AddEntry(CString(szBuffer), (CObject *)pClass); } // Output table CCodeChainCtx CCCtx; for (i = 0; i < Table.GetCount(); i++) { CShipClass *pClass = (CShipClass *)Table.GetValue(i); // Output each row for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Cols[j]; ICCItem *pResult = pClass->GetProperty(CCCtx, sField); if (strEquals(sField, FIELD_MANEUVER) || strEquals(sField, FIELD_THRUST_TO_WEIGHT)) printf("%.1f", pResult->GetIntegerValue() / 1000.0); else if (strEquals(sField, FIELD_SCORE_CALC)) printf("%d", pClass->CalcScore()); else { CString sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); printf(sValue.GetASCIIZPointer()); } } printf("\n"); } printf("\n"); }
int AlchemyMain (CXMLElement *pCmdLine) // AlchemyMain // // Main entry-point after kernel initialization { ALERROR error; bool bLogo = !pCmdLine->GetAttributeBool(NO_LOGO_SWITCH); if (bLogo) { printf("CCShell v1.0\n"); printf("Copyright (c) 2010 by George Moromisato. All Rights Reserved.\n\n"); } // Initialize CodeChain environment CCodeChain CC; if (error = CC.Boot()) { PrintError(ERR_UNABLE_TO_INIT_CODECHAIN); return 1; } // Load some functions if (error = RegisterShellPrimitives(CC)) { PrintError(ERR_UNABLE_TO_REGISTER_PRIMITIVES); return 1; } // Prepare context SExecuteCtx Ctx; Ctx.bQuit = false; // Interpreter loop while (!Ctx.bQuit) { // Prompt printf(": "); // Read a line CString sInput; char *pDest = sInput.GetWritePointer(65536); if (fgets(pDest, 65536, stdin) == NULL) { PrintError(ERR_INVALID_INPUT); continue; } sInput.Truncate(strlen(sInput.GetASCIIZPointer())); // Parse the line ICCItem *pCode = CC.Link(sInput, 0, NULL); if (pCode->IsError()) { printf("codechain: %s\n", pCode->Print(&CC).GetASCIIZPointer()); pCode->Discard(&CC); continue; } // Execute ICCItem *pResult = CC.TopLevel(pCode, &Ctx); // Output if (pResult->IsError()) printf("codechain: %s\n", pResult->Print(&CC).GetASCIIZPointer()); else printf("%s\n", pResult->Print(&CC).GetASCIIZPointer()); // Done pCode->Discard(&CC); pResult->Discard(&CC); } return 0; }
void GenerateTypeTable (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j; // Get the criteria from the command line. CString sCriteria = pCmdLine->GetAttribute(CRITERIA_ATTRIB); // Parse it CDesignTypeCriteria Criteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } // Generate a table of all matching types TSortMap<CString, CDesignType *> Table; // Loop over all items for this level and add them to // a sorted table. for (i = 0; i < Universe.GetDesignTypeCount(); i++) { CDesignType *pType = Universe.GetDesignType(i); int iLevel = pType->GetLevel(); if (!pType->MatchesCriteria(Criteria)) continue; // Get the name CString sName = pType->GetDataField(FIELD_NAME); if (*sName.GetASCIIZPointer() == '(') sName = strSubString(sName, 1, -1); // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%02d%s%08x", iLevel, sName.GetASCIIZPointer(), pType->GetUNID()); Table.Insert(CString(szBuffer), pType); } // Generate a list of columns to display TArray<CString> Cols; Cols.Insert(FIELD_LEVEL); Cols.Insert(FIELD_NAME); for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, CONSTLIT("typetable"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // If we need to output total count, then load the table CDesignTypeStats TotalCount; if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT) || pCmdLine->GetAttributeBool(FIELD_COUNT_DISTRIBUTION)) { if (LoadDesignTypeStats(Universe.GetDesignCollection().GetAdventureUNID(), &TotalCount) != NOERROR) { printf("ERROR: Unable to load type count table.\n"); return; } } // If we've got any entries in the table, output now if (Table.GetCount()) { // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols[j].GetASCIIZPointer()); } printf("\n"); // Output each row CCodeChainCtx CCCtx; for (i = 0; i < Table.GetCount(); i++) { CDesignType *pType = Table[i]; for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Cols[j]; // Format and output if (strEquals(sField, FIELD_TOTAL_COUNT)) { SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID()); double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0); printf("%.2f", rCount); } else if (strEquals(sField, FIELD_COUNT_DISTRIBUTION)) { SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID()); printf("%s", (pInfo ? pInfo->sDistribution : NULL_STR).GetASCIIZPointer()); } else { ICCItem *pResult = pType->GetProperty(CCCtx, sField); CString sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); pResult->Discard(&g_pUniverse->GetCC()); printf(sValue.GetASCIIZPointer()); } } printf("\n"); } printf("\n"); } else printf("No entries match criteria.\n"); }
void CCommandLineDisplay::OnKeyDown (int iVirtKey, DWORD dwKeyState) // OnKeyDown // // Handle WM_KEYDOWN { switch (iVirtKey) { case VK_BACK: InputBackspace(); break; case VK_DELETE: InputDelete(); break; case VK_RETURN: { CString sInput = GetInput(); if (!sInput.IsBlank()) { CCodeChain &CC = g_pUniverse->GetCC(); InputEnter(); CCodeChainCtx Ctx; ICCItem *pCode = Ctx.Link(sInput, 0, NULL); ICCItem *pResult = Ctx.Run(pCode); CString sOutput; if (pResult->IsIdentifier()) sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); else sOutput = CC.Unlink(pResult); Ctx.Discard(pResult); Ctx.Discard(pCode); Output(sOutput); } break; } case VK_TAB: { AutoCompleteSearch(); break; } case VK_UP: InputHistoryUp(); break; case VK_DOWN: InputHistoryDown(); break; case VK_LEFT: if (m_iCursorPos > 0) m_iCursorPos--; m_bInvalid = true; break; case VK_RIGHT: if (m_iCursorPos < m_sInput.GetLength()) m_iCursorPos++; m_bInvalid = true; break; case VK_HOME: m_iCursorPos = 0; m_bInvalid = true; break; case VK_END: m_iCursorPos = m_sInput.GetLength(); m_bInvalid = true; break; case VK_PRIOR: if (m_iScrollPos < 2*MAX_LINES) m_iScrollPos++; m_bInvalid = true; break; case VK_NEXT: if (m_iScrollPos > 0) m_iScrollPos--; m_bInvalid = true; break; } }