示例#1
0
文件: map.c 项目: creswick/GF
void*
gu_map_insert(GuMap* map, const void* key)
{
	size_t idx;
	bool found = gu_map_lookup(map, key, &idx);
	if (!found) {
		if (gu_map_maybe_resize(map)) {
			found = gu_map_lookup(map, key, &idx);
			gu_assert(!found);
		}
		if (map->kind == GU_MAP_ADDR) {
			((const void**)map->data.keys)[idx] = key;
		} else if (map->kind == GU_MAP_STRING) {
			((GuString*)map->data.keys)[idx] = key;
		} else {
			memcpy(&map->data.keys[idx * map->key_size],
			       key, map->key_size);
		}
		if (map->default_value) {
			memcpy(&map->data.values[idx * map->value_size],
			       map->default_value, map->value_size);
		}
		if (gu_map_entry_is_free(map, &map->data, idx)) {
			gu_assert(map->data.zero_idx == SIZE_MAX);
			map->data.zero_idx = idx;
		}
		map->data.n_occupied++;
	}
	return &map->data.values[idx * map->value_size];
}
示例#2
0
文件: choice.c 项目: McMbuvi/GF
GuChoiceMark
gu_choice_mark(GuChoice* ch)
{
	gu_assert(ch->path_idx <= gu_buf_length(ch->path));
	gu_debug("%p@%d: mark", ch, ch->path_idx);
	return (GuChoiceMark){ch->path_idx};
}
示例#3
0
文件: out.c 项目: Deseaus/GF
static bool
gu_out_begin_buf(GuOut* out, size_t req, GuExn* err)
{
	GuOutStream* stream = out->stream;
	if (gu_out_is_buffering(out)) {
		if (out->buf_curr < 0) {
			return true;
		} else {
			gu_out_end_buf(out, err);
			if (!gu_ok(err)) {
				return false;
			}
		}
	}
	if (stream->begin_buf) {
		size_t sz = 0;
		uint8_t* buf = stream->begin_buf(stream, req, &sz, err);
		gu_assert(sz <= PTRDIFF_MAX);
		if (buf) {
			out->buf_end = &buf[sz];
			out->buf_curr = -(ptrdiff_t) sz;
			out->buf_size = sz;
			return true;
		}
	}
	return false;
}
示例#4
0
文件: out.c 项目: McMbuvi/GF
GuOut
gu_init_out(GuOutStream* stream)
{
	gu_require(stream != NULL);
	GuOut out = {
		.buf_end = NULL,
		.buf_curr = 0,
		.stream = stream,
		.fini.fn = NULL
	};
	return out;
}

static bool
gu_out_is_buffering(GuOut* out)
{
	return !!out->buf_end;
}


static void
gu_out_end_buf(GuOut* out, GuExn* err)
{
	if (!gu_out_is_buffering(out)) {
		return;
	}
	GuOutStream* stream = out->stream;
	size_t curr_len = ((ptrdiff_t)out->buf_size) + out->buf_curr;
	stream->end_buf(stream, curr_len, err);
	out->buf_end = NULL;
	out->buf_size = out->buf_curr = 0;
}

static bool
gu_out_begin_buf(GuOut* out, size_t req, GuExn* err)
{
	GuOutStream* stream = out->stream;
	if (gu_out_is_buffering(out)) {
		if (out->buf_curr < 0) {
			return true;
		} else {
			gu_out_end_buf(out, err);
			if (!gu_ok(err)) {
				return false;
			}
		}
	}
	if (stream->begin_buf) {
		size_t sz = 0;
		uint8_t* buf = stream->begin_buf(stream, req, &sz, err);
		gu_assert(sz <= PTRDIFF_MAX);
		if (buf) {
			out->buf_end = &buf[sz];
			out->buf_curr = -(ptrdiff_t) sz;
			out->buf_size = sz;
			return true;
		}
	}
	return false;
}
示例#5
0
文件: choice.c 项目: McMbuvi/GF
void
gu_choice_reset(GuChoice* ch, GuChoiceMark mark)
{
	gu_assert(ch->path_idx <= gu_buf_length(ch->path));
	gu_debug("%p@%d: reset %d", ch, ch->path_idx, mark.path_idx);
	gu_require(mark.path_idx <= ch->path_idx );
	ch->path_idx = mark.path_idx;
}
示例#6
0
文件: choice.c 项目: McMbuvi/GF
int
gu_choice_next(GuChoice* ch, int n_choices)
{
	gu_assert(n_choices >= 0);
	gu_assert(ch->path_idx <= gu_buf_length(ch->path));
	if (n_choices == 0) {
		return -1;
	}
	int i = 0;
	if (gu_buf_length(ch->path) > ch->path_idx) {
		i = (int) gu_buf_get(ch->path, size_t, ch->path_idx);
		gu_assert(i <= n_choices);
	} else {
		gu_buf_push(ch->path, size_t, n_choices);
		i = n_choices;
	}
	int ret = (i == 0) ? -1 : n_choices - i;
	gu_debug("%p@%d: %d", ch, ch->path_idx, ret);
	ch->path_idx++;
	return ret;
}
示例#7
0
文件: expr.c 项目: jutta526/GF
PgfApplication*
pgf_expr_unapply(PgfExpr expr, GuPool* pool)
{
	int arity = pgf_expr_arity(expr);
	if (arity < 0) {
		return NULL;
	}
	PgfApplication* appl = gu_new_flex(pool, PgfApplication, args, arity);
	appl->n_args = arity;
	for (int n = arity - 1; n >= 0; n--) {
		PgfExpr e = pgf_expr_unwrap(expr);
		gu_assert(gu_variant_tag(e) == PGF_EXPR_APP);
		PgfExprApp* app = gu_variant_data(e);
		appl->args[n] = app->arg;
		expr = app->fun;
	}
	PgfExpr e = pgf_expr_unwrap(expr);
	gu_assert(gu_variant_tag(e) == PGF_EXPR_FUN);
	PgfExprFun* fun = gu_variant_data(e);
	appl->fun = fun->fun;
	return appl;
}
示例#8
0
文件: choice.c 项目: McMbuvi/GF
bool
gu_choice_advance(GuChoice* ch)
{
	gu_assert(ch->path_idx <= gu_buf_length(ch->path));
	
	while (gu_buf_length(ch->path) > ch->path_idx) {
		size_t last = gu_buf_pop(ch->path, size_t);
		if (last > 1) {
			gu_buf_push(ch->path, size_t, last-1);
			return true;
		}
	}
	return false;
}
示例#9
0
文件: map.c 项目: McMbuvi/GF
static bool
gu_map_entry_is_free(GuMap* map, GuMapData* data, size_t idx)
{
	if (idx == data->zero_idx) {
		return false;
	} else if (map->kind == GU_MAP_ADDR) {
		const void* key = ((const void**)data->keys)[idx];
		return key == NULL;
	} else if (map->kind == GU_MAP_WORD) {
		GuWord key = ((GuWord*)data->keys)[idx];
		return key == 0;
	}
	gu_assert(map->kind == GU_MAP_GENERIC);
	const void* key = &data->keys[idx * map->key_size];
	return gu_map_buf_is_zero(key, map->key_size);
}
示例#10
0
文件: map.c 项目: creswick/GF
static void
gu_map_resize(GuMap* map)
{
	GuMapData* data = &map->data;
	GuMapData old_data = *data;
	size_t req_entries =
		gu_twin_prime_sup(GU_MAX(11, map->data.n_occupied * 4 / 3 + 1));

	size_t key_size = map->key_size;
	size_t key_alloc = 0;
	data->keys = gu_mem_buf_alloc(req_entries * key_size, &key_alloc);

	size_t value_size = map->value_size;
	size_t value_alloc = 0;
	if (value_size) {
		data->values = gu_mem_buf_alloc(req_entries * value_size,
						    &value_alloc);
		memset(data->values, 0, value_alloc);
	}
	
	data->n_entries = gu_twin_prime_inf(value_size ?
					    GU_MIN(key_alloc / key_size,
						   value_alloc / value_size)
					    : key_alloc / key_size);
	switch (map->kind) {
	case GU_MAP_GENERIC:
	case GU_MAP_WORD:
		memset(data->keys, 0, key_alloc);
		break;
	case GU_MAP_ADDR:
		for (size_t i = 0; i < data->n_entries; i++) {
			((const void**)data->keys)[i] = NULL;
		}
		break;
	case GU_MAP_STRING:
		for (size_t i = 0; i < data->n_entries; i++) {
			((GuString*)data->keys)[i] = NULL;
		}
		break;
	default:
		gu_impossible();
	}

	gu_assert(data->n_entries > data->n_occupied);
	
	data->n_occupied = 0;
	data->zero_idx = SIZE_MAX;

	for (size_t i = 0; i < old_data.n_entries; i++) {
		if (gu_map_entry_is_free(map, &old_data, i)) {
			continue;
		}
		void* old_key = &old_data.keys[i * key_size];
		if (map->kind == GU_MAP_ADDR) {
			old_key = *(void**)old_key;
		} else if (map->kind == GU_MAP_STRING) {
			old_key = (void*) *(GuString*)old_key;
		}
		void* old_value = &old_data.values[i * value_size];

		memcpy(gu_map_insert(map, old_key),
		       old_value, map->value_size);
	}

	gu_mem_buf_free(old_data.keys);
	if (value_size) {
		gu_mem_buf_free(old_data.values);
	}
}
示例#11
0
文件: evaluator.c 项目: Deseaus/GF
PgfClosure*
pgf_evaluate_expr_thunk(PgfReasoner* rs, PgfExprThunk* thunk)
{
	PgfEnv* env  = thunk->env;
	PgfExpr expr = thunk->expr;

	size_t n_args = 0;
	PgfClosure** args = NULL;
	PgfClosure* res = NULL;

repeat:;
	GuVariantInfo ei = gu_variant_open(expr);
	switch (ei.tag) {
	case PGF_EXPR_ABS: {
		PgfExprAbs* eabs = ei.data;

		if (n_args > 0) {
			PgfEnv* new_env  = gu_new(PgfEnv, rs->pool);
			new_env->next    = env;
			new_env->closure = args[--n_args];

			env  = new_env;
			expr = eabs->body;
			goto repeat;
		} else {
			thunk->header.code = rs->eval_gates->evaluate_value_lambda;
			thunk->expr = eabs->body;
			res = &thunk->header;
		}
		break;
	}
	case PGF_EXPR_APP: {
		PgfExprApp* eapp = ei.data;
		PgfExprThunk* thunk = 
			gu_new(PgfExprThunk, rs->pool);
		thunk->header.code = rs->eval_gates->evaluate_expr_thunk;
		thunk->env  = env;
		thunk->expr = eapp->arg;
		
		if (n_args % PGF_ARGS_DELTA == 0) {
			args = realloc(args, n_args + PGF_ARGS_DELTA);
		}
		args[n_args++] = &thunk->header;

		expr = eapp->fun;
		goto repeat;
	}
	case PGF_EXPR_LIT: {
		PgfExprLit* elit = ei.data;
		PgfValueLit* val = (PgfValueLit*) thunk;
		val->header.code = rs->eval_gates->evaluate_value_lit;
		val->lit = elit->lit;
		res = &val->header;
		break;
	}
	case PGF_EXPR_META: {
		PgfExprMeta* emeta = ei.data;

		PgfValueMeta* val =
			gu_new(PgfValueMeta, rs->pool);
		val->header.code = rs->eval_gates->evaluate_meta;
		val->env = env;
		val->id  = emeta->id;
		res = pgf_mk_pap(rs, &val->header, n_args, args);
		break;
	}
	case PGF_EXPR_FUN: {
		PgfExprFun* efun = ei.data;

		PgfAbsFun* absfun =
			gu_seq_binsearch(rs->abstract->funs, pgf_absfun_order, PgfAbsFun, efun->fun);
		gu_assert(absfun != NULL);

		if (absfun->closure.code != NULL) {
			res = pgf_mk_pap(rs, (PgfClosure*) &absfun->closure, n_args, args);
		} else {
			size_t arity = absfun->arity;

			if (n_args == arity) {
				PgfValue* val = gu_new_flex(rs->pool, PgfValue, args, arity);
				val->header.code = rs->eval_gates->evaluate_value;
				val->con = (PgfClosure*) &absfun->closure;

				for (size_t i = 0; i < arity; i++) {
					val->args[i] = args[--n_args];
				}
				res = &val->header;
			} else {
				gu_assert(n_args < arity);

				PgfExprThunk* lambda = gu_new(PgfExprThunk, rs->pool);
				lambda->header.code = rs->eval_gates->evaluate_value_lambda;
				lambda->env = NULL;
				res = pgf_mk_pap(rs, &lambda->header, n_args, args);

				for (size_t i = 0; i < arity; i++) {
					PgfExpr new_expr, arg;

					PgfExprVar *evar =
						gu_new_variant(PGF_EXPR_VAR,
									   PgfExprVar,
									   &arg, rs->pool);
					evar->var = arity-i-1;

					PgfExprApp *eapp =
						gu_new_variant(PGF_EXPR_APP,
									   PgfExprApp,
									   &new_expr, rs->pool);
					eapp->fun = expr;
					eapp->arg = arg;
					
					expr = new_expr;
				}
				
				for (size_t i = 0; i < arity-1; i++) {
					PgfExpr new_expr;

					PgfExprAbs *eabs =
						gu_new_variant(PGF_EXPR_ABS,
									   PgfExprAbs,
									   &new_expr, rs->pool);
					eabs->bind_type = PGF_BIND_TYPE_EXPLICIT;
					eabs->id = "_";
					eabs->body = expr;

					expr = new_expr;
				}
				
				lambda->expr = expr;
			}
		}
		break;
	}
	case PGF_EXPR_VAR: {
		PgfExprVar* evar = ei.data;
		PgfEnv* tmp_env = env;
		size_t i = evar->var;
		while (i > 0) {
			tmp_env = tmp_env->next;
			if (tmp_env == NULL) {
				GuExnData* err_data = gu_raise(rs->err, PgfExn);
				if (err_data) {
					err_data->data = "invalid de Bruijn index";
				}
				return NULL;
			}
			i--;
		}

		res = pgf_mk_pap(rs, tmp_env->closure, n_args, args);
		break;
	}
	case PGF_EXPR_TYPED: {
		PgfExprTyped* etyped = ei.data;
		expr = etyped->expr;
		goto repeat;
	}
	case PGF_EXPR_IMPL_ARG: {
		PgfExprImplArg* eimpl = ei.data;
		expr = eimpl->expr;
		goto repeat;
	}
	default:
		gu_impossible();
	}

	free(args);
	return res;
}