Beispiel #1
0
static void free_variable( const var_t *arg, const char *local_var_prefix )
{
  unsigned int type_offset = arg->type->typestring_offset;
  expr_t *iid;
  type_t *type = arg->type;
  expr_t *size = get_size_is_expr(type, arg->name);

  if (size)
  {
    print_proxy( "__frame->_StubMsg.MaxCount = " );
    write_expr(proxy, size, 0, 1, NULL, NULL, local_var_prefix);
    fprintf(proxy, ";\n\n");
    print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, ");
    fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
    fprintf(proxy, "(void*)%s );\n", arg->name );
    return;
  }

  switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
  {
  case TGT_ENUM:
  case TGT_BASIC:
    break;

  case TGT_STRUCT:
    if (get_struct_fc(type) != RPC_FC_STRUCT)
      print_proxy("/* FIXME: %s code for %s struct type 0x%x missing */\n", __FUNCTION__, arg->name, get_struct_fc(type) );
    break;

  case TGT_IFACE_POINTER:
    iid = get_attrp( arg->attrs, ATTR_IIDIS );
    if( iid )
    {
      print_proxy( "__frame->_StubMsg.MaxCount = (ULONG_PTR) " );
      write_expr(proxy, iid, 1, 1, NULL, NULL, local_var_prefix);
      print_proxy( ";\n\n" );
    }
    /* fall through */
  case TGT_POINTER:
    if (get_pointer_fc(type, arg->attrs, TRUE) == RPC_FC_FP)
    {
      print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, ");
      fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
      fprintf(proxy, "(void*)%s );\n", arg->name );
    }
    else
      print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) );
    break;

  default:
    print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) );
  }
}
Beispiel #2
0
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++;
  }
}
Beispiel #3
0
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;
  }
}
Beispiel #4
0
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();
}
Beispiel #5
0
Datei: expr.c Projekt: kybp/basic
void write_expr(FILE *f, expr *e)
{
    switch (e->type) {
    case INTEGER:
        fprintf(f, "%d", e->val.integer);
        return;
    case REAL:
        fprintf(f, "%f", e->val.real);
        return;
    case STRING:
        fprintf(f, "\"%s\"", e->val.string);
        return;
    case INT_VAR: case REAL_VAR: case STR_VAR:
        fprintf(f, "%s", e->val.string);
        return;
    }

    switch (e->op) {
    /* Arithmetic */
    case ADD:
        write_expr(f, e->arg1);
        fprintf(f, " + ");
        write_expr(f, e->arg2);
        return;
    case SUB:
        write_expr(f, e->arg1);
        fprintf(f, " - ");
        write_expr(f, e->arg2);
        return;
    case MUL:
        write_expr(f, e->arg1);
        fprintf(f, " * ");
        write_expr(f, e->arg2);
        return;
    case DIV:
        write_expr(f, e->arg1);
        fprintf(f, " / ");
        write_expr(f, e->arg2);
        return;
    case EXPT:
        write_expr(f, e->arg1);
        fprintf(f, " ** ");
        write_expr(f, e->arg2);
        return;

    /* Comparisons */
    case LT:
        write_expr(f, e->arg1);
        fprintf(f, " < ");
        write_expr(f, e->arg2);
        return;
    case LE:
        write_expr(f, e->arg1);
        fprintf(f, " <= ");
        write_expr(f, e->arg2);
        return;
    case EQ:
        write_expr(f, e->arg1);
        fprintf(f, " = ");
        write_expr(f, e->arg2);
        return;
    case GE:
        write_expr(f, e->arg1);
        fprintf(f, " >= ");
        write_expr(f, e->arg2);
        return;
    case NE:
        write_expr(f, e->arg1);
        fprintf(f, " <> ");
        write_expr(f, e->arg2);
        return;

    /* Casts */
    case CEIL:
        fprintf(f, "CEIL(");
        write_expr(f, e->arg1);
        fprintf(f, ")");
        return;
    case FLOOR:
        fprintf(f, "FLOOR(");
        write_expr(f, e->arg1);
        fprintf(f, ")");
        return;
    case REAL_CAST:
        fprintf(f, "REAL(");
        write_expr(f, e->arg1);
        fprintf(f, ")");
        return;
    case ROUND:
        fprintf(f, "ROUND(");
        write_expr(f, e->arg1);
        fprintf(f, ")");
        return;

    /* Numerical functions */
    case RAND:
        fprintf(f, "RAND(");
        write_expr(f, e->arg1);
        fprintf(f, ")");
        return;
    case SQRT:
        fprintf(f, "SQRT(");
        write_expr(f, e->arg1);
        fprintf(f, ")");
        return;

    default:
        fprintf(f, "???");
        return;
    }
}