dungeoneer-cs/src/Parse.cs

56 lines
1.3 KiB
C#

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");
}
}
}
}