Skip to content

Instantly share code, notes, and snippets.

@kodo-pp
Created September 12, 2018 21:24
Show Gist options
  • Save kodo-pp/08558f48bdeb0981f67c45972ace0a99 to your computer and use it in GitHub Desktop.
Save kodo-pp/08558f48bdeb0981f67c45972ace0a99 to your computer and use it in GitHub Desktop.
// LICENSE: Unlicense <https://unlicense.org/> (Public domain)
// I am not liable for any damage to your eyes and mind while you are reading this code
#include <cmath>
#include <iostream>
#define CreateType( NewType, OldType ) typedef OldType NewType
#define CPlusPlusAttribute( AttributeName ) AttributeName
#define ADoesNotThrow CPlusPlusAttribute( noexcept )
#define ANonNegative CPlusPlusAttribute( unsigned )
#define AReadOnly CPlusPlusAttribute( const )
#define AStatic CPlusPlusAttribute( static )
#define AMessage CPlusPlusAttribute( constexpr ) CPlusPlusAttribute( static )
#define Pointer( TypeName ) TypeName *
#define TakeAddress( Variable ) &Variable
#define PointerDereference( Pointer ) *Pointer
#define Reference( TypeName ) TypeName &
#define EntryPoint( Namespace, Class, Method ) \
TInteger \
main( ) \
{ \
return Namespace::Class::Method( ); \
}
CreateType( TBool, bool );
CreateType( TInteger, int );
CreateType( TLongInteger, long );
CreateType( TVoid, void );
CreateType( TFloat, float );
CreateType( TLongFloat, double );
CreateType( TString, std::string );
CreateType( TCharacter, char );
CreateType( TMessage, AReadOnly Pointer( TCharacter ) );
#define TAMessage AMessage TMessage
#define Zero 0
#define One 1
#define EQUALS ==
#define TRUE true
#define FALSE false
#define Exception std::runtime_error
#define Floor floor
#define BuildString( s ) TString( s )
#define APPEND +
#define ConvertToString( Number ) std::to_string( Number )
#define StrLen( String ) String.length( )
namespace Calculator
{
class Messages
{
public:
TAMessage MessageInvalidStringLength = "Invalid string length: ";
TAMessage MessageInvalidInteger = "Invalid integer: ";
TAMessage MessagePrompt = "Enter the first number or type 'Quit' to exit";
TAMessage MessageQuit = "Quit";
TAMessage MessageExiting = "Exiting";
TAMessage MessageSecondPrompt = "Enter the second number";
TAMessage MessageOperationPrompt = "Enter the operation from the list: +, -, *, /";
TAMessage MessageDivisionByZero = "Division by zero is not defined";
TAMessage MessageInvalidOperation = "Invalid operation";
TAMessage MessageEquals = " = ";
TAMessage MessagePlus = " + ";
TAMessage MessageMinus = " - ";
TAMessage MessageAsterisk = " * ";
TAMessage MessageSlash = " / ";
};
class IOManager
{
public:
AStatic TVoid
WriteLine( AReadOnly Reference( TString ) crsString )
{
std::cout << crsString << std::endl;
}
AStatic TString
ReadLine( )
{
TString sString;
std::cin >> sString;
return sString;
}
};
class Converter
{
public:
AStatic TInteger
StringToInteger( AReadOnly Reference( TString ) crsString )
{
return std::stoi( crsString );
}
AStatic TFloat
StringToFloat( AReadOnly Reference( TString ) crsString )
{
return std::stof( crsString );
}
AStatic TLongFloat
StringToLongFloat( AReadOnly Reference( TString ) crsString )
{
return std::stod( crsString );
}
AStatic TCharacter
StringToCharacter( AReadOnly Reference( TString ) crsString )
{
if( StrLen( crsString ) EQUALS One )
{
return crsString[ 0 ];
}
else
{
throw Exception( BuildString( Messages::MessageInvalidStringLength ) APPEND ConvertToString( StrLen( crsString ) ) );
}
}
};
class Entry
{
public:
AStatic TBool
IsInteger( TLongFloat lfNumber ) ADoesNotThrow
{
return Floor( lfNumber ) EQUALS lfNumber;
}
AStatic TVoid
ValidateInteger( TLongFloat lfNumber )
{
if( !IsInteger( lfNumber ) )
{
throw Exception( BuildString( Messages::MessageInvalidInteger ) APPEND ConvertToString( lfNumber ) );
}
}
AStatic TInteger
Main( )
{
while( TRUE )
{
TLongFloat lfFirstNumber, lfSecondNumber;
TCharacter cOperator;
TString sUserInput;
IOManager::WriteLine( Messages::MessagePrompt );
sUserInput = IOManager::ReadLine( );
if( sUserInput EQUALS Messages::MessageQuit )
{
IOManager::WriteLine( Messages::MessageExiting );
return Zero;
}
else
{
lfFirstNumber = Converter::StringToLongFloat( sUserInput );
}
IOManager::WriteLine( Messages::MessageSecondPrompt );
sUserInput = IOManager::ReadLine( );
lfSecondNumber = Converter::StringToLongFloat( sUserInput );
IOManager::WriteLine( Messages::MessageOperationPrompt );
sUserInput = IOManager::ReadLine( );
cOperator = Converter::StringToCharacter( sUserInput );
switch( cOperator )
{
case '+':
IOManager::WriteLine( ConvertToString( lfFirstNumber ) APPEND Messages::MessagePlus APPEND ConvertToString( lfSecondNumber ) APPEND Messages::MessageEquals APPEND ConvertToString( lfFirstNumber + lfSecondNumber ) );
break;
case '-':
IOManager::WriteLine( ConvertToString( lfFirstNumber ) APPEND Messages::MessageMinus APPEND ConvertToString( lfSecondNumber ) APPEND Messages::MessageEquals APPEND ConvertToString( lfFirstNumber - lfSecondNumber ) );
break;
case '*':
IOManager::WriteLine( ConvertToString( lfFirstNumber ) APPEND Messages::MessageAsterisk APPEND ConvertToString( lfSecondNumber ) APPEND Messages::MessageEquals APPEND ConvertToString( lfFirstNumber * lfSecondNumber ) );
break;
case '/':
if( lfSecondNumber EQUALS Zero )
{
IOManager::WriteLine( Messages::MessageDivisionByZero );
continue;
}
IOManager::WriteLine( ConvertToString( lfFirstNumber ) APPEND Messages::MessageSlash APPEND ConvertToString( lfSecondNumber ) APPEND Messages::MessageEquals APPEND ConvertToString( lfFirstNumber / lfSecondNumber ) );
break;
default:
IOManager::WriteLine( Messages::MessageInvalidOperation );
break;
}
}
}
};
}
EntryPoint( Calculator, Entry, Main );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment