tlang/source/tlang/compiler/configuration.d

202 lines
4.3 KiB
D

module compiler.configuration;
import compiler.core : CompilerException, CompilerError;
import std.string : cmp;
private union ConfigValue
{
ulong number;
bool boolean;
string text;
string[] textArray;
}
public enum ConfigType
{
NUMBER,
BOOLEAN,
TEXT,
TEXT_ARRAY
}
public struct ConfigEntry
{
private string name;
private ConfigValue value;
private ConfigType type;
private this(string entryName, ConfigType entryType)
{
this.name = entryName;
this.type = entryType;
}
this(VType)(string entryName, VType valType)
{
this(entryName, ConfigType.TEXT);
value.text = to!(string)(valType);
}
this(string entryName, ulong entryValue)
{
this(entryName, ConfigType.NUMBER);
value.number = entryValue;
}
this(string entryName, bool entryValue)
{
this(entryName, ConfigType.BOOLEAN);
value.boolean = entryValue;
}
this(string entryName, string entryValue)
{
this(entryName, ConfigType.TEXT);
value.text = entryValue;
}
this(string entryName, string[] entryValue)
{
this(entryName, ConfigType.TEXT_ARRAY);
value.textArray = entryValue;
}
public ulong getNumber()
{
if(type == ConfigType.NUMBER)
{
return value.number;
}
else
{
throw new CompilerException(CompilerError.CONFIG_TYPE_ERROR, "Type mismatch for key '"~name~"'");
}
}
public bool getBoolean()
{
if(type == ConfigType.BOOLEAN)
{
return value.boolean;
}
else
{
throw new CompilerException(CompilerError.CONFIG_TYPE_ERROR, "Type mismatch for key '"~name~"'");
}
}
public string getText()
{
if(type == ConfigType.TEXT)
{
return value.text;
}
else
{
throw new CompilerException(CompilerError.CONFIG_TYPE_ERROR, "Type mismatch for key '"~name~"'");
}
}
public string[] getArray()
{
if(type == ConfigType.TEXT_ARRAY)
{
return value.textArray;
}
else
{
throw new CompilerException(CompilerError.CONFIG_TYPE_ERROR, "Type mismatch for key '"~name~"'");
}
}
public string getName()
{
return name;
}
public ConfigType getType()
{
return type;
}
}
/**
* TODO: Add a union and then also a get funciton that
* interprets per each for us (using templatescan be automated
* maybe)
* Implement this!
*/
/**
* TODO: Implement a union below as the value
* of tye key-value pair
*/
public class CompilerConfiguration
{
private ConfigEntry[] entries;
public void addConfig(ConfigEntry entry)
{
// If duplicate then update entry
if(hasConfig(entry.getName()))
{
updateConfig(entry);
}
// Else, add a new entry
else
{
entries ~= entry;
}
}
private void updateConfig(ConfigEntry newEntry)
{
for(ulong i = 0; i < entries.length; i++)
{
if(cmp(entries[i].getName(), newEntry.getName()) == 0)
{
if(entries[i].getType() == newEntry.getType())
{
entries[i] = newEntry;
break;
}
else
{
throw new CompilerException(CompilerError.CONFIG_TYPE_ERROR, "Tried updating an entry to a different type");
}
}
}
}
public ConfigEntry getConfig(string key)
{
ConfigEntry foundEntry;
if(hasConfig_internal(key, foundEntry))
{
return foundEntry;
}
else
{
throw new CompilerException(CompilerError.CONFIG_KEY_NOT_FOUND);
}
}
private bool hasConfig_internal(string key, ref ConfigEntry foundEntry)
{
foreach(ConfigEntry curEntry; entries)
{
if(cmp(curEntry.getName(), key) == 0)
{
foundEntry = curEntry;
return true;
}
}
return false;
}
public bool hasConfig(string key)
{
ConfigEntry _discard;
return hasConfig_internal(key, _discard);
}
}