예제 #1
0
        private void SetIdent(ref ParserValue obj, out string varName, out ParserValue indexer)
        {
            // EBNF: ident ( ["[" Expression "]"] | [MethodCall ["[" Expression "]"]] )
            varName = scanner.Token;
            indexer = ParserValue.Empty;
            if (scanner.TokenType != TokenType.Ident)
            {
                Fail("Error while parsing ident");
            }
            scanner.Next();

            if (scanner.IsSymbol("["))
            {
                obj     = semantics.Get(obj, varName, indexer);
                indexer = Index();
                varName = null;
            }
            else if (scanner.IsSymbol("("))
            {
                obj     = MethodCall(varName, obj);
                varName = null;
                if (scanner.IsSymbol("["))
                {
                    indexer = Index();
                }
            }
        }
예제 #2
0
        private ParserValue TryOperator(ParserValue obj1, ParserValue obj2, string symbol)
        {
            string operation = "";

            switch (symbol)
            {
            case "+":
                operation = "op_Addition";
                break;

            case "*":
                operation = "op_Multiplication";
                break;

            case "/":
                operation = "op_Division";
                break;

            case "-":
                operation = "op_Subtraction";
                break;

            case "==":
                operation = "op_Equality";
                break;

            case "!=":
                operation = "op_Inequality";
                break;

            case "<":
                operation = "op_LessThan";
                break;

            case "<=":
                operation = "op_LessThanOrEqual";
                break;

            case ">":
                operation = "op_GreaterThan";
                break;

            case ">=":
                operation = "op_GreaterThanOrEqual";
                break;

            default:
                Fail("Coudln't find operation for symbol: " + symbol);
                break;
            }

            MethodInfo m = obj1.Type.GetMethod(operation, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
                                               null, new Type[] { obj1.Type, obj2.Type }, null);

            if (m != null)
            {
                return(new ParserValue(m.Invoke(null, new object[] { obj1.Value, obj2.Value }), m.ReturnType));
            }
            return(ParserValue.Empty);
        }
예제 #3
0
        public ParserValue Calc(ParserValue obj1, ParserValue obj2, string symbol)
        {
            if (!Enabled)
            {
                return(ParserValue.Empty);
            }

            ParserValue result = TryOperator(obj1, obj2, symbol);

            if (result.IsNotNull)
            {
                return(result);
            }

            if (obj1.IsAString || obj2.IsAString)
            {
                return(CalcString(obj1.Value.ToString(), obj2.Value.ToString(), symbol));
            }

            if (obj1.IsAFloat || obj2.IsAFloat)
            {
                return(CalcFloat(Convert.ToSingle(obj1.Value), Convert.ToSingle(obj2.Value), symbol));
            }

            if (obj1.IsAInt && obj2.IsAInt)
            {
                return(CalcInt((int)obj1.Value, (int)obj2.Value, symbol));
            }

            return(ParserValue.Empty);
        }
예제 #4
0
        private ParserValue Expression()
        {
            // EBNF: ConcatenatedExpression "then" ConcatenatedExpression "else" ConcatenatedExpression
            ParserValue result = ConcatenatedExpression();

            if (scanner.IsIdent("then"))
            {
                scanner.Next();
                semantics.If(result);
                ParserValue trueExpression = ConcatenatedExpression();
                if (!scanner.IsIdent("else"))
                {
                    Fail("Missing else in if expression!");
                }
                scanner.Next();
                semantics.BeginElse(result);
                ParserValue falseExpression = ConcatenatedExpression();
                semantics.EndElse(result);
                semantics.EndIf(result);
                if ((bool)result.Value)
                {
                    return(trueExpression);
                }
                else
                {
                    return(falseExpression);
                }
            }
            return(result);
        }
예제 #5
0
        private void Param(ArrayList parameters)
        {
            // EBNF: Expression
            ParserValue result = Expression();

            parameters.Add(result);
        }
예제 #6
0
        public ParserValue Index(ParserValue obj, ParserValue indexer)
        {
            if (!Enabled)
            {
                return(ParserValue.Empty);
            }

            if (obj.Type.IsArray)
            {
                int index = Convert.ToInt32(indexer.Value);
                if ((obj.Value as Array).Length > index)
                {
                    Array array = (obj.Value as Array);
                    return(new ParserValue(array.GetValue(index), array.GetType().GetElementType()));
                }
                Fail("Index out of range: " + index);
            }


            PropertyInfo info = obj.Type.GetProperty("Item", new Type[] { indexer.Type });

            if (info == null)
            {
                Fail("Couldn't find indexer for: " + indexer.Value);
            }
            MethodInfo mi = info.GetGetMethod();

            if (mi == null)
            {
                Fail("Indexer has no getter method!");
            }
            return(new ParserValue(mi.Invoke(obj.Value, new object[] { indexer.Value }), mi.ReturnType));
        }
예제 #7
0
 public void Push(ParserValue linkedObject)
 {
     if (Enabled)
     {
         scopes.Add(new ResourceScope(CurrentScope, linkedObject));
     }
 }
예제 #8
0
        public void SetIndex(ParserValue obj, ParserValue indexer, ParserValue val)
        {
            if (!Enabled)
            {
                return;
            }

            if (obj.Type.IsArray)
            {
                (obj.Value as Array).SetValue(val.Value, Convert.ToInt32(indexer.Value));
            }
            else
            {
                PropertyInfo info = obj.Type.GetProperty("Item", new Type[] { indexer.Type });
                if (info == null)
                {
                    Fail("Couldn't find indexer for: " + indexer);
                }
                MethodInfo mi = info.GetSetMethod();
                if (mi == null)
                {
                    Fail("Indexer has no getter method!");
                }
                mi.Invoke(obj.Value, new object[] { val.Value, indexer.Value });
            }
        }
예제 #9
0
 public void If(ParserValue exp)
 {
     // Push();
     if (exp.IsNull || exp.Value.Equals(false))
     {
         enabledCounter--;
     }
 }
예제 #10
0
 public void EndIf(ParserValue exp)
 {
     if (exp.IsNull || exp.Value.Equals(false))
     {
         enabledCounter++;
     }
     // Pop();
 }
예제 #11
0
 private ParserValue FirstIndex(ParserValue result)
 {
     //EBNF: Expression | "[" [size] "]" ["{" [ expression ] { "," expresson } "}"]
     if (result is ResourceSemantics.StaticClass)
     {
         ResourceSemantics.StaticClass sc = (ResourceSemantics.StaticClass)result;
         scanner.Next();
         int arraySize = 0;
         if (!scanner.IsSymbol("]"))
         {
             ParserValue size = Expression();
             if (size.Type != typeof(int))
             {
                 Fail("Assumed size of a array as integer");
             }
             arraySize = (int)size.Value;
         }
         if (!scanner.IsSymbol("]"))
         {
             FailSymbol("]", "Array");
         }
         scanner.Next();
         if (scanner.IsSymbol("{"))
         {
             semantics.PushShortCut(sc.Type);
             scanner.Next();
             ArrayList list = new ArrayList();
             while (!scanner.IsSymbol("}"))
             {
                 list.Add(Expression());
                 if (!scanner.IsSymbol("}", ","))
                 {
                     Fail("Error when parsing array members");
                 }
                 if (scanner.IsSymbol(","))
                 {
                     scanner.Next();
                 }
             }
             result = ParserValue.ToArray(list, sc.Type);
             semantics.PopShortCut();
         }
         else
         {
             Array array = Array.CreateInstance(sc.Type, arraySize);
             result = new ParserValue(array, array.GetType());
         }
         scanner.Next();
         return(result);
     }
     else
     {
         ParserValue indexer = Index();
         result = semantics.Index(result, indexer);
         return(result);
     }
 }
예제 #12
0
        /// <summary>
        /// Converts an <see cref="ArrayList"/> of <see cref="ParserValue"/>s to an array.
        /// </summary>
        /// <param name="list"><see cref="ArrayList"/> of <see cref="ParserValue"/>s.</param>
        /// <param name="type">The elementType of the array.</param>
        /// <returns>A new parserValue containing the array.</returns>
        public static ParserValue ToArray(ArrayList list, Type type)
        {
            Array array = Array.CreateInstance(type, list.Count);

            for (int i = 0; i < list.Count; i++)
            {
                ParserValue val = (ParserValue)list[i];
                array.SetValue(val.Value, i);
            }
            return(new ParserValue(array, array.GetType()));
        }
예제 #13
0
 public void EndElse(ParserValue exp)
 {
     if (exp.IsNull || exp.Value.Equals(false))
     {
         enabledCounter--;
     }
     else
     {
         enabledCounter++;
     }
 }
예제 #14
0
        private void SetIdents(out ParserValue obj, out string varName, out ParserValue indexer)
        {
            // EBNF: SetIdent {. SetIdent }
            obj = ParserValue.Empty;
            SetIdent(ref obj, out varName, out indexer);

            while (scanner.IsSymbol("."))
            {
                scanner.Next();
                obj = semantics.Get(obj, varName, indexer);
                SetIdent(ref obj, out varName, out indexer);
            }
        }
예제 #15
0
        public ParserValue InvokeConstructor(Type type, ArrayList parameters)
        {
            Type[]          types = ParserValue.GetTypes(parameters);
            ConstructorInfo info  = type.GetConstructor(types);

            if (info == null)
            {
                Fail("Couldn't find suiting constructor for: " + type.FullName);
            }
            object createdInstance = info.Invoke(ParserValue.GetValues(parameters));

            return(new ParserValue(createdInstance, info.ReflectedType));
        }
예제 #16
0
        private void IfStatement()
        {
            // EBNF: IfStatement = "if" "(" Expression ")" (
            scanner.Next();
            if (!scanner.IsSymbol("("))
            {
                FailSymbol("(", "if");
            }
            scanner.Next();
            ParserValue result = Expression();

            if (!scanner.IsSymbol(")"))
            {
                FailSymbol(")", "if");
            }
            scanner.Next();
            semantics.If(result);
            if (scanner.IsSymbol("{"))
            {
                scanner.Next();
                while (!scanner.IsSymbol("}"))
                {
                    Statement();
                }
                scanner.Next();
            }
            else
            {
                Statement();
            }
            if (scanner.IsIdent("else"))
            {
                semantics.BeginElse(result);
                scanner.Next();
                if (scanner.IsSymbol("{"))
                {
                    scanner.Next();
                    while (!scanner.IsSymbol("}"))
                    {
                        Statement();
                    }
                    scanner.Next();
                }
                else
                {
                    Statement();
                }
                semantics.EndElse(result);
            }
            semantics.EndIf(result);
        }
예제 #17
0
        private ParserValue CompareExpression()
        {
            // EBNF: SimpleExpression [ ("==", "!=", "<", ">", "<=", ">=") SimpleExpression]
            ParserValue result = SimpleExpression();

            if (scanner.IsSymbol("==", "!=", "<", ">", "<=", ">="))
            {
                string symbol = scanner.Token;
                scanner.Next();
                ParserValue result2 = SimpleExpression();
                result = semantics.Calc(result, result2, symbol);
            }
            return(result);
        }
예제 #18
0
        private ParserValue ConcatenatedExpression()
        {
            // EBNF: CompareExpression [ ("&&", "||") CompareExpression]
            ParserValue result = CompareExpression();

            if (scanner.IsSymbol("&&", "||"))
            {
                string symbol = scanner.Token;
                scanner.Next();
                ParserValue result2 = CompareExpression();
                result = semantics.Concatenation((bool)result.Value, (bool)result2.Value, symbol);
            }
            return(result);
        }
예제 #19
0
        private void Ident(ref ParserValue result)
        {
            //EBNF: ( ident | "#" ) ["[" FirstIndex "]"] [MethodCall ["[" Expression "]"]] [ "{" newObject "}" ][MethodCall ["[" Expression "]"]]
            if (scanner.TokenType != TokenType.Ident && !scanner.IsSymbol("#"))
            {
                Fail("Error while parsing ident");
            }
            string token = scanner.Token;

            scanner.Next();
            if (!scanner.IsSymbol("{", "("))
            {
                result = semantics.Get(result, token);
            }

            if (scanner.IsSymbol("["))
            {
                result = FirstIndex(result);
            }
            if (scanner.IsSymbol("{"))
            {
                scanner.Next();
                result = NewObject(result, token);
                if (!scanner.IsSymbol("}"))
                {
                    FailSymbol("}", "new object");
                }
                scanner.Next();
            }
            if (scanner.IsSymbol("("))
            {
                result = MethodCall(token, result);
                if (scanner.IsSymbol("["))
                {
                    ParserValue indexer = Index();
                    result = semantics.Index(result, indexer);
                }
            }
            if (scanner.IsSymbol("{"))
            {
                scanner.Next();
                result = NewObject(result, token);
                if (!scanner.IsSymbol("}"))
                {
                    FailSymbol("}", "new object");
                }
                scanner.Next();
            }
        }
예제 #20
0
 private ParserValue NewObject(ParserValue result, string type)
 {
     if (result.IsNull)
     {
         result = semantics.CreateObject(type);
     }
     if (result.IsNull)
     {
         Fail("Couldn't create object of type: " + type);
     }
     semantics.Push(result);
     Block();
     semantics.Pop();
     return(result);
 }
예제 #21
0
        private ParserValue SimpleExpression()
        {
            // EBNF: Expression = Term [("+" | "-") Term]
            ParserValue result = Term();

            while (scanner.IsSymbol("+", "-"))
            {
                string symbol = scanner.Token;

                scanner.Next();
                ParserValue result2 = Term();

                result = semantics.Calc(result, result2, symbol); // SEM
            }
            return(result);
        }
예제 #22
0
        private ParserValue Term()
        {
            // EBNF: Term = RValue [("*" | "/") RValue]
            ParserValue result = RValue();

            while (scanner.IsSymbol("*", "/"))
            {
                string symbol = scanner.Token;

                scanner.Next();
                ParserValue result2 = RValue();

                result = semantics.Calc(result, result2, symbol); // SEM
            }
            return(result);
        }
예제 #23
0
        public void Invert(ParserValue obj1, int sign)
        {
            if (!Enabled || sign == 1)
            {
                return;
            }

            if (obj1.IsAFloat)
            {
                obj1.Value = sign * (float)(obj1.Value);
            }
            else if (obj1.IsAInt)
            {
                obj1.Value = sign * (int)(obj1.Value);
            }
        }
예제 #24
0
        private ParserValue Index()
        {
            if (!scanner.IsSymbol("["))
            {
                FailSymbol("[", "index");
            }
            scanner.Next();
            ParserValue indexer = Expression();

            if (!scanner.IsSymbol("]"))
            {
                FailSymbol("]", "index");
            }
            scanner.Next();
            return(indexer);
        }
예제 #25
0
        internal static bool ContainsField(ParserValue obj, string name)
        {
            FieldInfo info = obj.Type.GetField(name, BindingFlags.Public | BindingFlags.Instance);

            if (info != null)
            {
                return(true);
            }
            PropertyInfo pInfo = obj.Type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);

            if (pInfo != null)
            {
                return(true);
            }
            return(false);
        }
예제 #26
0
        public ParserValue Get(ParserValue obj, string varName, ParserValue indexer)
        {
            if (!Enabled)
            {
                return(ParserValue.Empty);
            }

            if (varName != null)
            {
                obj = Get(obj, varName);
            }
            if (indexer.IsNotNull)
            {
                obj = Index(obj, indexer);
            }
            return(obj);
        }
예제 #27
0
        public void Set(ParserValue obj, string varName, ParserValue indexer, ParserValue result)
        {
            if (!this.Enabled)
            {
                return;
            }

            if (obj is StaticClass)
            {
                StaticClass staticClass = (StaticClass)obj;
                Type        type        = staticClass.Type;
                if (type == null)
                {
                    Fail("Couldn't get type for: " + staticClass.Type.FullName);
                }
                if (!SetStaticField(type, varName, result))
                {
                    obj = CurrentScope.Get(staticClass.Name);
                }
                else
                {
                    return;
                }
            }

            if (indexer.IsNotNull)
            {
                obj = Get(obj, varName, ParserValue.Empty);
                SetIndex(obj, indexer, result);
            }
            else
            {
                if (obj.IsNull)
                {
                    CurrentScope.Set(varName, result);
                }
                else
                {
                    if (!SetField(obj, varName, result))
                    {
                        Fail("Couldn't find field: " + varName);
                    }
                }
            }
        }
예제 #28
0
        public void PreInvoke(string name, ParserValue obj,
                              out ParserValue invokeObject, out bool invokeConstructor)
        {
            invokeObject      = new ParserValue(null, obj.Type);
            invokeConstructor = true;

            if (!Enabled)
            {
                return;
            }

            if (obj.IsNull)
            {
                // constructor
                if (name == "#")
                {
                    invokeObject.Type = ShortCut;
                }
                else if (TypeBinding.ContainsKey(name))
                {
                    invokeObject.Type = (Type)TypeBinding[name];
                }
                else if (CurrentScope.LinkedObject.IsNotNull)
                {
                    invokeConstructor = false;
                    invokeObject      = CurrentScope.LinkedObject;
                }
                else
                {
                    Fail("Error: " + name + "!");
                }
            } // static method
            else if (obj is StaticClass)
            {
                invokeConstructor = false;
                // static method
                invokeObject.Type = (obj as StaticClass).Type;
            }// method
            else
            {
                invokeConstructor = false;
                invokeObject      = obj;
            }
        }
예제 #29
0
        internal static bool GetStaticField(Type type, string token, out ParserValue result)
        {
            result = ParserValue.Empty;
            FieldInfo info = type.GetField(token, BindingFlags.Public | BindingFlags.Static);

            if (info != null)
            {
                result = new ParserValue(info.GetValue(null), info.FieldType);
                return(true);
            }

            PropertyInfo pInfo = type.GetProperty(token, BindingFlags.Public | BindingFlags.Static);

            if (pInfo != null)
            {
                result = new ParserValue(pInfo.GetValue(null, null), pInfo.PropertyType);
                return(true);
            }
            return(false);
        }
예제 #30
0
        internal static bool GetField(ParserValue obj, string token, out ParserValue result)
        {
            result = ParserValue.Empty;
            FieldInfo info = obj.Type.GetField(token, BindingFlags.Public | BindingFlags.Instance);

            if (info != null)
            {
                result = new ParserValue(info.GetValue(obj.Value), info.FieldType);
                return(true);
            }

            PropertyInfo pInfo = obj.Type.GetProperty(token, BindingFlags.Public | BindingFlags.Instance);

            if (pInfo != null)
            {
                result = new ParserValue(pInfo.GetValue(obj.Value, null), pInfo.PropertyType);
                return(true);
            }
            return(false);
        }