Skip to content

Commit

Permalink
token: re-factored conversion code handling
Browse files Browse the repository at this point in the history
and attempted to improve readability and clarity of functions

changed table find code function to token convert function
- added is last operand helper function
- added change constant ignore error helper function (to ignore error)
renamed convert code to convert code entry (and its argument)
renamed convert constant to changed constant (and its argument)
rearranged these functions from top to bottom calling order
removed unnecessary comments (including callers in translator)

(also started updating copyright year in files)
  • Loading branch information
thunder422 committed Jan 11, 2015
1 parent 2f013da commit ce6adff
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 116 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -72,7 +72,7 @@ if (NOT CMAKE_BUILD_TYPE)
endif (NOT CMAKE_BUILD_TYPE)
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

set(ibcp_COPYRIGHT_YEAR 2014)
set(ibcp_COPYRIGHT_YEAR 2015)

set(ibcp_RELEASE_MAJOR 0)
set(ibcp_RELEASE_MINOR 6)
Expand Down
52 changes: 1 addition & 51 deletions table.cpp
Expand Up @@ -2,7 +2,7 @@

// Interactive BASIC Compiler Project
// File: table.cpp - operator/command/function table source file
// Copyright (C) 2010-2013 Thunder422
// Copyright (C) 2010-2015 Thunder422
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -1615,56 +1615,6 @@ TableEntry *TableEntry::alternate(int operandIndex, DataType operandDataType)
}


//=================================
// TOKEN RELATED TABLE FUNCTIONS
//=================================

// function to find and set code in token for a data type
// and possibly return a conversion code if data type is convertible
//
// - if data type matches expected data type for operand, no action
// - else finds alternate code that matches data type
// - if no alternate code, returns conversion code for data type
// - if no alternate code, throws error status

TableEntry *Table::findCode(TokenPtr &token, TokenPtr &operandToken,
int operandIndex)
{
DataType expectedDataType {token->table()->operandDataType(operandIndex)};

if (operandToken->dataType() == expectedDataType) // exact match?
{
operandToken->removeSubCode(IntConst_SubCode); // safe for any token
return {};
}

// check if constant should be converted to needed data type
if (operandIndex == token->table()->operandCount() - 1 // last operand?
&& !token->hasFlag(UseConstAsIs_Flag))
try
{
operandToken->convertConstant(expectedDataType);
}
catch (Status)
{
// don't throw unconvertible doubles to integer errors here
// doubles as is may be acceptable depending on operator
// (will catch if double can't be converted if integer needed below)
}

// see if any alternate code's data types match
if (TableEntry *entry = token->table()->alternate(operandIndex,
operandToken->dataType()))
{
token->setCode(entry->code());
return {};
}

// get a conversion code if no alternate code was found
return operandToken->convertCode(expectedDataType);
}


//============================
// TABLE SPECIFIC FUNCTIONS
//============================
Expand Down
6 changes: 1 addition & 5 deletions table.h
Expand Up @@ -2,7 +2,7 @@
//
// Interactive BASIC Compiler Project
// File: table.h - table class header file
// Copyright (C) 2012 Thunder422
// Copyright (C) 2012-2015 Thunder422
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -229,10 +229,6 @@ class Table
// function to return a reference to the single table instance
static Table &instance(void);

// TOKEN RELATED TABLE FUNCTIONS
TableEntry *findCode(TokenPtr &token, TokenPtr &operandToken,
int operandIndex = 0);

// TABLE SPECIFIC FUNCTIONS
static TableEntry *entry(int index);
static TableEntry *entry(int index, DataType dataType);
Expand Down
121 changes: 74 additions & 47 deletions token.cpp
Expand Up @@ -2,7 +2,7 @@
//
// Interactive BASIC Compiler Project
// File: token.cpp - token class source file
// Copyright (C) 2012-2013 Thunder422
// Copyright (C) 2012-2015 Thunder422
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -84,64 +84,37 @@ std::string Token::stringWithDataType() const
}


// function to change constant token to desired data type
// - resets integer constant sub-code on double constants
// - does nothing if constant is not changed
// - throws error if double cannot be converted to integer
bool Token::convertConstant(DataType dataType)
TableEntry *Token::convert(TokenPtr &operandToken, int operandIndex)
{
if (!isType(Type::Constant))
DataType expectedDataType {table()->operandDataType(operandIndex)};

if (operandToken->dataType() == expectedDataType)
{
return false;
operandToken->removeSubCode(IntConst_SubCode); // safe for any token
return {};
}
if (dataType == DataType::Double)

if (isLastOperand(operandIndex) && !hasFlag(UseConstAsIs_Flag))
{
if (table()->returnDataType() == DataType::Double)
{
removeSubCode(IntConst_SubCode);
return true;
}
if (table()->returnDataType() != DataType::Integer)
{
return false;
}
// fall to below and change constant type to double
operandToken->changeConstantIgnoreError(expectedDataType);
}
else if (dataType == DataType::Integer)
{
if (table()->returnDataType() == DataType::Double)
{
if (!hasSubCode(IntConst_SubCode))
{
throw Status::ExpIntConst;
}
removeSubCode(IntConst_SubCode);
// fall to below and change constant type to integer
}
else
{
return table()->returnDataType() == DataType::Integer;
}
}
else

if (TableEntry *entry = table()->alternate(operandIndex,
operandToken->dataType()))
{
return false; // can't convert to number or any
setCode(entry->code());
return {};
}
m_code = Table::entry(Const_Code, dataType)->code();
return true;

return operandToken->convertCodeEntry(expectedDataType);
}


// function to get convert code needed to convert token to data type
// - changes number constant tokens to desired data type
// - returns conversion code if needed
// - returns null code if no conversion needed
// - throws error status if cannot be converted
TableEntry *Token::convertCode(DataType dataType)
TableEntry *Token::convertCodeEntry(DataType toDataType)
{
if (!convertConstant(dataType) && table()->returnDataType() != dataType)
if (!changeConstant(toDataType) && table()->returnDataType() != toDataType)
{
switch (dataType)
switch (toDataType)
{
case DataType::Double:
if (table()->returnDataType() != DataType::Integer)
Expand Down Expand Up @@ -176,6 +149,60 @@ TableEntry *Token::convertCode(DataType dataType)
}


void Token::changeConstantIgnoreError(DataType toDataType) noexcept
{
try
{
changeConstant(toDataType);
}
catch (Status) {} // ignore unconvertible double to integer error
}


bool Token::changeConstant(DataType toDataType)
{
if (!isType(Type::Constant))
{
return false;
}
if (toDataType == DataType::Double)
{
if (table()->returnDataType() == DataType::Double)
{
removeSubCode(IntConst_SubCode);
return true;
}
if (table()->returnDataType() != DataType::Integer)
{
return false;
}
// fall to below
}
else if (toDataType == DataType::Integer)
{
if (table()->returnDataType() == DataType::Double)
{
if (!hasSubCode(IntConst_SubCode))
{
throw Status::ExpIntConst;
}
removeSubCode(IntConst_SubCode);
// fall to below
}
else
{
return table()->returnDataType() == DataType::Integer;
}
}
else
{
return false; // can't convert to number or any
}
m_code = Table::entry(Const_Code, toDataType)->code();
return true;
}


// function to overload the comparison operator
bool Token::operator==(const Token &other) const
{
Expand Down
12 changes: 9 additions & 3 deletions token.h
Expand Up @@ -2,7 +2,7 @@
//
// Interactive BASIC Compiler Project
// File: token.h - token class header file
// Copyright (C) 2012-2013 Thunder422
// Copyright (C) 2012-2015 Thunder422
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -161,6 +161,10 @@ class Token
{
return code == m_code;
}
bool isLastOperand(int operandIndex)
{
return operandIndex == table()->operandCount() - 1;
}
void setFirstAlternate(int operandIndex)
{
m_code = table()->alternate(operandIndex)->code();
Expand Down Expand Up @@ -233,8 +237,10 @@ class Token
}

// other functions
bool convertConstant(DataType dataType);
TableEntry *convertCode(DataType dataType);
TableEntry *convert(TokenPtr &operandToken, int operandIndex);
TableEntry *convertCodeEntry(DataType dataType);
void changeConstantIgnoreError(DataType toDataType) noexcept;
bool changeConstant(DataType toDataType);

private:
// instance members
Expand Down
12 changes: 3 additions & 9 deletions translator.cpp
Expand Up @@ -2,7 +2,7 @@

// Interactive BASIC Compiler Project
// File: translator.cpp - translator class source file
// Copyright (C) 2010-2013 Thunder422
// Copyright (C) 2010-2015 Thunder422
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -298,9 +298,8 @@ void Translator::getExpression(DataType dataType, int level)
if (level == 0)
try
{
// add convert code if needed or report error
TokenPtr doneToken {m_doneStack.top().rpnItem->token()};
if (TableEntry *convert = doneToken->convertCode(dataType))
if (TableEntry *convert = doneToken->convertCodeEntry(dataType))
{
m_output.append(std::make_shared<Token>(convert->code()));
}
Expand Down Expand Up @@ -834,15 +833,10 @@ void Translator::processDoneStackTop(TokenPtr &token, int operandIndex,
}
m_doneStack.pop(); // remove from done stack

// see if main code's data type matches
try
{
if (TableEntry *convert = m_table.findCode(token, topToken,
operandIndex))
if (TableEntry *convert = token->convert(topToken, operandIndex))
{
// INSERT CONVERSION CODE
// create convert token with convert code
// append token to end of output list (after operand)
m_output.append(std::make_shared<Token>(convert->code()));
}
}
Expand Down

0 comments on commit ce6adff

Please sign in to comment.