public ActiveEvent(EventData d) { data = d; type = (EventData.Type)Enum.Parse(typeof(EventData.Type), data.type); var tokens = EventParser.tokenize(data.conditional); conditionalRoot = EventParser.parse(tokens); }
public static bool evaluate(EventParser.SyntaxNode root, EventContext ctx) { if (evaluateNode(root, ctx) is TypedValue <bool> resb) { return(resb.data); } else { throw new Exception("expression does not evaluate to boolean."); } }
static Value evaluateNode(EventParser.SyntaxNode n, EventContext ctx) { if (n is EventParser.BinaryNode bn) { Value a = evaluateNode(bn.lhs, ctx); Value b = evaluateNode(bn.rhs, ctx); (a, b) = promoteTypes(a, b); switch (a.type) { case Type.DOUBLE: { double av = (a as TypedValue <double>).data; double bv = (b as TypedValue <double>).data; switch (bn.token.type) { case EventParser.Token.Type.PLUS: return(new TypedValue <double>(av + bv)); case EventParser.Token.Type.MINUS: return(new TypedValue <double>(av - bv)); case EventParser.Token.Type.EQUALS: return(new TypedValue <bool>(av == bv)); case EventParser.Token.Type.NEQUALS: return(new TypedValue <bool>(av != bv)); case EventParser.Token.Type.LESS: return(new TypedValue <bool>(av < bv)); case EventParser.Token.Type.GREATER: return(new TypedValue <bool>(av > bv)); default: throw new Exception("invalid operation on double types."); } } case Type.INT: { int av = (a as TypedValue <int>).data; int bv = (b as TypedValue <int>).data; switch (bn.token.type) { case EventParser.Token.Type.PLUS: return(new TypedValue <int>(av + bv)); case EventParser.Token.Type.MINUS: return(new TypedValue <int>(av - bv)); case EventParser.Token.Type.MODULO: return(new TypedValue <int>(av % bv)); case EventParser.Token.Type.EQUALS: return(new TypedValue <bool>(av == bv)); case EventParser.Token.Type.NEQUALS: return(new TypedValue <bool>(av != bv)); case EventParser.Token.Type.LESS: return(new TypedValue <bool>(av < bv)); case EventParser.Token.Type.GREATER: return(new TypedValue <bool>(av > bv)); default: throw new Exception("invalid operation on int types."); } } case Type.BOOL: { bool av = (a as TypedValue <bool>).data; bool bv = (b as TypedValue <bool>).data; switch (bn.token.type) { case EventParser.Token.Type.EQUALS: return(new TypedValue <bool>(av == bv)); case EventParser.Token.Type.NEQUALS: return(new TypedValue <bool>(av != bv)); case EventParser.Token.Type.AND: return(new TypedValue <bool>(av && bv)); case EventParser.Token.Type.OR: return(new TypedValue <bool>(av || bv)); default: throw new Exception("invalid operation on bool types."); } } } } else if (n is EventParser.UnaryNode un) { Value e = evaluateNode(un.child, ctx); switch (e.type) { case Type.DOUBLE: { double ev = (e as TypedValue <double>).data; switch (un.token.type) { case EventParser.Token.Type.MINUS: return(new TypedValue <double>(-ev)); default: throw new Exception("invalid operation on double type."); } } case Type.INT: { int ev = (e as TypedValue <int>).data; switch (un.token.type) { case EventParser.Token.Type.MINUS: return(new TypedValue <int>(-ev)); default: throw new Exception("invalid operation on in type."); } } case Type.BOOL: { bool ev = (e as TypedValue <bool>).data; switch (un.token.type) { case EventParser.Token.Type.NOT: return(new TypedValue <bool>(!ev)); default: throw new Exception("invalid operation on bool type."); } } } } else { switch (n.token.type) { case EventParser.Token.Type.NUMBER: if (n.token.value.Contains('.')) { return(new TypedValue <double>(Convert.ToDouble(n.token.value))); } else { return(new TypedValue <int>(Convert.ToInt32(n.token.value))); } case EventParser.Token.Type.BOOLEAN: return(new TypedValue <bool>(Convert.ToBoolean(n.token.value))); case EventParser.Token.Type.LOCATION_FIELD: case EventParser.Token.Type.PERSON_FIELD: case EventParser.Token.Type.UNIT_FIELD: case EventParser.Token.Type.WORLD_FIELD: if (!fields.ContainsKey(n.token.value)) { throw new Exception("unknown field name."); } else { return(fields[n.token.value].getValue(ctx)); } case EventParser.Token.Type.VARIABLE: return(new TypedValue <string>(ctx.readEnvironment(n.token.value))); default: throw new Exception("invalid atom type."); } } throw new Exception("unable to evaluate node."); }
public static string evaluateAny(EventParser.SyntaxNode root, EventContext ctx) { return(evaluateNode(root, ctx).ToString()); }