protected Parsed.Object TempDeclarationOrAssignment() { Whitespace(); bool isNewDeclaration = ParseTempKeyword(); Whitespace(); Identifier varIdentifier = null; if (isNewDeclaration) { varIdentifier = (Identifier)Expect(IdentifierWithMetadata, "variable name"); } else { varIdentifier = Parse(IdentifierWithMetadata); } if (varIdentifier == null) { return(null); } Whitespace(); // += -= bool isIncrement = ParseString("+") != null; bool isDecrement = ParseString("-") != null; if (isIncrement && isDecrement) { Error("Unexpected sequence '+-'"); } if (ParseString("=") == null) { // Definitely in an assignment expression? if (isNewDeclaration) { Error("Expected '='"); } return(null); } Expression assignedExpression = (Expression)Expect(Expression, "value expression to be assigned"); if (isIncrement || isDecrement) { var result = new IncDecExpression(varIdentifier, assignedExpression, isIncrement); return(result); } else { var result = new VariableAssignment(varIdentifier, assignedExpression); result.isNewTemporaryDeclaration = isNewDeclaration; return(result); } }
protected Expression ExpressionUnary() { // Divert target is a special case - it can't have any other operators // applied to it, and we also want to check for it first so that we don't // confuse "->" for subtraction. var divertTarget = Parse(ExpressionDivertTarget); if (divertTarget != null) { return(divertTarget); } var prefixOp = (string)OneOf(String("-"), String("!")); // Don't parse like the string rules above, in case its actually // a variable that simply starts with "not", e.g. "notable". // This rule uses the Identifier rule, which will scan as much text // as possible before returning. if (prefixOp == null) { prefixOp = Parse(ExpressionNot); } Whitespace(); // - Since we allow numbers at the start of variable names, variable names are checked before literals // - Function calls before variable names in case we see parentheses var expr = OneOf(ExpressionList, ExpressionParen, ExpressionFunctionCall, ExpressionVariableName, ExpressionLiteral) as Expression; // Only recurse immediately if we have one of the (usually optional) unary ops if (expr == null && prefixOp != null) { expr = ExpressionUnary(); } if (expr == null) { return(null); } if (prefixOp != null) { expr = UnaryExpression.WithInner(expr, prefixOp); } Whitespace(); var postfixOp = (string)OneOf(String("++"), String("--")); if (postfixOp != null) { bool isInc = postfixOp == "++"; if (!(expr is VariableReference)) { Error("can only increment and decrement variables, but saw '" + expr + "'"); // Drop down and succeed without the increment after reporting error } else { // TODO: Language Server - (Identifier combined into one vs. list of Identifiers) var varRef = (VariableReference)expr; expr = new IncDecExpression(varRef.identifier, isInc); } } return(expr); }