public DogeSymbolTable BuildSymbolTable(DogeNamespaceDefinition @namespace) { var symbolTable = new DogeSymbolTable(); symbolTable.AddNamespaceSymbolTable(@namespace, symbolTable.FullName); return(symbolTable); }
private void ResolveSymbolTypes(DogeClassDefinition @class, DogeSymbolTable symbolTable, ICollection <IList <string> > usingDefinitions, IList <string> fullName) { foreach (var field in @class.FieldDefinitions) { var symbol = symbolTable.GetSymbolTable(fullName).GetSymbol(field.Name); symbol.TypeSymbol = symbolTable.ResolveSymbol( symbol.Type !, s => s.SymbolType == DogeSymbolType.Type, s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type, usingDefinitions); } foreach (var property in @class.PropertyDefinitions) { var symbol = symbolTable.GetSymbolTable(fullName).GetSymbol(property.Name); symbol.TypeSymbol = symbolTable.ResolveSymbol( symbol.Type !, s => s.SymbolType == DogeSymbolType.Type, s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type, usingDefinitions); } foreach (var method in @class.MethodDefinitions) { var symbol = symbolTable.GetSymbolTable(fullName).GetSymbol(method.Name); if (symbol.Type == null) { continue; } symbol.TypeSymbol = symbolTable.ResolveSymbol( symbol.Type !, s => s.SymbolType == DogeSymbolType.Type, s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type, usingDefinitions); method.Method.ReturnTypeSymbol = new DogeSymbolNode(symbolTable.ResolveSymbol( method.Method.ReturnType, s => s.SymbolType == DogeSymbolType.Type, s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type, usingDefinitions), method.Method.ReturnTypeIdentifier.File, method.Method.ReturnTypeIdentifier.TokenRange); foreach (var parameter in method.Method.Parameters) { parameter.TypeSymbol = new DogeSymbolNode(symbolTable.ResolveSymbol( parameter.Type, s => s.SymbolType == DogeSymbolType.Type, s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type, usingDefinitions), parameter.TypeIdentifier.File, parameter.TypeIdentifier.TokenRange); } } }
public DogeSymbolTable GetOrAddSymbolTable(string key, DogeSymbolTableType symbolTableType) => SymbolTables.TryGetValue(key, out var newSymbolTable) ? newSymbolTable : (SymbolTables[key] = new DogeSymbolTable( key, FullName.With(key), symbolTableType, this));
public DogeSymbolTable GetOrAddSymbolTable(ICollection <string> key, DogeSymbolTableType symbolTableType) { DogeSymbolTable symbolTable = this; foreach (var subkey in key) { symbolTable = symbolTable.GetOrAddSymbolTable(subkey, symbolTableType); } return(symbolTable); }
private void ResolveSymbols(DogeNamespaceDefinition @namespace, DogeSymbolTable symbolTable, ICollection <IList <string> > usingDefinitions, IList <string> fullName) { usingDefinitions = usingDefinitions .Concat( @namespace .UsingDefinitions .Select(x => x.ReferenceName)) .ToList(); if (fullName.Count > 0) { usingDefinitions = usingDefinitions .With(fullName) .Distinct() .ToList(); } foreach (var nestedNamespace in @namespace.NestedNamespaces) { ResolveSymbols(nestedNamespace, symbolTable, usingDefinitions, fullName.With(nestedNamespace.Name)); } foreach (var @class in @namespace.ClassDefinitions) { ResolveSymbolTypes(@class, symbolTable, usingDefinitions, fullName.With(@class.Name)); ResolveSymbols(@class, symbolTable, usingDefinitions, fullName.With(@class.Name)); } }
private void ResolveSymbols(DogeClassDefinition @class, DogeSymbolTable symbolTable, ICollection <IList <string> > usingDefinitions, IList <string> fullName) { foreach (var property in @class.PropertyDefinitions) { if (property.Get != null) { ResolveSymbols( property.Get.MethodBody, symbolTable, new Dictionary <string, DogeLocalDeclarationStatement>(), usingDefinitions, fullName); } if (property.Set != null) { ResolveSymbols( property.Set.MethodBody, symbolTable, new Dictionary <string, DogeLocalDeclarationStatement>(), usingDefinitions, fullName); } } foreach (var method in @class.MethodDefinitions) { ResolveSymbols( method.Method.MethodBody, symbolTable, new Dictionary <string, DogeLocalDeclarationStatement>(), usingDefinitions, fullName); } }
public void ResolveSymbols(DogeNamespaceDefinition @namespace, DogeSymbolTable symbolTable) => ResolveSymbols(@namespace, symbolTable, new List <IList <string> >(), new List <string>());
private DogeNode ResolveExpressionSymbols(DogeNode node, DogeSymbolTable symbolTable, IDictionary <string, DogeLocalDeclarationStatement> locals, ICollection <IList <string> > usingDefinitions, IList <string> fullName) { void resolveSymbols(ref DogeNode node) => node = ResolveExpressionSymbols( node, symbolTable, locals, usingDefinitions, fullName); switch (node) { case DogeBinaryExpression binaryExpression: resolveSymbols(ref binaryExpression.LeftHandSide); resolveSymbols(ref binaryExpression.RightHandSide); break; case DogeUnaryExpression unaryExpression: resolveSymbols(ref unaryExpression.InternalExpression); break; case DogeListExpression <DogeNode> listExpression: var nodeElements = listExpression.Elements.ToArray(); for (int i = 0; i < nodeElements.Length; i++) { resolveSymbols(ref nodeElements[i]); } break; case DogeListExpression <DogeMemberAccessorExpression> listExpression: DogeSymbolTable lastType = symbolTable.GetSymbolTable(fullName); int startSkip = 1; List <DogeMemberAccessorExpression> accumulator = new List <DogeMemberAccessorExpression>(); if (!lastType.TryGetSymbol(listExpression.Elements.First().Name, out _)) { for (; startSkip <= listExpression.Elements.Count; startSkip++) { if (symbolTable.TryResolveSymbol( listExpression.Elements.Select(x => x.Name).Take(startSkip).ToList(), s => s.SymbolType == DogeSymbolType.Field || s.SymbolType == DogeSymbolType.Local || s.SymbolType == DogeSymbolType.Property || s.SymbolType == DogeSymbolType.Method, s => s == DogeSymbolTableType.Type, usingDefinitions, out var lastTypeSymbol)) { DogeMemberAccessorExpression last = listExpression.Elements.ElementAt(startSkip - 1); if (lastTypeSymbol !.SymbolType != DogeSymbolType.Method) { if (last is DogeMethodCallStatement) { throw new InvalidCastException(); } lastType = symbolTable.GetSymbolTable(lastTypeSymbol.FullName); Range <int> range = new Range <int>(listExpression.Elements.First().TokenRange.First, last.TokenRange.Last); accumulator.Add( new DogeMemberAccessorExpression( new DogeIdentifier( new DogeToken( DogeTokenType.Identifier, string.Join('.', lastTypeSymbol.FullName), range.First), DogeFile.Console), false, false, listExpression.File, range) { NameSymbol = new DogeSymbolNode(lastTypeSymbol !, listExpression.File, range) }); }
private void ResolveSymbols(DogeNode node, DogeSymbolTable symbolTable, IDictionary <string, DogeLocalDeclarationStatement> locals, ICollection <IList <string> > usingDefinitions, IList <string> fullName) { void resolveSymbols(DogeNode node) => ResolveSymbols( node, symbolTable, locals, usingDefinitions, fullName); switch (node) { case DogeStatementList statementList: var localsOuter = locals.ToDictionary(x => x.Key, x => x.Value); foreach (var statement in statementList.Statements) { resolveSymbols(statement); } locals = localsOuter; break; case DogeWhileStatement whileStatement: resolveSymbols(whileStatement.Condition); resolveSymbols(whileStatement.Body); break; case DogeIfStatement ifStatement: resolveSymbols(ifStatement.Condition); resolveSymbols(ifStatement.Body); if (ifStatement.Else != null) { resolveSymbols(ifStatement.Else); } break; case DogeLocalDeclarationStatement localDeclarationStatement: if (localDeclarationStatement.Value != null) { resolveSymbols(localDeclarationStatement.Value); } localDeclarationStatement.TypeSymbol = new DogeSymbolNode(symbolTable.ResolveSymbol( localDeclarationStatement.Type, s => s.SymbolType == DogeSymbolType.Type, s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type, usingDefinitions), localDeclarationStatement.File, localDeclarationStatement.TokenRange); locals.Add(localDeclarationStatement.Name, localDeclarationStatement); break; case DogeExpressionStatement expressionStatement: expressionStatement.Expression = ResolveExpressionSymbols( expressionStatement.Expression, symbolTable, locals, usingDefinitions, fullName); break; } }