Beispiel #1
0
void CEffectCreator::InitPainterParameters (CCreatePainterCtx &Ctx, IEffectPainter *pPainter)

//	InitPainterParameters
//
//	Initialize painter parameters

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerEffectType(evtGetParameters, &Event))
		{
		CCodeChainCtx CCCtx;

		CCCtx.SaveAndDefineDataVar(Ctx.GetData());

		ICCItem *pResult = CCCtx.Run(Event);
		if (pResult->IsError())
			::kernelDebugLogMessage(CONSTLIT("EffectType %x GetParameters: %s"), GetUNID(), (LPSTR)pResult->GetStringValue());
		else if (pResult->IsSymbolTable())
			{
			int i;
			CCSymbolTable *pTable = (CCSymbolTable *)pResult;

			for (i = 0; i < pTable->GetCount(); i++)
				{
				CString sParam = pTable->GetKey(i);
				ICCItem *pValue = pTable->GetElement(i);
				CEffectParamDesc Value;

				if (pValue->IsNil())
					Value.InitNull();
				else if (pValue->IsInteger())
					Value.InitInteger(pValue->GetIntegerValue());
				else if (pValue->IsIdentifier())
					{
					CString sValue = pValue->GetStringValue();
					char *pPos = sValue.GetASCIIZPointer();

					//	If this is a color, parse it

					if (*pPos == '#')
						Value.InitColor(::LoadRGBColor(sValue));

					//	Otherwise, a string

					else
						Value.InitString(sValue);
					}

				pPainter->SetParam(Ctx, sParam, Value);
				}
			}
		else
			::kernelDebugLogMessage(CONSTLIT("EffectType %x GetParameters: Expected struct result."), GetUNID());

		CCCtx.Discard(pResult);
		}
	}
ALERROR CLanguageDataBlock::InitFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	InitFromXML
//
//	Initializes from an XML block

	{
	int i;

	for (i = 0; i < pDesc->GetContentElementCount(); i++)
		{
		CXMLElement *pItem = pDesc->GetContentElement(i);
		CString sID = pItem->GetAttribute(ID_ATTRIB);
		if (sID.IsBlank())
			{
			Ctx.sError = strPatternSubst(CONSTLIT("Invalid id in <Language> block"));
			return ERR_FAIL;
			}

		if (strEquals(pItem->GetTag(), TEXT_TAG))
			{
			//	Link the code

			CCodeChainCtx CCCtx;
			ICCItem *pCode = CCCtx.Link(pItem->GetContentText(0), 0, NULL);
			if (pCode->IsError())
				{
				Ctx.sError = strPatternSubst(CONSTLIT("Language id: %s : %s"), sID, pCode->GetStringValue());
				return ERR_FAIL;
				}

			//	Add an entry

			bool bIsNew;
			SEntry *pEntry = m_Data.SetAt(sID, &bIsNew);
			if (!bIsNew)
				{
				Ctx.sError = strPatternSubst(CONSTLIT("Duplicate <Language> element: %s"), sID);
				return ERR_FAIL;
				}

			//	If pCode is a string and not an identifier, then we can just
			//	store it directly.

			if (pCode->IsIdentifier() && pCode->IsQuoted())
				{
				pEntry->pCode = NULL;
				pEntry->sText = pCode->GetStringValue();
				}

			//	Otherwise we store the code

			else
				pEntry->pCode = pCode->Reference();

			//	Done

			CCCtx.Discard(pCode);
			}
		else if (strEquals(pItem->GetTag(), MESSAGE_TAG))
			{
			//	Add an entry

			bool bIsNew;
			SEntry *pEntry = m_Data.SetAt(sID, &bIsNew);
			if (!bIsNew)
				{
				Ctx.sError = strPatternSubst(CONSTLIT("Duplicate <Language> element: %s"), sID);
				return ERR_FAIL;
				}

			//	Set the text

			pEntry->pCode = NULL;
			pEntry->sText = pItem->GetAttribute(TEXT_ATTRIB);
			}
		else
			{
			Ctx.sError = strPatternSubst(CONSTLIT("Invalid element in <Language> block: <%s>"), pItem->GetTag());
			return ERR_FAIL;
			}
		}

	return NOERROR;
	}
Beispiel #3
0
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());
				}
			}
		}
	}
Beispiel #4
0
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());
	}
Beispiel #5
0
ICCItem *CCodeChain::EvaluateArgs (CEvalContext *pCtx, ICCItem *pArgs, const CString &sArgValidation)

//	EvaluateArgs
//
//	Evaluate arguments and validate their types

	{
	ICCItem *pArg;
	ICCItem *pNew;
	ICCItem *pError;
	CCLinkedList *pEvalList;
	char *pValidation;
	int i;
	BOOL bNoEval;

	//	If the argument list if quoted, then it means that the arguments
	//	have already been evaluated. This happens if we've been called by
	//	(apply).

	bNoEval = pArgs->IsQuoted();

	//	Create a list to hold the results

	pNew = CreateLinkedList();
	if (pNew->IsError())
		return pNew;

	pEvalList = dynamic_cast<CCLinkedList *>(pNew);

	//	Start parsing at the beginning

	pValidation = sArgValidation.GetPointer();

	//	If there is a '*' in the validation, figure out
	//	how many arguments it represents

	int iVarArgs = Max(0, pArgs->GetCount() - (sArgValidation.GetLength() - 1));

	//	Loop over each argument

	for (i = 0; i < pArgs->GetCount(); i++)
		{
		ICCItem *pResult;

		pArg = pArgs->GetElement(i);

		//	If we're processing variable args, see if we're done

		if (*pValidation == '*')
			{
			if (iVarArgs == 0)
				pValidation++;
			else
				iVarArgs--;
			}

		//	Evaluate the item. If the arg is 'q' or 'u' then we 
		//	don't evaluate it.

		if (bNoEval || *pValidation == 'q' || *pValidation == 'u')
			pResult = pArg->Reference();

		//	If the arg is 'c' then we don't evaluate unless it is
		//	a lambda expression (or an identifier)

		else if (*pValidation == 'c' && !pArg->IsLambdaExpression() && !pArg->IsIdentifier())
			pResult = pArg->Reference();

		//	Evaluate

		else
			{
			pResult = Eval(pCtx, pArg);

			//	We don't want to return on error because some functions
			//	might want to pass errors around

			if (*pValidation != 'v' && *pValidation != '*')
				{
				if (pResult->IsError())
					{
					pEvalList->Discard(this);
					return pResult;
					}
				}
			}

		//	Check to see if the item is valid

		switch (*pValidation)
			{
			//	We expect a function...

			case 'f':
				{
				if (!pResult->IsFunction())
					{
					pError = CreateError(LITERAL("Function expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//  We expect a numeral...
			//
			//	NOTE: We treat integer the same a numeral because it's not always
			//	clear to the user when they've created a double or an integer.
			//	It is up to the actual function to use the integer or double 
			//	value appropriately.

			case 'i':
			case 'n':
				{
				if (!pResult->IsDouble() && !pResult->IsInteger())
					{
					pError = CreateError(LITERAL("Numeral expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//  We expect a double...

			case 'd':
				{
				if (!pResult->IsDouble())
					{
					pError = CreateError(LITERAL("Double expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//  We expect a vEctor...

			case 'e':
				{
				if (!(pResult->GetValueType() == ICCItem::Vector))
					{
					pError = CreateError(LITERAL("Vector expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//	We expect a linked list

			case 'k':
				{
				if (pResult->GetClass()->GetObjID() != OBJID_CCLINKEDLIST)
					{
					pError = CreateError(LITERAL("Linked-list expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//	We expect a list

			case 'l':
				{
				if (!pResult->IsList())
					{
					pError = CreateError(LITERAL("List expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//	We expect an identifier

			case 's':
			case 'q':
				{
				if (!pResult->IsIdentifier())
					{
					pError = CreateError(LITERAL("Identifier expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//	We expect an atom table

			case 'x':
				{
				if (!pResult->IsAtomTable())
					{
					pError = CreateError(LITERAL("Atom table expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//	We expect a symbol table

			case 'y':
				{
				if (!pResult->IsSymbolTable())
					{
					pError = CreateError(LITERAL("Symbol table expected"), pResult);
					pResult->Discard(this);
					pEvalList->Discard(this);
					return pError;
					}
				break;
				}

			//	We expect anything

			case 'c':
			case 'u':
			case 'v':
				break;

			//	We expect any number of anythings...

			case '*':
				break;

			//	Too many arguments

			case '\0':
				{
				pError = CreateError(LITERAL("Too many arguments"), NULL);
				pResult->Discard(this);
				pEvalList->Discard(this);
				return pError;
				}

			default:
				ASSERT(FALSE);
			}

		//	Add the result to the list

		pEvalList->Append(*this, pResult);
		pResult->Discard(this);

		//	Next validation sequence (note that *pValidation can never
		//	be '\0' because we return above if we find it)

		if (*pValidation != '*')
			pValidation++;
		}

	//	Make sure we have enough arguments

	if (*pValidation != '\0' && *pValidation != '*')
		{
		pError = CreateError(LITERAL("Insufficient arguments"), NULL);
		pEvalList->Discard(this);
		return pError;
		}

	//	Return the evaluation list

	return pEvalList;
	}
Beispiel #6
0
ICCItem *CCodeChain::Eval (CEvalContext *pEvalCtx, ICCItem *pItem)

//	Eval
//
//	Evaluates the given item and returns a result

	{
	//	Errors always evaluate to themselves

	if (pItem->IsError())
		return pItem->Reference();

	//	If this item is quoted, then return an unquoted item

	if (pItem->IsQuoted())
		{
		//	If this is a literal symbol table then we need to evaluate its 
		//	values.

		if (pItem->IsSymbolTable())
			return EvalLiteralStruct(pEvalCtx, pItem);

		//	HACK: We clone the item so that when we try to modify a literal list we
		//	mody a copy instead of the original.

		else
			{
			ICCItem *pResult = pItem->Clone(this);
			pResult->ClearQuoted();
			return pResult;
			}
		}

	//	Evaluate differently depending on whether or not
	//	this is an atom or a list. If it is an atom, either return
	//	the value or look up the atom in a symbol table. If the item
	//	is a list, try to evaluate as a function

	else if (pItem->IsIdentifier())
		return Lookup(pEvalCtx, pItem);

	//	If this is an expression (a list with multiple terms) then we
	//	try to evaluate it.

	else if (pItem->IsExpression())
		{
		ICCItem *pFunctionName;
		ICCItem *pFunction;
		ICCItem *pArgs;
		ICCItem *pResult;

		//	The first element of the list is the function

		pFunctionName = pItem->Head(this);

		//	We must have a first element since this is a list (but not Nil)

		ASSERT(pFunctionName);

		//	If this is an identifier, then look up the function
		//	in the global symbols

		if (pFunctionName->IsIdentifier())
			pFunction = LookupFunction(pEvalCtx, pFunctionName);

		//	Otherwise, evaluate it

		else
			pFunction = Eval(pEvalCtx, pFunctionName);

		//	If we get an error, return it

		if (pFunction->IsError())
			return pFunction;

		//	Make sure this is a function

		if (!pFunction->IsFunction())
			{
			pFunction->Discard(this);
			return CreateError(LITERAL("Function name expected"), pFunctionName);
			}

		//	Get the arguments

		pArgs = pItem->Tail(this);

		//	Do it

		pResult = pFunction->Execute(pEvalCtx, pArgs);

		//	Handle error by appending the function call that failed

		if (pResult->IsError())
			{
			CCString *pError = dynamic_cast<CCString *>(pResult);
			if (pError)
				{
				CString sError = pError->GetValue();
				if (!sError.IsBlank())
					{
					char *pPos = sError.GetASCIIZPointer() + sError.GetLength() - 1;
					if (*pPos != '#')
						{
						sError.Append(strPatternSubst(CONSTLIT(" ### %s ###"), pItem->Print(this)));
						pError->SetValue(sError);
						}
					}
				}
			}

		//	Done

		pFunction->Discard(this);
		pArgs->Discard(this);
		return pResult;
		}
	
	//	Anything else is a literal so we return it.

	else
		return pItem->Reference();
	}
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;
		}
	}