using System; using Dungeoneer.Error; namespace Dungeoneer.Interpreter { public static class Parser { public static int ParseRoll(string text) { return ParseRoll(Lexer.Tokenize(text)); } public static int ParseRoll(TokenSet tokens) { int result = 0; bool wasValue = false; char operation = '+'; int? rollDc = null; foreach(Token token in tokens) { switch(token) { case ValueToken value: if(wasValue) throw new SyntaxException("Value followed by value"); result = Operate(result, value.Value, operation); wasValue = true; break; case OperatorToken op: if(!wasValue) throw new SyntaxException("Operator followed by operator"); operation = op.Value; wasValue = false; break; case DcToken dc: if(rollDc.HasValue) throw new SyntaxException("Duplicate element: DC"); rollDc = dc.Value; break; default: throw new SyntaxException($"invalid token: {token.GetType()}"); } } return result; } public static int Operate(int a, int b, char op) { switch(op) { case '+': return (a + b); case '-': return (a - b); case '*': return (a * b); case '/': return (a / b); case '%': return (a % b); case '^': return (int)Math.Pow(a, b); default: throw new SyntaxException("unmatched operator"); } } } }