Skip to content

Commit

Permalink
table: first round of refactoring add to table function
Browse files Browse the repository at this point in the history
broke add to table function into multiple functions (one level)
added 'noexcept' to functions that don't throw
made functions 'inline' that are only called once
  • Loading branch information
thunder422 committed Jan 21, 2015
1 parent 07064db commit 23515be
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 121 deletions.
281 changes: 165 additions & 116 deletions table.cpp
Expand Up @@ -1512,11 +1512,59 @@ int TableEntry::index() const
}


void TableEntry::addToTable()
inline void TableEntry::addToTable() noexcept
try
{
int index = this - tableEntries;
addToCodeMap();
if (addTwoWordCommand())
{
return;
}

if (!m_name.empty())
{
auto iterator = Table::s_nameToEntry.find(m_name);
if (iterator == Table::s_nameToEntry.end())
{
addPrimaryCodeToNameMap();
return;
}
if (m_exprInfo->m_operandCount > 0 && !hasFlag(Reference_Flag))
{
TableEntry *primary;
if (!(primary = setNewPrimaryOrGetPrimary(iterator->second)))
{
return;
}

if (isOperator() && m_exprInfo->m_operandCount
> primary->m_exprInfo->m_operandCount)
{
// not the correct primary entry
if (!(primary = getCorrectPrimary(primary)))
{
return;
}
}

if (!(primary = addAlternateOrGetNewPrimary(primary)))
{
return;
}

checkIfMulipleFunctionEntry(primary);
}
}
}
catch (std::string &error)
{
std::cerr << "Table Error: " << error << std::endl;
abort();
}


inline void TableEntry::addToCodeMap() noexcept
{
if (m_code != Code{})
{
auto iterator = Table::s_codeToEntry.find(m_code);
Expand All @@ -1525,7 +1573,11 @@ try
Table::s_codeToEntry[m_code] = this;
}
}
}


inline bool TableEntry::addTwoWordCommand()
{
if (hasFlag(Two_Flag) && !m_name2.empty())
{
std::string name {m_name + ' ' + m_name2};
Expand All @@ -1535,141 +1587,119 @@ try
throw "Multiple two-word command '" + name + '\'';
}
Table::s_nameToEntry.emplace(std::move(name), this);
return;
return true;
}
return false;
}

if (!m_name.empty())

inline void TableEntry::addPrimaryCodeToNameMap()
{
if (isOperator() && m_exprInfo->m_operandCount == 2
&& m_exprInfo->m_operandDataType[0]
!= m_exprInfo->m_operandDataType[1])
{
auto iterator = Table::s_nameToEntry.find(m_name);
if (iterator == Table::s_nameToEntry.end())
throw "Binary operator '" + m_name + m_name2 + "' not homogeneous";
}
Table::s_nameToEntry.emplace(m_name, this);
if (m_exprInfo->m_operandCount > 0)
{
int index = isOperator() ? m_exprInfo->m_operandCount - 1 : 0;
addExpectedDataType(m_exprInfo->m_operandDataType[index]);
}
}

inline TableEntry *TableEntry::setNewPrimaryOrGetPrimary(TableEntry *primary)
noexcept
{
if (m_exprInfo->m_operandCount < primary->m_exprInfo->m_operandCount)
{
TableEntry *alternate = primary;
primary = this;
Table::s_alternate[this][alternate->lastOperand()].push_back(alternate);
if (isFunction())
{
if (isOperator() && m_exprInfo->m_operandCount == 2
&& m_exprInfo->m_operandDataType[0]
!= m_exprInfo->m_operandDataType[1])
{
throw "Binary operator '" + m_name + m_name2
+ "' not homogeneous";
}
Table::s_nameToEntry.emplace(m_name, this);
if (m_exprInfo->m_operandCount > 0)
{
int index = isOperator() ? m_exprInfo->m_operandCount - 1 : 0;
addExpectedDataType(m_exprInfo->m_operandDataType[index]);
}
return; // primary code, nothing more to do
m_flags |= Multiple_Flag;
Table::s_expectedDataType.erase(alternate);
}
if (m_exprInfo->m_operandCount > 0 && !hasFlag(Reference_Flag))
{
TableEntry *primary = iterator->second;
addExpectedDataType(m_exprInfo->m_operandDataType[0]);
return {};
}
return primary;
}

if (m_exprInfo->m_operandCount
< primary->m_exprInfo->m_operandCount)
{
TableEntry *alternate = primary;
iterator->second = this;
Table::s_alternate[this][alternate->m_exprInfo->m_operandCount
- 1].push_back(alternate);
if (isFunction())
{
m_flags |= Multiple_Flag;
Table::s_expectedDataType.erase(alternate);
}
addExpectedDataType(m_exprInfo->m_operandDataType[0]);
return; // new primary code, nothing more to do
}

if (isOperator() && m_exprInfo->m_operandCount
> primary->m_exprInfo->m_operandCount)
{
// not the correct primary entry
// need to get correct primary entry
auto &vector = Table::s_alternate[primary]
[m_exprInfo->m_operandCount - 1];
if (vector.empty())
{
if (isOperator() && m_exprInfo->m_operandCount == 2
&& m_exprInfo->m_operandDataType[0]
!= m_exprInfo->m_operandDataType[1])
{
throw "First binary operator '" + m_name + m_name2
+ "' not homogeneous";
}
vector.push_back(this);
addExpectedDataType(m_exprInfo->m_operandDataType[0]);
return; // first alternate, nothing more to do
}
primary = vector.front();
}
inline TableEntry *TableEntry::getCorrectPrimary(TableEntry *primary)
{
Table::EntryVector &vector = Table::s_alternate[primary][lastOperand()];
if (vector.empty())
{
if (isOperator() && m_exprInfo->m_operandCount == 2
&& m_exprInfo->m_operandDataType[0]
!= m_exprInfo->m_operandDataType[1])
{
throw "First binary operator '" + m_name + m_name2
+ "' not homogeneous";
}
vector.push_back(this);
addExpectedDataType(m_exprInfo->m_operandDataType[0]);
return {};
}
return vector.front();
}


for (int i = 0; i < primary->m_exprInfo->m_operandCount; ++i)
inline TableEntry *TableEntry::addAlternateOrGetNewPrimary(TableEntry *primary)
noexcept
{
for (int i = 0; i < primary->m_exprInfo->m_operandCount; ++i)
{
if (m_exprInfo->m_operandDataType[i]
!= primary->m_exprInfo->m_operandDataType[i])
{
auto newEntry = this;
do
{
if (m_exprInfo->m_operandDataType[i]
!= primary->m_exprInfo->m_operandDataType[i])
TableEntry *newPrimary {};
for (auto &alternate : Table::s_alternate[primary][i])
{
auto newEntry = this;
do
if (m_exprInfo->m_operandDataType[i]
== alternate->m_exprInfo->m_operandDataType[i])
{
TableEntry *newPrimary {};
for (auto &alternate : Table::s_alternate[primary][i])
{
if (m_exprInfo->m_operandDataType[i]
== alternate->m_exprInfo->m_operandDataType[i])
{
if (isOperator()
&& m_exprInfo->m_operandCount == 2
&& m_exprInfo->m_operandDataType[0]
== m_exprInfo->m_operandDataType[1])
{
Table::s_expectedDataType.erase(alternate);
newEntry->addExpectedDataType(newEntry
->m_exprInfo->m_operandDataType[i]);
std::swap(newEntry, alternate);
}
newPrimary = alternate;
++i;
break;
}
}
if (!newPrimary)
if (isOperator() && m_exprInfo->m_operandCount == 2
&& m_exprInfo->m_operandDataType[0]
== m_exprInfo->m_operandDataType[1])
{
Table::s_alternate[primary][i].push_back(newEntry);
(i == 0 && newEntry->isOperator()
&& newEntry->m_exprInfo->m_operandCount == 2
? newEntry : primary)->addExpectedDataType(
newEntry->m_exprInfo->m_operandDataType[i]);
return; // alternate added, nothing more to do
Table::s_expectedDataType.erase(alternate);
newEntry->addExpectedDataType(newEntry
->m_exprInfo->m_operandDataType[i]);
std::swap(newEntry, alternate);
}
primary = newPrimary; // new primary, next operand
newPrimary = alternate;
++i;
break;
}
while (i < m_exprInfo->m_operandCount);
break; // no more operands, all operands match
}
if (!newPrimary)
{
Table::s_alternate[primary][i].push_back(newEntry);
(i == 0 && newEntry->isOperator()
&& newEntry->m_exprInfo->m_operandCount == 2
? newEntry : primary)->addExpectedDataType(
newEntry->m_exprInfo->m_operandDataType[i]);
return {};
}
primary = newPrimary; // new primary, next operand
}
if (isFunction() && m_exprInfo->m_operandCount
> primary->m_exprInfo->m_operandCount)
{
// multiple codes; set multiple flag on primary code
primary->m_flags |= Multiple_Flag;
Table::s_alternate[primary][m_exprInfo->m_operandCount - 1]
.push_back(this);
}
else
{
throw "Multiple entries with same operand data types ("
+ std::to_string(index) + ','
+ std::to_string(primary - tableEntries) + ')';
}
while (i < m_exprInfo->m_operandCount);
break; // no more operands, all operands match
}
}
}
catch (std::string &error)
{
std::cerr << "Table Error:" << error << std::endl;
abort();
return primary;
}


void TableEntry::addExpectedDataType(DataType dataType)
void TableEntry::addExpectedDataType(DataType dataType) noexcept
{
DataType current = Table::s_expectedDataType[this];
if (current == DataType{})
Expand All @@ -1683,6 +1713,25 @@ void TableEntry::addExpectedDataType(DataType dataType)
}


inline void TableEntry::checkIfMulipleFunctionEntry(TableEntry *primary)
{
if (isFunction()
&& m_exprInfo->m_operandCount > primary->m_exprInfo->m_operandCount)
{
// multiple codes; set multiple flag on primary code
primary->m_flags |= Multiple_Flag;
Table::s_alternate[primary][m_exprInfo->m_operandCount - 1]
.push_back(this);
}
else
{
throw "Multiple entries with same operand data types ("
+ std::to_string(this - tableEntries) + ','
+ std::to_string(primary - tableEntries) + ')';
}
}


std::string TableEntry::commandName() const
{
std::string string {m_name};
Expand Down
18 changes: 15 additions & 3 deletions table.h
Expand Up @@ -170,6 +170,10 @@ class TableEntry
}
DataType expectedDataType();

bool lastOperand() const
{
return m_exprInfo->m_operandCount - 1;
}
bool isUnaryOperator() const
{
return isOperator() && m_exprInfo->m_operandCount == 1;
Expand Down Expand Up @@ -211,8 +215,15 @@ class TableEntry
friend class Table;

private:
void addToTable();
void addExpectedDataType(DataType dataType);
void addToTable() noexcept;
void addToCodeMap() noexcept;
bool addTwoWordCommand();
void addPrimaryCodeToNameMap();
TableEntry *setNewPrimaryOrGetPrimary(TableEntry *primary) noexcept;
TableEntry *getCorrectPrimary(TableEntry *primary);
TableEntry *addAlternateOrGetNewPrimary(TableEntry *primary) noexcept;
void addExpectedDataType(DataType dataType) noexcept;
void checkIfMulipleFunctionEntry(TableEntry *primary);

Code m_code; // code type of table entry
const std::string m_name; // name for table entry
Expand Down Expand Up @@ -262,7 +273,8 @@ class Table
static CodeMap s_codeToEntry;

// entry to alternate entries arrays
using EntryVectorArray = std::array<std::vector<TableEntry *>, 3>;
using EntryVector = std::vector<TableEntry *>;
using EntryVectorArray = std::array<EntryVector, 3>;
static std::unordered_map<TableEntry *, EntryVectorArray> s_alternate;

// entry to expected data type map
Expand Down
4 changes: 2 additions & 2 deletions token.h
Expand Up @@ -250,7 +250,7 @@ class Token
}
bool lastOperand() const
{
return tableEntry()->operandCount() - 1;
return m_entry->lastOperand();
}
bool isLastOperand(int operandIndex) const
{
Expand Down Expand Up @@ -279,7 +279,7 @@ class Token
}
void setFirstAlternate(int operandIndex)
{
m_entry = tableEntry()->alternate(operandIndex);
m_entry = m_entry->alternate(operandIndex);
}

// other functions
Expand Down

0 comments on commit 23515be

Please sign in to comment.