예제 #1
0
        private void CompileNextFieldDefinition(LexList theLexList, Type varType)
        {
            string varId = theLexList.GetIdentifier("Expected the name of the field here.");

            MostRecentNameAdded = varId;
            theLexList.CheckStr(";", "Expected a ; here");
            if (MadeFieldsDict.ContainsKey(varId))
            {
                theLexList.ThrowException("This field already defined.");
            }
            if (CompileMethodsDict.ContainsKey(varId))
            {
                theLexList.ThrowException("This field name already used as a method name.");
            }
            MadeFieldsDict.Add(varId, new MadeField()
            {
                VarName = varId, VarType = varType, Index = MadeFieldsDict.Count
            });
            FieldInfo fi = ClassType.GetField("Fields", BindingFlags.Public | BindingFlags.Instance);

            if (fi == null)
            {
                theLexList.ThrowException("Can only add fields to a class that has a 'List<Object> Fields' field.");
            }
            if (fi.FieldType != typeof(List <object>))
            {
                theLexList.ThrowException("Can only add fields to a class where its Fields field is of type List<object>.");
            }
            theLexList.Next();
        }
예제 #2
0
        private static int CountCommas(LexList list, int rank, bool arrayIndexActualsAllowed)
        {
            Stack <string> stack = new Stack <string>();

            if (arrayIndexActualsAllowed)
            {
                int  saveIndex = list.Index - 1;
                bool finished  = false;
                while (!list.AtEnd() && !finished)
                {
                    switch (list.Str)
                    {
                    case ",": if (stack.Count == 0)
                        {
                            rank++;
                        }
                        break;

                    case "(": stack.Push(")"); break;

                    case "{": stack.Push("}"); break;

                    case "[": stack.Push("]"); break;

                    case ")":
                    case "}": if (stack.Pop() != list.Str)
                        {
                            list.ThrowException("Unbalanced brackets in array initialiser");
                        }
                        break;

                    case "]":
                        if (stack.Count == 0)
                        {
                            list.Prev();
                            finished = true;
                        }
                        else
                        {
                            if (stack.Pop() != list.Str)
                            {
                                list.ThrowException("Unbalanced brackets in array initialiser");
                            }
                        }
                        break;
                    }
                    list.Next();
                }
                list.Index = saveIndex;
            }
            else
            {
                while (list.Str == ",")
                {
                    list.Next();
                    rank++;
                }
            }
            return(rank);
        }
예제 #3
0
            public void CheckArithmetical(ExpState state)
            {
                if (state == null)
                {
                    if ((List.Str == "-" || List.Str == "+") && List.Prev().Str == List.Str)
                    {
                        List.ThrowException("Sorry, " + List.Str + List.Str + " is not implemented.");
                    }
                    List.ThrowException("Missing operand here.");
                }
                if (state.ResultType == typeof(char) && (StartType == typeof(int) || StartType == typeof(long)))
                {
                    return;
                }
                if (state.ResultType == typeof(bool) && ((Sizes & OperandSizes.Bool) == OperandSizes.Bool))
                {
                    return;
                }
                if ((state.ResultType == typeof(int) || state.ResultType == typeof(long)) && ((Sizes & OperandSizes.Integer) == OperandSizes.Integer))
                {
                    return;
                }
                if ((state.ResultType == typeof(float) || state.ResultType == typeof(double)) && ((Sizes & OperandSizes.Real) == OperandSizes.Real))
                {
                    return;
                }
                string s = "";

                if (((Sizes & OperandSizes.Bool) == OperandSizes.Bool))
                {
                    s += "bool ";
                }
                if (((Sizes & OperandSizes.Integer) == OperandSizes.Integer))
                {
                    if (s != "")
                    {
                        s += "or ";
                    }
                    s += "integer ";
                }
                if (((Sizes & OperandSizes.Real) == OperandSizes.Real))
                {
                    if (s != "")
                    {
                        s += "or ";
                    }
                    s += "real ";
                }
                List.ThrowException("Expected an operand of type '" + s + "'.");
            }
예제 #4
0
 public void CheckTypeIs(LexList list, Type type, string msg)
 {
     if (ResultType != type)
     {
         list.ThrowException(msg);
     }
 }
예제 #5
0
        public static MethodInfo GetDelegateInfo(LexList list, Type type, out Type returnType, out Type[] paras)
        {
            if (type.BaseType != typeof(MulticastDelegate))
            {
                list.ThrowException("Type '" + type.Name + " is not a multicast delegate type.");
            }
            MethodInfo invoke = type.GetMethod("Invoke");

            if (invoke == null)
            {
                list.ThrowException("Type '" + type.Name + " is not a delegate type.");
            }
            paras      = (from p in invoke.GetParameters() select p.ParameterType).ToArray();
            returnType = invoke.ReturnType;
            return(invoke);
        }
예제 #6
0
 public void CheckEqualityTypes(LexList InputList, Type type)
 {
     if (ResultType == null && type == null)
     {
         return;
     }
     if (ResultType == null && !type.IsValueType)
     {
         return;
     }
     if (!ResultType.IsValueType && (type == null))
     {
         return;
     }
     if (ResultType.IsEnum && type == Enum.GetUnderlyingType(ResultType))
     {
         return;
     }
     if (type.IsEnum && ResultType == Enum.GetUnderlyingType(type))
     {
         return;
     }
     if ((ResultType == type) || ((IsIntType(ResultType) || IsRealType(ResultType)) && (IsIntType(type) || IsRealType(type))))
     {
         return;
     }
     InputList.ThrowException("The left hand operand type '" + ResultType.ToString() + "'\n is not Equality compatible with the right hand operand type '" + type.ToString() + "'.");
 }
예제 #7
0
 public void CheckIsBoolType(LexList InputList, string msg)
 {
     if (ResultType == typeof(bool))
     {
         return;
     }
     InputList.ThrowException(msg);
 }
예제 #8
0
 public void CheckIsArrayType(LexList InputList, string p)
 {
     if (ResultType.IsArray)
     {
         return;
     }
     InputList.ThrowException(p);
 }
예제 #9
0
 public void CheckIsIntType(LexList InputList, string p)
 {
     if (IsIntType(ResultType))
     {
         return;
     }
     InputList.ThrowException(p);
 }
예제 #10
0
        public Type ParseType(LexList list, bool typeOnly, bool arrayIndexActualsAllowed, out bool pendingCloseAngle, BindingFlags visibility)
        {
            Type type = Parse(list, typeOnly, arrayIndexActualsAllowed, out pendingCloseAngle, visibility);

            if (pendingCloseAngle)
            {
                list.ThrowException("Unexpected > here");
            }
            return(type);
        }
예제 #11
0
 // ClassVisibility = ( 'partial' 'class' | 'class' 'partial' ) .
 private void DoClassVisibility()
 {
     if (InputList.AtEnd())
     {
         InputList.ThrowException("Unexpected end of text.");
     }
     if (InputList.Str == "partial")
     {
         InputList.Next();
         InputList.CheckStrAndAdvance("class", "Expected a 'class' after the 'partial'.");
     }
     else if (InputList.Str == "class")
     {
         InputList.Next();
         InputList.CheckStrAndAdvance("partial", "Expected a 'partial' after the 'class'.");
     }
     else
     {
         InputList.ThrowException("Expected either a 'partial class' or a 'class partial' here.");
     }
 }
예제 #12
0
 private Type ParseArrayTypeModifier(LexList list, Type returnType, bool arrayIndexActualsAllowed)
 {
     if (list.Str == "[")
     {
         list.Next();
         if (list.Kind == LexKind.End)
         {
             list.ThrowException("Unexpected end of input.");
         }
         if (!arrayIndexActualsAllowed)
         {
             if (list.Str != "]")
             {
                 list.ThrowException("Expected a ']' here.");
             }
             list.Next();
         }
         Type arrayType = returnType.MakeArrayType();
         while (list.Str == "[")
         {
             list.Next();
             arrayType = arrayType.MakeArrayType();
             if (list.Str != "]")
             {
                 list.ThrowException("Expected a ']' here");
             }
             list.Next();
         }
         if (arrayIndexActualsAllowed)
         {
             list.Prev();
         }
         return(arrayType);
     }
     else
     {
         return(returnType);
     }
 }
예제 #13
0
        private void CompileNextMethodHeader(LexList theLexList, bool overwriteAllowed, List <CompileMethod> currentListOfMethods)
        {
            CompileMethod cm = DoOneMethod(theLexList);

            currentListOfMethods.Add(cm);
            AddMethodToDictionary(cm, overwriteAllowed);
            if (cm.MethodName != "FieldsInitialiser")
            {
                MostRecentNameAdded = cm.MethodName;
            }
            if (MadeFieldsDict.ContainsKey(cm.MethodName))
            {
                theLexList.ThrowException("This method name already used for a field.");
            }
        }
예제 #14
0
        public static Type GetMethodDelegateType(LexList list, Type[] argumentTypes, bool lastIsReturnType)
        {
            if (lastIsReturnType)
            {
                switch (argumentTypes.Length)
                {
                case 1: return(typeof(Func <>).MakeGenericType(argumentTypes));

                case 2: return(typeof(Func <,>).MakeGenericType(argumentTypes));

                case 3: return(typeof(Func <, ,>).MakeGenericType(argumentTypes));

                case 4: return(typeof(Func <, , ,>).MakeGenericType(argumentTypes));

                case 5: return(typeof(Func <, , , ,>).MakeGenericType(argumentTypes));

                case 6: return(typeof(Func <, , , , ,>).MakeGenericType(argumentTypes));

                case 7: return(typeof(Func <, , , , , ,>).MakeGenericType(argumentTypes));
                }
            }
            else
            {
                switch (argumentTypes.Length)
                {
                case 0: return(typeof(Action));

                case 1: return(typeof(Action <>).MakeGenericType(argumentTypes));

                case 2: return(typeof(Action <,>).MakeGenericType(argumentTypes));

                case 3: return(typeof(Action <, ,>).MakeGenericType(argumentTypes));

                case 4: return(typeof(Action <, , ,>).MakeGenericType(argumentTypes));

                case 5: return(typeof(Action <, , , ,>).MakeGenericType(argumentTypes));

                case 6: return(typeof(Action <, , , , ,>).MakeGenericType(argumentTypes));

                case 7: return(typeof(Action <, , , , , ,>).MakeGenericType(argumentTypes));
                }
            }
            list.ThrowException("GetMethodDelegateType program error " + argumentTypes.Length + " " + lastIsReturnType);
            return(null);
        }
예제 #15
0
        // Each method declaration starts with a 'private' or a 'public' and then continues as per a method processed in MakeMethod.cs
        private CompileMethod DoOneMethod(LexList theLexList)
        {
            BindingFlags vis = BindingFlags.Public;

            if (theLexList.Str == "public")
            {
                vis = BindingFlags.Public;
            }
            else if (theLexList.Str == "private")
            {
                vis = BindingFlags.NonPublic;
            }
            else
            {
                theLexList.ThrowException("Expected this method to be marked either public or private.");
            }
            theLexList.Next();
            CompileMethod cm = new CompileMethod(Parser, theLexList, ClassType, vis);

            theLexList.CheckStrAndAdvance("}", "Expected a closing } at the end of the method.");
            return(cm);
        }
예제 #16
0
        public void CheckComparisonTypes(LexList InputList, Type type)
        {
            if ((ResultType == typeof(string) || ResultType == typeof(bool) || ResultType == typeof(char)) && (ResultType == type))
            {
                return;
            }
            //if ((IsIntType(ResultType) || IsRealType(ResultType)) && (IsIntType(type) || IsRealType(type))) return;
            if ((IsIntType(ResultType) && IsIntType(type)) ||
                (IsRealType(ResultType) && IsRealType(type)) ||
                (IsIntType(ResultType) && IsRealType(type)) ||
                (IsRealType(ResultType) && IsIntType(type))

                )
            {
                return;//wootra
            }
            if (ResultType.IsEnum && type.IsEnum && ResultType == type)
            {
                return;
            }
            InputList.ThrowException("The left hand operand type '" + ResultType.ToString() + "'\n is not Comparison compatible with the right hand operand type '" + type.ToString() + "'.");
        }
예제 #17
0
        private Type[] ParseGenericTypeModifier(LexList list, out bool pendingCloseAngle, BindingFlags visibility)
        {
            list.Next();
            pendingCloseAngle = false;
            List <Type> types   = new List <Type>();
            bool        pending = false;

            while (true)
            {
                types.Add(Parse(list, true, false, out pending, visibility));
                if (pending)
                {
                    break;
                }
                else if (list.Kind == LexKind.End)
                {
                    list.ThrowException("Unexpected end of input.");
                }
                else if (list.Str == ",")
                {
                    list.Next();
                }
                else if (list.Str == ">")
                {
                    list.Next();
                    break;
                }
                else if (list.Str == ">>")
                {
                    list.Next();
                    pendingCloseAngle = true;
                    break;
                }
            }
            return(types.ToArray());
        }
예제 #18
0
        public MakeClass AddMethodsAndFields(LexList list, bool overwriteAllowed)
        {
            if (InputList != null)
            {
                PreviousInputLists.Add(InputList);
            }
            InputList = list;
            Type varType = null;
            var  currentListOfMethods = new List <CompileMethod>();

            try {
                Crosslink();
                DoClassVisibility();
                DoClassType();
                InputList.CheckStrAndAdvance("{", "Expected an { after the class header.");
                while (true)
                {
                    if (InputList.Str == "}" && InputList.NextIsAtEnd())
                    {
                        break;
                    }
                    else if ((InputList.Str == "public" || InputList.Str == "private" || InputList.Str == "[") && !IsAFieldDefinition())
                    {
                        CompileNextMethodHeader(InputList, overwriteAllowed, currentListOfMethods);
                    }
                    else if ((InputList.Str == "public" || InputList.Str == "private") && IsAFieldDefinition())
                    {
                        InputList.Next();
                        varType = IsVarKind();
                        if (varType == null)
                        {
                            InputList.ThrowException("Unknown field type here");
                        }
                        CompileNextFieldDefinition(InputList, varType);
                    }
                    else if ((varType = IsVarKind()) != null)
                    {
                        CompileNextFieldDefinition(InputList, varType);
                    }
                    else
                    {
                        InputList.ThrowException("Expected either a 'public' or 'private' keyword (to start a method) or a type (to start a field declaration) here or the closing } of the class.");
                    }
                }
                InputList.CheckStrAndAdvance("}", "Expected a closing } here.");
                if (!InputList.AtEnd())
                {
                    InputList.ThrowException("Expected the end of the source text here.");
                }
                if (MadeFieldsDict.Count > 0)
                {
                    MakeFieldInitialiser(currentListOfMethods);
                }
                FinishClass(currentListOfMethods);
            } catch (LexListException lle) {
                throw lle;
            } catch (Exception ex) {
                list.CurrentToken().ThrowException(ex.Message, list);
            }
            return(this);
        }
예제 #19
0
        // Syntax:
        // Type               =  TypeNonArray [ TypeArrayPart ] .
        // TypeNonArray       =  TypeIdAndGenerics *( '.' TypeIdAndGenerics ) .
        // TypeIdAndGenerics  =  TypeIdentifier [ Generics ] .
        // Generics           =  '<' Type *( ',' Type ) '>' .
        // TypeArrayPart      =  '[' ']' *( '[' ']' ) .

        public Type Parse(LexList list, bool typeOnly, bool arrayIndexActualsAllowed, out bool pendingCloseAngle, BindingFlags visibility)
        {
            string id         = "";
            Type   returnType = null;
            int    checkPoint = list.Index;

            pendingCloseAngle = false;

            while (true)
            {
                if (list.Kind == LexKind.Type)
                {
                    returnType = list.CurrentToken().ActualObject as Type;
                    list.Next();
                    return(returnType);
                }
                if (list.Kind != LexKind.Identifier)
                {
                    if (typeOnly)
                    {
                        list.ThrowException("Unable to convert this to a type.");
                    }
                    return(returnType);
                }
                if (id != "")
                {
                    id += ".";
                }
                id += list.GetIdentifier();
                Type ty = null;
                if (list.Str != "<" || !IsGenericSpec(list))
                {
                    ty = FindTypeFromDottedIds(returnType, id, visibility);
                }
                if (ty != null)
                {
                    id         = "";
                    returnType = ty;
                    checkPoint = list.Index;
                    if (list.Kind == LexKind.End)
                    {
                        return(returnType);
                    }
                    if (list.Str != ".")
                    {
                        return(ParseArrayTypeModifier(list, returnType, arrayIndexActualsAllowed));
                    }
                }
                else if (ty == null && list.Str == "<" && IsGenericSpec(list))
                {
                    // The test for the GenericSpec is needed to separate out comparision '<' or shift '<' from generic brackets.
                    int    save  = list.Index;
                    Type[] types = ParseGenericTypeModifier(list, out pendingCloseAngle, visibility);
                    id += "`" + types.Length.ToString();
                    ty  = FindTypeFromDottedIds(returnType, id, visibility);
                    if (ty != null)
                    {
                        ty = ty.MakeGenericType(types.ToArray());
                    }
                    if (ty == null)
                    {
                        if (typeOnly)
                        {
                            list[save].ThrowException("Unable to resolve generic type.", list);
                        }
                        list.Index = checkPoint;
                        return(returnType);
                    }
                    return(ParseArrayTypeModifier(list, ty, arrayIndexActualsAllowed));
                }
                else
                {
                    if (list.Str != ".")
                    {
                        if (typeOnly)
                        {
                            list.Prev(); list.ThrowException("Unable to convert this to a type.");
                        }
                        list.Index = checkPoint;
                        return(returnType);
                    }
                }
                list.Next(); // skips over the '.'
            }
        }
예제 #20
0
        public MethodInfo GetExtensionMethod(string name, Type dispatchType, Type[] parameterTypes, LexList lexList)
        {
            List <MethodInfo> newListExact    = new List <MethodInfo>();
            List <MethodInfo> newListSubclass = new List <MethodInfo>();
            List <MethodInfo> list            = null;

            ExtensionMethods.TryGetValue(name, out list);
            if (list != null)
            {
                foreach (var m in list)
                {
                    ParameterInfo[] pai = m.GetParameters();
                    if (pai.Length == 0 && parameterTypes.Length == 0)
                    {
                        newListExact.Add(m);
                    }
                    else
                    {
                        if (MatchingParameters(pai, parameterTypes))
                        {
                            if (pai[0].ParameterType == dispatchType)
                            {
                                newListExact.Add(m);
                            }
                            else if (pai[0].ParameterType.IsSubclassOf(dispatchType))
                            {
                                newListSubclass.Add(m);
                            }
                        }
                    }
                }
            }
            if (newListExact.Count == 1)
            {
                return(newListExact[0]);
            }
            if (newListExact.Count == 0 && newListSubclass.Count == 1)
            {
                return(newListSubclass[0]);
            }

            string msg = "Method '" + name + "' ";

            if (newListExact.Count == 0 && newListSubclass.Count == 0)
            {
                msg += "was not found";
            }
            else
            {
                msg += "is ambigious";
            }
            msg += " in class '" + TypeToString(dispatchType) + "'.";

            if (lexList != null)
            {
                lexList.ThrowException(msg);
            }
            else
            {
                throw new TypeParserException(msg);
            }
            return(null);
        }