예제 #1
0
            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);
            }
예제 #2
0
 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.");
     }
 }
예제 #3
0
        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.");
        }
예제 #4
0
 public static string evaluateAny(EventParser.SyntaxNode root, EventContext ctx)
 {
     return(evaluateNode(root, ctx).ToString());
 }