Browse Source

Initial implmentation of ternary logic

Bepsi 6 years ago
parent
commit
28e74f3c05

+ 12 - 0
NTERA.Interpreter/Compiler/Lexer.cs

@@ -236,6 +236,18 @@ namespace NTERA.Interpreter.Compiler
 
 					return Token.And;
 
+				case '\\':
+					if (peek)
+						GetNextChar();
+
+					if (GetNextChar(true) == '@')
+					{
+						GetNextChar();
+						return Token.TernaryEscape;
+					}
+
+					return Token.Unknown;
+
 				case '|':
 					if (peek)
 						GetNextChar();

+ 54 - 4
NTERA.Interpreter/Compiler/Parser.cs

@@ -625,7 +625,7 @@ namespace NTERA.Interpreter.Compiler
 			{ Token.Caret, 4 }
 		};
 
-		protected ExecutionNode Expression(out ParserError error, bool useModulo = true)
+		protected ExecutionNode Expression(out ParserError error, bool useModulo = true, bool ternaryString = false)
 		{
 			error = null;
 			var operators = new Stack<Token>();
@@ -699,6 +699,9 @@ namespace NTERA.Interpreter.Compiler
 				   && token != Token.Colon
 				   && token != Token.CloseBracket
 				   && token != Token.RParen
+				   && token != Token.QuestionMark
+				   && token != Token.Sharp
+				   && token != Token.TernaryEscape
 				   && (useModulo || token != Token.Modulo))
 			{
 				if (token == Token.Value)
@@ -794,10 +797,23 @@ namespace NTERA.Interpreter.Compiler
 				return null;
 			}
 
-			return operands.Pop();
+			var result = operands.Pop();
+
+			if (token != Token.QuestionMark)
+				return result;
+
+			var resultTrue = ternaryString ? ParseString(out error, useModulo, true, true) : Expression(out error);
+			if (error != null)
+				return null;
+
+			var resultFalse = ternaryString ? ParseString(out error, useModulo, true, true) : Expression(out error);
+			if (error != null)
+				return null;
+
+			return CallMethod("__IMPLICITIF", CurrentPosition, result, resultTrue, resultFalse);
 		}
 
-		protected ExecutionNode ParseString(out ParserError error, bool implicitString, bool canFormat = false)
+		protected ExecutionNode ParseString(out ParserError error, bool implicitString, bool canFormat = false, bool nestedTernary = false)
 		{
 			error = null;
 			ExecutionNode value = null;
@@ -805,6 +821,9 @@ namespace NTERA.Interpreter.Compiler
 			if (Lexer.IsPeeking)
 				Lexer.GetNextChar();
 
+			if (nestedTernary && (Lexer.CurrentChar == '?' || Lexer.CurrentChar == '#'))
+				Lexer.GetNextChar();
+
 			if (char.IsWhiteSpace(Lexer.CurrentChar))
 				Lexer.GetNextChar();
 
@@ -828,9 +847,38 @@ namespace NTERA.Interpreter.Compiler
 					continue;
 				}
 
+				if (nestedTernary && Lexer.CurrentChar == '#')
+					break;
+
+				if (Lexer.CurrentChar == '\\')
+				{
+					Lexer.GetNextChar();
+
+					if (Lexer.CurrentChar == '@')
+					{
+						if (nestedTernary)
+							break;
+
+						var expressionValue = Expression(out error, true, true);
+						if (error != null)
+							return null;
+
+						value = value == null
+							? expressionValue
+							: OperateNodes(value, expressionValue, Token.Plus);
+					}
+
+					currentBlock.Append(Lexer.CurrentChar);
+
+					Lexer.GetNextChar();
+					continue;
+				}
+
 				if (canFormat && Lexer.CurrentChar == '%')
 				{
 					var expressionValue = Expression(out error, false);
+					if (error != null)
+						return null;
 
 					value = value == null
 						? expressionValue
@@ -843,6 +891,8 @@ namespace NTERA.Interpreter.Compiler
 				if (canFormat && Lexer.CurrentChar == '{')
 				{
 					var expressionValue = Expression(out error, true);
+					if (error != null)
+						return null;
 
 					value = value == null
 						? expressionValue
@@ -856,7 +906,7 @@ namespace NTERA.Interpreter.Compiler
 				Lexer.GetNextChar();
 			}
 
-			if (!implicitString && (Lexer.CurrentChar == '\0' || Lexer.CurrentChar == '\n'))
+			if (!nestedTernary && !implicitString && (Lexer.CurrentChar == '\0' || Lexer.CurrentChar == '\n'))
 			{
 				error = new ParserError("Was expecting string to be closed", CurrentPosition);
 				return null;

+ 5 - 0
NTERA.Interpreter/Compiler/Token.cs

@@ -84,6 +84,11 @@
 		[LexerCharacter(')')]
 		RParen,
 
+		[LexerCharacter('?')]
+		QuestionMark,
+
+		TernaryEscape,
+
 		EOF = -1 //End Of File
 	}