src/Expression.cc

changeset 92
3a00d396bce2
parent 91
427eb377d53e
child 93
11a24b697f43
--- a/src/Expression.cc	Mon Feb 03 20:12:44 2014 +0200
+++ b/src/Expression.cc	Tue Feb 04 02:28:33 2014 +0200
@@ -54,7 +54,7 @@
 
 // =============================================================================
 //
-Expression::Expression (BotscriptParser* parser, EType reqtype, Lexer* lx) :
+Expression::Expression (BotscriptParser* parser, Lexer* lx, EType reqtype) :
 	mParser (parser),
 	mLexer (lx),
 	mType (reqtype),
@@ -68,8 +68,46 @@
 	if (mSymbols.IsEmpty())
 		Error ("Expected expression");
 
+	AdjustOperators();
+
+	for (ExpressionSymbol* sym : mSymbols)
+	{
+		switch (sym->GetType())
+		{
+			case ExpressionSymbol::eOperatorSymbol:
+			{
+				Print ("\t- Operator: %1\n", static_cast<ExpressionOperator*> (sym)->GetID());
+				break;
+			}
+
+			case ExpressionSymbol::eValueSymbol:
+			{
+				ExpressionValue* val = static_cast<ExpressionValue*> (sym);
+
+				if (val->IsConstexpr())
+					Print ("\t- Constant expression value: %1\n", val->GetValue());
+				else
+				{
+					Print ("\t- Databuffer value:\n");
+					val->GetBuffer()->Dump();
+				}
+				break;
+			}
+
+			case ExpressionSymbol::eColonSymbol:
+			{
+				Print ("\t- Colon");
+				break;
+			}
+		}
+	}
+
+	exit (0);
+
+	/*
 	Verify();
 	mResult = Evaluate();
+	*/
 }
 
 // =============================================================================
@@ -98,24 +136,25 @@
 		ScriptVariable* globalvar;
 		mLexer->MustGetNext();
 
+		Print ("Token type: %1\n", mLexer->DescribeTokenType (mLexer->GetTokenType()));
+
 		if (mLexer->GetTokenType() == tkColon)
 			return new ExpressionColon;
 
 		// Check for operator
-		for (const OperatorInfo* op : gOperators)
-			if (mLexer->GetTokenType() == op->token)
-				return new ExpressionOperator (op - gOperators);
+		for (const OperatorInfo& op : gOperators)
+			if (mLexer->GetTokenType() == op.token)
+				return new ExpressionOperator ((EOperator) (&op - &gOperators[0]));
 
 		// Check sub-expression
 		if (mLexer->GetTokenType() == tkParenStart)
 		{
-			mLexer->MustGetNext();
 			Expression expr (mParser, mLexer, mType);
 			mLexer->MustGetNext (tkParenEnd);
 			return expr.GetResult();
 		}
 
-		op = new ExpressionValue;
+		op = new ExpressionValue (mType);
 
 		// Check function
 		if (CommandInfo* comm = FindCommandByName (GetTokenString()))
@@ -171,28 +210,36 @@
 		{
 			case EVoidType:
 			case EUnknownType:
+			{
 				Error ("unknown identifier `%1` (expected keyword, function or variable)", GetTokenString());
 				break;
+			}
 
 			case EBoolType:
+			{
 				if ((tt = mLexer->GetTokenType()) == tkTrue || tt == tkFalse)
 				{
 					op->SetValue (tt == tkTrue ? 1 : 0);
 					return op;
 				}
+			}
 			case EIntType:
-				if (!mLexer->GetTokenType() != tkNumber)
+			{
+				if (mLexer->GetTokenType() != tkNumber)
 					throw failed;
 
 				op->SetValue (GetTokenString().ToLong());
 				return op;
+			}
 
 			case EStringType:
-				if (!mLexer->GetTokenType() != tkString)
+			{
+				if (mLexer->GetTokenType() != tkString)
 					throw failed;
 
 				op->SetValue (GetStringTableIndex (GetTokenString()));
 				return op;
+			}
 		}
 
 		assert (false);
@@ -203,11 +250,39 @@
 		// We use a local enum here since catch(...) would catch Error() calls.
 		mLexer->SetPosition (pos);
 		delete op;
-		return false;
+		return null;
 	}
 
 	assert (false);
-	return false;
+	return null;
+}
+
+// =============================================================================
+//
+// The symbol parsing process only does token-based checking for operators. Thus
+// ALL minus operators are actually unary minuses simply because both have
+// tkMinus as their token and the unary minus is prior to the binary minus in
+// the operator table. Now that we have all symbols present, we can correct
+// cases like this.
+//
+void Expression::AdjustOperators()
+{
+	for (auto it = mSymbols.begin() + 1; it != mSymbols.end(); ++it)
+	{
+		if ((*it)->GetType() != ExpressionSymbol::eOperatorSymbol)
+			continue;
+
+		ExpressionOperator* op = static_cast<ExpressionOperator*> (*it);
+
+		// Unary minus with a value as the previous symbol cannot really be
+		// unary; replace with binary minus.
+		if (op->GetID() == opUnaryMinus && (*(it - 1))->GetType() == ExpressionSymbol::eValueSymbol)
+		{
+			Print ("Changing symbol operator #%1 from %2 to %3\n",
+				it - mSymbols.begin(), op->GetID(), opSubtraction);
+			op->SetID (opSubtraction);
+		}
+	}
 }
 
 // =============================================================================
@@ -233,19 +308,26 @@
 
 // =============================================================================
 //
-ExpressionOperator::ExpressionOperator (int id) :
-	mID (id),
-	mType (eOperator) {}
+ExpressionOperator::ExpressionOperator (EOperator id) :
+	ExpressionSymbol (eOperatorSymbol),
+	mID (id) {}
 
 // =============================================================================
 //
-ExpressionValue::ExpressionValue(EType valuetype) :
+ExpressionValue::ExpressionValue (EType valuetype) :
+	ExpressionSymbol (eValueSymbol),
 	mBuffer (null),
-	mType (eOperand),
 	mValueType (valuetype) {}
 
 // =============================================================================
 //
+ExpressionValue::~ExpressionValue()
+{
+	delete mBuffer;
+}
+
+// =============================================================================
+//
 void ExpressionValue::ConvertToBuffer()
 {
 	if (IsConstexpr() == false)

mercurial