Exemplo n.º 1
0
        private static void ReducePreOperator(Operator op, List <ParsingUnit> units)
        {
            for (int i = 0; i < units.Count; i++)
            {
                if (units[i].OperatorType == op)
                {
                    if (i == units.Count - 1)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Unable to parse PreOperator {op}: No following value");
                    }

                    if (units[i + 1].AsValueGetter == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i + 1].FirstToken,
                                  message: $"Unable to parse PreOperator {op}: Following value is not value not retrievable: {units[i + 1].FirstToken}");
                    }

                    //Cache Value and remove
                    IValueGetter value = units[i + 1].AsValueGetter;
                    units.RemoveAt(i + 1);

                    OperatorToken operatorToken = units[i].FirstToken as OperatorToken;

                    //Swap the ParsingUnit for the calculated value
                    switch (op)
                    {
                    case Operator.CastInteger:
                    case Operator.CastDouble:
                        units[i] = new ParsedValuedUnit(
                            value: CastOperation.CreateCastOperation(
                                arg: value,
                                operatorToken: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.Negate:
                        units[i] = new ParsedValuedUnit(
                            value: NegationOperation.CreateNegationOperation(
                                arg: value,
                                source: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.Not:
                        units[i] = new ParsedValuedUnit(
                            value: NotOperation.CreateNotOperation(
                                arg: value,
                                operatorToken: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    default:
                        throw new ArgumentException($"Unexpected Operator: {op}");
                    }
                }
            }
        }
Exemplo n.º 2
0
        private static void ReducePreFixes(List <ParsingUnit> units)
        {
            for (int i = 0; i < units.Count; i++)
            {
                if (units[i].OperatorType == Operator.Increment || units[i].OperatorType == Operator.Decrement)
                {
                    if (i == units.Count - 1 || units[i + 1].AsValue == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Operator {units[i].OperatorType} could not be resolved as a Post-Fix or a Pre-Fix.  It can only be attached to a modifiable value: {units[i].FirstToken}");
                    }

                    //Cache Value and remove
                    IValue value = units[i + 1].AsValue;
                    units.RemoveAt(i + 1);

                    OperatorToken operatorToken = units[i].FirstToken as OperatorToken;

                    //Swap the ParsingUnit for the calculated value
                    units[i] = new ParsedValuedUnit(
                        value: new UnaryValueOperation(
                            arg: value,
                            operatorToken: operatorToken,
                            prefix: true),
                        firstToken: units[i].FirstToken);
                }
            }
        }
Exemplo n.º 3
0
        private static void ReducePostFixes(List <ParsingUnit> units)
        {
            for (int i = 0; i < units.Count; i++)
            {
                //It's a postfix operator if it follows a modifiable value
                if (units[i].OperatorType == Operator.Increment || units[i].OperatorType == Operator.Decrement)
                {
                    if (i == 0 || units[i - 1].AsValue == null)
                    {
                        //Definitely not a postfix
                        continue;
                    }

                    //Cache operatortoken and remove operator
                    OperatorToken operatorToken = units[i].FirstToken as OperatorToken;
                    units.RemoveAt(i);

                    //Move to Variable position
                    i--;

                    //Swap the ParsingUnit for the calculated value
                    units[i] = new ParsedValuedUnit(
                        value: new UnaryValueOperation(
                            arg: units[i].AsValue,
                            operatorToken: operatorToken,
                            prefix: false),
                        firstToken: units[i].FirstToken);
                }
            }
        }
Exemplo n.º 4
0
        private static void ReduceMemberAccessAndIndexing(List <ParsingUnit> units)
        {
            for (int i = 0; i < units.Count; i++)
            {
                if (units[i] is MemberAccessUnit memberAccessUnit)
                {
                    if (i == 0)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression began with a {units[i].OperatorType} operator: {units[i].FirstToken}");
                    }

                    //Remove
                    units.RemoveAt(i);
                    i--;

                    //Swap the ParsingUnit for the calculated value
                    units[i] = new ParsedValuedUnit(
                        value: MemberManagement.HandleMemberExpression(
                            value: units[i].AsValueGetter,
                            args: memberAccessUnit.args,
                            identifier: memberAccessUnit.identifier,
                            source: memberAccessUnit.FirstToken),
                        firstToken: units[i].FirstToken);
                }
                else if (units[i] is IndexAccessUnit indexAccessUnit)
                {
                    if (i == 0)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression began with a {units[i].OperatorType} operator: {units[i].FirstToken}");
                    }

                    //Remove
                    units.RemoveAt(i);
                    i--;

                    //Swap the ParsingUnit for the calculated value
                    units[i] = new ParsedValuedUnit(
                        value: new IndexerOperation(
                            valueArg: units[i].AsValueGetter,
                            indexArg: indexAccessUnit.arg,
                            source: units[i].FirstToken),
                        firstToken: units[i].FirstToken);
                }
            }
        }
Exemplo n.º 5
0
        private static void ReduceAssignmentOperators(List <ParsingUnit> units)
        {
            for (int i = 0; i < units.Count; i++)
            {
                if (units[i].OperatorType == Operator.Assignment ||
                    units[i].OperatorType == Operator.PlusEquals ||
                    units[i].OperatorType == Operator.MinusEquals ||
                    units[i].OperatorType == Operator.TimesEquals ||
                    units[i].OperatorType == Operator.DivideEquals ||
                    units[i].OperatorType == Operator.PowerEquals ||
                    units[i].OperatorType == Operator.ModuloEquals ||
                    units[i].OperatorType == Operator.AndEquals ||
                    units[i].OperatorType == Operator.OrEquals)
                {
                    if (i == 0)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression began with a {units[i].OperatorType} operator: {units[i].FirstToken}");
                    }

                    if (i == units.Count - 1)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression ended with a {units[i].OperatorType} operator: {units[i].FirstToken}");
                    }

                    if (units[i - 1].AsValue == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i - 1].FirstToken,
                                  message: $"Expression before {units[i].OperatorType} operator must be modifiable: {units[i - 1].FirstToken}");
                    }

                    if (units[i + 1].AsValueGetter == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i + 1].FirstToken,
                                  message: $"Expression after {units[i].OperatorType} operator must have a value: {units[i + 1].FirstToken}");
                    }

                    OperatorToken operatorToken = units[i].FirstToken as OperatorToken;

                    //Cache Value and remove Right value and operator
                    IValueGetter value = units[i + 1].AsValueGetter;
                    units.RemoveAt(i + 1);
                    units.RemoveAt(i);

                    //adjust our current position
                    i--;

                    //Swap the ParsingUnit for the calculated value

                    switch (operatorToken.operatorType)
                    {
                    case Operator.Assignment:
                        units[i] = new ParsedValuedUnit(
                            value: new AssignmentOperation(
                                assignee: units[i].AsValue,
                                value: value,
                                source: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.PlusEquals:
                        units[i] = new ParsedValuedUnit(
                            value: new PlusEqualsOperation(
                                assignee: units[i].AsValue,
                                value: value,
                                source: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.MinusEquals:
                    case Operator.TimesEquals:
                    case Operator.DivideEquals:
                    case Operator.PowerEquals:
                    case Operator.ModuloEquals:
                        //Handle Numerical Operators
                        units[i] = new ParsedValuedUnit(
                            value: new NumericalInPlaceOperation(
                                assignee: units[i].AsValue,
                                value: value,
                                operatorType: operatorToken.operatorType,
                                source: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.AndEquals:
                    case Operator.OrEquals:
                        units[i] = new ParsedValuedUnit(
                            value: new BooleanInPlaceOperation(
                                assignee: units[i].AsValue,
                                value: value,
                                operatorType: operatorToken.operatorType,
                                source: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    default:
                        throw new ArgumentException($"Unexpected Operator: {operatorToken.operatorType}");
                    }
                }
            }
        }
Exemplo n.º 6
0
        private static void ReduceTernaryOperator(List <ParsingUnit> units)
        {
            for (int i = 0; i < units.Count; i++)
            {
                if (units[i].OperatorType == Operator.Ternary)
                {
                    if (i == 0)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression began with a {units[i].OperatorType} operator: {units[i].FirstToken}");
                    }

                    if (i >= units.Count - 2)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression with a {units[i].OperatorType} operator didn't contain enought arguments: {units[i].FirstToken}");
                    }

                    if (units[i - 1].AsValueGetter == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i - 1].FirstToken,
                                  message: $"Unexpected token before {units[i].OperatorType} operator: {units[i - 1].FirstToken}");
                    }

                    if (units[i + 1].AsValueGetter == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i + 1].FirstToken,
                                  message: $"Unexpected token after {units[i].OperatorType} operator: {units[i + 1].FirstToken}");
                    }

                    if (units[i + 2].AsValueGetter == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i + 1].FirstToken,
                                  message: $"Unexpected token for second arguemnt of {units[i].OperatorType} operator: {units[i + 2].FirstToken}");
                    }

                    OperatorToken operatorToken = units[i].FirstToken as OperatorToken;

                    //Cache Value and remove Right value and operator
                    IValueGetter arg1Value = units[i + 1].AsValueGetter;
                    IValueGetter arg2Value = units[i + 2].AsValueGetter;
                    units.RemoveAt(i + 2);
                    units.RemoveAt(i + 1);
                    units.RemoveAt(i);

                    //adjust our current position
                    i--;

                    //Swap the ParsingUnit for the calculated value
                    units[i] = new ParsedValuedUnit(
                        value: new TernaryOperation(
                            condition: units[i].AsValueGetter,
                            arg1: arg1Value,
                            arg2: arg2Value,
                            operatorToken: operatorToken),
                        firstToken: units[i].FirstToken);
                }
            }
        }
Exemplo n.º 7
0
        private static void ReduceBinaryOperator(
            Operator op,
            List <ParsingUnit> units)
        {
            for (int i = 0; i < units.Count; i++)
            {
                if (units[i].OperatorType == op)
                {
                    if (i == 0)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression began with a {units[i].OperatorType} operator: {units[i].FirstToken}");
                    }

                    if (i == units.Count - 1)
                    {
                        throw new ScriptParsingException(
                                  source: units[i].FirstToken,
                                  message: $"Expression ended with a {units[i].OperatorType} operator: {units[i].FirstToken}");
                    }

                    if (units[i - 1].AsValueGetter == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i - 1].FirstToken,
                                  message: $"Unexpected token before {units[i].OperatorType} operator: {units[i - 1].FirstToken}");
                    }

                    if (units[i + 1].AsValueGetter == null)
                    {
                        throw new ScriptParsingException(
                                  source: units[i + 1].FirstToken,
                                  message: $"Unexpected token after {units[i].OperatorType} operator: {units[i + 1].FirstToken}");
                    }

                    OperatorToken operatorToken = units[i].FirstToken as OperatorToken;

                    //Cache Value and remove Right value and operator
                    IValueGetter arg2Value = units[i + 1].AsValueGetter;
                    units.RemoveAt(i + 1);
                    units.RemoveAt(i);

                    //adjust our current position
                    i--;

                    //Swap the ParsingUnit for the calculated value

                    switch (op)
                    {
                    case Operator.Plus:
                        if (units[i].AsValueGetter.GetValueType() == typeof(string) ||
                            arg2Value.GetValueType() == typeof(string))
                        {
                            //Handle String Concatenation
                            units[i] = new ParsedValuedUnit(
                                value: ConcatenateOperator.CreateConcatenateOperator(
                                    arg1: units[i].AsValueGetter,
                                    arg2: arg2Value),
                                firstToken: units[i].FirstToken);
                            break;
                        }
                        //Handle like addition
                        goto case Operator.Minus;

                    case Operator.Minus:
                    case Operator.Times:
                    case Operator.Divide:
                    case Operator.Power:
                    case Operator.Modulo:
                        //Handle Numerical Operators
                        units[i] = new ParsedValuedUnit(
                            value: BinaryNumericalOperation.CreateBinaryNumericalOperation(
                                arg1: units[i].AsValueGetter,
                                arg2: arg2Value,
                                operatorToken: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.IsEqualTo:
                    case Operator.IsNotEqualTo:
                        units[i] = new ParsedValuedUnit(
                            value: EqualityCompairsonOperation.CreateEqualityComparisonOperator(
                                arg1: units[i].AsValueGetter,
                                arg2: arg2Value,
                                operatorToken: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.IsGreaterThan:
                    case Operator.IsGreaterThanOrEqualTo:
                    case Operator.IsLessThan:
                    case Operator.IsLessThanOrEqualTo:
                        units[i] = new ParsedValuedUnit(
                            value: ComparisonOperation.CreateComparisonOperation(
                                arg1: units[i].AsValueGetter,
                                arg2: arg2Value,
                                operatorToken: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    case Operator.And:
                    case Operator.Or:
                        units[i] = new ParsedValuedUnit(
                            value: BinaryBoolOperation.CreateBinaryBoolOperator(
                                arg1: units[i].AsValueGetter,
                                arg2: arg2Value,
                                operatorToken: operatorToken),
                            firstToken: units[i].FirstToken);
                        break;

                    default:
                        throw new ArgumentException($"Unexpected Operator: {op}");
                    }
                }
            }
        }