/// <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); }
/// <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"); } }
/// <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)); }
/// <inheritdoc/> protected override RpnConst GetResultCore(RpnConst left, RpnConst right) => left.ValueType switch {
/// <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);
/// <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]); } } }
/// <inheritdoc/> protected override RpnConst GetResultCore(RpnConst left, RpnConst right) => new RpnInteger(left.GetBool() && right.GetBool());