Пример #1
0
builder_t* builder_create(const char* description)
{
  if(description == NULL)
    return NULL;

  source_t* source = source_open_string(description);
  symtab_t* symtab = symtab_new();

  ast_t* ast = build_ast(source, symtab);

  if(ast == NULL)
  {
    // Error, tidy up
    source_close(source);
    symtab_free(symtab);
    return NULL;
  }

  // Success, create builder
  builder_t* builder = POOL_ALLOC(builder_t);

  builder->sources = NULL;
  builder->defs = symtab;
  builder->dummy_root = ast_blank(TK_TEST);

  ast_add(builder->dummy_root, ast);
  add_source(builder, source);

  return builder;
}
Пример #2
0
void check_block(SymTab *st, Block* b) {
  if(!b) return;
  SymTab *local_scope;
  local_scope = symtab_new(st);
  check_declrlist(local_scope, b->declrs);
  check_commlist(local_scope, b->comms);
  symtab_free(local_scope);
}
Пример #3
0
void ast_clear_local(ast_t* ast)
{
  if(ast->symtab != NULL)
  {
    symtab_free(ast->symtab);
    ast_scope(ast);
  }
}
Пример #4
0
void
cook_reset(void)
{
    leaf_reset();
    string_list_destructor(&cook_auto_list);
    /* Don't nuke cook_auto_list_nonleaf, we need it for later */
    cook_implicit_nth_by_name(0, 0);
    if (explicit_stp)
    {
        symtab_free(explicit_stp);
        explicit_stp = 0;
    }
    if (implicit_stp)
    {
        symtab_free(implicit_stp);
        implicit_stp = 0;
    }
    recipe_list_destructor(&explicit);
    recipe_list_destructor(&implicit);
    cascade_reset();
}
Пример #5
0
static void compile(const char *pgm, int framework)
{
	struct patch *patch;

	patch = patch_do_compile("/", pgm, report, framework);
	if (!patch) {
		symtab_free();
		exit(1);
	}
	if (!quiet)
		show_patch(patch);
	if (trace_var)
		play_midi(patch);
	symtab_free();
	stim_put(patch->stim);
	/*
	 * We can't use patch_free here because that function also accesses
	 * image data, which isn't available in standalone builds. A simple
	 * free(3) has the same effect in this case.
	 */
	free(patch);
}
Пример #6
0
void ast_clear(ast_t* ast)
{
  if(ast->symtab != NULL)
  {
    symtab_free(ast->symtab);
    ast_scope(ast);
  }

  ast_t* child = ast->child;

  while(child != NULL)
  {
    ast_clear(child);
    child = child->sibling;
  }
}
Пример #7
0
Файл: sem.c Проект: aji/nursery
static struct s_fn_decl *s_fn_decl(struct p_fn_decl *p)
{
	struct s_fn_decl *s;
	struct symtab *tab;

	tab = symtab_new(NULL);

	s = malloc(sizeof(*s));
	s->name = p->name;
	s_arg_list(tab, s->name, p->args);
	s->body = s_expr(tab, p->body);

	symtab_free(tab);

	return s;
}
Пример #8
0
void check_declr(SymTab *st, Declr* d) {
  switch(d->tag) {
    case DECLR_VAR:
      {
        if(st->prev)
	  check_array_sizes(d->type);
        else
          check_array_empty(d->type);
	if(!symtab_add(st, d))
	  print_error("double declaration of variable", d->line);
	break;
      }
    case DECLR_FUNC:
      {
	check_array_empty(d->type);
	if(d->u.func.block) {
	  Declr *proto;
	  SymTab *param;
	  
	  proto = symtab_find(st, d->u.func.name);
	  if(!proto) {
	    symtab_add(st, d);
	    proto = d;
	  } else if(proto->u.func.block) {
	    print_error("double declaration of function", d->line);
	  } else {
	    proto->u.func.block = d->u.func.block;
	  }
	  return_type = d->type;
	  param = symtab_new(st);
	  check_paramlist(param, proto->u.func.params, d->line);
	  check_block(param, proto->u.func.block);
	  symtab_free(param);
	}
	else {
	  if(!symtab_add(st, d))
	    print_error("double declaration of function prototype", d->line);
	}
	break;
      }
    default: print_error("bug in compiler!", 0);
  }
}
Пример #9
0
void builder_free(builder_t* builder)
{
  if(builder == NULL)
    return;

  ast_free(builder->dummy_root);
  symtab_free(builder->defs);

  builder_src_t* p = builder->sources;

  while(p != NULL)
  {
    builder_src_t* next = p->next;
    source_close(p->source);
    POOL_FREE(builder_src_t, p);
    p = next;
  }

  POOL_FREE(builder_t, builder);
}
Пример #10
0
void ast_free(ast_t* ast)
{
  if(ast == NULL)
    return;

  ast_t* child = ast->child;
  ast_t* next;

  while(child != NULL)
  {
    next = child->sibling;
    ast_free(child);
    child = next;
  }

  ast_free(ast->type);

  switch(token_get_id(ast->t))
  {
    case TK_PROGRAM:
      program_free((program_t*)ast->data);
      break;

    case TK_PACKAGE:
      package_free((package_t*)ast->data);
      break;

    case TK_MODULE:
      source_close((source_t*)ast->data);
      break;

    default:
      break;
  }

  token_free(ast->t);
  symtab_free(ast->symtab);
  POOL_FREE(ast_t, ast);
}
Пример #11
0
// Add methods from provided traits into the given entity
static bool build_entity_def(ast_t* entity)
{
  assert(entity != NULL);

  ast_state_t state = (ast_state_t)(uint64_t)ast_data(entity);

  // Check for recursive definitions
  switch(state)
  {
    case AST_STATE_INITIAL:
      ast_setdata(entity, (void*)AST_STATE_INPROGRESS);
      break;

    case AST_STATE_INPROGRESS:
      ast_error(entity, "traits can't be recursive");
      return false;

    case AST_STATE_DONE:
      return true;

    default:
      assert(0);
      return false;
  }

  symtab_t* symtab = symtab_new();
  ast_t* name_lists = ast_blank(TK_MEMBERS);
  methods_t method_info = { symtab, name_lists, NULL };

  bool r = process_provides(entity, &method_info);

  symtab_free(symtab);
  ast_free(name_lists);

  ast_setdata(entity, (void*)AST_STATE_DONE);
  return r;
}
Пример #12
0
static void compile_vm(const char *pgm)
{
	struct fpvm_fragment fragment;
	struct parser_comm comm = {
		.u.fragment = &fragment,
		.assign_default = assign_raw,
		.assign_per_frame = assign_raw,
		.assign_per_vertex = assign_raw_fail,
		.assign_image_name = assign_image_fail,
	};
	int ok;

	init_fpvm(&fragment, 0);
	fpvm_set_bind_mode(&fragment, FPVM_BIND_ALL);
	symtab_init();
	ok = parse(pgm, TOK_START_ASSIGN, &comm);

	if (ok)
		fpvm_dump(&fragment);
	symtab_free();
	if (ok)
		return;

	fflush(stdout);
	fprintf(stderr, "%s\n", comm.msg);
	free((void *) comm.msg);
	exit(1);
}


/* ----- Command-line processing ------------------------------------------- */


static void free_buffer(void)
{
	free((void *) buffer);
}
Пример #13
0
void check_prog(DeclrListNode *ast) {
  SymTab *global;
  global = symtab_new(NULL);
  check_declrlist(global, ast);
  symtab_free(global);
}
Пример #14
0
static void parse_only(const char *pgm)
{
	static struct patch patch;
	static struct compiler_sc sc = {
		.p = &patch,
	};
	struct parser_comm comm = {
		.u.sc = &sc,
		.assign_default = assign_default,
		.assign_per_frame = assign_per_frame,
		.assign_per_vertex = assign_per_vertex,
		.assign_image_name = assign_image_name,
	};
	int ok;

	symtab_init();
	ok = parse(pgm, TOK_START_ASSIGN, &comm);
	if (symbols) {
		const struct sym *sym;
		int user = 0;

		foreach_sym(sym) {
			if (!user && !(sym->flags & SF_SYSTEM)) {
				printf("\n");
				user = 1;
			}
			if (sym->flags & SF_CONST)
				printf("%s = %g\n", sym->fpvm_sym.name, sym->f);
			else
				printf("%s\n", sym->fpvm_sym.name);
		}
	}
	symtab_free();
	stim_db_free(); /* @@@ */
	stim_put(patch.stim);
	if (ok)
		return;
	fflush(stdout);
	fprintf(stderr, "%s\n", comm.msg);
	free((void *) comm.msg);
	exit(1);
}


/* ----- Compile the patch into PFPU code ---------------------------------- */


/*
 * "sym" and "field" are used to access a field chosen by the caller in the
 * "struct sym". For this, the caller provides a buffer (sym) and a pointer to
 * the respective field inside the buffer. This way, it's perfectly type-safe
 * and we don't need offsetof acrobatics.
 */

static const char *lookup_name(int idx, struct sym *sym, const int *field)
{
	const struct sym *walk;

	foreach_sym(walk) {
		*sym = *walk;
		if (*field == idx)
			return walk->fpvm_sym.name;
	}
	return NULL;
}


static void dump_regs(const int *alloc, struct sym *sym, const int *field,
    const float *values, int n)
{
	const char *mapped[n];
	int i;

	for (i = 0; i != n; i++)
		mapped[i] = NULL;
	for (i = 0; i != n; i++)
		if (alloc[i] != -1)
			mapped[alloc[i]] = lookup_name(i, sym, field);
	for (i = 0; i != n; i++) {
		if (!values[i] && !mapped[i])
			continue;
		printf("R%03d = %f", i, values[i]);
		if (mapped[i])
			printf(" %s", mapped[i]);
		printf("\n");
	}
}


static void show_patch(const struct patch *patch)
{
	int i;
	struct sym sym;

	printf("global:\n");
	for (i = 0; i != COMP_PFV_COUNT; i++)
		if (patch->pfv_initial[i])
			printf("R%03d = %f %s\n", i, patch->pfv_initial[i],
			    lookup_name(i, &sym, &sym.pfv_idx));
	printf("per-frame PFPU fragment:\n");
	dump_regs(patch->pfv_allocation, &sym, &sym.pfv_idx,
	    patch->perframe_regs, COMP_PFV_COUNT);
	pfpu_dump(patch->perframe_prog, patch->perframe_prog_length);
	printf("per-vertex PFPU fragment:\n");
	dump_regs(patch->pvv_allocation, &sym, &sym.pvv_idx,
	     patch->pervertex_regs, COMP_PVV_COUNT);
	pfpu_dump(patch->pervertex_prog, patch->pervertex_prog_length);
}
Пример #15
0
void VG_(redir_notify_delete_SegInfo)( SegInfo* delsi )
{
   TopSpec* ts;
   TopSpec* tsPrev;
   Spec*    sp;
   Spec*    sp_next;
   OSet*    tmpSet;
   Active*  act;
   Bool     delMe;
   Addr*    addrP;

   vg_assert(delsi);

   /* Search for it, and make tsPrev point to the previous entry, if
      any. */
   tsPrev = NULL;
   ts     = topSpecs;
   while (True) {
     if (ts == NULL) break;
     if (ts->seginfo == delsi) break;
     tsPrev = ts;
     ts = ts->next;
   }

   vg_assert(ts); /* else we don't have the deleted SegInfo */
   vg_assert(ts->seginfo == delsi);

   /* Traverse the actives, copying the addresses of those we intend
      to delete into tmpSet. */
   tmpSet = VG_(OSet_Create)( 0/*keyOff*/, NULL/*fastCmp*/,
                              symtab_alloc, symtab_free);

   ts->mark = True;

   VG_(OSet_ResetIter)( activeSet );
   while ( (act = VG_(OSet_Next)(activeSet)) ) {
      delMe = act->parent_spec != NULL
              && act->parent_sym != NULL
              && act->parent_spec->seginfo != NULL
              && act->parent_sym->seginfo != NULL
              && (act->parent_spec->mark || act->parent_sym->mark);

      /* While we're at it, a bit of paranoia: delete any actives
         which don't have both feet in valid client executable areas.
         But don't delete hardwired-at-startup ones; these are denoted
         by having parent_spec or parent_sym being NULL.  */
      if ( (!delMe)
           && act->parent_spec != NULL
           && act->parent_sym  != NULL ) {
         if (!is_plausible_guest_addr(act->from_addr))
            delMe = True;
         if (!is_plausible_guest_addr(act->to_addr))
            delMe = True;
      }

      if (delMe) {
         addrP = VG_(OSet_AllocNode)( tmpSet, sizeof(Addr) );
         *addrP = act->from_addr;
         VG_(OSet_Insert)( tmpSet, addrP );
         /* While we have our hands on both the 'from' and 'to'
            of this Active, do paranoid stuff with tt/tc. */
         VG_(discard_translations)( (Addr64)act->from_addr, 1,
                                    "redir_del_SegInfo(from_addr)");
         VG_(discard_translations)( (Addr64)act->to_addr, 1,
                                    "redir_del_SegInfo(to_addr)");
      }
   }

   /* Now traverse tmpSet, deleting corresponding elements in
      activeSet. */
   VG_(OSet_ResetIter)( tmpSet );
   while ( (addrP = VG_(OSet_Next)(tmpSet)) ) {
      act = VG_(OSet_Remove)( activeSet, addrP );
      vg_assert(act);
      VG_(OSet_FreeNode)( activeSet, act );
   }

   VG_(OSet_Destroy)( tmpSet, NULL );

   /* The Actives set is now cleaned up.  Free up this TopSpec and
      everything hanging off it. */
   for (sp = ts->specs; sp; sp = sp_next) {
      if (sp->from_sopatt) symtab_free(sp->from_sopatt);
      if (sp->from_fnpatt) symtab_free(sp->from_fnpatt);
      sp_next = sp->next;
      symtab_free(sp);
   }

   if (tsPrev == NULL) {
      /* first in list */
      topSpecs = ts->next;
   } else {
      tsPrev->next = ts->next;
   }
   symtab_free(ts);

   if (VG_(clo_trace_redir))
      show_redir_state("after VG_(redir_notify_delete_SegInfo)");
}