|
@@ -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;
|