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; } }
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 } }); } }