/// <summary> /// This ought to be implemented with a FunctionMartix but it would be huge. /// This way is easier! /// </summary> internal static Tuple <OperandType, OperandType> DoSetEquals(DoubleOperandFunctionMatrix matrix, Stack <IOperand> stack, IBackingStore backingStore, long parserPosition) { IOperand second = PopAndResolve(stack, backingStore); IOperand first = stack.Pop(); // Not PopAndResolve. LHS must be a variable. if (first.Type != OperandType.Variable) { throw new ExpressionEvaluatorException(parserPosition, ExpressionEvaluatorException.ExceptionCause.BadOperand, "LHS of '=' is a '" + first.Type + "' when it must be a variable"); } else { string varName = (string)first.GetValue(); (OperandType type, object value)valueAndType; try { // We need the type, don't need the value because it's going to be overwritten. valueAndType = backingStore.GetValue(varName); } catch (Exception ex) { throw new ExpressionEvaluatorException(-1, ExpressionEvaluatorException.ExceptionCause.UndefinedVariable, $"'{varName}'"); } // type is needed so we can pick out the correct martrix operation. Value is irrelevant as it is overwritten. var firstOperand = new Operand(first.ParserPosition, valueAndType.type, valueAndType.value); IOperand result = matrix.PerformDelegate(firstOperand, second); if (result != null) { backingStore.SetValue(varName, result.GetValue()); stack.Push(result); return(null); } else { // Signal an error ... return(new Tuple <OperandType, OperandType>(first.Type, second.Type)); } } }
/// <summary> /// Peeks an operand from the stack. If it's a variable it returns an operand holding the variable value, otherwise it returns the operand. /// </summary> /// <param name="stack"></param> /// <param name="variables"></param> /// <returns></returns> public static IOperand PeekAndResolve(Stack <IOperand> stack, IBackingStore backingStore) { IOperand operand = stack.Peek(); if (operand.Type == OperandType.Variable) { //var variable = ResolveVariable(variables, retVal); try { var valueAndType = backingStore.GetValue((string)operand.GetValue()); operand = new Operand(operand.ParserPosition, valueAndType.type, valueAndType.value); } catch// (KeyNotFoundException) { throw new ExpressionEvaluatorException(operand.ParserPosition, ExpressionEvaluatorException.ExceptionCause.UndefinedVariable, $"'{operand.GetValue().ToString()}'"); } } return(operand); }
public Task <TValue> GetValueAsync(TKey key) { return(_taskFactory.StartNew(() => { lock (_cache) { if (_cache.ContainsKey(key)) { return _cache[key]; } } var result = _backingStore.GetValue(key); lock (_cache) { if (_cache.ContainsKey(key)) { return _cache[key]; } _cache[key] = result; } return result; })); }