示例#1
0
文件: docgen.c 项目: JamesLinus/ponyc
// Write the given package home page to its own file
static void doc_package_home(docgen_t* docgen,
  ast_t* package,
  ast_t* doc_string)
{
  assert(docgen != NULL);
  assert(docgen->index_file != NULL);
  assert(docgen->home_file != NULL);
  assert(docgen->package_file == NULL);
  assert(docgen->test_types == NULL);
  assert(docgen->public_types == NULL);
  assert(docgen->private_types == NULL);
  assert(docgen->type_file == NULL);
  assert(package != NULL);
  assert(ast_id(package) == TK_PACKAGE);

  // First open a file
  size_t tqfn_len;
  char* tqfn = write_tqfn(package, "-index", &tqfn_len);

  // Package group
  fprintf(docgen->index_file, "- package %s:\n",
    package_qualified_name(package));

  docgen->type_file = doc_open_file(docgen, true, tqfn, ".md");

  if(docgen->type_file == NULL)
    return;

  // Add reference to new file to index file
  fprintf(docgen->index_file, "  - Package: \"%s.md\"\n", tqfn);

  // Add reference to package to home file
  fprintf(docgen->home_file, "* [%s](%s)\n", package_qualified_name(package),
    tqfn);

  // Now we can write the actual documentation for the package
  if(doc_string != NULL)
  {
    assert(ast_id(doc_string) == TK_STRING);
    fprintf(docgen->type_file, "%s", ast_name(doc_string));
  }
  else
  {
    fprintf(docgen->type_file, "No package doc string provided for %s.",
      package_qualified_name(package));
  }


  ponyint_pool_free_size(tqfn_len, tqfn);

  docgen->test_types = printbuf_new();
  docgen->public_types = printbuf_new();
  docgen->private_types = printbuf_new();
  docgen->package_file = docgen->type_file;
  docgen->type_file = NULL;
}
示例#2
0
static void test_printbuf_memappend(int *before_resize)
{
	struct printbuf *pb;
	int initial_size;

	printf("%s: starting test\n", __func__);
	pb = printbuf_new();
	printf("Buffer length: %d\n", printbuf_length(pb));

	initial_size = pb->size;

	while(pb->size == initial_size)
	{
		printbuf_memappend_fast(pb, "x", 1);
	}
	*before_resize = printbuf_length(pb) - 1;
	printf("Appended %d bytes for resize: [%s]\n", *before_resize + 1, pb->buf);

	printbuf_reset(pb);
	printbuf_memappend_fast(pb, "bluexyz123", 3);
	printf("Partial append: %d, [%s]\n", printbuf_length(pb), pb->buf);

	char with_nulls[] = { 'a', 'b', '\0', 'c' };
	printbuf_reset(pb);
	printbuf_memappend_fast(pb, with_nulls, (int)sizeof(with_nulls));
	printf("With embedded \\0 character: %d, [%s]\n", printbuf_length(pb), pb->buf);

	printbuf_free(pb);
	pb = printbuf_new();
	char *data = malloc(*before_resize);
	memset(data, 'X', *before_resize);
	printbuf_memappend_fast(pb, data, *before_resize);
	printf("Append to just before resize: %d, [%s]\n", printbuf_length(pb), pb->buf);

	free(data);
	printbuf_free(pb);

	pb = printbuf_new();
	data = malloc(*before_resize + 1);
	memset(data, 'X', *before_resize + 1);
	printbuf_memappend_fast(pb, data, *before_resize + 1);
	printf("Append to just after resize: %d, [%s]\n", printbuf_length(pb), pb->buf);

	free(data);
	printbuf_free(pb);

#define SA_TEST_STR "XXXXXXXXXXXXXXXX"
	pb = printbuf_new();
	printbuf_strappend(pb, SA_TEST_STR);
	printf("Buffer size after printbuf_strappend(): %d, [%s]\n", printbuf_length(pb), pb->buf);
	printbuf_free(pb);
#undef  SA_TEST_STR

	printf("%s: end test\n", __func__);
}
示例#3
0
static void test_sprintbuf(int before_resize)
{
	struct printbuf *pb;

	printf("%s: starting test\n", __func__);
	pb = printbuf_new();
	printf("Buffer length: %d\n", printbuf_length(pb));

	char *data = malloc(before_resize + 1 + 1);
	memset(data, 'X', before_resize + 1 + 1);
	data[before_resize + 1] = '\0';
	sprintbuf(pb, "%s", data);
	free(data);
	printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf));

	printbuf_reset(pb);
	sprintbuf(pb, "plain");
	printf("%d, [%s]\n", printbuf_length(pb), pb->buf);

	sprintbuf(pb, "%d", 1);
	printf("%d, [%s]\n", printbuf_length(pb), pb->buf);

	sprintbuf(pb, "%d", INT_MAX);
	printf("%d, [%s]\n", printbuf_length(pb), pb->buf);

	sprintbuf(pb, "%d", INT_MIN);
	printf("%d, [%s]\n", printbuf_length(pb), pb->buf);

	sprintbuf(pb, "%s", "%s");
	printf("%d, [%s]\n", printbuf_length(pb), pb->buf);

	printbuf_free(pb);
	printf("%s: end test\n", __func__);
}
示例#4
0
文件: json_util.c 项目: tjyang/abmon
struct json_object* json_object_from_file(const char *filename)
{
    struct printbuf *pb;
    struct json_object *obj;
    char buf[JSON_FILE_BUF_SIZE];
    int fd, ret;

    if((fd = open(filename, O_RDONLY)) < 0) {
        MC_ERROR("json_object_from_file: error reading file %s: %s\n",
                 filename, strerror(errno));
        return (struct json_object*)error_ptr(-1);
    }
    if(!(pb = printbuf_new())) {
        MC_ERROR("json_object_from_file: printbuf_new failed\n");
        return (struct json_object*)error_ptr(-1);
    }
    while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
        printbuf_memappend(pb, buf, ret);
    }
    close(fd);
    if(ret < 0) {
        MC_ABORT("json_object_from_file: error reading file %s: %s\n",
                 filename, strerror(errno));
        printbuf_free(pb);
        return (struct json_object*)error_ptr(-1);
    }
    obj = json_tokener_parse(pb->buf);
    printbuf_free(pb);
    return obj;
}
示例#5
0
const char* genname_type(ast_t* ast)
{
  // package_Type[_Arg1_Arg2]
  printbuf_t* buf = printbuf_new();
  type_append(buf, ast, true);
  return stringtab_buf(buf);
}
示例#6
0
const char* genname_fun(token_id cap, const char* name, ast_t* typeargs)
{
  // cap_name[_Arg1_Arg2]
  printbuf_t* buf = printbuf_new();
  printbuf(buf, "%s_%s", lexer_print(cap), name);
  types_append(buf, typeargs);
  return stringtab_buf(buf);
}
示例#7
0
文件: reach.c 项目: Sendence/ponyc
static const char* make_full_name(reach_type_t* t, reach_method_t* m)
{
  // Generate the full mangled name.
  // pkg_Type[_Arg1_Arg2]_cap_name[_Arg1_Arg2]_args_result
  printbuf_t* buf = printbuf_new();
  printbuf(buf, "%s_%s", t->name, m->mangled_name);
  const char* name = stringtab(buf->m);
  printbuf_free(buf);
  return name;
}
示例#8
0
文件: ast.c 项目: awaidmann/ponyc
const char* ast_print_type(ast_t* type)
{
  printbuf_t* buffer = printbuf_new();
  print_type(buffer, type);

  const char* s = stringtab(buffer->m);
  printbuf_free(buffer);

  return s;
}
示例#9
0
static const char* stringtab_two(const char* a, const char* b)
{
  if(a == NULL)
    a = "_";

  assert(b != NULL);
  printbuf_t* buf = printbuf_new();
  printbuf(buf, "%s_%s", a, b);
  return stringtab_buf(buf);
}
示例#10
0
static void test_basic_printbuf_memset()
{
	struct printbuf *pb;

	printf("%s: starting test\n", __func__);
	pb = printbuf_new();
	sprintbuf(pb, "blue:%d", 1);
	printbuf_memset(pb, -1, 'x', 52);
	printf("Buffer contents:%.*s\n", printbuf_length(pb), pb->buf);
	printbuf_free(pb);
	printf("%s: end test\n", __func__);
}
示例#11
0
文件: genheader.c 项目: Preetam/ponyc
bool genheader(compile_t* c)
{
  // Open a header file.
  const char* file_h = suffix_filename(c->opt->output, "", c->filename, ".h");
  FILE* fp = fopen(file_h, "wt");

  if(fp == NULL)
  {
    errorf(NULL, "couldn't write to %s", file_h);
    return false;
  }

  fprintf(fp,
    "#ifndef pony_%s_h\n"
    "#define pony_%s_h\n"
    "\n"
    "/* This is an auto-generated header file. Do not edit. */\n"
    "\n"
    "#include <stdint.h>\n"
    "#include <stdbool.h>\n"
    "\n"
    "#ifdef __cplusplus\n"
    "extern \"C\" {\n"
    "#endif\n"
    "\n"
    "#ifdef _MSC_VER\n"
    "typedef struct __int128_t { uint64_t low; int64_t high; } __int128_t;\n"
    "typedef struct __uint128_t { uint64_t low; uint64_t high; } "
      "__uint128_t;\n"
    "#endif\n"
    "\n",
    c->filename,
    c->filename
    );

  printbuf_t* buf = printbuf_new();
  print_types(c, fp, buf);
  fwrite(buf->m, 1, buf->offset, fp);
  printbuf_free(buf);

  fprintf(fp,
    "\n"
    "#ifdef __cplusplus\n"
    "}\n"
    "#endif\n"
    "\n"
    "#endif\n"
    );

  fclose(fp);
  return true;
}
示例#12
0
int main (int argc, char **argv) {
  struct arguments arguments;
  struct list_elem elem;
  struct list_elem *elemptr = &elem;
  elem.has_next = 0;
  
  arguments.include_files = elemptr;
  arguments.output_file = "-";
  arguments.parsley = "-";
  argp_parse (&argp, argc, argv, 0, 0, &arguments);
  
  struct printbuf* parsley = printbuf_new();
  struct printbuf* incl = printbuf_new();
  sprintbuf(parsley, "");
  sprintbuf(incl, "");

  FILE* in = parsley_fopen(arguments.parsley, "r");
  
  printbuf_file_read(in, parsley);
  while(elemptr->has_next) {
    elemptr = elemptr->next;
    FILE* f = parsley_fopen(elemptr->string, "r");
    printbuf_file_read(f, incl);
    fclose(f);
  }
  
  parsleyPtr compiled = parsley_compile(parsley->buf, incl->buf);
  if(compiled->error != NULL) {
    fprintf(stderr, "%s\n", compiled->error);
     exit(1);
  }
  
  FILE* fo = parsley_fopen(arguments.output_file, "w");
  xmlDocFormatDump(fo, compiled->stylesheet->doc, 1);
  fclose(fo);
  
  return 0;
}
示例#13
0
文件: reach.c 项目: Sendence/ponyc
static const char* make_mangled_name(reach_method_t* m)
{
  // Generate the mangled name.
  // cap_name[_Arg1_Arg2]_args_result
  printbuf_t* buf = printbuf_new();
  printbuf(buf, "%s_", m->name);

  for(size_t i = 0; i < m->param_count; i++)
    printbuf(buf, "%s", m->params[i].type->mangle);

  printbuf(buf, "%s", m->result->mangle);
  const char* name = stringtab(buf->m);
  printbuf_free(buf);
  return name;
}
示例#14
0
/**
 * Allocate a new empty connection.
 * Calls error() in case of any problems.
 */
static struct net_json *net_json_new(){
	struct net_json *connection;

	connection = checked_malloc(sizeof(*connection));

	errno = 0;
	connection->buf = printbuf_new();
	if(!connection->buf){
		error(errno, NULL);
	}
	
	errno = 0;
	connection->tok = json_tokener_new();
	if(!connection->tok){
		error(errno, NULL);
	}

	return connection;
}
示例#15
0
文件: reach.c 项目: Sendence/ponyc
static reach_type_t* add_tuple(reach_t* r, ast_t* type, pass_opt_t* opt)
{
  if(contains_dontcare(type))
    return NULL;

  reach_type_t* t = reach_type(r, type);

  if(t != NULL)
    return t;

  t = add_reach_type(r, type);
  t->underlying = TK_TUPLETYPE;
  t->type_id = r->next_type_id++;

  t->field_count = (uint32_t)ast_childcount(t->ast);
  t->fields = (reach_field_t*)calloc(t->field_count,
    sizeof(reach_field_t));

  printbuf_t* mangle = printbuf_new();
  printbuf(mangle, "%d", t->field_count);

  ast_t* child = ast_child(type);
  size_t index = 0;

  while(child != NULL)
  {
    t->fields[index].ast = ast_dup(child);
    t->fields[index].type = add_type(r, child, opt);
    printbuf(mangle, "%s", t->fields[index].type->mangle);
    index++;

    child = ast_sibling(child);
  }

  t->mangle = stringtab(mangle->m);
  printbuf_free(mangle);
  return t;
}
/*
 * Create a JSON object from already opened file descriptor.
 *
 * This function can be helpful, when you opened the file already,
 * e.g. when you have a temp file.
 * Note, that the fd must be readable at the actual position, i.e.
 * use lseek(fd, 0, SEEK_SET) before.
 */
struct json_object* json_object_from_fd(int fd)
{
  struct printbuf *pb;
  struct json_object *obj;
  char buf[JSON_FILE_BUF_SIZE];
  int ret;

  if(!(pb = printbuf_new())) {
    MC_ERROR("json_object_from_file: printbuf_new failed\n");
    return NULL;
  }
  while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
    printbuf_memappend(pb, buf, ret);
  }
  if(ret < 0) {
    MC_ERROR("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno));
    printbuf_free(pb);
    return NULL;
  }
  obj = json_tokener_parse(pb->buf);
  printbuf_free(pb);
  return obj;
}
示例#17
0
static void test_printbuf_memset_length()
{
	struct printbuf *pb;

	printf("%s: starting test\n", __func__);
	pb = printbuf_new();
	printbuf_memset(pb, -1, ' ', 0);
	printbuf_memset(pb, -1, ' ', 0);
	printbuf_memset(pb, -1, ' ', 0);
	printbuf_memset(pb, -1, ' ', 0);
	printbuf_memset(pb, -1, ' ', 0);
	printf("Buffer length: %d\n", printbuf_length(pb));
	printbuf_memset(pb, -1, ' ', 2);
	printbuf_memset(pb, -1, ' ', 4);
	printbuf_memset(pb, -1, ' ', 6);
	printf("Buffer length: %d\n", printbuf_length(pb));
	printbuf_memset(pb, -1, ' ', 6);
	printf("Buffer length: %d\n", printbuf_length(pb));
	printbuf_memset(pb, -1, ' ', 8);
	printbuf_memset(pb, -1, ' ', 10);
	printbuf_memset(pb, -1, ' ', 10);
	printbuf_memset(pb, -1, ' ', 10);
	printbuf_memset(pb, -1, ' ', 20);
	printf("Buffer length: %d\n", printbuf_length(pb));

	// No length change should occur
	printbuf_memset(pb, 0, 'x', 30);
	printf("Buffer length: %d\n", printbuf_length(pb));

	// This should extend it by one.
	printbuf_memset(pb, 0, 'x', printbuf_length(pb) + 1);
	printf("Buffer length: %d\n", printbuf_length(pb));

	printbuf_free(pb);
	printf("%s: end test\n", __func__);
}
示例#18
0
bool expr_lambda(pass_opt_t* opt, ast_t** astp)
{
  pony_assert(astp != NULL);
  ast_t* ast = *astp;
  pony_assert(ast != NULL);

  AST_GET_CHILDREN(ast, receiver_cap, name, t_params, params, captures,
    ret_type, raises, body, reference_cap);
  ast_t* annotation = ast_consumeannotation(ast);

  bool bare = ast_id(ast) == TK_BARELAMBDA;
  ast_t* members = ast_from(ast, TK_MEMBERS);
  ast_t* last_member = NULL;
  bool failed = false;

  if(bare)
    pony_assert(ast_id(captures) == TK_NONE);

  // Process captures
  for(ast_t* p = ast_child(captures); p != NULL; p = ast_sibling(p))
  {
    ast_t* field = NULL;
    bool ok = make_capture_field(opt, p, &field);

    if(field != NULL)
      ast_list_append(members, &last_member, field);
    else if(!ok)
      // An error occurred, just keep going to potentially find more errors
      failed = true;
  }

  if(failed)
  {
    ast_free(members);
    return false;
  }

  // Stop the various elements being marked as preserve
  ast_clearflag(t_params, AST_FLAG_PRESERVE);
  ast_clearflag(params, AST_FLAG_PRESERVE);
  ast_clearflag(ret_type, AST_FLAG_PRESERVE);
  ast_clearflag(body, AST_FLAG_PRESERVE);

  const char* fn_name = "apply";

  if(ast_id(name) == TK_ID)
    fn_name = ast_name(name);

  // Make the apply function
  BUILD(apply, ast,
    NODE(TK_FUN, AST_SCOPE
      ANNOTATE(annotation)
      TREE(receiver_cap)
      ID(fn_name)
      TREE(t_params)
      TREE(params)
      TREE(ret_type)
      TREE(raises)
      TREE(body)
      NONE    // Doc string
      NONE)); // Guard

  ast_list_append(members, &last_member, apply);
  ast_setflag(members, AST_FLAG_PRESERVE);

  printbuf_t* buf = printbuf_new();
  printbuf(buf, bare ? "@{(" : "{(");
  bool first = true;

  for(ast_t* p = ast_child(params); p != NULL; p = ast_sibling(p))
  {
    if(first)
      first = false;
    else
      printbuf(buf, ", ");

    printbuf(buf, "%s", ast_print_type(ast_childidx(p, 1)));
  }

  printbuf(buf, ")");

  if(ast_id(ret_type) != TK_NONE)
    printbuf(buf, ": %s", ast_print_type(ret_type));

  if(ast_id(raises) != TK_NONE)
    printbuf(buf, " ?");

  printbuf(buf, "}");

  // Replace lambda with object literal
  REPLACE(astp,
    NODE(TK_OBJECT, DATA(stringtab(buf->m))
      TREE(reference_cap)
      NONE  // Provides list
      TREE(members)));

  printbuf_free(buf);

  if(bare)
  {
    BUILD(bare_annotation, *astp,
      NODE(TK_ANNOTATION,
        ID("ponyint_bare")));

    // Record the syntax pass as done to avoid the error about internal
    // annotations.
    ast_pass_record(bare_annotation, PASS_SYNTAX);
    ast_setannotation(*astp, bare_annotation);
  }

  // Catch up passes
  if(ast_visit(astp, pass_syntax, NULL, opt, PASS_SYNTAX) != AST_OK)
    return false;

  return ast_passes_subtree(astp, opt, PASS_EXPR);
}
示例#19
0
文件: lambda.c 项目: Praetonus/ponyc
bool expr_lambda(pass_opt_t* opt, ast_t** astp)
{
  assert(astp != NULL);
  ast_t* ast = *astp;
  assert(ast != NULL);

  AST_GET_CHILDREN(ast, cap, name, t_params, params, captures, ret_type,
    raises, body);

  ast_t* members = ast_from(ast, TK_MEMBERS);
  ast_t* last_member = NULL;
  bool failed = false;

  // Process captures
  for(ast_t* p = ast_child(captures); p != NULL; p = ast_sibling(p))
  {
    ast_t* field = make_capture_field(opt, p);

    if(field != NULL)
      ast_list_append(members, &last_member, field);
    else  // An error occurred, just keep going to potentially find more errors
      failed = true;
  }

  if(failed)
  {
    ast_free(members);
    return false;
  }

  // Stop the various elements being marked as preserve
  ast_clearflag(t_params, AST_FLAG_PRESERVE);
  ast_clearflag(params, AST_FLAG_PRESERVE);
  ast_clearflag(ret_type, AST_FLAG_PRESERVE);
  ast_clearflag(body, AST_FLAG_PRESERVE);

  const char* fn_name = "apply";

  if(ast_id(name) == TK_ID)
    fn_name = ast_name(name);

  // Make the apply function
  BUILD(apply, ast,
    NODE(TK_FUN, AST_SCOPE
      TREE(cap)
      ID(fn_name)
      TREE(t_params)
      TREE(params)
      TREE(ret_type)
      TREE(raises)
      TREE(body)
      NONE    // Doc string
      NONE)); // Guard

  ast_list_append(members, &last_member, apply);

  printbuf_t* buf = printbuf_new();
  printbuf(buf, "lambda(");
  bool first = true;

  for(ast_t* p = ast_child(params); p != NULL; p = ast_sibling(p))
  {
    if(first)
      first = false;
    else
      printbuf(buf, ", ");

    printbuf(buf, "%s", ast_print_type(ast_childidx(p, 1)));
  }

  printbuf(buf, ")");

  if(ast_id(ret_type) != TK_NONE)
    printbuf(buf, ": %s", ast_print_type(ret_type));

  if(ast_id(raises) != TK_NONE)
    printbuf(buf, " ?");

  printbuf(buf, " end");

  // Replace lambda with object literal
  REPLACE(astp,
    NODE(TK_OBJECT, DATA(stringtab(buf->m))
      NONE
      NONE  // Provides list
      TREE(members)));

  printbuf_free(buf);

  // Catch up passes
  if(ast_visit(astp, pass_syntax, NULL, opt, PASS_SYNTAX) != AST_OK)
    return false;

  return ast_passes_subtree(astp, opt, PASS_EXPR);
}
示例#20
0
bool expr_lambda(pass_opt_t* opt, ast_t** astp)
{
  pony_assert(astp != NULL);
  ast_t* ast = *astp;
  pony_assert(ast != NULL);

  AST_GET_CHILDREN(ast, receiver_cap, name, t_params, params, captures,
    ret_type, raises, body, obj_cap);
  ast_t* annotation = ast_consumeannotation(ast);

  // Try to find an antecedent type, and find possible lambda interfaces in it.
  ast_t* antecedent_type = find_antecedent_type(opt, ast, NULL);
  astlist_t* possible_fun_defs = NULL;
  astlist_t* possible_obj_caps = NULL;
  if(!is_typecheck_error(antecedent_type))
    find_possible_fun_defs(opt, antecedent_type, &possible_fun_defs,
      &possible_obj_caps);

  // If there's more than one possible fun defs, rule out impossible ones by
  // comparing each fun def by some basic criteria against the lambda,
  // creating a new list containing only the remaining possibilities.
  if(astlist_length(possible_fun_defs) > 1)
  {
    astlist_t* new_fun_defs = NULL;
    astlist_t* new_obj_caps = NULL;

    astlist_t* fun_def_cursor = possible_fun_defs;
    astlist_t* obj_cap_cursor = possible_obj_caps;
    for(; (fun_def_cursor != NULL) && (obj_cap_cursor != NULL);
      fun_def_cursor = astlist_next(fun_def_cursor),
      obj_cap_cursor = astlist_next(obj_cap_cursor))
    {
      ast_t* fun_def = astlist_data(fun_def_cursor);
      ast_t* def_obj_cap = astlist_data(obj_cap_cursor);

      if(is_typecheck_error(fun_def))
        continue;

      AST_GET_CHILDREN(fun_def, def_receiver_cap, def_name, def_t_params,
        def_params, def_ret_type, def_raises);

      // Must have the same number of parameters.
      if(ast_childcount(params) != ast_childcount(def_params))
        continue;

      // Must have a supercap of the def's receiver cap (if present).
      if((ast_id(receiver_cap) != TK_NONE) && !is_cap_sub_cap(
        ast_id(def_receiver_cap), TK_NONE, ast_id(receiver_cap), TK_NONE)
        )
        continue;

      // Must have a supercap of the def's object cap (if present).
      if((ast_id(obj_cap) != TK_NONE) &&
        !is_cap_sub_cap(ast_id(obj_cap), TK_NONE, ast_id(def_obj_cap), TK_NONE))
        continue;

      // TODO: This logic could potentially be expanded to do deeper
      // compatibility checks, but checks involving subtyping here would be
      // difficult, because the lambda's AST is not caught up yet in the passes.

      new_fun_defs = astlist_push(new_fun_defs, fun_def);
      new_obj_caps = astlist_push(new_obj_caps, def_obj_cap);
    }

    astlist_free(possible_fun_defs);
    astlist_free(possible_obj_caps);
    possible_fun_defs = new_fun_defs;
    possible_obj_caps = new_obj_caps;
  }

  if(astlist_length(possible_fun_defs) == 1)
  {
    ast_t* fun_def = astlist_data(possible_fun_defs);
    ast_t* def_obj_cap = astlist_data(possible_obj_caps);

    // Try to complete the lambda's type info by inferring from the lambda type.
    if(!is_typecheck_error(fun_def))
    {
      // Infer the object cap, receiver cap, and return type if unspecified.
      if(ast_id(obj_cap) == TK_NONE)
        ast_replace(&obj_cap, def_obj_cap);
      if(ast_id(receiver_cap) == TK_NONE)
        ast_replace(&receiver_cap, ast_child(fun_def));
      if(ast_id(ret_type) == TK_NONE)
        ast_replace(&ret_type, ast_childidx(fun_def, 4));

      // Infer the type of any parameters that were left unspecified.
      ast_t* param = ast_child(params);
      ast_t* def_param = ast_child(ast_childidx(fun_def, 3));
      while((param != NULL) && (def_param != NULL))
      {
        ast_t* param_id = ast_child(param);
        ast_t* param_type = ast_sibling(param_id);

        // Convert a "_" parameter to whatever the expected parameter is.
        if(is_name_dontcare(ast_name(param_id)))
        {
          ast_replace(&param_id, ast_child(def_param));
          ast_replace(&param_type, ast_childidx(def_param, 1));
        }
        // Give a type-unspecified parameter the type of the expected parameter.
        else if(ast_id(param_type) == TK_NONE)
        {
          ast_replace(&param_type, ast_childidx(def_param, 1));
        }

        param = ast_sibling(param);
        def_param = ast_sibling(def_param);
      }
    }

    ast_free_unattached(fun_def);
  }

  astlist_free(possible_obj_caps);

  // If any parameters still have no type specified, it's an error.
  ast_t* param = ast_child(params);
  while(param != NULL)
  {
    if(ast_id(ast_childidx(param, 1)) == TK_NONE)
    {
      ast_error(opt->check.errors, param,
        "a lambda parameter must specify a type or be inferable from context");

      if(astlist_length(possible_fun_defs) > 1)
      {
        for(astlist_t* fun_def_cursor = possible_fun_defs;
          fun_def_cursor != NULL;
          fun_def_cursor = astlist_next(fun_def_cursor))
        {
          ast_error_continue(opt->check.errors, astlist_data(fun_def_cursor),
            "this lambda interface is inferred, but it's not the only one");
        }
      }

      astlist_free(possible_fun_defs);
      return false;
    }
    param = ast_sibling(param);
  }

  astlist_free(possible_fun_defs);

  bool bare = ast_id(ast) == TK_BARELAMBDA;
  ast_t* members = ast_from(ast, TK_MEMBERS);
  ast_t* last_member = NULL;
  bool failed = false;

  if(bare)
    pony_assert(ast_id(captures) == TK_NONE);

  // Process captures
  for(ast_t* p = ast_child(captures); p != NULL; p = ast_sibling(p))
  {
    ast_t* field = NULL;
    bool ok = make_capture_field(opt, p, &field);

    if(field != NULL)
      ast_list_append(members, &last_member, field);
    else if(!ok)
      // An error occurred, just keep going to potentially find more errors
      failed = true;
  }

  if(failed)
  {
    ast_free(members);
    return false;
  }

  // Stop the various elements being marked as preserve
  ast_clearflag(t_params, AST_FLAG_PRESERVE);
  ast_clearflag(params, AST_FLAG_PRESERVE);
  ast_clearflag(ret_type, AST_FLAG_PRESERVE);
  ast_clearflag(body, AST_FLAG_PRESERVE);

  const char* fn_name = "apply";

  if(ast_id(name) == TK_ID)
    fn_name = ast_name(name);

  // Make the apply function
  BUILD(apply, ast,
    NODE(TK_FUN, AST_SCOPE
      ANNOTATE(annotation)
      TREE(receiver_cap)
      ID(fn_name)
      TREE(t_params)
      TREE(params)
      TREE(ret_type)
      TREE(raises)
      TREE(body)
      NONE)); // Doc string

  ast_list_append(members, &last_member, apply);
  ast_setflag(members, AST_FLAG_PRESERVE);

  printbuf_t* buf = printbuf_new();
  printbuf(buf, bare ? "@{(" : "{(");
  bool first = true;

  for(ast_t* p = ast_child(params); p != NULL; p = ast_sibling(p))
  {
    if(first)
      first = false;
    else
      printbuf(buf, ", ");

    printbuf(buf, "%s", ast_print_type(ast_childidx(p, 1)));
  }

  printbuf(buf, ")");

  if(ast_id(ret_type) != TK_NONE)
    printbuf(buf, ": %s", ast_print_type(ret_type));

  if(ast_id(raises) != TK_NONE)
    printbuf(buf, " ?");

  printbuf(buf, "}");

  // Replace lambda with object literal
  REPLACE(astp,
    NODE(TK_OBJECT, DATA(stringtab(buf->m))
      TREE(obj_cap)
      NONE  // Provides list
      TREE(members)));

  printbuf_free(buf);

  if(bare)
  {
    BUILD(bare_annotation, *astp,
      NODE(TK_ANNOTATION,
        ID("ponyint_bare")));

    // Record the syntax pass as done to avoid the error about internal
    // annotations.
    ast_pass_record(bare_annotation, PASS_SYNTAX);
    ast_setannotation(*astp, bare_annotation);
  }

  // Catch up passes
  if(ast_visit(astp, pass_syntax, NULL, opt, PASS_SYNTAX) != AST_OK)
    return false;

  return ast_passes_subtree(astp, opt, PASS_EXPR);
}
示例#21
0
static void print_monitor_value0(rb_message *message,
				 const struct monitor_value *monitor_value,
				 const rb_monitor_t *monitor,
				 int instance) {
	assert(monitor_value->type == MONITOR_VALUE_T__VALUE);

	struct printbuf *buf = printbuf_new();
	if (likely(NULL != buf)) {
		const char *monitor_instance_prefix =
				rb_monitor_instance_prefix(monitor);
		const char *monitor_name_split_suffix =
				rb_monitor_name_split_suffix(monitor);
		const struct json_object *monitor_enrichment =
				rb_monitor_enrichment(monitor);
		// @TODO use printbuf_memappend_fast instead! */
		sprintbuf(buf, "{");
		sprintbuf(buf,
			  "\"timestamp\":%lu",
			  monitor_value->value.timestamp);
		if (NO_INSTANCE != instance && monitor_name_split_suffix) {
			sprintbuf(buf,
				  ",\"monitor\":\"%s%s\"",
				  rb_monitor_name(monitor),
				  monitor_name_split_suffix);
		} else {
			sprintbuf(buf,
				  ",\"monitor\":\"%s\"",
				  rb_monitor_name(monitor));
		}

		if (NO_INSTANCE != instance && monitor_instance_prefix) {
			sprintbuf(buf,
				  ",\"instance\":\"%s%d\"",
				  monitor_instance_prefix,
				  instance);
		}

		if (rb_monitor_is_integer(monitor)) {
			sprintbuf(buf,
				  ",\"value\":%" PRId64,
				  (int64_t)monitor_value->value.value);
		} else {
			sprintbuf(buf,
				  ",\"value\":\"%lf\"",
				  monitor_value->value.value);
		}

		if (rb_monitor_group_id(monitor)) {
			sprintbuf(buf,
				  ",\"group_id\":%s",
				  rb_monitor_group_id(monitor));
		}

		if (monitor_enrichment) {
			print_monitor_value_enrichment(buf, monitor_enrichment);
		}
		sprintbuf(buf, "}");

		message->payload = buf->buf;
		message->len = (size_t)buf->bpos;

		buf->buf = NULL;
		printbuf_free(buf);
	}
}
SharedPreferences* tg_shared_preferences_open(const CHAR* path,SharedPreferences_Open_Mode mode)
{

    struct json_object *obj;

    UINT32 ret;
    TG_FILE * fp = NULL;
    SharedPreferences* sp = NULL;
    BOOL new_file = FALSE;
    return_val_if_fail(path,NULL);
    if (mode == SharedPreferences_ReadWrite_Mode)  //if already lock, can not open it with write mode
    {
        if (tg_shared_preferences_is_locked(path))
            return NULL;
        if (!tg_shared_preferences_is_ready(path))
        {
            fp =tg_fopen(path, "w+");
            return_val_if_fail(fp,NULL);
            tg_fclose(fp);
            new_file = TRUE;
        }
    }
    if (!new_file)
    {
        struct printbuf *pb;
        CHAR* buf=NULL;
        fp =tg_fopen(path, "r");
        return_val_if_fail((fp),NULL);

        if (!(pb = printbuf_new()))
        {
            tg_fclose(fp);
            return NULL;
        }
        buf =TG_MALLOC(SHARED_PREFERENCE_FILE_BUF_SIZE);
        while ((ret = tg_fread(buf, SHARED_PREFERENCE_FILE_BUF_SIZE,1,fp)) > 0)
        {
            printbuf_memappend(pb, buf, ret);
        }
        TG_FREE(buf);
        tg_fclose(fp);

        obj = json_tokener_parse(pb->buf);
        printbuf_free(pb);
    }
    else
    {
        obj = json_object_new_object();
    }
    sp = TG_CALLOC_V2(sizeof(SharedPreferences));
    return_val_if_fail((sp),NULL);
    sp->obj=obj;
    sp->mode = mode;
    if (mode == SharedPreferences_ReadWrite_Mode)
    {
        sp->path = TG_CALLOC_V2(strlen(path)+1);
        strcpy(sp->path ,path);
        tg_shared_preferences_lock(path,TRUE);

    }
    return sp;
}