Example #1
0
ast_result_t pass_verify(ast_t** astp, pass_opt_t* options)
{
  ast_t* ast = *astp;
  bool r = true;

  switch(ast_id(ast))
  {
    case TK_FUN:
    case TK_NEW:
    case TK_BE:           r = verify_fun(options, ast); break;
    case TK_FUNREF:
    case TK_FUNCHAIN:
    case TK_NEWREF:       r = verify_function_call(options, ast); break;
    case TK_BEREF:
    case TK_BECHAIN:
    case TK_NEWBEREF:     r = verify_behaviour_call(options, ast); break;
    case TK_FFICALL:      r = verify_ffi_call(options, ast); break;
    case TK_TRY:
    case TK_TRY_NO_CHECK: r = verify_try(options, ast); break;
    case TK_LETREF:
    case TK_VARREF:
    case TK_FLETREF:
    case TK_FVARREF:
    case TK_EMBEDREF:
    case TK_CALL:
    case TK_QUALIFY:
    case TK_TUPLE:
    case TK_ASSIGN:
    case TK_MATCH:
    case TK_CASES:
    case TK_CASE:
    case TK_IS:
    case TK_ISNT:
    case TK_SEQ:
    case TK_BREAK:
    case TK_RETURN:
    case TK_IF:
    case TK_IFDEF:
    case TK_WHILE:
    case TK_REPEAT:
    case TK_RECOVER:
    case TK_POSITIONALARGS:
    case TK_NAMEDARGS:
    case TK_NAMEDARG:
    case TK_UPDATEARG:    ast_inheritflags(ast); break;
    case TK_ERROR:        ast_seterror(ast); break;

    default: {}
  }

  if(!r)
  {
    assert(errors_get_count(options->check.errors) > 0);
    return AST_ERROR;
  }

  return AST_OK;
}
Example #2
0
bool expr_fun(pass_opt_t* opt, ast_t* ast)
{
  typecheck_t* t = &opt->check;

  AST_GET_CHILDREN(ast,
    cap, id, typeparams, params, type, can_error, body);

  if(ast_id(body) == TK_NONE)
    return true;

  if(!coerce_literals(&body, type, opt))
    return false;

  bool is_trait =
    (ast_id(t->frame->type) == TK_TRAIT) ||
    (ast_id(t->frame->type) == TK_INTERFACE) ||
    (ast_id((ast_t*)ast_data(ast)) == TK_TRAIT) ||
    (ast_id((ast_t*)ast_data(ast)) == TK_INTERFACE);

  // Check partial functions.
  if(ast_id(can_error) == TK_QUESTION)
  {
    // If a partial function, check that we might actually error.
    ast_t* body_type = ast_type(body);

    if(body_type == NULL)
    {
      // An error has already occurred.
      assert(errors_get_count(t->errors) > 0);
      return false;
    }

    if(!is_trait &&
      !ast_canerror(body) &&
      (ast_id(body_type) != TK_COMPILE_INTRINSIC))
    {
      ast_error(opt->check.errors, can_error,
        "function body is not partial but the function is");
      return false;
    }
  } else {
    // If not a partial function, check that we can't error.
    if(ast_canerror(body))
    {
      ast_error(opt->check.errors, can_error,
        "function body is partial but the function is not");
      show_partiality(opt, body);
      return false;
    }
  }

  if(!check_primitive_init(opt, ast) || !check_finaliser(opt, ast))
    return false;

  if(!check_main_create(opt, ast))
    return false;

  switch(ast_id(ast))
  {
    case TK_NEW:
    {
      bool ok = true;

      if(is_machine_word(type))
      {
        if(!check_return_type(opt, ast))
         ok = false;
      }

      if(!check_fields_defined(opt, ast))
        ok = false;

      return ok;
    }

    case TK_FUN:
      return check_return_type(opt, ast);

    default: {}
  }

  return true;
}
Example #3
0
int main(int argc, char* argv[])
{
  stringtab_init();

  pass_opt_t opt;
  pass_opt_init(&opt);

  opt.release = true;
  opt.output = ".";

  ast_setwidth(get_width());
  bool print_program_ast = false;
  bool print_package_ast = false;

  opt_state_t s;
  ponyint_opt_init(args, &s, &argc, argv);

  bool ok = true;
  bool print_usage = false;
  int id;

  while((id = ponyint_opt_next(&s)) != -1)
  {
    switch(id)
    {
      case OPT_VERSION:
        printf("%s [%s] (llvm %s)\n", PONY_VERSION, PONY_BUILD_CONFIG,
          LLVM_VERSION);
        return 0;

      case OPT_DEBUG: opt.release = false; break;
      case OPT_BUILDFLAG: define_build_flag(s.arg_val); break;
      case OPT_STRIP: opt.strip_debug = true; break;
      case OPT_PATHS: package_add_paths(s.arg_val, &opt); break;
      case OPT_OUTPUT: opt.output = s.arg_val; break;
      case OPT_LIBRARY: opt.library = true; break;
      case OPT_RUNTIMEBC: opt.runtimebc = true; break;
      case OPT_PIC: opt.pic = true; break;
      case OPT_DOCS: opt.docs = true; break;

      case OPT_SAFE:
        if(!package_add_safe(s.arg_val, &opt))
          ok = false;
        break;

      case OPT_IEEEMATH: opt.ieee_math = true; break;
      case OPT_CPU: opt.cpu = s.arg_val; break;
      case OPT_FEATURES: opt.features = s.arg_val; break;
      case OPT_TRIPLE: opt.triple = s.arg_val; break;
      case OPT_STATS: opt.print_stats = true; break;
      case OPT_LINK_ARCH: opt.link_arch = s.arg_val; break;
      case OPT_LINKER: opt.linker = s.arg_val; break;

      case OPT_AST: print_program_ast = true; break;
      case OPT_ASTPACKAGE: print_package_ast = true; break;
      case OPT_TRACE: parse_trace(true); break;
      case OPT_WIDTH: ast_setwidth(atoi(s.arg_val)); break;
      case OPT_IMMERR: errors_set_immediate(opt.check.errors, true); break;
      case OPT_VERIFY: opt.verify = true; break;
      case OPT_EXTFUN: opt.extfun = true; break;
      case OPT_FILENAMES: opt.print_filenames = true; break;
      case OPT_CHECKTREE: opt.check_tree = true; break;

      case OPT_BNF: print_grammar(false, true); return 0;
      case OPT_ANTLR: print_grammar(true, true); return 0;
      case OPT_ANTLRRAW: print_grammar(true, false); return 0;

      case OPT_VERBOSE:
        {
          int v = atoi(s.arg_val);
          if (v >= 0 && v <= 4) {
            opt.verbosity = (verbosity_level)v;
          } else {
            ok = false;
          }
        }
        break;

      case OPT_PASSES:
        if(!limit_passes(&opt, s.arg_val))
        {
          ok = false;
          print_usage = true;
        }
        break;

      default: usage(); return -1;
    }
  }

  for(int i = 1; i < argc; i++)
  {
    if(argv[i][0] == '-')
    {
      printf("Unrecognised option: %s\n", argv[i]);
      ok = false;
      print_usage = true;
    }
  }

#if defined(PLATFORM_IS_WINDOWS)
  opt.strip_debug = true;
#endif

  if(!ok)
  {
    errors_print(opt.check.errors);

    if(print_usage)
      usage();

    return -1;
  }

  if(ponyc_init(&opt))
  {
    if(argc == 1)
    {
      ok &= compile_package(".", &opt, print_program_ast, print_package_ast);
    } else {
      for(int i = 1; i < argc; i++)
        ok &= compile_package(argv[i], &opt, print_program_ast,
          print_package_ast);
    }
  }

  if(!ok && errors_get_count(opt.check.errors) == 0)
    printf("Error: internal failure not reported\n");

  ponyc_shutdown(&opt);
  pass_opt_done(&opt);

  return ok ? 0 : -1;
}