Пример #1
0
bool genexe(compile_t* c, ast_t* program)
{
  // The first package is the main package. It has to have a Main actor.
  const char* main_actor = stringtab("Main");
  const char* env_class = stringtab("Env");

  ast_t* package = ast_child(program);
  ast_t* main_def = ast_get(package, main_actor, NULL);

  if(main_def == NULL)
  {
    errorf(NULL, "no Main actor found in package '%s'", c->filename);
    return false;
  }

  // Generate the Main actor and the Env class.
  ast_t* main_ast = type_builtin(c->opt, main_def, main_actor);
  ast_t* env_ast = type_builtin(c->opt, main_def, env_class);

  genprim_reachable_init(c, program);
  reach(c->reachable, main_ast, stringtab("create"), NULL);
  reach(c->reachable, env_ast, stringtab("_create"), NULL);
  paint(c->reachable);

  gentype_t main_g;
  gentype_t env_g;

  bool ok = gentype(c, main_ast, &main_g) && gentype(c, env_ast, &env_g);

  if(ok)
    gen_main(c, &main_g, &env_g);

  ast_free_unattached(main_ast);
  ast_free_unattached(env_ast);

  if(!ok)
    return false;

  if(!genopt(c))
    return false;

  const char* file_o = genobj(c);

  if(file_o == NULL)
    return false;

  if(c->opt->limit < PASS_ALL)
    return true;

  if(!link_exe(c, program, file_o))
    return false;

#ifdef PLATFORM_IS_WINDOWS
  _unlink(file_o);
#else
  unlink(file_o);
#endif

  return true;
}
Пример #2
0
bool genlib(compile_t* c, ast_t* program)
{
  if(!reachable_actors(c, program) ||
    !generate_actors(c, program) ||
    !genheader(c)
    )
    return false;

  const char* file_o = genobj(c);

  if(file_o == NULL)
    return false;

  if(c->opt->limit < PASS_ALL)
    return true;

  if(!link_lib(c, file_o))
    return false;

#ifdef PLATFORM_IS_WINDOWS
  _unlink(file_o);
#else
  unlink(file_o);
#endif

  return true;
}
Пример #3
0
bool genlib(compile_t* c, ast_t* program)
{
  if(!reachable_actors(c, program) ||
    !gentypes(c) ||
    !genheader(c)
    )
    return false;

  plugin_visit_compile(c, c->opt);

  if(!genopt(c, true))
    return false;

  if(c->opt->runtimebc)
  {
    if(!codegen_merge_runtime_bitcode(c))
      return false;

    // Rerun the optimiser without the Pony-specific optimisation passes.
    // Inlining runtime functions can screw up these passes so we can't
    // run the optimiser only once after merging.
    if(!genopt(c, false))
      return false;
  }

  const char* file_o = genobj(c);

  if(file_o == NULL)
    return false;

  if(c->opt->limit < PASS_ALL)
    return true;

  if(!link_lib(c, file_o))
    return false;

#ifdef PLATFORM_IS_WINDOWS
  _unlink(file_o);
#else
  unlink(file_o);
#endif

  return true;
}
Пример #4
0
bool genexe(compile_t* c, ast_t* program)
{
  errors_t* errors = c->opt->check.errors;

  // The first package is the main package. It has to have a Main actor.
  const char* main_actor = c->str_Main;
  const char* env_class = c->str_Env;

  ast_t* package = ast_child(program);
  ast_t* main_def = ast_get(package, main_actor, NULL);

  if(main_def == NULL)
  {
    errorf(errors, NULL, "no Main actor found in package '%s'", c->filename);
    return false;
  }

  // Generate the Main actor and the Env class.
  ast_t* main_ast = type_builtin(c->opt, main_def, main_actor);
  ast_t* env_ast = type_builtin(c->opt, main_def, env_class);

  if(lookup(c->opt, main_ast, main_ast, c->str_create) == NULL)
    return false;

  if(c->opt->verbosity >= VERBOSITY_INFO)
    fprintf(stderr, " Reachability\n");
  reach(c->reach, main_ast, c->str_create, NULL, c->opt);
  reach(c->reach, env_ast, c->str__create, NULL, c->opt);

  if(c->opt->limit == PASS_REACH)
    return true;

  if(c->opt->verbosity >= VERBOSITY_INFO)
    fprintf(stderr, " Selector painting\n");
  paint(&c->reach->types);

  if(c->opt->limit == PASS_PAINT)
    return true;

  if(!gentypes(c))
    return false;

  if(c->opt->verbosity >= VERBOSITY_ALL)
    reach_dump(c->reach);

  reach_type_t* t_main = reach_type(c->reach, main_ast);
  reach_type_t* t_env = reach_type(c->reach, env_ast);

  if((t_main == NULL) || (t_env == NULL))
    return false;

  gen_main(c, t_main, t_env);

  if(!genopt(c, true))
    return false;

  if(c->opt->runtimebc)
  {
    if(!codegen_merge_runtime_bitcode(c))
      return false;

    // Rerun the optimiser without the Pony-specific optimisation passes.
    // Inlining runtime functions can screw up these passes so we can't
    // run the optimiser only once after merging.
    if(!genopt(c, false))
      return false;
  }

  const char* file_o = genobj(c);

  if(file_o == NULL)
    return false;

  if(c->opt->limit < PASS_ALL)
    return true;

  if(!link_exe(c, program, file_o))
    return false;

#ifdef PLATFORM_IS_WINDOWS
  _unlink(file_o);
#else
  unlink(file_o);
#endif

  return true;
}
Пример #5
0
bool genexe(compile_t* c, ast_t* program)
{
  errors_t* errors = c->opt->check.errors;

  // The first package is the main package. It has to have a Main actor.
  const char* main_actor = c->str_Main;
  const char* env_class = c->str_Env;

  ast_t* package = ast_child(program);
  ast_t* main_def = ast_get(package, main_actor, NULL);

  if(main_def == NULL)
  {
    errorf(errors, NULL, "no Main actor found in package '%s'", c->filename);
    return false;
  }

  // Generate the Main actor and the Env class.
  ast_t* main_ast = type_builtin(c->opt, main_def, main_actor);
  ast_t* env_ast = type_builtin(c->opt, main_def, env_class);

  if(lookup(NULL, main_ast, main_ast, c->str_create) == NULL)
    return false;

  if(c->opt->verbosity >= VERBOSITY_INFO)
    fprintf(stderr, " Reachability\n");
  reach(c->reach, main_ast, c->str_create, NULL, c->opt);
  reach(c->reach, env_ast, c->str__create, NULL, c->opt);

  if(c->opt->limit == PASS_REACH)
    return true;

  if(c->opt->verbosity >= VERBOSITY_INFO)
    fprintf(stderr, " Selector painting\n");
  paint(&c->reach->types);

  if(c->opt->limit == PASS_PAINT)
    return true;

  if(!gentypes(c))
    return false;

  if(c->opt->verbosity >= VERBOSITY_ALL)
    reach_dump(c->reach);

  reach_type_t* t_main = reach_type(c->reach, main_ast);
  reach_type_t* t_env = reach_type(c->reach, env_ast);

  if((t_main == NULL) || (t_env == NULL))
    return false;

  gen_main(c, t_main, t_env);

  if(!genopt(c))
    return false;

  const char* file_o = genobj(c);

  if(file_o == NULL)
    return false;

  if(c->opt->limit < PASS_ALL)
    return true;

  if(!link_exe(c, program, file_o))
    return false;

#ifdef PLATFORM_IS_WINDOWS
  _unlink(file_o);
#else
  unlink(file_o);
#endif

  return true;
}
Пример #6
0
int main( int argc, char **argv )
{
    int     i;
    FILE    *skeleton, *temp, *tokout, *actout;
    int     ch;
    char    tempfname[10];
    char    *fileprefix = "y";
    size_t  size;

    param_requested = 0;
    for( i = 1; i < argc; ++i ) {
        ch = argv[i][0];
        switch( param_requested ) {
        case 'b':
            if( ch != '-' ) {
                if( ch != '\0' )
                    fileprefix = argv[i];
                ++i;
            }
            break;
        case 'p':
            if( ch != '-' ) {
                if( ch != '\0' )
                    symprefix = argv[i];
                ++i;
            }
            break;
        default:
            break;
        }
        param_requested = 0;
        if( argv[i][0] != '-' )
            break;
        setoptions( &argv[i][1] );
    }
    if( i != argc - 1 && i != argc - 2 ) {
        puts( "usage: yacc [-dlv] [-d[bcdfhpstuw]] [-b <file_prefix>] [-p <sym_prefix>]" );
        puts( "                  <grammar> [<driver>]" );
        puts( "options:" );
        puts( "    -b <file_prefix> file prefix used in place of default 'y' prefix" );
        puts( "    -d    output header file" );
        puts( "    -db   output bigger (less optimal) tables" );
        puts( "    -dc   output compact tables (slower to execute)" );
        puts( "    -dd   use dense tokens (no '+' style tokens allowed)" );
        puts( "    -de   dump all symbols to header file as enum items, no macros" );
        puts( "    -df   output fast tables (larger size)" );
        puts( "    -dh   use 'default shift' optimization" );
        puts( "    -dp   dump all productions" );
        puts( "    -ds   dump full state tables" );
        puts( "    -dt   translate 'keyword' to Y_KEYWORD, '++' to Y_PLUS_PLUS, etc." );
        puts( "    -du   eliminate useless unit production reduction" );
        puts( "    -dw   disable default action type checking" );
        puts( "    -l    output #line directives" );
        puts( "    -p <sym_prefix> symbol prefix used in place of default 'yy' prefix" );
        puts( "    -v    write description and report into file" );
        exit( 1 );
    }
    skeleton = NULL;
    if( i == argc - 2 ) {
        skeleton = openr( argv[argc - 1] );
        if( skeleton == NULL ) {
            msg( "could not open driver source code '%s'\n", argv[argc - 1] );
        }
    }
    loadpath = argv[0];
    *getname( loadpath ) = '\0';
    srcname = argv[i];
    if( !strrchr( srcname, '.' ) ) {
        srcname = alloca( strlen( argv[i] )+3 );
        srcname = strcat( strcpy( srcname, argv[i] ), ".y" );
    }
    yaccin = openr( srcname );

    size = strlen( fileprefix);
    codefilename   = MALLOC( size + 6, char );
    strcat( strcpy( codefilename, fileprefix), "tab.c" );
    headerfilename = MALLOC( size + 6, char );
    strcat( strcpy( headerfilename, fileprefix), "tab.h" );
    descfilename   = MALLOC( size + 5, char );
    strcat( strcpy( descfilename, fileprefix), ".out" );
    actout = openw( codefilename );
    defs( actout );
    tokout = openw( headerfilename );
    dump_header( tokout );
    temp = NULL;
    for( i = 0; i < 1000 && temp == NULL; ++i ) {
        sprintf( tempfname, "ytab.%3d", i );
        temp = fopen( tempfname, "w+" );
    }
    if( temp == NULL ) {
        msg( "Cannot create temporary file\n" );
    }
    rules( temp );
    buildpro();
    CalcMinSentence();
    if( proflag || showflag ) {
        showpro();
    }
    lr0();
    lalr1();
    SetupStateTable();
    /* apply state filters */
    FindUnused();
    if( eliminateunitflag ) {
        EliminateUnitReductions();
    }
    if( default_shiftflag ) {
        if( keyword_id_low == 0 ) {
            msg( "No %%keyword_id <low> <high> specified." );
        } else {
            MarkDefaultShifts();
        }
    }
    MarkNoUnitRuleOptimizationStates();
    RemoveDeadStates();
    MarkDefaultReductions();
    if( showflag ) {
        showstates();
    }
    if( warnings ) {
        if( warnings == 1 ) {
            printf( "%s: 1 warning\n", srcname );
        } else {
            printf( "%s: %d warnings\n", srcname, warnings );
        }
        exit( 1 );
    }
    parsestats();
    dumpstatistic( "parser states", nstate );
    dumpstatistic( "# states (1 reduce only)", nstate_1_reduce );
    dumpstatistic( "reduce/reduce conflicts", RR_conflicts );
    dumpstatistic( "shift/reduce conflicts", SR_conflicts );
    show_unused();
    if( skeleton == NULL ) {
        skeleton = fpopen( loadpath, "yydriver.c" );
        if( skeleton == NULL ) {
            warn( "Can't find yacc skeleton yydriver.c\n" );
        }
    }
    /* copy first part of skeleton */
    if( skeleton != NULL )
        copy_part( skeleton, actout );
    rewind( tokout );
    /* copy tokens */
    copy_rest( tokout, actout );
    close_header( tokout );
    genobj( actout );
    /* copy middle part of skeleton */
    if( skeleton != NULL )
        copy_part( skeleton, actout );
    rewind( temp );
    copy_rest( temp, actout );
    fclose( temp );
    remove( tempfname );
    /* copy last part of skeleton */
    if( skeleton != NULL ) {
        copy_rest( skeleton, actout );
        fclose( skeleton );
    }
    tail( actout );
    fclose( actout );
    FREE( codefilename );
    FREE( headerfilename );
    FREE( descfilename );
    return( 0 );
}