// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Linq;
using System.Collections.Generic;
using PascalABCCompiler.TreeConverter;
namespace SymbolTable
{
///
/// Динамическая хеш таблица строк
///
public class SymbolsDictionary
{
public override string ToString() => namesToInfos.SkipWhile(x => x.Key != "").Skip(1).JoinIntoString(Environment.NewLine);
// Регистронезависимый словарь символов
private readonly Dictionary namesToInfos = new Dictionary(StringComparer.OrdinalIgnoreCase);
//public SymbolsDictionary(int start_size)
//{
// dictCaseInsensitive = new Dictionary(start_size, StringComparer.OrdinalIgnoreCase);
//}
///
/// Очистка сохраненных символов
///
public void ClearTable()
{
namesToInfos.Clear();
}
///
/// Добавить информацию info о символе с именем name
///
public void Add(string name, SymbolInfo info)
{
bool exists = namesToInfos.TryGetValue(name, out var node);
if (!exists)
{
node = new HashTableNode();
namesToInfos[name] = node;
}
node.InfoList.Add(info);
}
///
/// Найти информацию о символе с именем name.
/// caseSensitiveSearch определяет регистрозависимость поиска
///
public IEnumerable Find(string name, bool caseSensitiveSearch)
{
// Если ищем регистрозависимо
if (caseSensitiveSearch)
{
if (namesToInfos.TryGetValue(name, out var node))
{
// Если есть точные совпадения, то надо взять только их
var infos = node.InfoList.Where(info => info.Name == name);
if (infos.Any())
return infos;
}
}
// Если ищем регистронезависимо
else
{
if (namesToInfos.TryGetValue(name, out var node))
return node.InfoList;
}
return null;
}
///
/// Получить информацию обо всех сохраненных символах
///
public IEnumerable GetAllSymbolInfos() => namesToInfos.Values;
}
}