diff options
author | Morgan Deters <mdeters@cs.nyu.edu> | 2013-12-12 18:24:54 -0500 |
---|---|---|
committer | Morgan Deters <mdeters@cs.nyu.edu> | 2013-12-16 22:28:26 -0500 |
commit | 5186ca79710fe935d1f7ed27c4a34e913ab547e8 (patch) | |
tree | 4f5ce4957063085f607492a6474b0d244e4b2da4 /proofs/lfsc_checker/sccwriter.cpp | |
parent | 4d9caf9782c59823fb95519b9b518b7d7f89738a (diff) |
First attempt at incorporating LFSC proof checker into CVC4.
Diffstat (limited to 'proofs/lfsc_checker/sccwriter.cpp')
-rw-r--r-- | proofs/lfsc_checker/sccwriter.cpp | 977 |
1 files changed, 977 insertions, 0 deletions
diff --git a/proofs/lfsc_checker/sccwriter.cpp b/proofs/lfsc_checker/sccwriter.cpp new file mode 100644 index 000000000..d11a96b19 --- /dev/null +++ b/proofs/lfsc_checker/sccwriter.cpp @@ -0,0 +1,977 @@ +#include "sccwriter.h"
+
+#include <fstream>
+#include <sstream>
+
+int sccwriter::exprCount = 0;
+int sccwriter::strCount = 0;
+int sccwriter::argsCount = 0;
+int sccwriter::rnumCount = 0;
+
+int sccwriter::get_prog_index( const std::string& str )
+{
+ for( int a=0; a<(int)progNames.size(); a++ ){
+ if( progNames[a]==str ){
+ return a;
+ }
+ }
+ return -1;
+}
+
+int sccwriter::get_prog_index_by_expr( Expr* e )
+{
+ for( int a=0; a<(int)progPtrs.size(); a++ ){
+ if( progPtrs[a]==e ){
+ return a;
+ }
+ }
+ return -1;
+}
+
+bool sccwriter::is_var( const std::string& str )
+{
+ for( int a=0; a<(int)vars.size(); a++ ){
+ if( vars[a]==str ){
+ return true;
+ }
+ }
+ return false;
+}
+
+void sccwriter::add_global_sym( const std::string& str )
+{
+ for( int a=0; a<(int)globalSyms.size(); a++ ){
+ if( globalSyms[a]==str ){
+ return;
+ }
+ }
+ globalSyms.push_back( str );
+}
+
+void sccwriter::indent( std::ostream& os, int ind )
+{
+ for( int a=0; a<ind; a++ )
+ {
+ os << " ";
+ }
+}
+
+void sccwriter::write_function_header( std::ostream& os, int index, int opts )
+{
+ //write the function header
+ std::string fname;
+ get_function_name( progNames[index], fname );
+ os << "Expr* " << fname.c_str() << "( ";
+ CExpr* progvars = (CExpr*)get_prog( index )->kids[1];
+ int counter = 0;
+ //write each argument
+ while( progvars->kids[counter] )
+ {
+ if( counter!=0 )
+ {
+ os << ", ";
+ }
+ os << "Expr* ";
+ write_variable( ((SymSExpr*)progvars->kids[counter])->s, os );
+ //add to vars if options are set to do so
+ if( opts&opt_write_add_args )
+ {
+ vars.push_back( ((SymSExpr*)progvars->kids[counter])->s );
+ }
+ counter++;
+ }
+ os << " )";
+ if( opts&opt_write_call_debug )
+ {
+ os << "{" << std::endl;
+ indent( os, 1 );
+ os << "std::cout << \"Call function " << fname.c_str() << " with arguments \";" << std::endl;
+ counter = 0;
+ while( progvars->kids[counter] )
+ {
+ if( counter!=0 )
+ {
+ indent( os, 1 );
+ os << "std::cout << \", \";" << std::endl;
+ }
+ indent( os, 1 );
+ write_variable( ((SymSExpr*)progvars->kids[counter])->s, os );
+ os << "->print( std::cout );" << std::endl;
+ counter++;
+ }
+ indent( os, 1 );
+ os << "std::cout << std::endl;" << std::endl;
+ }
+}
+
+void sccwriter::get_function_name( const std::string& pname, std::string& fname )
+{
+ fname = std::string( "f_" );
+ fname.append( pname );
+}
+
+void sccwriter::write_variable( const std::string& n, std::ostream& os )
+{
+ std::string nn;
+ get_var_name( n, nn );
+ os << nn.c_str();
+}
+
+void sccwriter::get_var_name( const std::string& n, std::string& nn ) {
+ nn = std::string( n.c_str() );
+ for( int i = 0; i <(int)n.length(); i++ ){
+ char c = n[i];
+ if (c <= 47)
+ c += 65;
+ else if (c >= 58 && c <= 64)
+ c += 97-58;
+ if ((c >= 91 && c <= 94) || c == 96)
+ c += 104-91;
+ else if (c >= 123)
+ c -= 4;
+ nn[i] = c;
+ }
+}
+
+void sccwriter::write_file()
+{
+ static std::string filename( "scccode" );
+
+ //writer the h file
+ std::fstream fsh;
+ std::string fnameh( filename );
+ fnameh.append(".h");
+ fsh.open( fnameh.c_str(), std::ios::out );
+ //write the header in h
+ fsh << "#ifndef SCC_CODE_H" << std::endl;
+ fsh << "#define SCC_CODE_H" << std::endl << std::endl;
+ //include necessary files in h file
+ fsh << "#include \"check.h\"" << std::endl << std::endl;
+ //write the init function
+ fsh << "void init_compiled_scc();" << std::endl << std::endl;
+ //write the entry function
+ fsh << "Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args );" << std::endl << std::endl;
+ //write the side condition code functions
+ for( int n=0; n<(int)progs.size(); n++ )
+ {
+ //write the header in the h file
+ fsh << "inline ";
+ write_function_header( fsh, n );
+ fsh << ";" << std::endl << std::endl;
+ }
+ fsh << "#endif" << std::endl << std::endl;
+ fsh.close();
+
+
+ //writer the cpp code
+ std::fstream fsc;
+ std::string fnamec( filename );
+ fnamec.append(".cpp");
+ fsc.open( fnamec.c_str(), std::ios::out );
+ //include the h file in the cpp
+ fsc << "#include \"scccode.h\"" << std::endl << std::endl;
+ std::ostringstream fsc_funcs;
+ //write the side condition code functions
+ for( currProgram=0; currProgram<(int)progs.size(); currProgram++ )
+ {
+ //reset naming counters
+ vars.clear();
+ exprCount = 0;
+ strCount = 0;
+ argsCount = 0;
+ rnumCount = 0;
+
+ //for debugging
+ std::cout << "program #" << currProgram << " " << progNames[currProgram].c_str() << std::endl;
+
+ //write the function header
+ write_function_header( fsc_funcs, currProgram, opt_write_add_args|options );
+ if( (options&opt_write_call_debug)==0 )
+ {
+ fsc_funcs << "{" << std::endl;
+ }
+ //write the code
+ //std::vector< std::string > cleanVec;
+ //write_code( get_prog( n )->kids[2], fsc, 1, "return ", cleanVec );
+ //debug_write_code( progs[n].second->kids[2], fsc, 1 );
+ std::string expr;
+ write_expr( get_prog( currProgram )->kids[2], fsc_funcs, 1, expr );
+ indent( fsc_funcs, 1 );
+ fsc_funcs << "return " << expr.c_str() << ";" << std::endl;
+ fsc_funcs << "}" << std::endl << std::endl;
+ }
+ //write the predefined symbols necessary - symbols and progs
+ for( int a=0; a<(int)globalSyms.size(); a++ )
+ {
+ fsc << "Expr* e_" << globalSyms[a].c_str() << ";" << std::endl;
+ }
+ for( int a=0; a<(int)progs.size(); a++ )
+ {
+ fsc << "Expr* e_" << progNames[a].c_str() << ";" << std::endl;
+ }
+ fsc << std::endl;
+ //write the init function - initialize symbols and progs
+ fsc << "void init_compiled_scc(){" << std::endl;
+ for( int a=0; a<(int)globalSyms.size(); a++ )
+ {
+ indent( fsc, 1 );
+ fsc << "e_" << globalSyms[a].c_str() << " = symbols->get(\"" << globalSyms[a].c_str() << "\").first;" << std::endl;
+ }
+ for( int a=0; a<(int)progs.size(); a++ )
+ {
+ indent( fsc, 1 );
+ fsc << "e_" << progNames[a].c_str() << " = progs[\"" << progNames[a].c_str() << "\"];" << std::endl;
+ }
+ fsc << "}" << std::endl << std::endl;
+ fsc << "Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args ){" << std::endl;
+ //for( int n=0; n<(int)progs.size(); n++ ){
+ // indent( fsc, 1 );
+ // fsc << "static std::string s_" << progNames[n].c_str() << " = std::string( \"" << progNames[n].c_str() << "\" );" << std::endl;
+ //}
+ for( int n=0; n<(int)progs.size(); n++ ){
+ indent( fsc, 1 );
+ if( n!=0 ){
+ fsc << "}else ";
+ }
+ //for each function, test to see if the string matches the name of the function
+ fsc << "if( p==e_" << progNames[n].c_str() << " ){" << std::endl;
+ indent( fsc, 2 );
+ std::string fname;
+ get_function_name( progNames[n], fname );
+ //map the function to the proper function
+ fsc << "return " << fname.c_str() << "( ";
+ //write the arguments to the function from args
+ CExpr* progvars = (CExpr*)get_prog( n )->kids[1];
+ int counter = 0;
+ bool firstTime = true;
+ while( progvars->kids[counter] )
+ {
+ if( !firstTime )
+ {
+ fsc << ", ";
+ }
+ fsc << "args[" << counter << "]";
+ firstTime = false;
+ counter++;
+ }
+ fsc << " );" << std::endl;
+ }
+ indent( fsc, 1 );
+ fsc << "}else{" << std::endl;
+ indent( fsc, 2 );
+ //return null in the case the function could not be found
+ fsc << "return NULL;" << std::endl;
+ indent( fsc, 1 );
+ fsc << "}" << std::endl;
+ fsc << "}" << std::endl << std::endl;
+ fsc << fsc_funcs.str().c_str();
+
+ fsc.close();
+}
+
+void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* retModStr, int opts )
+{
+ std::string retModString;
+ std::string incString;
+ if ( retModStr )
+ {
+ retModString = std::string( retModStr );
+ retModString.append( " = " );
+ incString = std::string( retModStr );
+ incString.append( "->inc();" );
+ }
+ switch( code->getclass() )
+ {
+ case INT_EXPR:
+ {
+ indent( os, ind );
+ os << retModString.c_str();
+ os << "new IntExpr( " << mpz_get_si( ((IntExpr*)code)->n ) << " );" << std::endl;
+ indent( os, ind );
+ os << incString.c_str() << std::endl;
+ }
+ break;
+ case RAT_EXPR:
+ {
+ mpz_t num, den;
+ mpz_init(num);
+ mpz_init(den);
+ mpq_get_num( num, ((RatExpr*)code)->n );
+ mpq_get_den( den, ((RatExpr*)code)->n );
+ indent( os, ind );
+ os << retModString.c_str();
+ os << "new RatExpr( " << mpz_get_si( num ) << ", " << mpz_get_si( den ) << " );" << std::endl;
+ indent( os, ind );
+ os << incString.c_str() << std::endl;
+ }
+ break;
+ case SYMS_EXPR:
+ {
+ //if it is a variable, simply write it to buffer
+ if( is_var( ((SymSExpr*)code)->s ) )
+ {
+ indent( os, ind );
+ os << retModString.c_str();
+ write_variable( ((SymSExpr*)code)->s.c_str(), os );
+ os << ";" << std::endl;
+ }
+ else //else must look at symbol lookup table
+ {
+ std::string var;
+ get_var_name( ((SymSExpr*)code)->s, var );
+ indent( os, ind );
+ os << retModString.c_str() << "e_" << var.c_str() << ";" << std::endl;
+ add_global_sym( var );
+ }
+ indent( os, ind );
+ os << incString.c_str() << std::endl;
+ }
+ break;
+ default:
+ switch( code->getop() )
+ {
+ case APP: + { + //collect the arguments + std::vector< Expr* > argVector; + code->collect_args( argVector ); + //write the arguments + std::vector< std::string > args; + for( int a=0; a<(int)argVector.size(); a++ ) + { + std::string expr; + write_expr( argVector[a], os, ind, expr ); + args.push_back( expr ); + } + //write_args( (CExpr*)code, os, ind, 1, args ); + Expr* hd = code->get_head(); + //map to a program in the case that it is a program + if( hd->getop()==PROG && get_prog_index_by_expr( hd )!=-1 ) + { + indent( os, ind ); + os << retModString << "f_" << progNames[ get_prog_index_by_expr( hd ) ].c_str() << "( "; + for( int a=0; a<(int)args.size(); a++ ) + { + os << args[a].c_str(); + if( a!=(int)( args.size()-1 ) ){ + os << ", "; + } + } + os << " );" << std::endl; + for( int a=0; a<(int)args.size(); a++ ) + { + write_dec( args[a], os, ind ); + } + } + else + { +#ifdef USE_FLAT_APP + std::string expr; + write_expr( hd, os, ind, expr ); + indent( os, ind ); + os << retModString << "new CExpr( APP, "; + os << expr.c_str() << ", "; + for( int a=0; a<(int)args.size(); a++ ) + { + os << args[a].c_str(); + if( a!=(int)( args.size()-1 ) ){ + os << ", "; + } + } + os << " );" << std::endl; +#else + std::string expr; + write_expr( hd, os, ind, expr ); + indent( os, ind ); + os << retModString; + for( int a=0; a<(int)args.size(); a++ ) + { + os << "new CExpr( APP, "; + } + os << expr.c_str() << ", "; + for( int a=0; a<(int)args.size(); a++ ) + { + os << args[a].c_str(); + os << " )"; + if( a!=(int)( args.size()-1 ) ){ + os << ", "; + } + } + os << ";" << std::endl; +#endif + //indent( os, ind ); + //os << expr.c_str() << "->dec();" << std::endl; + } + } + break;
+ case MATCH: + { + //calculate the value for the expression + std::string expr; + write_expr( ((CExpr*)code)->kids[0], os, ind, expr ); + //get the head + std::ostringstream sshd; + sshd << "e" << exprCount; + exprCount++; + indent( os, ind ); + os << "Expr* " << sshd.str().c_str() << " = " << expr.c_str() << "->followDefs()->get_head();" << std::endl; + //write the arguments + std::vector< std::string > args; + write_args( (CExpr*)code, os, ind, 1, args ); + bool encounterDefault = false; + //now make an if statement corresponding to the match + int a = 0; + while( ((CExpr*)code)->kids[a+1] ) + { + indent( os, ind ); + if( a!=0 ){ + os << "}else"; + } + if( ((CExpr*)code)->kids[a+1]->getop()!=CASE ){ + encounterDefault = true; + os << "{" << std::endl; + //write the body of the case + write_code( ((CExpr*)code)->kids[a+1], os, ind+1, retModStr ); + indent( os, ind ); + os << "}" << std::endl; + }else{ + if( a!=0 ) + os << " "; + os << "if( " << sshd.str().c_str() << "==" << args[a].c_str() << " ){" << std::endl; + //collect args from the variable in the code + std::ostringstream ssargs; + ssargs << "args" << argsCount; + argsCount++; +#ifndef USE_FLAT_APP + indent( os, ind+1 ); + os << "std::vector< Expr* > " << ssargs.str().c_str() << ";" << std::endl; + indent( os, ind+1 ); + os << expr.c_str() << "->followDefs()->collect_args( " << ssargs.str().c_str() << " );" << std::endl; +#endif + //set the variables defined in the pattern equal to the arguments + std::vector< Expr* > caseArgs; + ((CExpr*)((CExpr*)code)->kids[a+1])->kids[0]->collect_args( caseArgs ); + for( int b=0; b<(int)caseArgs.size(); b++ ) + { + indent( os, ind+1 ); + os << "Expr* "; + write_variable( ((SymSExpr*)caseArgs[b])->s.c_str(), os ); +#ifdef USE_FLAT_APP + os << " = ((CExpr*)" << expr.c_str() << "->followDefs())->kids[" << b+1 << "];" << std::endl; +#else + os << " = " << ssargs.str().c_str() << "[" << b << "];" << std::endl; +#endif + vars.push_back( ((SymSExpr*)caseArgs[b])->s ); + } + //write the body of the case + write_code( ((CExpr*)code)->kids[a+1], os, ind+1, retModStr, opt_write_case_body ); + } + a++; + } + if( !encounterDefault ) + { + indent( os, ind ); + os << "}else{" << std::endl; + indent( os, ind + 1 ); + os << "std::cout << \"Could not find match for expression in function f_"; + os << progNames[currProgram].c_str() << " \";" << std::endl; + indent( os, ind + 1 ); + os << sshd.str().c_str() << "->print( std::cout );" << std::endl; + indent( os, ind + 1 ); + os << "std::cout << std::endl;" << std::endl; + indent( os, ind + 1 ); + os << "exit( 1 );" << std::endl; + indent( os, ind ); + os << "}" << std::endl; + } + write_dec( expr, os, ind ); + for( int a=0; a<(int)args.size(); a++ ) + { + write_dec( args[a], os, ind ); + } + } + break; + case CASE: + if( opts&opt_write_case_body ) + { + write_code( ((CExpr*)code)->kids[1], os, ind, retModStr ); + } + else + { + write_code( ((CExpr*)code)->kids[0]->get_head(), os, ind, retModStr ); + } + break; + case DO: + { + //write each of the children in sequence + int counter = 0; + while( ((CExpr*)code)->kids[counter] ) + { + if( ((CExpr*)code)->kids[counter+1]==NULL ) + { + write_code( ((CExpr*)code)->kids[counter], os, ind, retModStr ); + } + else + { + std::string expr; + write_expr( ((CExpr*)code)->kids[counter], os, ind, expr ); + //clean up memory + write_dec( expr, os, ind ); + } + counter++; + } + } + break; + case LET: + { + indent( os, ind ); + os << "Expr* "; + write_variable( ((SymSExpr*)((CExpr*)code)->kids[0])->s, os ); + os << ";" << std::endl; + std::ostringstream ss; + write_variable( ((SymSExpr*)((CExpr*)code)->kids[0])->s, ss ); + write_code( ((CExpr*)code)->kids[1], os, ind, ss.str().c_str() ); + //add it to the variables + vars.push_back( ((SymSExpr*)((CExpr*)code)->kids[0])->s ); + write_code( ((CExpr*)code)->kids[2], os, ind, retModStr ); + //clean up memory + indent( os, ind ); + write_variable( ((SymSExpr*)((CExpr*)code)->kids[0])->s, os ); + os << "->dec();" << std::endl; + } + break; + case FAIL: + { + indent( os, ind ); + os << retModString.c_str() << "NULL;" << std::endl; + } + break; +#ifndef MARKVAR_32 + case MARKVAR: + { + //calculate the value for the expression + std::string expr; + write_expr( ((CExpr*)code)->kids[0], os, ind, expr, opt_write_check_sym_expr ); + //set the mark on the expression + indent( os, ind ); + os << "if (" << expr.c_str() << "->followDefs()->getmark())" << std::endl; + indent( os, ind+1 ); + os << expr.c_str() << "->followDefs()->clearmark();" << std::endl; + indent( os, ind ); + os << "else" << std::endl; + indent( os, ind+1 ); + os << expr.c_str() << "->followDefs()->setmark();" << std::endl; + //write the return if necessary + if( retModStr!=NULL ){ + indent( os, ind ); + os << retModString.c_str() << expr.c_str() << ";" << std::endl; + indent( os, ind );
+ os << incString.c_str() << std::endl; + } + write_dec( expr, os, ind ); + } + break; + case IFMARKED:
+ { + //calculate the value for the expression + std::string expr; + write_expr( ((CExpr*)code)->kids[0], os, ind, expr, opt_write_check_sym_expr ); + //if mark is set, write code for kids[1] + indent( os, ind ); + os << "if (" << expr.c_str() << "->followDefs()->getmark()){" << std::endl; + write_code( ((CExpr*)code)->kids[1], os, ind+1, retModStr ); + //else write code for kids[2] + indent( os, ind ); + os << "}else{" << std::endl; + write_code( ((CExpr*)code)->kids[2], os, ind+1, retModStr ); + indent( os, ind ); + os << "}" << std::endl;
+ //clean up memory
+ write_dec( expr, os, ind );
+ }
+ break; +#else + case MARKVAR: + { + //calculate the value for the expression + std::string expr; + write_expr( ((CExpr*)code)->kids[1], os, ind, expr, opt_write_check_sym_expr ); + //set the mark on the expression + indent( os, ind ); + os << "if ( ((SymExpr*)" << expr.c_str() << "->followDefs())->getmark("; + os << ((IntExpr*)((CExpr*)code)->kids[0])->get_num() << "))" << std::endl; + indent( os, ind+1 ); + os << "((SymExpr*)" << expr.c_str() << "->followDefs())->clearmark("; + os << ((IntExpr*)((CExpr*)code)->kids[0])->get_num() << ");" << std::endl; + indent( os, ind ); + os << "else" << std::endl; + indent( os, ind+1 ); + os << "((SymExpr*)" << expr.c_str() << "->followDefs())->setmark("; + os << ((IntExpr*)((CExpr*)code)->kids[0])->get_num() << ");" << std::endl; + //write the return if necessary + if( retModStr!=NULL ){ + indent( os, ind ); + os << retModString.c_str() << expr.c_str() << ";" << std::endl; + indent( os, ind );
+ os << incString.c_str() << std::endl; + } + write_dec( expr, os, ind ); + } + break; + case COMPARE: + { + std::string expr1, expr2; + write_expr( ((CExpr*)code)->kids[0], os, ind, expr1, opt_write_check_sym_expr ); + write_expr( ((CExpr*)code)->kids[1], os, ind, expr2, opt_write_check_sym_expr ); + indent( os, ind ); + os << "if( ((SymExpr*)" << expr1.c_str() << ")->followDefs() < ((SymExpr*)" << expr2.c_str() << ")->followDefs() ){" << std::endl; + write_code( ((CExpr*)code)->kids[2], os, ind+1, retModStr ); + indent( os, ind ); + os << "}else{" << std::endl; + write_code( ((CExpr*)code)->kids[3], os, ind+1, retModStr ); + indent( os, ind ); + os << "}" << std::endl; + //clean up memory
+ write_dec( expr1, os, ind ); + write_dec( expr2, os, ind ); + } + break; + case IFMARKED:
+ { + //calculate the value for the expression + std::string expr; + write_expr( ((CExpr*)code)->kids[1], os, ind, expr, opt_write_check_sym_expr ); + //if mark is set, write code for kids[1] + indent( os, ind ); + os << "if ( ((SymExpr*)" << expr.c_str() << "->followDefs())->getmark("; + os << ((IntExpr*)((CExpr*)code)->kids[0])->get_num() << ")){" << std::endl; + write_code( ((CExpr*)code)->kids[2], os, ind+1, retModStr ); + //else write code for kids[2] + indent( os, ind ); + os << "}else{" << std::endl; + write_code( ((CExpr*)code)->kids[3], os, ind+1, retModStr ); + indent( os, ind ); + os << "}" << std::endl;
+ //clean up memory
+ write_dec( expr, os, ind );
+ }
+ break; +#endif + case ADD: + case MUL: + case DIV: + { + //calculate the value for the first expression + std::string expr1; + write_expr( ((CExpr*)code)->kids[0], os, ind, expr1 ); + //calculate the value for the second expression + std::string expr2; + write_expr( ((CExpr*)code)->kids[1], os, ind, expr2 ); + std::ostringstream ss; + ss << "rnum" << rnumCount; + rnumCount++; + indent( os, ind ); + os << "if( " << expr1.c_str() << "->followDefs()->getclass()==INT_EXPR ){" << std::endl; + indent( os, ind+1 ); + os << "mpz_t " << ss.str().c_str() << ";" << std::endl; + indent( os, ind+1 ); + os << "mpz_init(" << ss.str().c_str() << ");" << std::endl; + indent( os, ind+1 ); + os << "mpz_"; + if( code->getop()==ADD ) + os << "add"; + else + os << "mul"; + os << "( " << ss.str().c_str() << ", ((IntExpr*)" << expr1.c_str() << "->followDefs())->n, ((IntExpr*)" << expr2.c_str() << "->followDefs())->n);" << std::endl; + indent( os, ind+1 ); + os << retModString.c_str() << "new IntExpr(" << ss.str().c_str() << ");" << std::endl; + indent( os, ind ); + os << "}else if( " << expr1.c_str() << "->followDefs()->getclass()==RAT_EXPR ){" << std::endl; + indent( os, ind+1 ); + os << "mpq_t " << ss.str().c_str() << ";" << std::endl; + indent( os, ind+1 ); + os << "mpq_init(" << ss.str().c_str() << ");" << std::endl; + indent( os, ind+1 ); + os << "mpq_"; + if( code->getop()==ADD ) + os << "add"; + else if( code->getop()==MUL ) + os << "mul"; + else + os << "div"; + os << "( " << ss.str().c_str() << ", ((RatExpr*)" << expr1.c_str() << "->followDefs())->n, ((RatExpr*)" << expr2.c_str() << "->followDefs())->n);" << std::endl; + indent( os, ind+1 ); + os << retModString.c_str() << "new RatExpr(" << ss.str().c_str() << ");" << std::endl; + indent( os, ind ); + os << "}" << std::endl; + //clean up memory + write_dec( expr1, os, ind ); + write_dec( expr2, os, ind ); + } + break; + case NEG:
+ {
+ //calculate the value for the first expression + std::string expr1; + write_expr( ((CExpr*)code)->kids[0], os, ind, expr1 ); + std::ostringstream ss; + ss << "rnum" << rnumCount; + rnumCount++; + indent( os, ind ); + os << "if( " << expr1.c_str() << "->followDefs()->getclass()==INT_EXPR ){" << std::endl; + indent( os, ind+1 ); + os << "mpz_t " << ss.str().c_str() << ";" << std::endl; + indent( os, ind+1 ); + os << "mpz_init(" << ss.str().c_str() << ");" << std::endl; + indent( os, ind+1 ); + os << "mpz_neg( " << ss.str().c_str() << ", ((IntExpr*)" << expr1.c_str() << "->followDefs())->n );" << std::endl; + indent( os, ind+1 ); + os << retModString.c_str() << "new IntExpr(" << ss.str().c_str() << ");" << std::endl;
+ indent( os, ind ); + os << "}else if( " << expr1.c_str() << "->followDefs()->getclass()==RAT_EXPR ){" << std::endl;
+ indent( os, ind+1 ); + os << "mpq_t " << ss.str().c_str() << ";" << std::endl; + indent( os, ind+1 ); + os << "mpq_init(" << ss.str().c_str() << ");" << std::endl; + indent( os, ind+1 ); + os << "mpq_neg( " << ss.str().c_str() << ", ((RatExpr*)" << expr1.c_str() << "->followDefs())->n );" << std::endl; + indent( os, ind+1 ); + os << retModString.c_str() << "new RatExpr(" << ss.str().c_str() << ");" << std::endl;
+ indent( os, ind ); + os << "}" << std::endl;
+ //clean up memory
+ write_dec( expr1, os, ind );
+ }
+ break;
+ case IFNEG:
+ case IFZERO:
+ {
+ std::string expr1; + write_expr( ((CExpr*)code)->kids[0], os, ind, expr1 );
+ indent( os, ind ); + os << "if( " << expr1.c_str() << "->followDefs()->getclass()==INT_EXPR ){" << std::endl;
+ indent( os, ind+1 );
+ os << "if( mpz_sgn( ((IntExpr *)" << expr1.c_str() << "->followDefs())->n ) ";
+ if( code->getop()==IFNEG )
+ os << "<";
+ else
+ os << "==";
+ os << " 0 ){" << std::endl;
+ write_code( ((CExpr*)code)->kids[1], os, ind+2, retModStr );
+ indent( os, ind+1 );
+ os << "}else{" << std::endl;
+ write_code( ((CExpr*)code)->kids[2], os, ind+2, retModStr );
+ indent( os, ind+1 );
+ os << "}" << std::endl;
+ indent( os, ind ); + os << "}else if( " << expr1.c_str() << "->followDefs()->getclass()==RAT_EXPR ){" << std::endl;
+ indent( os, ind+1 );
+ os << "if( mpq_sgn( ((RatExpr *)" << expr1.c_str() << "->followDefs())->n ) ";
+ if( code->getop()==IFNEG )
+ os << "<";
+ else
+ os << "==";
+ os << " 0 ){" << std::endl;
+ write_code( ((CExpr*)code)->kids[1], os, ind+2, retModStr );
+ indent( os, ind+1 );
+ os << "}else{" << std::endl;
+ write_code( ((CExpr*)code)->kids[2], os, ind+2, retModStr );
+ indent( os, ind+1 );
+ os << "}" << std::endl;
+ indent( os, ind ); + os << "}" << std::endl;
+ //clean up memory
+ write_dec( expr1, os, ind );
+ }
+ break;
+ case RUN:/*?*/break;
+ case PI:/*?*/break; + case LAM:/*?*/break; + case TYPE:/*?*/break; + case KIND:/*?*/break; + case ASCRIBE:/*?*/break; + case MPZ:/*?*/break; + case PROG:/*?*/break; + case PROGVARS:/*?*/break; + case PAT:/*?*/break;
+ }
+ break;
+ }
+}
+
+void sccwriter::write_args( CExpr* code, std::ostream& os, int ind, int childCounter,
+ std::vector< std::string >& args, int opts )
+{
+ bool encounterCase = false;
+ while( code->kids[childCounter] && + (!encounterCase || code->kids[childCounter]->getop()==CASE ) ) + { + encounterCase = encounterCase || code->kids[childCounter]->getop()==CASE; + if( code->kids[childCounter]->getclass()==SYMS_EXPR ) + { + args.push_back( ((SymSExpr*)code->kids[childCounter])->s ); + } + else + { + //calculate the value for the argument + std::string expr; + write_expr( code->kids[childCounter], os, ind, expr, opts ); + args.push_back( expr ); + } + childCounter++; + }
+}
+
+void sccwriter::write_expr( Expr* code, std::ostream& os, int ind, std::string& expr, int opts )
+{
+ if( code->getclass()==SYMS_EXPR && is_var( ((SymSExpr*)code)->s ) )
+ {
+ get_var_name( ((SymSExpr*)code)->s, expr );
+ indent( os, ind );
+ os << expr.c_str() << "->inc();" << std::endl;
+ }
+ else
+ {
+ std::ostringstream ss; + ss << "e" << exprCount; + exprCount++;
+ //declare the expression
+ indent( os, ind );
+ if( code->getclass()==SYMS_EXPR && !is_var( ((SymSExpr*)code)->s ) )
+ {
+ os << "static ";
+ }
+ os << "Expr* " << ss.str().c_str() << ";" << std::endl;
+ //write the expression
+ std::ostringstream ss2; + ss2 << ss.str().c_str(); + write_code( code, os, ind, ss2.str().c_str(), opts );
+
+ //if is not a sym expression, then decrement the expression and return null
+ if( opts&opt_write_check_sym_expr )
+ { + indent( os, ind ); + os << "if (" << expr.c_str() << "->getclass() != SYM_EXPR) {" << std::endl; + indent( os, ind+1 ); + os << "exit( 1 );" << std::endl; + indent( os, ind ); + os << "}" << std::endl;
+ }
+
+ expr = std::string( ss.str().c_str() );
+ vars.push_back( expr );
+ }
+ //increment the counter for memory management
+ //indent( os, ind );
+ //os << expr.c_str() << "->inc();" << std::endl;
+}
+
+void sccwriter::write_dec( const std::string& expr, std::ostream& os, int ind )
+{
+ bool wd = true;
+ if( wd )
+ {
+ indent( os, ind );
+ os << expr.c_str() << "->dec();" << std::endl;
+ }
+}
+
+void sccwriter::debug_write_code( Expr* code, std::ostream& os, int ind )
+{
+ indent( os, ind );
+ switch( code->getclass() )
+ {
+ case INT_EXPR: + os << "int_expr"; + break; + case HOLE_EXPR: + os << "hole_expr"; + break; + case SYM_EXPR: + os << "sym_expr"; + break; + case SYMS_EXPR:
+ os << "syms_expr: " << ((SymSExpr*)code)->s.c_str();
+ break;
+ default:
+ switch( code->getop() )
+ {
+ case APP: + os << "app"; + break; + case PI: + os << "pi"; + break; + case LAM: + os << "lam"; + break; + case TYPE: + os << "type"; + break; + case KIND: + os << "kind"; + break; + case ASCRIBE: + os << "ascribe"; + break; + case MPZ: + os << "mpz"; + break; + case PROG: + os << "prog"; + break; + case PROGVARS:
+ os << "progvars";
+ break;
+ case MATCH: + os << "match"; + break; + case CASE: + os << "case"; + break; + case PAT: + os << "pat"; + break; + case DO: + os << "do"; + break; + case ADD: + os << "add"; + break; + case NEG: + os << "neg"; + break; + case LET: + os << "let"; + break; + case RUN: + os << "run"; + break; + case FAIL: + os << "fail"; + break; + case MARKVAR: + os << "markvar"; + break; + case IFMARKED:
+ os << "ifmarked";
+ break;
+ case COMPARE:
+ os << "compare";
+ break;
+ default:
+ os << "???";
+ break;
+ }
+ }
+ os << std::endl;
+ if( code->getop()!=0 )
+ {
+ CExpr* ce = (CExpr*)code;
+ int counter = 0;
+ while( ce->kids[counter] ){
+ debug_write_code( ce->kids[counter], os, ind+1 );
+ counter++;
+ }
+ }
+}
|