Beispiel #1
0
        /// <inheritdoc/>
        protected override RpnConst GetResultCore(RpnConst left, RpnConst right)
        {
            if (right.ValueType != RpnConst.Type.Variable)
            {
                throw new InterpretationException("Cannot assign to the non-variable value");
            }

            variables[right.GetString()] = left;
            return(right);
        }
Beispiel #2
0
        /// <inheritdoc/>
        protected override RpnConst GetResultCore(RpnConst operand)
        {
            if (operand.ValueType != RpnConst.Type.Variable)
            {
                throw new InterpretationException("Cannot get a value of a non-variable entity");
            }

            if (variables.TryGetValue(operand.GetString(), out var value))
            {
                return(value);
            }
            else
            {
                throw new InterpretationException($"The variable '{operand.Token?.Value}' doesn't exist");
            }
        }
Beispiel #3
0
        /// <inheritdoc/>
        protected override RpnConst GetResultCore(RpnConst left, RpnConst right)
        {
            if (right.ValueType != RpnConst.Type.String &&
                right.ValueType != RpnConst.Type.Float &&
                right.ValueType != RpnConst.Type.Integer &&
                left.ValueType != RpnConst.Type.String &&
                left.ValueType != RpnConst.Type.Float &&
                left.ValueType != RpnConst.Type.Integer &&
                left.ValueType != RpnConst.Type.Variable &&
                left.ValueType != RpnConst.Type.BuiltIn)
            {
                return(new RpnInteger(0));
            }

            if (left.ValueType == RpnConst.Type.String)
            {
                if (right.ValueType == RpnConst.Type.Integer)
                {
                    return
                        (int.TryParse(
                             left.GetString(),
                             NumberStyles.Integer,
                             CultureInfo.InvariantCulture,
                             out _)
                        ? new RpnInteger(1)
                        : new RpnInteger(0));
                }

                if (right.ValueType == RpnConst.Type.Float)
                {
                    return
                        (double.TryParse(
                             left.GetString(),
                             NumberStyles.Float,
                             CultureInfo.InvariantCulture,
                             out _)
                        ? new RpnInteger(1)
                        : new RpnInteger(0));
                }
            }

            return(new RpnInteger(1));
        }
Beispiel #4
0
 /// <inheritdoc/>
 protected override RpnConst GetResultCore(RpnConst left, RpnConst right)
 => left.ValueType switch
 {
Beispiel #5
0
 /// <summary>
 /// The main calculations of the result.
 /// </summary>
 /// <param name="operand">The operand of the operation.</param>
 /// <returns>Result of the operation.</returns>
 protected abstract RpnConst GetResultCore(RpnConst operand);
 /// <summary>
 /// The main calculations of the result.
 /// </summary>
 /// <param name="left">The left operand of the operation.</param>
 /// <param name="right">The right operand of the operation.</param>
 /// <returns>Result of the operation.</returns>
 protected abstract RpnConst GetResultCore(RpnConst left, RpnConst right);
Beispiel #7
0
        /// <inheritdoc/>
        public override LinkedListNode <Rpn> Eval(
            Stack <RpnConst> stack,
            LinkedListNode <Rpn> currentCmd)
        {
            var parameters = new RpnConst[paramCount];

            for (int i = paramCount - 1; i >= 0; i--)
            {
                parameters[i] = stack.Pop();
            }

            var func = stack.Pop();

            if (func.ValueType == RpnConst.Type.BuiltIn)
            {
                if (builtIns.TryGetValue(func.GetString(), out var builtIn))
                {
                    OnBuiltIn(stack, builtIn);
                    return(currentCmd.Next);
                }
                else
                {
                    throw new InterpretationException(
                              $"Unknown built-in function '{func.GetString()}'"
                              );
                }
            }

            string funcName;

            if (func.ValueType == RpnConst.Type.Func)
            {
                funcName = func.GetString();
            }
            else if (func.ValueType == RpnConst.Type.Variable)
            {
                if (variables.TryGetValue(func.GetString(), out var value))
                {
                    funcName = value.GetString();
                }
                else
                {
                    throw new InterpretationException($"Unknown variable {func.GetString()}");
                }
            }
            else
            {
                throw new InterpretationException("Cannot evaluate not function");
            }

            if (functions.TryGetValue(funcName, out var funcStart))
            {
                OnFunc(stack);
                return(funcStart);
            }
            else
            {
                throw new InterpretationException(
                          "Unknown function"
                          );
            }

            void OnBuiltIn(Stack <RpnConst> stack, BuiltInLibrary.Func builtIn)
            {
                if (paramCount != builtIn.ParamCount)
                {
                    throw new InterpretationException(
                              $"Buil-in fucntion '{func.GetString()}' should have " +
                              $"{builtIn.ParamCount} parameters"
                              );
                }

                var result = builtIn.Main(parameters);

                stack.Push(result);
            }

            void OnFunc(Stack <RpnConst> stack)
            {
                stack.Push(returnLabel);
                for (int i = parameters.Length - 1; i >= 0; i--)
                {
                    stack.Push(parameters[i]);
                }
            }
        }
Beispiel #8
0
 /// <inheritdoc/>
 protected override RpnConst GetResultCore(RpnConst left, RpnConst right)
 => new RpnInteger(left.GetBool() && right.GetBool());