// this method must be invoked in any subclass immediatly after constructor completion protected void CompleteInitialization() { lock (this) { if (_isReadOnly) { return; } _isReadOnly = true; } if (typeof(ISyntaxExtender).IsAssignableFrom(typeof(TExtender))) { var api = new TExtender().CastTo <ISyntaxExtender>(); api.ExtendSyntax(this); } NonBreakingIdentifierChars = NonBreakingIdentifierChars.CastTo <List <char> >().AsReadOnly(); SyntaxChars = SyntaxChars.CastTo <Dictionary <int, TokenType> >().AsReadOnly(); Constants = Constants.CastTo <Dictionary <string, object> >().AsReadOnly(); Symbols = Symbols.CastTo <Dictionary <string, TokenType> >().AsReadOnly(); Functions = Functions.CastTo <List <FunctionMap> >().AsReadOnly(); KnownTypes = KnownTypes.CastTo <Dictionary <string, TypeParser> >().AsReadOnly(); ImplementsVariables = Symbols.Values.Any(v => v == TokenType.Declaration) || SyntaxChars.Values.Any(v => v == TokenType.Declaration); IdentifierDelimiter = (char)SyntaxChars.Where(kv => kv.Value == TokenType.IdentifierDelimiter).Select(kv => kv.Key).FirstOrDefault(); }