public void ParseInterpretedCode(string filename, string code) { FileScope fileScope = new FileScope(filename); int fileId = this.GetNextFileId(); this.RegisterFileUsed(filename, code, fileId); Token[] tokenList = Tokenizer.Tokenize(filename, code, fileId, true); TokenStream tokens = new TokenStream(tokenList, filename); List <string> namespaceImportsBuilder = new List <string>(); tokens.InsertTokens(this.GetImplicitCoreImport()); if (this.CurrentLibrary != null && this.CurrentLibrary.CanonicalKey != "en:Core") { Library coreLibrary = this.LibraryManager.GetCoreLibrary(this); this.CurrentLibrary.AddLibraryDependency(coreLibrary); } List <CompilationScope> scopesAdded = new List <CompilationScope>(); while (tokens.HasMore && tokens.IsNext(this.Keywords.IMPORT)) { ImportStatement importStatement = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope) as ImportStatement; if (importStatement == null) { throw new Exception(); } namespaceImportsBuilder.Add(importStatement.ImportPath); Library library = this.LibraryManager.ImportLibrary(this, importStatement.FirstToken, importStatement.ImportPath); if (library == null) { this.unresolvedImports.Add(importStatement); } else { if (this.CurrentLibrary != null) { this.CurrentLibrary.AddLibraryDependency(library); } scopesAdded.Add(library.Scope); } } string[] namespaceImports = namespaceImportsBuilder.ToArray(); while (tokens.HasMore) { TopLevelConstruct executable = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope); if (executable is ImportStatement) { throw new ParserException( executable.FirstToken, this.CurrentLocale.Strings.Get("ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE")); } this.CurrentScope.AddExecutable(executable); } }
internal EnumSyntax(FileScope pScope, string pName, List <IdentifierSyntax> pNames, List <int> pValues) { Scope = pScope; Name = pName; Names = pNames; Values = pValues; }
protected override FunctionDefinition MaybeParseFunctionDefinition( TokenStream tokens, Node owner, FileScope fileScope, AnnotationCollection annotations, ModifierCollection modifiers) { TokenStream.StreamState tss = tokens.RecordState(); AType returnType = this.parser.TypeParser.TryParse(tokens); if (returnType == null) { return(null); } Token functionName = tokens.PopIfWord(); if (functionName == null) { tokens.RestoreState(tss); return(null); } if (tokens.IsNext("(")) { tokens.RestoreState(tss); return(this.ParseFunction(tokens, owner as TopLevelEntity, fileScope, modifiers, annotations)); } tokens.RestoreState(tss); return(null); }
protected override FunctionDefinition ParseFunction( TokenStream tokens, TopLevelEntity nullableOwner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations) { AType returnType = this.parser.TypeParser.Parse(tokens); Token firstToken = modifiers.FirstToken ?? returnType.FirstToken; Token functionNameToken = tokens.Pop(); this.parser.VerifyIdentifier(functionNameToken); FunctionDefinition fd = new FunctionDefinition(firstToken, returnType, nullableOwner, functionNameToken, modifiers, annotations, fileScope); tokens.PopExpected("("); List <AType> argTypes = new List <AType>(); List <Token> argNames = new List <Token>(); List <Expression> defaultValues = new List <Expression>(); this.ParseArgumentListDeclaration(tokens, fd, argTypes, argNames, defaultValues); fd.ArgTypes = argTypes.ToArray(); fd.ArgNames = argNames.ToArray(); fd.DefaultValues = defaultValues.ToArray(); fd.FinalizeArguments(); IList <Executable> code = this.parser.ExecutableParser.ParseBlock(tokens, true, fd); fd.Code = code.ToArray(); return(fd); }
public ClassDefinition( Token classToken, Token nameToken, IList <Token> subclassTokens, IList <string> subclassNames, Node owner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations, ParserContext context) : base(classToken, owner, fileScope, modifiers) { this.ClassID = context.ClassIdAlloc++; this.NameToken = nameToken; this.BaseClassTokens = subclassTokens.ToArray(); this.BaseClassDeclarations = subclassNames.ToArray(); this.annotations = annotations; if (this.Modifiers.HasPrivate) { throw new ParserException(this.Modifiers.PrivateToken, "Private classes are not supported yet."); } if (this.Modifiers.HasProtected) { throw new ParserException(this.Modifiers.ProtectedToken, "Protected classes are not supported yet."); } }
internal TypeDefinitionSyntax(FileScope pScope, TypeSyntax pType, TypeSyntax pImplements, DefinitionTypes pDefinitionType, List <TypedIdentifierSyntax> pFields, List <MethodSyntax> pMethods) { System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(pType.Value), "Define name cannot be empty"); System.Diagnostics.Debug.Assert(pDefinitionType != DefinitionTypes.Unknown); Scope = pScope; DeclaredType = pType; DefinitionType = pDefinitionType; AppliesTo = pImplements; Fields = pFields; Methods = pMethods; var tp = new List <string>(); foreach (var pa in DeclaredType.GenericArguments) { tp.Add(pa.Value); } TypeParameters = tp; _typeMappings = new List <Dictionary <string, SmallType> >(); }
public static string FastToString(this FileScope scope) { return(scope switch { FileScope.Global => nameof(FileScope.Global), FileScope.World => nameof(FileScope.World), _ => throw new ArgumentOutOfRangeException(nameof(scope), scope, null) });
internal Token(string value, TokenType type, FileScope file, int lineNum, int colNum) { this.Value = value; this.Type = type; this.File = file; this.Line = lineNum; this.Col = colNum; this.AggregateTokenCount = 1; }
public MethodDefinition(string pName, List <SmallType> pArguments) { Scope = FileScope.Public; Name = pName; MangledName = pName; ArgumentTypes = pArguments; ReturnType = SmallTypeCache.Undefined; External = false; }
public MethodDefinition(FileScope pScope, string pName, string pMangled, bool pExternal, List <SmallType> pArguments, SmallType pReturn) { Scope = pScope; Name = pName; MangledName = pMangled; External = pExternal; ArgumentTypes = pArguments; ReturnType = pReturn; }
internal MethodSyntax(FileScope pScope, string pName, List <TypeSyntax> pReturns, List <TypedIdentifierSyntax> pParameters, BlockSyntax pBody, bool pExternal) { Scope = pScope; Name = pName; ReturnValues = pReturns; Parameters = pParameters; Body = pBody; External = pExternal; }
/// <summary> /// Registers a new file with the file manager. /// </summary> /// <param name="fileName">Name of the file.</param> /// <param name="fileScope">The file scope [Global | World].</param> public ModFileInfo RegisterFile(string fileName, FileScope fileScope) { var modFile = new ModFileInfo(GetScopedPath(fileScope, fileName)); ModFiles.Add(fileName, modFile); if (!modFile.Exists) { modFile.DisembedFrom(Assembly.GetCallingAssembly()); } return(modFile); }
public static MethodSyntax ExternalMethod(FileScope pScope, string pName, TypeSyntax pReturns, List <TypedIdentifierSyntax> pParameters, BlockSyntax pBody) { List <TypeSyntax> returns = new List <TypeSyntax>(); if (pReturns != null) { returns.Add(pReturns); } return(new MethodSyntax(pScope, pName, returns, pParameters, pBody, true)); }
protected override void ParseClassMember( TokenStream tokens, FileScope fileScope, ClassDefinition classDef, IList <FunctionDefinition> methodsOut, IList <FieldDefinition> fieldsOut, IList <PropertyDefinition> propertiesOutIgnored) { AnnotationCollection annotations = this.parser.AnnotationParser.ParseAnnotations(tokens); ModifierCollection modifiers = ModifierCollection.Parse(tokens); if (tokens.IsNext(this.parser.Keywords.FUNCTION)) { methodsOut.Add(this.ParseFunction(tokens, classDef, fileScope, modifiers, annotations)); } else if (tokens.IsNext(this.parser.Keywords.CONSTRUCTOR)) { if (modifiers.HasStatic) { if (classDef.StaticConstructor != null) { throw new ParserException(tokens.Pop(), "Multiple static constructors are not allowed."); } classDef.StaticConstructor = this.ParseConstructor(tokens, classDef, modifiers, annotations); } else { if (classDef.Constructor != null) { throw this.parser.GenerateParseError( ErrorMessages.CLASS_CANNOT_HAVE_MULTIPLE_CONSTRUCTORS, tokens.Pop()); } classDef.Constructor = this.ParseConstructor(tokens, classDef, modifiers, annotations); } } else if (tokens.IsNext(this.parser.Keywords.FIELD)) { fieldsOut.Add(this.ParseField(tokens, classDef, modifiers, annotations)); } else if (tokens.IsNext(this.parser.Keywords.CLASS)) { throw new ParserException(tokens.Pop(), "Nested classes are not currently supported."); } else { tokens.PopExpected("}"); } // TODO: check for annotations that aren't used. // https://github.com/blakeohare/crayon/issues/305 }
protected PropertyDefinition ParseProperty( TokenStream tokens, ClassDefinition classDef, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations) { AType propertyType = this.parser.TypeParser.Parse(tokens); tokens.EnsureNotEof(); Token propertyName = tokens.PopIfWord(); if (propertyName == null) { throw new ParserException(tokens.Peek(), "Expected property name."); } tokens.PopExpected("{"); PropertyMember getter = null; PropertyMember setter = null; PropertyDefinition property = new PropertyDefinition(propertyType.FirstToken, classDef, fileScope, modifiers); while (!tokens.PopIfPresent("}")) { PropertyMember member = this.ParsePropertyMember(tokens, property); if (member.IsGetter) { if (getter != null) { throw new ParserException(member.FirstToken, "Property has multiple getters"); } getter = member; } else if (member.IsSetter) { if (setter != null) { throw new ParserException(member.FirstToken, "Property has multiple setters"); } setter = member; } } property.Getter = getter; property.Setter = setter; return(property); }
public FunctionDefinition( Token functionToken, AType returnType, TopLevelEntity nullableOwner, Token nameToken, ModifierCollection modifiers, AnnotationCollection annotations, FileScope fileScope) : base(functionToken, nullableOwner, fileScope, modifiers) { this.ReturnType = returnType; this.NameToken = nameToken; this.Annotations = annotations; this.MemberID = -1; this.Lambdas = new List <Lambda>(); this.ArgumentNameLookup = new HashSet <string>(); }
protected override ConstDefinition ParseConst( TokenStream tokens, Node owner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations) { Token constToken = tokens.PopExpected(this.parser.Keywords.CONST); Token nameToken = tokens.Pop(); ConstDefinition constStatement = new ConstDefinition(constToken, AType.Any(constToken), nameToken, owner, fileScope, modifiers, annotations); this.parser.VerifyIdentifier(nameToken); tokens.PopExpected("="); constStatement.Expression = this.parser.ExpressionParser.Parse(tokens, constStatement); tokens.PopExpected(";"); return(constStatement); }
public EnumDefinition( Token enumToken, Token nameToken, Node owner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations) : base(enumToken, owner, fileScope, modifiers) { this.NameToken = nameToken; this.Name = nameToken.Value; this.annotations = annotations; if (modifiers.AccessModifierType == AccessModifierType.PRIVATE || modifiers.AccessModifierType == AccessModifierType.PROTECTED) { // TODO: this will not be true when you can start nesting these into classes. throw new ParserException(modifiers.PrivateToken ?? modifiers.ProtectedToken, "This is not a valid access modifier for enums."); } }
protected override FunctionDefinition ParseFunction( TokenStream tokens, TopLevelEntity nullableOwner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations) { bool isStatic = nullableOwner != null && nullableOwner is ClassDefinition && tokens.PopIfPresent(this.parser.Keywords.STATIC); Token functionToken = tokens.PopExpected(this.parser.Keywords.FUNCTION); Token functionNameToken = tokens.Pop(); this.parser.VerifyIdentifier(functionNameToken); FunctionDefinition fd = new FunctionDefinition(functionToken, AType.Any(functionToken), nullableOwner, functionNameToken, modifiers, annotations, fileScope); tokens.PopExpected("("); List <Token> argNames = new List <Token>(); List <Expression> defaultValues = new List <Expression>(); List <AType> argTypes = new List <AType>(); this.ParseArgumentListDeclaration(tokens, fd, argTypes, argNames, defaultValues); fd.ArgTypes = argTypes.ToArray(); fd.ArgNames = argNames.ToArray(); fd.DefaultValues = defaultValues.ToArray(); fd.FinalizeArguments(); IList <Executable> code = this.parser.ExecutableParser.ParseBlock(tokens, true, fd); fd.Code = code.ToArray(); return(fd); }
public W3CebnfParsingResults(Document item) : base(item) { Passes.Add(() => { int before_count = 0; if (!ParsingResults.InverseImports.ContainsKey(this.FullFileName)) { ParsingResults.InverseImports.Add(this.FullFileName, new HashSet <string>()); } foreach (KeyValuePair <string, HashSet <string> > x in ParsingResults.InverseImports) { before_count++; before_count = before_count + x.Value.Count; } if (ParseTree == null) { return(false); } int after_count = 0; foreach (KeyValuePair <string, HashSet <string> > dep in ParsingResults.InverseImports) { string name = dep.Key; Workspaces.Document x = item.Workspace.FindDocument(name); if (x == null) { // Add document. Workspaces.Container proj = Item.Parent; Workspaces.Document new_doc = new Workspaces.Document(name); proj.AddChild(new_doc); after_count++; } after_count++; after_count = after_count + dep.Value.Count; } return(before_count != after_count); }); Passes.Add(() => { // The workspace is completely loaded. Create scopes for all files in workspace // if they don't already exist. foreach (KeyValuePair <string, HashSet <string> > dep in InverseImports) { string name = dep.Key; _scopes.TryGetValue(name, out IScope file_scope); if (file_scope != null) { continue; } _scopes[name] = new FileScope(name, null); } // Set up search path scopes for Imports relationship. IScope root = _scopes[FullFileName]; foreach (string dep in Imports) { // Don't add if already have this search path. IScope dep_scope = _scopes[dep]; bool found = false; foreach (IScope scope in root.NestedScopes) { if (scope is SearchPathScope) { SearchPathScope spc = scope as SearchPathScope; if (spc.NestedScopes.First() == dep_scope) { found = true; break; } } } if (!found) { SearchPathScope import = new SearchPathScope(root); import.nest(dep_scope); root.nest(import); } } root.empty(); RootScope = root; return(false); }); Passes.Add(() => { if (ParseTree == null) { return(false); } ParseTreeWalker.Default.Walk(new Pass2Listener(this), ParseTree); return(false); }); Passes.Add(() => { if (ParseTree == null) { return(false); } ParseTreeWalker.Default.Walk(new Pass3Listener(this), ParseTree); return(false); }); }
public JavaParserDetails(Workspaces.Document item) : base(item) { // Passes executed in order for all files. Passes.Add(() => { // Gather Imports from grammars. // Gather _dependent_grammars map. ParseTreeWalker.Default.Walk(new Pass3Listener(this), ParseTree); return(false); }); Passes.Add(() => { // For all imported grammars across the entire universe, // make sure all are loaded in the workspace, // then restart. foreach (KeyValuePair <string, List <string> > dep in _dependent_grammars) { var name = dep.Key; var x = Workspaces.Workspace.Instance.FindDocument(name); if (x == null) { // Add document. var proj = this.Item.Parent; var new_doc = new Workspaces.Document(name, name); proj.AddChild(new_doc); return(true); } foreach (var y in dep.Value) { var z = Workspaces.Workspace.Instance.FindDocument(y); if (z == null) { // Add document. var proj = this.Item.Parent; var new_doc = new Workspaces.Document(y, y); proj.AddChild(new_doc); return(true); } } } // The workspace is completely loaded. Create scopes for all files in workspace // if they don't already exist. foreach (KeyValuePair <string, List <string> > dep in _dependent_grammars) { var name = dep.Key; _scopes.TryGetValue(name, out IScope file_scope); if (file_scope != null) { continue; } _scopes[name] = new FileScope(name, null); } // Set up search path scopes for Imports relationship. var root = _scopes[this.FullFileName]; foreach (var dep in this.Imports) { var import = new SearchPathScope(root); _scopes.TryGetValue(dep, out IScope dep_scope); if (dep_scope == null) { _scopes[dep] = new FileScope(dep, null); } dep_scope = _scopes[dep]; import.nest(dep_scope); root.nest(import); } root.empty(); this.RootScope = root; return(false); }); Passes.Add(() => { ParseTreeWalker.Default.Walk(new Pass1Listener(this), ParseTree); return(false); }); Passes.Add(() => { ParseTreeWalker.Default.Walk(new Pass2Listener(this), ParseTree); return(false); }); }
private TypeScope CreateInterfaceCommonType(string name, int offset) { TypeScope ctn = (TypeScope)members[offset]; if (ctn != null) { return(ctn); } bool in_scope = false; if (name != null) { in_scope = true; } bool is_interface = br.ReadBoolean(); if (is_interface)//ïðîïóñêàåì ôëàã - èíòåðôåéñíîñòè { name = GetString(br.ReadInt32()); } else { name = br.ReadString(); } //br.ReadInt32(); //ssyy //×èòàåì, ÿâëÿåòñÿ ëè òèï èíòåðôåéñîì bool type_is_interface = (br.ReadByte() == 1); //×èòàåì, ÿâëÿåòñÿ ëè òèï äåëåãàòîì bool type_is_delegate = (br.ReadByte() == 1); //\ssyy bool type_is_generic_definition = (br.ReadByte() == 1); if (type_is_generic_definition) { throw new Exception(); } TypeScope base_type = GetTypeReference(); bool is_value_type = br.ReadBoolean(); //ssyy //×èòàåì ïîääåðæèâàåìûå èíòåðôåéñû int interf_count = br.ReadInt32(); List <TypeScope> interfaces = new List <TypeScope>(); for (int i = 0; i < interf_count; i++) { interfaces.Add(GetTypeReference()); } //\ssyy object low_val = null; object upper_val = null; PascalABCCompiler.SemanticTree.type_access_level tal = (PascalABCCompiler.SemanticTree.type_access_level)br.ReadByte(); PascalABCCompiler.SemanticTree.type_special_kind tsk = (PascalABCCompiler.SemanticTree.type_special_kind)br.ReadByte(); bool is_sealed = br.ReadBoolean(); bool is_abstract = br.ReadBoolean(); if (tsk == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) { low_val = CreateExpression(); upper_val = CreateExpression(); } TypeScope element_type = null; if (CanReadObject()) { element_type = GetTypeReference(); } switch (tsk) { case PascalABCCompiler.SemanticTree.type_special_kind.none_kind: ctn = new TypeScope(SymbolKind.Class, cur_scope, base_type); break; case PascalABCCompiler.SemanticTree.type_special_kind.record: ctn = new TypeScope(SymbolKind.Struct, cur_scope, base_type); break; case PascalABCCompiler.SemanticTree.type_special_kind.array_wrapper: ctn = new ArrayScope(); break; case PascalABCCompiler.SemanticTree.type_special_kind.enum_kind: ctn = new EnumScope(SymbolKind.Enum, cur_scope, base_type); break; case PascalABCCompiler.SemanticTree.type_special_kind.set_type: ctn = new SetScope(element_type); break; case PascalABCCompiler.SemanticTree.type_special_kind.array_kind: if (!in_scope) { ctn = new ArrayScope(); } else { return(null); } break; case PascalABCCompiler.SemanticTree.type_special_kind.diap_type: ctn = new DiapasonScope(low_val, upper_val); break; case PascalABCCompiler.SemanticTree.type_special_kind.typed_file: ctn = new FileScope(element_type, null); break; case PascalABCCompiler.SemanticTree.type_special_kind.binary_file: ctn = new FileScope(null, null); break; } ctn.declaringUnit = root_scope; ctn.si.name = name; ctn.is_abstract = is_abstract; ctn.is_final = is_sealed; AddMember(ctn, offset); ctn.elementType = element_type; br.ReadInt32(); br.ReadInt32();//attributes //common_namespace_node ns = cun.namespaces[0]; byte flag = br.ReadByte(); int def_prop_off = 0; if (flag == 1) { def_prop_off = br.ReadInt32(); } ReadDebugInfo(); ctn.si.description = ctn.GetDescription(); //ñîçäàåì scope äëÿ êëàññà //ctn = new wrapped_common_type_node(this, base_type, name, tal, ns, scope, loc, offset); //members[offset] = ctn; //AddMember(ctn, offset); RestoreAllMembers(ctn); return(ctn); }
public FileScopedEntityLookup SetFileScope(FileScope fileScope) { this.fileScope = fileScope; return(this); }
private FunctionDefinition ParseFunction(TokenStream tokens, TopLevelConstruct nullableOwner, FileScope fileScope) { bool isStatic = nullableOwner != null && nullableOwner is ClassDefinition && tokens.PopIfPresent(this.parser.Keywords.STATIC); Token functionToken = tokens.PopExpected(this.parser.Keywords.FUNCTION); List <Annotation> functionAnnotations = new List <Annotation>(); while (tokens.IsNext("@")) { functionAnnotations.Add(this.parser.AnnotationParser.ParseAnnotation(tokens)); } Token functionNameToken = tokens.Pop(); this.parser.VerifyIdentifier(functionNameToken); FunctionDefinition fd = new FunctionDefinition(functionToken, parser.CurrentLibrary, nullableOwner, isStatic, functionNameToken, functionAnnotations, parser.CurrentNamespace, fileScope); tokens.PopExpected("("); List <Token> argNames = new List <Token>(); List <Expression> defaultValues = new List <Expression>(); List <Annotation> argAnnotations = new List <Annotation>(); bool optionalArgFound = false; while (!tokens.PopIfPresent(")")) { if (argNames.Count > 0) { tokens.PopExpected(","); } Annotation annotation = tokens.IsNext("@") ? this.parser.AnnotationParser.ParseAnnotation(tokens) : null; Token argName = tokens.Pop(); Expression defaultValue = null; this.parser.VerifyIdentifier(argName); if (tokens.PopIfPresent("=")) { optionalArgFound = true; defaultValue = this.parser.ExpressionParser.Parse(tokens, fd); } else if (optionalArgFound) { throw new ParserException(argName, "All optional arguments must come at the end of the argument list."); } argAnnotations.Add(annotation); argNames.Add(argName); defaultValues.Add(defaultValue); } IList <Executable> code = Parser.ParseBlock(parser, tokens, true, fd); fd.ArgNames = argNames.ToArray(); fd.DefaultValues = defaultValues.ToArray(); fd.ArgAnnotations = argAnnotations.ToArray(); fd.Code = code.ToArray(); return(fd); }
private Namespace ParseNamespace(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope) { Token namespaceToken = tokens.PopExpected(this.parser.Keywords.NAMESPACE); Token first = tokens.Pop(); this.parser.VerifyIdentifier(first); List <Token> namespacePieces = new List <Token>() { first }; string namespaceBuilder = first.Value; parser.RegisterNamespace(namespaceBuilder); while (tokens.PopIfPresent(".")) { Token nsToken = tokens.Pop(); this.parser.VerifyIdentifier(nsToken); namespacePieces.Add(nsToken); namespaceBuilder += "." + nsToken.Value; parser.RegisterNamespace(namespaceBuilder); } string name = string.Join(".", namespacePieces.Select <Token, string>(t => t.Value)); parser.PushNamespacePrefix(name); Namespace namespaceInstance = new Namespace(namespaceToken, name, owner, parser.CurrentLibrary, fileScope); tokens.PopExpected("{"); List <TopLevelConstruct> namespaceMembers = new List <TopLevelConstruct>(); while (!tokens.PopIfPresent("}")) { TopLevelConstruct executable = this.parser.ExecutableParser.ParseTopLevel(tokens, namespaceInstance, fileScope); if (executable is FunctionDefinition || executable is ClassDefinition || executable is EnumDefinition || executable is ConstStatement || executable is Namespace) { namespaceMembers.Add(executable); } else { throw new ParserException(executable.FirstToken, "Only function, class, and nested namespace declarations may exist as direct members of a namespace."); } } namespaceInstance.Code = namespaceMembers.ToArray(); parser.PopNamespacePrefix(); return(namespaceInstance); }
private ClassDefinition ParseClassDefinition(TokenStream tokens, TopLevelConstruct owner, Token staticToken, Token finalToken, FileScope fileScope) { Token classToken = tokens.PopExpected(this.parser.Keywords.CLASS); Token classNameToken = tokens.Pop(); this.parser.VerifyIdentifier(classNameToken); List <Token> baseClassTokens = new List <Token>(); List <string> baseClassStrings = new List <string>(); if (tokens.PopIfPresent(":")) { if (baseClassTokens.Count > 0) { tokens.PopExpected(","); } Token baseClassToken = tokens.Pop(); string baseClassName = baseClassToken.Value; this.parser.VerifyIdentifier(baseClassToken); while (tokens.PopIfPresent(".")) { Token baseClassTokenNext = tokens.Pop(); this.parser.VerifyIdentifier(baseClassTokenNext); baseClassName += "." + baseClassTokenNext.Value; } baseClassTokens.Add(baseClassToken); baseClassStrings.Add(baseClassName); } ClassDefinition cd = new ClassDefinition( classToken, classNameToken, baseClassTokens, baseClassStrings, parser.CurrentNamespace, owner, parser.CurrentLibrary, staticToken, finalToken, fileScope); tokens.PopExpected("{"); List <FunctionDefinition> methods = new List <FunctionDefinition>(); List <FieldDeclaration> fields = new List <FieldDeclaration>(); ConstructorDefinition constructorDef = null; ConstructorDefinition staticConstructorDef = null; while (!tokens.PopIfPresent("}")) { Dictionary <string, List <Annotation> > annotations = null; while (tokens.IsNext("@")) { annotations = annotations ?? new Dictionary <string, List <Annotation> >(); Annotation annotation = this.parser.AnnotationParser.ParseAnnotation(tokens); if (!annotations.ContainsKey(annotation.Type)) { annotations[annotation.Type] = new List <Annotation>(); } annotations[annotation.Type].Add(annotation); } if (tokens.IsNext(this.parser.Keywords.FUNCTION) || tokens.AreNext(this.parser.Keywords.STATIC, this.parser.Keywords.FUNCTION)) { methods.Add((FunctionDefinition)this.parser.ExecutableParser.ParseFunction(tokens, cd, fileScope)); } else if (tokens.IsNext(this.parser.Keywords.CONSTRUCTOR)) { if (constructorDef != null) { throw new ParserException(tokens.Pop(), "Multiple constructors are not allowed. Use optional arguments."); } constructorDef = (ConstructorDefinition)this.parser.ExecutableParser.ParseConstructor(tokens, cd); if (annotations != null && annotations.ContainsKey(this.parser.Keywords.PRIVATE)) { constructorDef.PrivateAnnotation = annotations[this.parser.Keywords.PRIVATE][0]; annotations[this.parser.Keywords.PRIVATE].RemoveAt(0); } } else if (tokens.AreNext(this.parser.Keywords.STATIC, this.parser.Keywords.CONSTRUCTOR)) { tokens.Pop(); // static token if (staticConstructorDef != null) { throw new ParserException(tokens.Pop(), "Multiple static constructors are not allowed."); } staticConstructorDef = (ConstructorDefinition)this.parser.ExecutableParser.ParseConstructor(tokens, cd); } else if (tokens.IsNext(this.parser.Keywords.FIELD) || tokens.AreNext(this.parser.Keywords.STATIC, this.parser.Keywords.FIELD)) { fields.Add(this.parser.ExecutableParser.ParseField(tokens, cd)); } else { tokens.PopExpected("}"); } if (annotations != null) { foreach (List <Annotation> annotationsOfType in annotations.Values) { if (annotationsOfType.Count > 0) { throw new ParserException(annotationsOfType[0].FirstToken, "Unused or extra annotation."); } } } } cd.Methods = methods.ToArray(); cd.Constructor = constructorDef; cd.StaticConstructor = staticConstructorDef; cd.Fields = fields.ToArray(); return(cd); }
private EnumDefinition ParseEnumDefinition(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope) { Token enumToken = tokens.PopExpected(this.parser.Keywords.ENUM); Token nameToken = tokens.Pop(); this.parser.VerifyIdentifier(nameToken); string name = nameToken.Value; EnumDefinition ed = new EnumDefinition(enumToken, nameToken, parser.CurrentNamespace, owner, parser.CurrentLibrary, fileScope); tokens.PopExpected("{"); bool nextForbidden = false; List <Token> items = new List <Token>(); List <Expression> values = new List <Expression>(); while (!tokens.PopIfPresent("}")) { if (nextForbidden) { tokens.PopExpected("}"); // crash } Token enumItem = tokens.Pop(); this.parser.VerifyIdentifier(enumItem); if (tokens.PopIfPresent("=")) { values.Add(this.parser.ExpressionParser.Parse(tokens, ed)); } else { values.Add(null); } nextForbidden = !tokens.PopIfPresent(","); items.Add(enumItem); } ed.SetItems(items, values); return(ed); }
private ConstStatement ParseConst(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope) { Token constToken = tokens.PopExpected(this.parser.Keywords.CONST); Token nameToken = tokens.Pop(); ConstStatement constStatement = new ConstStatement(constToken, nameToken, parser.CurrentNamespace, owner, parser.CurrentLibrary, fileScope); this.parser.VerifyIdentifier(nameToken); tokens.PopExpected("="); constStatement.Expression = this.parser.ExpressionParser.Parse(tokens, constStatement); tokens.PopExpected(";"); return(constStatement); }
public TopLevelConstruct ParseTopLevel( TokenStream tokens, TopLevelConstruct owner, FileScope fileScope) { string value = tokens.PeekValue(); Token staticToken = null; Token finalToken = null; while (value == this.parser.Keywords.STATIC || value == this.parser.Keywords.FINAL) { if (value == this.parser.Keywords.STATIC && staticToken == null) { staticToken = tokens.Pop(); value = tokens.PeekValue(); } if (value == this.parser.Keywords.FINAL && finalToken == null) { finalToken = tokens.Pop(); value = tokens.PeekValue(); } } if (staticToken != null || finalToken != null) { if (value != this.parser.Keywords.CLASS) { if (staticToken != null) { throw new ParserException(staticToken, "Only classes, methods, and fields may be marked as static"); } else { throw new ParserException(finalToken, "Only classes may be marked as final."); } } if (staticToken != null && finalToken != null) { throw new ParserException(staticToken, "Classes cannot be both static and final."); } } if (value == parser.Keywords.IMPORT) { Token importToken = tokens.PopExpected(parser.Keywords.IMPORT); List <string> importPathBuilder = new List <string>(); while (!tokens.PopIfPresent(";")) { if (importPathBuilder.Count > 0) { tokens.PopExpected("."); } Token pathToken = tokens.Pop(); parser.VerifyIdentifier(pathToken); importPathBuilder.Add(pathToken.Value); } string importPath = string.Join(".", importPathBuilder); return(new ImportStatement(importToken, importPath, parser.CurrentLibrary, fileScope)); } if (value == this.parser.Keywords.ENUM) { return(this.ParseEnumDefinition(tokens, owner, fileScope)); } if (value == this.parser.Keywords.NAMESPACE) { return(this.ParseNamespace(tokens, owner, fileScope)); } if (value == this.parser.Keywords.CONST) { return(this.ParseConst(tokens, owner, fileScope)); } if (value == this.parser.Keywords.FUNCTION) { return(this.ParseFunction(tokens, owner, fileScope)); } if (value == this.parser.Keywords.CLASS) { return(this.ParseClassDefinition(tokens, owner, staticToken, finalToken, fileScope)); } if (value == this.parser.Keywords.ENUM) { return(this.ParseEnumDefinition(tokens, owner, fileScope)); } if (value == this.parser.Keywords.CONSTRUCTOR) { return(this.ParseConstructor(tokens, owner)); } throw new ParserException(tokens.Peek(), "Unrecognized token."); }
public static EnumSyntax Enum(FileScope pScope, string pName, List <IdentifierSyntax> pNames, List <int> pValues) { return(new EnumSyntax(pScope, pName, pNames, pValues)); }