protected void VarDefinitionNode(SymbolResolverVisitor visitor, VariableDefinitionNode vardecl) { foreach (var definition in vardecl.Definitions) { // Get the identifier name var variableName = definition.Left.Value; var storage = SymbolHelper.GetStorage(vardecl.Information.Mutability); // Check if the symbol is already defined if (visitor.SymbolTable.HasVariableSymbol(variableName)) { throw new SymbolException($"Symbol {variableName} is already defined."); } // If it is a variable definition, visit the right-hand side expression var rhsSymbol = definition.Right?.Visit(visitor); IVariable lhsSymbol = null; if (rhsSymbol == null) { // Create the new symbol for the variable var typeInfo = SymbolHelper.GetTypeSymbol(visitor.SymbolTable, visitor.Inferrer, vardecl.Information.Type); lhsSymbol = visitor.SymbolTable.AddNewVariableSymbol(variableName, typeInfo, Access.Public, storage); } else { visitor.SymbolTable.AddNewVariableSymbol(variableName, rhsSymbol.GetTypeSymbol(), Access.Public, storage); } } }
private void CreateParameterSymbol(SymbolResolverVisitor visitor, Function functionSymbol, ParameterNode parameter) { // If the parameter's type is present use it, if not use an anonymous type var paramTypeSymbol = parameter.SymbolInfo.Type == null ? visitor.Inferrer.NewAnonymousType() : SymbolHelper.GetTypeSymbol(visitor.SymbolTable, visitor.Inferrer, parameter.SymbolInfo.Type); // Check if the parameter has storage modifiers var storage = SymbolHelper.GetStorage(parameter.SymbolInfo.Mutability); // Create the parameter symbol in the function's scope var boundSymbol = functionSymbol.CreateParameter(parameter.Name.Value, paramTypeSymbol, storage); if (paramTypeSymbol is Anonymous asym) { visitor.Inferrer.TrackSymbol(asym, boundSymbol); } }
public ISymbol Visit(SymbolResolverVisitor visitor, ObjectPropertyNode node) { var storage = SymbolHelper.GetStorage(node.Information.Mutability); // Visit the property's value node var rhsSymbol = visitor.Visit(node.Value); if (rhsSymbol != null) { visitor.SymbolTable.AddNewVariableSymbol(node.Name.Value, rhsSymbol.GetTypeSymbol(), Access.Public, storage); return(rhsSymbol); } var typeSymbol = SymbolHelper.GetTypeSymbol(visitor.SymbolTable, visitor.Inferrer, node.Information.Type); // Create the symbol for the object's property visitor.SymbolTable.AddNewVariableSymbol(node.Name.Value, typeSymbol, Access.Public, storage); return(typeSymbol); }
protected void VarDestructuringNode(SymbolResolverVisitor visitor, VariableDestructuringNode destrnode) { var types = destrnode.Right.Visit(visitor); foreach (var declaration in destrnode.Left) { if (declaration == null) { continue; } // Get the identifier name var variableName = declaration.Value; // Check if the symbol is already defined if (visitor.SymbolTable.HasVariableSymbol(variableName)) { throw new SymbolException($"Symbol {variableName} is already defined."); } // If the type anotation is not specific (uses 'var'), we need to create an anonymous type // for every variable. If not, we just get the type information from the token var varType = destrnode.Information.Type.Type == Syntax.TokenType.Variable ? visitor.Inferrer.NewAnonymousType() : SymbolHelper.GetTypeSymbol(visitor.SymbolTable, visitor.Inferrer, destrnode.Information.Type); // Create the new symbol for the variable var boundSymbol = visitor.SymbolTable.AddNewVariableSymbol(variableName, varType, Access.Public, SymbolHelper.GetStorage(destrnode.Information.Mutability)); if (varType is Anonymous asym) { visitor.Inferrer.TrackSymbol(asym, boundSymbol); } } }