Пример #1
0
static FxExpression *ParseAtan2(FScanner &sc, FName identifier, PClassActor *cls)
{
	FxExpression *a = ParseExpressionM(sc, cls);
	sc.MustGetToken(',');
	FxExpression *b = ParseExpressionM(sc, cls);
	sc.MustGetToken(')');
	return identifier == NAME_ATan2 ? new FxATan2(a, b, sc) : new FxATan2(b, a, sc);
}
Пример #2
0
static FxExpression *ParseExpressionM (FScanner &sc, PClassActor *cls)
{
	FxExpression *condition = ParseExpressionL (sc, cls);

	if (sc.CheckToken('?'))
	{
		FxExpression *truex = ParseExpressionM (sc, cls);
		sc.MustGetToken(':');
		FxExpression *falsex = ParseExpressionM (sc, cls);
		return new FxConditional(condition, truex, falsex);
	}
	else
	{
		return condition;
	}
}
Пример #3
0
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls)
{
	FxExpression *data = ParseExpressionM (sc, cls);

	FCompileContext ctx(cls);
	data = data->Resolve(ctx);

	return data;
}
Пример #4
0
static FxExpression *ParseClamp(FScanner &sc, PClassActor *cls)
{
	FxExpression *src = ParseExpressionM(sc, cls);
	sc.MustGetToken(',');
	FxExpression *min = ParseExpressionM(sc, cls);
	sc.MustGetToken(',');
	FxExpression *max = ParseExpressionM(sc, cls);
	sc.MustGetToken(')');

	// Build clamp(a,x,y) as min(max(a,x),y)
	TArray<FxExpression *> list(2);
	list.Reserve(2);
	list[0] = src;
	list[1] = min;
	FxExpression *maxexpr = new FxMinMax(list, NAME_Max, sc);
	list[0] = maxexpr;
	list[1] = max;
	return new FxMinMax(list, NAME_Min, sc);
}
Пример #5
0
static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cls)
{
	FRandom *rng = ParseRNG(sc);

	sc.MustGetToken('(');
	FxExpression *min = ParseExpressionM (sc, cls);
	sc.MustGetToken(',');
	FxExpression *max = ParseExpressionM (sc, cls);
	sc.MustGetToken(')');

	if (identifier == NAME_Random)
	{
		return new FxRandom(rng, min, max, sc);
	}
	else
	{
		return new FxFRandom(rng, min, max, sc);
	}
}
Пример #6
0
static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls)
{
	TArray<FxExpression*> list;
	for (;;)
	{
		FxExpression *expr = ParseExpressionM(sc, cls);
		list.Push(expr);
		if (sc.CheckToken(')'))
			break;
		sc.MustGetToken(',');
	}
	return new FxMinMax(list, identifier, sc);
}
Пример #7
0
static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls)
{
	FRandom *rng = ParseRNG(sc);
	FxExpression *mask = NULL;

	sc.MustGetToken('(');

	if (!sc.CheckToken(')'))
	{
		mask = ParseExpressionM(sc, cls);
		sc.MustGetToken(')');
	}
	return new FxRandom2(rng, mask, sc);
}
Пример #8
0
static FxExpression *ParseExpressionA (FScanner &sc, PClassActor *cls)
{
	FxExpression *base_expr = ParseExpression0 (sc, cls);

	while(1)
	{
		FScriptPosition pos(sc);

#if 0
		if (sc.CheckToken('.'))
		{
			if (sc.CheckToken(TK_Default))
			{
				sc.MustGetToken('.');
				base_expr = new FxClassDefaults(base_expr, pos);
			}
			sc.MustGetToken(TK_Identifier);

			FName FieldName = sc.String;
			pos = sc;
			/* later!
			if (SC_CheckToken('('))
			{
				if (base_expr->IsDefaultObject())
				{
					SC_ScriptError("Cannot call methods for default.");
				}
				base_expr = ParseFunctionCall(base_expr, FieldName, false, false, pos);
			}
			else
			*/
			{
				base_expr = new FxDotIdentifier(base_expr, FieldName, pos);
			}
		}
		else 
#endif
			if (sc.CheckToken('['))
		{
			FxExpression *index = ParseExpressionM(sc, cls);
			sc.MustGetToken(']');
			base_expr = new FxArrayElement(base_expr, index);
		}
		else break;
	} 

	return base_expr;
}
Пример #9
0
static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls)
{
	bool floaty = identifier == NAME_FRandomPick;
	FRandom *rng;
	TArray<FxExpression*> list;
	list.Clear();
	int index = 0;

	rng = ParseRNG(sc);
	sc.MustGetToken('(');

	for (;;)
	{
		FxExpression *expr = ParseExpressionM(sc, cls);
		list.Push(expr);
		if (sc.CheckToken(')'))
			break;
		sc.MustGetToken(',');
	}
	return new FxRandomPick(rng, list, floaty, sc);
}
Пример #10
0
static FxExpression *ParseAbs(FScanner &sc, PClassActor *cls)
{
	FxExpression *x = ParseExpressionM (sc, cls);
	sc.MustGetToken(')');
	return new FxAbs(x); 
}
Пример #11
0
static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
{
	FScriptPosition scpos(sc);
	if (sc.CheckToken('('))
	{
		FxExpression *data = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');
		return data;
	}
	else if (sc.CheckToken(TK_True))
	{
		return new FxConstant(1, scpos);
	}
	else if (sc.CheckToken(TK_False))
	{
		return new FxConstant(0, scpos);
	}
	else if (sc.CheckToken(TK_IntConst))
	{
		return new FxConstant(sc.Number, scpos);
	}
	else if (sc.CheckToken(TK_FloatConst))
	{
		return new FxConstant(sc.Float, scpos);
	}
	else if (sc.CheckToken(TK_NameConst))
	{
		return new FxConstant(sc.Name, scpos);
	}
	else if (sc.CheckToken(TK_StringConst))
	{
		// String parameters are converted to names. Technically, this should be
		// done at a higher level, as needed, but since no functions take string
		// arguments and ACS_NamedExecuteWithResult/CallACS need names, this is
		// a cheap way to get them working when people use "name" instead of 'name'.
		return new FxConstant(FName(sc.String), scpos);
	}
	else if (sc.CheckToken(TK_Identifier))
	{
		FName identifier = FName(sc.String);
		FArgumentList *args;
		PFunction *func;

		switch (identifier)
		{
		case NAME_Random:
		case NAME_FRandom:
			return ParseRandom(sc, identifier, cls);
		case NAME_RandomPick:
		case NAME_FRandomPick:
			return ParseRandomPick(sc, identifier, cls);
		case NAME_Random2:
			return ParseRandom2(sc, cls);
		default:
			break;
		}
		if (sc.CheckToken('('))
		{
			switch (identifier)
			{
			case NAME_Min:
			case NAME_Max:
				return ParseMinMax(sc, identifier, cls);
			case NAME_Clamp:
				return ParseClamp(sc, cls);
			case NAME_Abs:
				return ParseAbs(sc, cls);
			default:
				args = new FArgumentList;
				func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
				try
				{
					// There is an action function ACS_NamedExecuteWithResult which must be ignored here for this to work.
					if (func != NULL && identifier != NAME_ACS_NamedExecuteWithResult)
					{
						sc.UnGet();
						ParseFunctionParameters(sc, cls, *args, func, "", NULL);
						return new FxVMFunctionCall(func, args, sc);
					}
					else if (!sc.CheckToken(')'))
					{
						do
						{
							args->Push(ParseExpressionM (sc, cls));
						}
						while (sc.CheckToken(','));
						sc.MustGetToken(')');
					}
					return new FxFunctionCall(NULL, identifier, args, sc);
				}
				catch (...)
				{
					delete args;
					throw;
				}
				break;
			}
		}	
		else
		{
			return new FxIdentifier(identifier, sc);
		}
	}
	else
	{
		FString tokname = sc.TokenName(sc.TokenType, sc.String);
		sc.ScriptError ("Unexpected token %s", tokname.GetChars());
	}
	return NULL;
}
Пример #12
0
static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
{
	FScriptPosition scpos(sc);
	if (sc.CheckToken('('))
	{
		FxExpression *data = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');
		return data;
	}
	else if (sc.CheckToken(TK_True))
	{
		return new FxConstant(1, scpos);
	}
	else if (sc.CheckToken(TK_False))
	{
		return new FxConstant(0, scpos);
	}
	else if (sc.CheckToken(TK_IntConst))
	{
		return new FxConstant(sc.Number, scpos);
	}
	else if (sc.CheckToken(TK_FloatConst))
	{
		return new FxConstant(sc.Float, scpos);
	}
	else if (sc.CheckToken(TK_NameConst))
	{
		return new FxConstant(sc.Name, scpos);
	}
	else if (sc.CheckToken(TK_StringConst))
	{
		// String parameters are converted to names. Technically, this should be
		// done at a higher level, as needed, but since no functions take string
		// arguments and ACS_NamedExecuteWithResult/CallACS need names, this is
		// a cheap way to get them working when people use "name" instead of 'name'.
		return new FxConstant(FName(sc.String), scpos);
	}
	else if (sc.CheckToken(TK_Random))
	{
		FRandom *rng;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}
		sc.MustGetToken('(');

		FxExpression *min = ParseExpressionM (sc, cls);
		sc.MustGetToken(',');
		FxExpression *max = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');

		return new FxRandom(rng, min, max, sc);
	}
	else if (sc.CheckToken(TK_RandomPick) || sc.CheckToken(TK_FRandomPick))
	{
		bool floaty = sc.TokenType == TK_FRandomPick;
		FRandom *rng;
		TArray<FxExpression*> list;
		list.Clear();
		int index = 0;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}
		sc.MustGetToken('(');

		for (;;)
		{
			FxExpression *expr = ParseExpressionM(sc, cls);
			list.Push(expr);
			if (sc.CheckToken(')'))
				break;
			sc.MustGetToken(',');
		}
		return new FxRandomPick(rng, list, floaty, sc);
	}
	else if (sc.CheckToken(TK_FRandom))
	{
		FRandom *rng;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}
		sc.MustGetToken('(');

		FxExpression *min = ParseExpressionM (sc, cls);
		sc.MustGetToken(',');
		FxExpression *max = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');

		return new FxFRandom(rng, min, max, sc);
	}
	else if (sc.CheckToken(TK_Random2))
	{
		FRandom *rng;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}

		sc.MustGetToken('(');

		FxExpression *mask = NULL;

		if (!sc.CheckToken(')'))
		{
			mask = ParseExpressionM(sc, cls);
			sc.MustGetToken(')');
		}
		return new FxRandom2(rng, mask, sc);
	}
	else if (sc.CheckToken(TK_Abs))
	{
		sc.MustGetToken('(');
		FxExpression *x = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');
		return new FxAbs(x); 
	}
	else if (sc.CheckToken(TK_Identifier))
	{
		FName identifier = FName(sc.String);
		if (sc.CheckToken('('))
		{
			FArgumentList *args = new FArgumentList;
			PFunction *func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
			try
			{
				if (func != NULL)
				{
					sc.UnGet();
					ParseFunctionParameters(sc, cls, *args, func, "", NULL);
					return new FxVMFunctionCall(func, args, sc);
				}
				else if (!sc.CheckToken(')'))
				{
					do
					{
						args->Push(ParseExpressionM (sc, cls));
					}
					while (sc.CheckToken(','));
					sc.MustGetToken(')');
				}
				return new FxFunctionCall(NULL, identifier, args, sc);
			}
			catch (...)
			{
				delete args;
				throw;
			}
		}	
		else
		{
			return new FxIdentifier(identifier, sc);
		}
	}
	else
	{
		FString tokname = sc.TokenName(sc.TokenType, sc.String);
		sc.ScriptError ("Unexpected token %s", tokname.GetChars());
	}
	return NULL;
}