mirror of https://github.com/tbklang/tlang.git
202 lines
4.3 KiB
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);
|
||
|
}
|
||
|
}
|