2013-11-01 02:52:18 -04:00
# include "CGenerator.h"
2013-12-22 01:34:59 -06:00
CGenerator : : CGenerator ( ) : generatorString ( " __C__ " ) {
2013-11-01 02:52:18 -04:00
tabLevel = 0 ;
}
CGenerator : : ~ CGenerator ( ) {
}
std : : string CGenerator : : tabs ( ) {
std : : string returnTabs ;
for ( int i = 0 ; i < tabLevel ; i + + )
returnTabs + = " \t " ;
return returnTabs ;
}
std : : string CGenerator : : generate ( NodeTree < ASTData > * from ) {
ASTData data = from - > getData ( ) ;
std : : vector < NodeTree < ASTData > * > children = from - > getChildren ( ) ;
std : : string output = " " ;
switch ( data . type ) {
case translation_unit :
2013-12-27 13:05:07 -06:00
//Declare everything in translation unit scope here. (allows stuff from other files, automatic forward declarations)
for ( auto i = data . scope . begin ( ) ; i ! = data . scope . end ( ) ; i + + ) {
NodeTree < ASTData > * declaration = i - > second ;
2013-12-28 21:54:22 -05:00
std : : vector < NodeTree < ASTData > * > decChildren = declaration - > getChildren ( ) ;
2013-12-27 13:05:07 -06:00
ASTData declarationData = i - > second - > getData ( ) ;
switch ( declarationData . type ) {
case identifier :
output + = ValueTypeToCType ( declarationData . valueType ) + " " + declarationData . symbol . getName ( ) + " ; /*identifier*/ \n " ;
break ;
case function :
2013-12-28 21:54:22 -05:00
output + = " \n " + ValueTypeToCType ( declarationData . valueType ) + " " + declarationData . symbol . getName ( ) + " ( " ;
for ( int j = 0 ; j < decChildren . size ( ) - 1 ; j + + ) {
if ( j > 0 )
output + = " , " ;
output + = ValueTypeToCType ( decChildren [ j ] - > getData ( ) . valueType ) + " " + generate ( decChildren [ j ] ) ;
}
output + = " ); /*func*/ \n " ;
2013-12-27 13:05:07 -06:00
break ;
default :
2013-12-28 21:54:22 -05:00
std : : cout < < " Declaration? named " < < declaration - > getName ( ) < < " of unknown type " < < ASTData : : ASTTypeToString ( declarationData . type ) < < " in translation unit scope " < < std : : endl ;
output + = " /*unknown declaration named " + declaration - > getName ( ) + " */ \n " ;
2013-12-27 13:05:07 -06:00
}
}
2013-11-01 02:52:18 -04:00
break ;
case interpreter_directive :
//Do nothing
break ;
case import :
2013-12-22 01:34:59 -06:00
return " /* would import \" " + data . symbol . getName ( ) + " \" but....*/ \n " ;
//return "#include <" + data.symbol.getName() + ">\n";
2013-11-01 02:52:18 -04:00
case identifier :
return data . symbol . getName ( ) ;
case function :
output + = " \n " + ValueTypeToCType ( data . valueType ) + " " + data . symbol . getName ( ) + " ( " ;
for ( int i = 0 ; i < children . size ( ) - 1 ; i + + ) {
if ( i > 0 )
output + = " , " ;
2013-12-22 01:34:59 -06:00
output + = ValueTypeToCType ( children [ i ] - > getData ( ) . valueType ) + " " + generate ( children [ i ] ) ;
2013-11-01 02:52:18 -04:00
}
output + = " ) \n " + generate ( children [ children . size ( ) - 1 ] ) ;
return output ;
case code_block :
2013-11-07 22:19:33 -05:00
output + = " { \n " ;
2013-11-01 02:52:18 -04:00
tabLevel + + ;
for ( int i = 0 ; i < children . size ( ) ; i + + )
output + = generate ( children [ i ] ) ;
tabLevel - - ;
output + = tabs ( ) + " } " ;
return output ;
case expression :
output + = " " + data . symbol . getName ( ) + " , " ;
case boolean_expression :
output + = " " + data . symbol . getName ( ) + " " ;
case statement :
return tabs ( ) + generate ( children [ 0 ] ) + " ; \ n " ;
case if_statement :
2013-11-07 22:19:33 -05:00
output + = " if ( " + generate ( children [ 0 ] ) + " ) \n \t " + generate ( children [ 1 ] ) ;
2013-11-01 02:52:18 -04:00
if ( children . size ( ) > 2 )
output + = " else " + generate ( children [ 2 ] ) ;
return output ;
2013-12-18 18:05:21 -06:00
case while_loop :
2013-12-19 10:39:36 -06:00
output + = " while ( " + generate ( children [ 0 ] ) + " ) \n \t " + generate ( children [ 1 ] ) ;
2013-12-18 18:05:21 -06:00
return output ;
case for_loop :
2013-12-28 21:54:22 -05:00
//The strSlice's are there to get ride of an unwanted return and an unwanted semicolon(s)
output + = " for ( " + strSlice ( generate ( children [ 0 ] ) , 0 , - 3 ) + generate ( children [ 1 ] ) + " ; " + strSlice ( generate ( children [ 2 ] ) , 0 , - 3 ) + " ) \n \t " + generate ( children [ 3 ] ) ;
2013-12-18 18:05:21 -06:00
return output ;
2013-11-01 02:52:18 -04:00
case return_statement :
2013-12-22 01:34:59 -06:00
if ( children . size ( ) )
return " return " + generate ( children [ 0 ] ) ;
else
return " return " ;
2013-11-01 02:52:18 -04:00
case assignment_statement :
return generate ( children [ 0 ] ) + " = " + generate ( children [ 1 ] ) ;
case declaration_statement :
2013-12-28 21:54:22 -05:00
return ValueTypeToCType ( children [ 0 ] - > getData ( ) . valueType ) + " " + generate ( children [ 0 ] ) + " = " + generate ( children [ 1 ] ) + " ; " ;
2013-12-22 01:34:59 -06:00
case if_comp :
if ( generate ( children [ 0 ] ) = = generatorString )
return generate ( children [ 1 ] ) ;
return " " ;
case simple_passthrough :
return strSlice ( generate ( children [ 0 ] ) , 3 , - 4 ) ;
2013-11-01 02:52:18 -04:00
case function_call :
{
2013-12-27 13:05:07 -06:00
//NOTE: The first (0th) child of a function call node is the declaration of the function
2013-11-01 02:52:18 -04:00
//Handle operators specially for now. Will later replace with
//Inlined functions in the standard library
std : : string name = data . symbol . getName ( ) ;
2013-12-27 13:05:07 -06:00
std : : cout < < name < < " == " < < children [ 0 ] - > getData ( ) . symbol . getName ( ) < < std : : endl ;
2013-12-19 10:39:36 -06:00
if ( name = = " ++ " | | name = = " -- " )
2013-12-27 13:05:07 -06:00
return generate ( children [ 1 ] ) + name ;
if ( name = = " * " & & children . size ( ) = = 2 ) //Is dereference, not multiplication
return " *( " + generate ( children [ 1 ] ) + " ) " ;
2013-12-19 10:39:36 -06:00
if ( name = = " + " | | name = = " - " | | name = = " * " | | name = = " / " | | name = = " == " | | name = = " >= " | | name = = " <= " | | name = = " != " | | name = = " < " | | name = = " > " | | name = = " % " | | name = = " += " | | name = = " -= " | | name = = " *= " | | name = = " /= " ) {
2013-12-27 13:05:07 -06:00
return " (( " + generate ( children [ 1 ] ) + " ) " + name + " ( " + generate ( children [ 2 ] ) + " )) " ;
2013-11-01 02:52:18 -04:00
}
output + = data . symbol . getName ( ) + " ( " ;
2013-12-27 13:05:07 -06:00
for ( int i = 1 ; i < children . size ( ) ; i + + ) //children[0] is the declaration
2013-11-01 02:52:18 -04:00
if ( i < children . size ( ) - 1 )
output + = generate ( children [ i ] ) + " , " ;
else output + = generate ( children [ i ] ) ;
output + = " ) " ;
return output ;
}
case value :
return data . symbol . getName ( ) ;
default :
std : : cout < < " Nothing! " < < std : : endl ;
}
for ( int i = 0 ; i < children . size ( ) ; i + + )
output + = generate ( children [ i ] ) ;
return output ;
}
2013-12-23 01:26:24 -06:00
std : : string CGenerator : : ValueTypeToCType ( Type type ) {
std : : string return_type ;
switch ( type . baseType ) {
2013-11-01 02:52:18 -04:00
case none :
2013-12-23 01:26:24 -06:00
return_type = " none " ;
break ;
2013-12-22 01:34:59 -06:00
case void_type :
2013-12-23 01:26:24 -06:00
return_type = " void " ;
break ;
2013-11-01 02:52:18 -04:00
case boolean :
2013-12-23 01:26:24 -06:00
return_type = " bool " ;
break ;
2013-11-01 02:52:18 -04:00
case integer :
2013-12-23 01:26:24 -06:00
return_type = " int " ;
2013-11-01 02:52:18 -04:00
break ;
case floating :
2013-12-23 01:26:24 -06:00
return_type = " float " ;
break ;
2013-11-01 02:52:18 -04:00
case double_percision :
2013-12-23 01:26:24 -06:00
return_type = " double " ;
break ;
case character :
return_type = " char " ;
2013-11-01 02:52:18 -04:00
break ;
default :
2013-12-23 01:26:24 -06:00
return_type = " unknown_ValueType " ;
break ;
2013-11-01 02:52:18 -04:00
}
2013-12-23 01:26:24 -06:00
for ( int i = 0 ; i < type . indirection ; i + + )
return_type + = " * " ;
return return_type ;
2013-11-01 02:52:18 -04:00
}