src/Parser.cc

changeset 92
3a00d396bce2
parent 91
427eb377d53e
child 97
49e38433b9fd
--- a/src/Parser.cc	Mon Feb 03 20:12:44 2014 +0200
+++ b/src/Parser.cc	Tue Feb 04 02:28:33 2014 +0200
@@ -393,7 +393,6 @@
 	mLexer->MustGetNext (tkParenStart);
 
 	// Read the expression and write it.
-	mLexer->MustGetNext();
 	DataBuffer* c = ParseExpression (EIntType);
 	buffer()->MergeAndDestroy (c);
 
@@ -459,7 +458,6 @@
 
 	// Condition
 	mLexer->MustGetNext (tkParenStart);
-	mLexer->MustGetNext();
 	DataBuffer* expr = ParseExpression (EIntType);
 	mLexer->MustGetNext (tkParenEnd);
 	mLexer->MustGetNext (tkBraceStart);
@@ -495,7 +493,6 @@
 	mLexer->MustGetNext (tkSemicolon);
 
 	// Condition
-	mLexer->MustGetNext();
 	DataBuffer* cond = ParseExpression (EIntType);
 
 	if (cond == null)
@@ -563,7 +560,6 @@
 	CheckNotToplevel();
 	PushScope();
 	mLexer->MustGetNext (tkParenStart);
-	mLexer->MustGetNext();
 	buffer()->MergeAndDestroy (ParseExpression (EIntType));
 	mLexer->MustGetNext (tkParenEnd);
 	mLexer->MustGetNext (tkBraceStart);
@@ -739,7 +735,6 @@
 			{
 				mLexer->MustGetNext (tkWhile);
 				mLexer->MustGetNext (tkParenStart);
-				mLexer->MustGetNext();
 				DataBuffer* expr = ParseExpression (EIntType);
 				mLexer->MustGetNext (tkParenEnd);
 				mLexer->MustGetNext (tkSemicolon);
@@ -1019,7 +1014,7 @@
 			Error ("too many arguments passed to %1\n\tusage is: %2",
 				comm->name, comm->GetSignature());
 
-		r->MergeAndDestroy (ParseExpression (comm->args[curarg].type));
+		r->MergeAndDestroy (ParseExpression (comm->args[curarg].type, true));
 		mLexer->MustGetNext();
 
 		if (curarg < comm->numargs - 1)
@@ -1061,80 +1056,6 @@
 }
 
 // ============================================================================
-// Is the given operator an assignment operator?
-//
-static bool IsAssignmentOperator (int oper)
-{
-	switch (oper)
-	{
-		case OPER_ASSIGNADD:
-		case OPER_ASSIGNSUB:
-		case OPER_ASSIGNMUL:
-		case OPER_ASSIGNDIV:
-		case OPER_ASSIGNMOD:
-		case OPER_ASSIGNLEFTSHIFT:
-		case OPER_ASSIGNRIGHTSHIFT:
-		case OPER_ASSIGN:
-			return true;
-	}
-
-	return false;
-}
-
-// ============================================================================
-// Finds an operator's corresponding dataheader
-//
-static word GetDataHeaderByOperator (ScriptVariable* var, int oper)
-{
-	if (IsAssignmentOperator (oper))
-	{
-		if (var == null)
-			Error ("operator %d requires left operand to be a variable\n", oper);
-
-		// TODO: At the moment, vars only are global
-		// OPER_ASSIGNLEFTSHIFT and OPER_ASSIGNRIGHTSHIFT do not
-		// have data headers, instead they are expanded out in
-		// the operator Parser
-		switch (oper)
-		{
-			case OPER_ASSIGNADD: return dhAddGlobalVar;
-			case OPER_ASSIGNSUB: return dhSubtractGlobalVar;
-			case OPER_ASSIGNMUL: return dhMultiplyGlobalVar;
-			case OPER_ASSIGNDIV: return dhDivideGlobalVar;
-			case OPER_ASSIGNMOD: return dhModGlobalVar;
-			case OPER_ASSIGN: return dhAssignGlobalVar;
-
-			default: Error ("bad assignment operator!\n");
-		}
-	}
-
-	switch (oper)
-	{
-		case OPER_ADD: return dhAdd;
-		case OPER_SUBTRACT: return dhSubtract;
-		case OPER_MULTIPLY: return dhMultiply;
-		case OPER_DIVIDE: return dhDivide;
-		case OPER_MODULUS: return dhModulus;
-		case OPER_EQUALS: return dhEquals;
-		case OPER_NOTEQUALS: return dhNotEquals;
-		case OPER_LESSTHAN: return dhLessThan;
-		case OPER_GREATERTHAN: return dhGreaterThan;
-		case OPER_LESSTHANEQUALS: return dhAtMost;
-		case OPER_GREATERTHANEQUALS: return dhAtLeast;
-		case OPER_LEFTSHIFT: return dhLeftShift;
-		case OPER_RIGHTSHIFT: return dhRightShift;
-		case OPER_OR: return dhOrLogical;
-		case OPER_AND: return dhAndLogical;
-		case OPER_BITWISEOR: return dhOrBitwise;
-		case OPER_BITWISEEOR: return dhEorBitwise;
-		case OPER_BITWISEAND: return dhAndBitwise;
-	}
-
-	Error ("DataHeaderByOperator: couldn't find dataheader for operator %d!\n", oper);
-	return 0;
-}
-
-// ============================================================================
 //
 String BotscriptParser::ParseFloat()
 {
@@ -1155,6 +1076,71 @@
 }
 
 // ============================================================================
+//
+// Parses an assignment operator.
+//
+EAssignmentOperator BotscriptParser::ParseAssignmentOperator()
+{
+	const List<EToken> tokens =
+	{
+		tkAssign,
+		tkAddAssign,
+		tkSubAssign,
+		tkMultiplyAssign,
+		tkDivideAssign,
+		tkModulusAssign
+	};
+
+	mLexer->MustGetAnyOf (tokens);
+
+	switch (mLexer->GetTokenType())
+	{
+		case tkAssign:			return EAssign;
+		case tkAddAssign:		return EAssignAdd;
+		case tkSubAssign:		return EAssignSub;
+		case tkMultiplyAssign:	return EAssignMul;
+		case tkDivideAssign:	return EAssignDiv;
+		case tkModulusAssign:	return EAssignMod;
+		default: break;
+	}
+
+	assert (false);
+	return (EAssignmentOperator) 0;
+}
+
+// ============================================================================
+//
+EDataHeader BotscriptParser::GetAssigmentDataHeader (EAssignmentOperator op, ScriptVariable* var)
+{
+	if (var->IsGlobal())
+	{
+		switch (op)
+		{
+			case EAssign:		return dhAssignGlobalVar;
+			case EAssignAdd:	return dhAddGlobalVar;
+			case EAssignSub:	return dhSubtractGlobalVar;
+			case EAssignMul:	return dhMultiplyGlobalVar;
+			case EAssignDiv:	return dhDivideGlobalVar;
+			case EAssignMod:	return dhModGlobalVar;
+		}
+	}
+
+	switch (op)
+	{
+		case EAssign:		return dhAssignLocalVar;
+		case EAssignAdd:	return dhAddLocalVar;
+		case EAssignSub:	return dhSubtractLocalVar;
+		case EAssignMul:	return dhMultiplyLocalVar;
+		case EAssignDiv:	return dhDivideLocalVar;
+		case EAssignMod:	return dhModLocalVar;
+	}
+
+	assert (false);
+	return (EDataHeader) 0;
+}
+
+// ============================================================================
+//
 // Parses an assignment. An assignment starts with a variable name, followed
 // by an assignment operator, followed by an expression value. Expects current
 // token to be the name of the variable, and expects the variable to be given.
@@ -1162,20 +1148,16 @@
 DataBuffer* BotscriptParser::ParseAssignment (ScriptVariable* var)
 {
 	// Get an operator
-	mLexer->MustGetNext();
-	int oper = ParseOperator();
-
-	if (IsAssignmentOperator (oper) == false)
-		Error ("expected assignment operator");
+	EAssignmentOperator oper = ParseAssignmentOperator();
 
 	if (mCurrentMode == ETopLevelMode)
 		Error ("can't alter variables at top level");
 
 	// Parse the right operand
-	mLexer->MustGetNext();
 	DataBuffer* retbuf = new DataBuffer;
 	DataBuffer* expr = ParseExpression (var->type);
 
+#if 0
 	// <<= and >>= do not have data headers. Solution: expand them.
 	// a <<= b -> a = a << b
 	// a >>= b -> a = a >> b
@@ -1190,11 +1172,14 @@
 	}
 	else
 	{
+#endif
 		retbuf->MergeAndDestroy (expr);
-		long dh = GetDataHeaderByOperator (var, oper);
+		EDataHeader dh = GetAssigmentDataHeader (oper, var);
 		retbuf->WriteDWord (dh);
 		retbuf->WriteDWord (var->index);
+#if 0
 	}
+#endif
 
 	return retbuf;
 }
@@ -1225,11 +1210,18 @@
 
 // ============================================================================
 //
-void BotscriptParser::ParseExpression (EType reqtype)
+DataBuffer* BotscriptParser::ParseExpression (EType reqtype, bool fromhere)
 {
-	Expression expr (this, reqtype, mLexer);
+	// hehe
+	if (fromhere == true)
+		mLexer->Skip (-1);
+
+	Expression expr (this, mLexer, reqtype);
 	expr.GetResult()->ConvertToBuffer();
-	buffer()->MergeAndDestroy (expr.GetResult()->GetBuffer());
+
+	// The buffer will be destroyed once the function ends so we need to
+	// clone it now.
+	return expr.GetResult()->GetBuffer()->Clone();
 }
 
 // ============================================================================

mercurial