예제 #1
0
        public void Parse()
        {
            globalNamespace = currentNamespace = new Namespace
            {
                name = "Global"
            };
            globalNamespace.classes.Add(globalNamespace.GlobalClass);
            while (true)
            {
Back:
                if (CurrentIs('\0'))
                {
                    return;
                }
                string word = GetWord();
                switch (word)
                {
                case "namespace":
                case "module":
                    string name = GetWord();
                    if (!GoForwardIf('{'))
                    {
                        throw new Exception();
                    }
                    var @namespace = new Namespace
                    {
                        name        = name,
                        UpNamespace = currentNamespace
                    };
                    @namespace.classes.Add(@namespace.GlobalClass);
                    currentNamespace.namespaces.Add(@namespace);
                    currentNamespace = @namespace;
                    break;

                case "declare":
                case "export":
                    goto Back;

                case "const":
                case "function":
                case "var":
                case "let":
                    GoForward(-word.Length);
                    currentClass = currentNamespace.GlobalClass;
                    if (ParseClassLine())
                    {
                        throw new Exception();
                    }
                    break;

                case "type":
                    currentClass = null;
                    string typeName = TypeDeclName = GetWord();
                    bool   generic  = CurrentIs('<');
                    Inherit.Clear();
                    GenericDeclaration genericDeclaration = ParseGenericDeclaration();
                    if (!GoForwardIf('='))
                    {
                        throw new Exception();
                    }
                    Inherit.Add(genericDeclaration);
                    var  type    = ParseType();
                    bool created = false;
                    if (type is NamedType namedType)
                    {
                        if (namedType.Name == typeName)
                        {
                            created = true;
                        }
                    }
                    if (generic && created)
                    {
                        currentNamespace.classes.Last(v => v.name == typeName).GenericDeclaration = genericDeclaration;
                    }
                    if (!created)
                    {
                        currentNamespace.ttypes.Add(new TTypeDeclaration
                        {
                            Name = typeName,
                            Type = type,
                            GenericDeclaration = genericDeclaration
                        });
                    }
                    if (!GoForwardIf(';'))
                    {
                        throw new Exception();
                    }
                    break;

                case "interface":
                case "class":
                    var interfaceName       = GetWord();
                    var implements          = new List <Type>();
                    var genericDeclaration2 = ParseGenericDeclaration();
                    Inherit.Clear();
                    Inherit.Add(genericDeclaration2);
                    while (GoForwardIf("extends") || GoForwardIf("implements"))
                    {
                        do
                        {
                            implements.Add(ParseType());
                        }while (GoForwardIf(','));
                    }
                    Details         details = ParseComment();
                    TypeDeclaration @class;
                    currentNamespace.classes.Add(@class = ParseClass(interfaceName, genericDeclaration2, implements, word == "interface"));
                    @class.details = details;
                    break;

                case "enum":
                    string enumName = GetWord();
                    var    enumDecl = new TypeDeclaration
                    {
                        name           = enumName,
                        fields         = new List <Field>(),
                        kind           = TypeDeclaration.Kind.Enum,
                        upperNamespace = currentNamespace
                    };
                    if (!GoForwardIf('{'))
                    {
                        throw new Exception();
                    }
                    while (!GoForwardIf('}'))
                    {
                        var key = GetWord();
                        if (string.IsNullOrWhiteSpace(key))
                        {
                            throw new Exception();
                        }
                        enumDecl.fields.Add(new Field
                        {
                            @readonly = true,
                            @static   = true,
                            @name     = key,
                            type      = new NamedType
                            {
                                Name = currentClass.name
                            }
                        });
                        GoForwardIf(',');
                    }
                    currentNamespace.classes.Add(enumDecl);
                    break;

                case "":
                    if (GoForwardIf('}'))
                    {
                        currentNamespace = currentNamespace.UpNamespace;
                    }
                    break;
                }
                LastComment = null;
            }
        }
예제 #2
0
        public Type ParseTypeLevel3()
        {
            Type   resultType = null;
            string word       = GetWord();

            switch (word)
            {
            case "":
            case "new":
                if (CurrentIs('(') || CurrentIs('<'))
                {
                    bool function = true;
                    if (!CurrentIs('<'))
                    {
                        CreateRestorePoint();
                        GoForwardUntilEndBracket('(', ')');
                        function = GoForwardIf("=>");
                        Restore();
                    }
                    if (function)
                    {
                        string             org = TypeDeclName;
                        GenericDeclaration genericDeclaration = ParseGenericDeclaration();
                        var newGen = new HashSet <string>();
                        foreach (var item in Inherit)
                        {
                            item.Generics.ForEach(v => newGen.Add(v));
                        }
                        genericDeclaration.Generics.AddRange(newGen);
                        GoForwardOne();
                        Inherit.Add(genericDeclaration);
                        var arguments = ParseArguments();
                        Inherit.RemoveAt(Inherit.Count - 1);
                        if (!GoForwardIf("=>"))
                        {
                            throw new Exception();
                        }
                        org         += "_ReturnType";
                        TypeDeclName = org;
                        var returnType = ParseType();
                        MethodOrDelegate newType;
                        (currentClass?.delegates ?? currentNamespace.delegates).Add(newType = new MethodOrDelegate
                        {
                            Arguments          = arguments,
                            ReturnType         = returnType,
                            Name               = TypeDeclName,
                            GenericDeclaration = genericDeclaration
                        });
                        resultType = new NamedType
                        {
                            Name = org,
                            ReferenceDelegates = newType,
                            Generics           = new Generics
                            {
                                Generic = newGen.ToList().ConvertAll <Type>(v => new NamedType
                                {
                                    Name = v
                                })
                            }
                        };
                    }
                    else
                    {
                        GoForwardOne();
                        resultType = ParseType();
                        if (!GoForwardIf(')'))
                        {
                            throw new Exception();
                        }
                    }
                    return(resultType);
                }
                else if (CurrentIs('{'))
                {
                    string          org = TypeDeclName;
                    TypeDeclaration created;
                    var             old = currentClass;
                    (currentClass?.nested ?? currentNamespace.classes).Add(created = ParseClass(org, new GenericDeclaration(), new List <Type>(), true));
                    currentClass = old;
                    return(new NamedType
                    {
                        Generics = new Generics
                        {
                            Generic = new List <Type>()
                        },
                        Name = org,
                        TypeDeclaration = created
                    });
                }
                else if (GoForwardIf('['))
                {
                    List <Type> types = new List <Type>();
                    string      org   = TypeDeclName;
                    int         n     = 0;
                    do
                    {
                        TypeDeclName = org + "_TupleParam" + n;
                        types.Add(ParseType());
                        ++n;
                    }while (GoForwardIf(','));
                    if (!GoForwardIf(']'))
                    {
                        throw new Exception();
                    }
                    return(new NamedType
                    {
                        Generics = new Generics
                        {
                            Generic = types
                        },
                        Name = "Tuple"
                    });
                }
                else if (CurrentIs('"') || CurrentIs('\''))
                {
                    var oldIdx = index;
                    GoForwardUntilEndBracket('"', '\'', '"', '\'');
                    int gIdx          = index - 2 - oldIdx;
                    var stringLiteral = gIdx <= 0 ? string.Empty : ParseString.Substring(oldIdx + 1, gIdx);
                    return(CreateStringLiteralType(stringLiteral));
                }    //
                throw new NotImplementedException();

            default:
                List <string> dotsSplit = word.Split('.').ToList();
                string        shortName = dotsSplit[dotsSplit.Count - 1];
                dotsSplit.RemoveAt(dotsSplit.Count - 1);
                List <Type> generics = new List <Type>();
                if (GoForwardIf('<'))
                {
                    do
                    {
                        generics.Add(ParseType());
                    }while (GoForwardIf(','));
                    if (!GoForwardIf('>'))
                    {
                        throw new Exception();
                    }
                }
                if (GoForwardIf("is"))
                {
                    shortName = "boolean";
                    dotsSplit.Clear();
                    ParseType();
                }
                return(new NamedType
                {
                    Name = shortName,
                    PreDots = dotsSplit.ToArray(),
                    Generics = new Generics
                    {
                        Generic = generics
                    }
                });
            }
        }