public ISymbol Visit(SymbolResolverVisitor binder, ConstantNode constdec) { IType typeSymbol = null; // Get the constant's type or assume it if not present if (constdec.Type != null) { typeSymbol = SymbolHelper.GetTypeSymbol(binder.SymbolTable, binder.Inferrer, constdec.Type); } else { typeSymbol = binder.Inferrer.NewAnonymousType(); } foreach (var definition in constdec.Definitions) { // Get the identifier name var constantName = definition.Left.Value; // Check if the symbol is already defined if (binder.SymbolTable.HasVariableSymbol(constantName)) { throw new SymbolException($"Symbol {constantName} is already defined."); } // If it is a variable definition, visit the right-hand side expression var rhsSymbol = definition.Right?.Visit(binder); if (rhsSymbol != null && !(rhsSymbol is IPrimitive)) { throw new SymbolException($"The expression to initialize '{constantName}' must be constant"); } // Create the new symbol for the variable var boundSymbol = binder.SymbolTable.AddNewVariableSymbol(constantName, typeSymbol, Access.Public, Storage.Constant); if (typeSymbol is Anonymous asym) { binder.Inferrer.TrackSymbol(asym, boundSymbol); } } return(null); }
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); }