private static bool GetToken(string input, out Token token) { if (string.IsNullOrWhiteSpace(input)) { token = null; return(false); } switch (input) { case "+": token = new OperatorToken(TokenType.Addition, 2); return(true); case "-": token = new OperatorToken(TokenType.Subtraction, 2); return(true); case "*": token = new OperatorToken(TokenType.Multiplication, 3); return(true); case "/": token = new OperatorToken(TokenType.Division, 3); return(true); case "(": token = new OperatorToken(TokenType.OpenPar, 2); return(true); case ")": token = new OperatorToken(TokenType.ClosePar, 2); return(true); } if (!input.StartsWith('-') && !input.StartsWith('+') && double.TryParse(input, System.Globalization.NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var d)) { token = new ValueToken(d); return(true); } if (input.All(c => char.IsLetter(c))) { switch (input) { case "inf": case "infinity": token = new ValueToken(double.PositiveInfinity); break; case "e": token = new ValueToken(Math.E); break; case "tau": case "τ": token = new ValueToken(Math.Tau); break; case "φ": token = new ValueToken(1.6180339887498948482d); break; case "pi": case "π": token = new ValueToken(Math.PI); break; case "rand": case "random": token = new ValueToken(rand.NextDouble()); break; default: token = new FunctionToken(input); break; } return(true); } token = null; return(false); }
private static void PerformFunction(Stack <double> numbers, FunctionToken f) { switch (f.Value) { case "lerp": case "mix": { var t = numbers.Pop(); var b = numbers.Pop(); var a = numbers.Pop(); numbers.Push(a * (1 - t) + b * t); } break; case "atan2": { var rhs = numbers.Pop(); var lhs = numbers.Pop(); numbers.Push(Math.Atan2(rhs, lhs)); } break; case "max": { var rhs = numbers.Pop(); var lhs = numbers.Pop(); numbers.Push(Math.Max(rhs, lhs)); } break; case "min": { var rhs = numbers.Pop(); var lhs = numbers.Pop(); numbers.Push(Math.Min(rhs, lhs)); } break; case "sq": case "square": { var vv = numbers.Pop(); numbers.Push(Math.Pow(vv, 2)); } break; case "pow": { var rhs = numbers.Pop(); var lhs = numbers.Pop(); numbers.Push(Math.Pow(lhs, rhs)); } break; case "saturate": { var vv = numbers.Pop(); numbers.Push(Math.Clamp(vv, 0, 1d)); } break; case "round": { var vv = numbers.Pop(); numbers.Push(Math.Round(vv)); } break; case "log": { var vv = numbers.Pop(); numbers.Push(Math.Log10(vv)); } break; case "logn": { var rhs = numbers.Pop(); var lhs = numbers.Pop(); numbers.Push(Math.Log(lhs, rhs)); } break; case "ceil": { var vv = numbers.Pop(); numbers.Push(Math.Ceiling(vv)); } break; case "floor": { var vv = numbers.Pop(); numbers.Push(Math.Floor(vv)); } break; case "exp": { var vv = numbers.Pop(); numbers.Push(Math.Exp(vv)); } break; case "sqrt": { var vv = numbers.Pop(); numbers.Push(Math.Sqrt(vv)); } break; case "sin": case "sine": { var vv = numbers.Pop(); numbers.Push(vv % Math.PI == 0 ? 0 : Math.Sin(vv)); } break; case "cos": case "cosine": { var vv = numbers.Pop(); numbers.Push(Math.Cos(vv)); } break; case "tan": case "tangent": { var vv = numbers.Pop(); numbers.Push(Math.Tan(vv)); } break; case "tanh": { var vv = numbers.Pop(); numbers.Push(Math.Tanh(vv)); } break; case "atan": { var vv = numbers.Pop(); numbers.Push(Math.Atan(vv)); } break; case "atanh": { var vv = numbers.Pop(); numbers.Push(Math.Atanh(vv)); } break; case "frac": case "fract": { var vv = numbers.Pop(); numbers.Push(vv - Math.Floor(vv)); } break; } }