Added support for the ternary operator.

Sat, 25 Aug 2012 03:04:14 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 25 Aug 2012 03:04:14 +0300
changeset 55
173956c1ac27
parent 54
8cc91ef94754
child 56
384c5605bda9

Added support for the ternary operator.

parser.cxx file | annotate | diff | comparison | revisions
scriptreader.h file | annotate | diff | comparison | revisions
--- a/parser.cxx	Tue Aug 14 01:54:17 2012 +0300
+++ b/parser.cxx	Sat Aug 25 03:04:14 2012 +0300
@@ -713,10 +713,31 @@
 		MustNext ();
 		DataBuffer* rb = ParseExprValue (reqtype);
 		
-		// Write to buffer
-		retbuf->Merge (rb);
-		long dh = DataHeaderByOperator (NULL, oper);
-		retbuf->Write<word> (dh);
+		// Ternary operator requires - naturally - a third operator
+		if (oper == OPER_TERNARY) {
+			MustNext (":");
+			MustNext ();
+			DataBuffer* tb = ParseExprValue (reqtype);
+			
+			// It also is handled differently: there isn't a dataheader for ternary
+			// operator. Instead, we abuse PUSHNUMBER and IFNOTGOTO for this.
+			int mark1 = retbuf->AddMark (""); // start of "else" case
+			int mark2 = retbuf->AddMark (""); // end of expression
+			retbuf->Write<word> (DH_IFNOTGOTO);
+			retbuf->AddMarkReference (mark1);
+			retbuf->Merge (rb);
+			retbuf->Write<word> (DH_GOTO);
+			retbuf->AddMarkReference (mark2);
+			retbuf->MoveMark (mark1); // start of "else" case
+			retbuf->Merge (tb);
+			retbuf->Write<word> (DH_GOTO);
+			retbuf->AddMarkReference (mark2);
+			retbuf->MoveMark (mark2); // move endmark to end
+		} else {
+			// Write to buffer
+			retbuf->Merge (rb);
+			retbuf->Write<word> (DataHeaderByOperator (NULL, oper));
+		}
 	}
 	
 	return retbuf;
@@ -746,6 +767,7 @@
 		!oper.compare ("*") ? OPER_MULTIPLY :
 		!oper.compare ("/") ? OPER_DIVIDE :
 		!oper.compare ("%") ? OPER_MODULUS :
+		!oper.compare ("?") ? OPER_TERNARY :
 		-1;
 	
 	if (o != -1) {
--- a/scriptreader.h	Tue Aug 14 01:54:17 2012 +0300
+++ b/scriptreader.h	Sat Aug 25 03:04:14 2012 +0300
@@ -182,6 +182,7 @@
 	OPER_BITWISEOR,
 	OPER_BITWISEAND,
 	OPER_BITWISEEOR,
+	OPER_TERNARY,
 };
 
 // Mark types

mercurial