예제 #1
0
파일: printer.c 프로젝트: McMbuvi/GF
static void
pgf_print_productions(GuMapItor* fn, const void* key, void* value,
			GuExn* err)
{
	PgfPrintFn* clo = (PgfPrintFn*) fn;
    int fid = *((int *) key);
    PgfCCat* ccat = *((PgfCCat**) value);
    GuWriter *wtr = clo->wtr;

	if (!gu_seq_is_null(ccat->prods)) {
		size_t n_prods = gu_seq_length(ccat->prods);
		for (size_t i = 0; i < n_prods; i++) {
			PgfProduction prod = gu_seq_get(ccat->prods, PgfProduction, i);
		
			gu_printf(wtr,err,"    C%d -> ",fid);

			GuVariantInfo i = gu_variant_open(prod);
			switch (i.tag) {
			case PGF_PRODUCTION_APPLY: {
				PgfProductionApply* papp = i.data;
				gu_printf(wtr,err,"F%d[",papp->fun->funid);
				size_t n_args = gu_seq_length(papp->args);
				for (size_t j = 0; j < n_args; j++) {
					if (j > 0)
						gu_putc(',',wtr,err);
                    
					PgfPArg arg = gu_seq_get(papp->args, PgfPArg, j);

					if (arg.hypos != NULL) {
						size_t n_hypos = gu_list_length(arg.hypos);
						for (size_t k = 0; k < n_hypos; k++) {
							if (k > 0)
								gu_putc(' ',wtr,err);
							PgfCCat *hypo = gu_list_index(arg.hypos, k);
							gu_printf(wtr,err,"C%d",hypo->fid);
						}
					}
            
					gu_printf(wtr,err,"C%d",arg.ccat->fid);
				}
				gu_printf(wtr,err,"]\n");
				break;
			}
			case PGF_PRODUCTION_COERCE: {
				PgfProductionCoerce* pcoerce = i.data;
				gu_printf(wtr,err,"_[C%d]\n",pcoerce->coerce->fid);
				break;
			}
			default:
				gu_impossible();
			}
		}
	}
}
예제 #2
0
파일: printer.c 프로젝트: McMbuvi/GF
void
pgf_print_symbol(PgfSymbol sym, GuWriter *wtr, GuExn *err)
{
	switch (gu_variant_tag(sym)) {
	case PGF_SYMBOL_CAT: {
		PgfSymbolCat* scat = gu_variant_data(sym);
		gu_printf(wtr, err, "<%d,%d>", scat->d, scat->r);
		break;
	}
	case PGF_SYMBOL_KS: {
		PgfSymbolKS* sks = gu_variant_data(sym);
		pgf_print_tokens(sks->tokens, wtr, err);
		break;
	}
	case PGF_SYMBOL_KP: {
		PgfSymbolKP* skp = gu_variant_data(sym);

		gu_puts("pre {", wtr, err);
		pgf_print_tokens(skp->default_form, wtr, err);
		
		for (size_t i = 0; i < skp->n_forms; i++) {
			gu_puts("; ", wtr, err);
            pgf_print_tokens(skp->forms[i].form, wtr, err);
            gu_puts(" / ", wtr, err);
            
            size_t n_prefixes = gu_list_length(skp->forms[i].prefixes);
            for (size_t j = 0; j < n_prefixes; j++) {
				if (j > 0) gu_putc(' ', wtr, err);
				
				GuString prefix = gu_list_index(skp->forms[i].prefixes, j);
				gu_putc('"', wtr, err);
				gu_string_write(prefix, wtr, err);
				gu_putc('"', wtr, err);
			}
		}
		
		gu_puts("}", wtr, err);
		break;
	}
	case PGF_SYMBOL_LIT: {
		PgfSymbolLit *slit = gu_variant_data(sym);
		gu_printf(wtr, err, "{%d,%d}", slit->d, slit->r);
		break;
	}
	case PGF_SYMBOL_VAR: {
		PgfSymbolVar *svar = gu_variant_data(sym);
		gu_printf(wtr, err, "<%d,$%d>", svar->d, svar->r);
		break;
	}
	default:
		gu_impossible();
	}
}
예제 #3
0
파일: parseval.c 프로젝트: lkhatiwada100/GF
static void
pgf_metrics_lzn_expr_literal(PgfLinFuncs** funcs, PgfLiteral lit)
{
	PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);

	GuVariantInfo i = gu_variant_open(lit);
    switch (i.tag) {
    case PGF_LITERAL_STR: {
        PgfLiteralStr* lstr = i.data;
        if (state->ps != NULL) {
			state->ps = pgf_parser_next_state(state->ps, lstr->val, state->pool);
		}
		state->pos++;
		break;
	}
    case PGF_LITERAL_INT: {
        PgfLiteralInt* lint = i.data;
        if (state->ps != NULL) {
			GuString tok =
				gu_format_string(state->pool, "%d", lint->val);

			state->ps = pgf_parser_next_state(state->ps, tok, state->pool);
		}
		state->pos++;
		break;
	}
    case PGF_LITERAL_FLT: {
        PgfLiteralFlt* lflt = i.data;
        if (state->ps != NULL) {
			GuString tok =
				gu_format_string(state->pool, "%f", lflt->val);

			state->ps = pgf_parser_next_state(state->ps, tok, state->pool);
		}
		state->pos++;
		break;
	}
	default:
		gu_impossible();
	}
}
예제 #4
0
파일: map.c 프로젝트: creswick/GF
static bool
gu_map_lookup(GuMap* map, const void* key, size_t* idx_out)
{
	size_t n = map->data.n_entries;
	switch (map->kind) {
	case GU_MAP_GENERIC: {
		GuHasher* hasher = map->hasher;
		GuEquality* eq = (GuEquality*) hasher;
		GuHash hash = hasher->hash(hasher, key);
		size_t idx = hash % n;
		size_t offset = (hash % (n - 2)) + 1;
		size_t key_size = map->key_size;
		while (true) {
			void* entry_key = &map->data.keys[idx * key_size];
			if (gu_map_buf_is_zero(entry_key, key_size) &&
			    map->data.zero_idx != idx) {
				*idx_out = idx;
				return false;
			} else if (eq->is_equal(eq, key, entry_key)) {
				*idx_out = idx;
				return true;
			}
			idx = (idx + offset) % n;
		}
		gu_impossible();
		break;
	}
	case GU_MAP_ADDR: {
		GuHash hash = (GuHash) key;
		size_t idx = hash % n;
		size_t offset = (hash % (n - 2)) + 1;
		while (true) {
			const void* entry_key =
				((const void**)map->data.keys)[idx];
			if (entry_key == NULL && map->data.zero_idx != idx) {
				*idx_out = idx;
				return false;
			} else if (entry_key == key) {
				*idx_out = idx;
				return true;
			}
			idx = (idx + offset) % n;
		}
		gu_impossible();
		break;
	}
	case GU_MAP_WORD: {
		GuWord w = *(const GuWord*)key;
		GuHash hash = (GuHash) w;
		size_t idx = hash % n;
		size_t offset = (hash % (n - 2)) + 1;
		while (true) {
			GuWord entry_key = ((GuWord*)map->data.keys)[idx];
			if (entry_key == 0 && map->data.zero_idx != idx) {
				*idx_out = idx;
				return false;
			} else if (entry_key == w) {
				*idx_out = idx;
				return true;
			}
			idx = (idx + offset) % n;
		}
		gu_impossible();
		break;
	}
	case GU_MAP_STRING: {
		GuHasher* hasher = map->hasher;
		GuEquality* eq = (GuEquality*) hasher;
		GuHash hash = hasher->hash(hasher, key);
		size_t idx = hash % n;
		size_t offset = (hash % (n - 2)) + 1;
		while (true) {
			GuString entry_key =
				((GuString*)map->data.keys)[idx];
			if (entry_key == NULL && map->data.zero_idx != idx) {
				*idx_out = idx;
				return false;
			} else if (eq->is_equal(eq, key, entry_key)) {
				*idx_out = idx;
				return true;
			}
			idx = (idx + offset) % n;
		}
		gu_impossible();
		break;
	}
	default:
		gu_impossible();
	}
	gu_impossible();
	return false;
}
예제 #5
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);
	}
}
예제 #6
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;
}
예제 #7
0
파일: evaluator.c 프로젝트: Deseaus/GF
static PgfExpr
pgf_value2expr(PgfReasoner* rs, int level, PgfClosure* clos)
{
	clos = rs->eval_gates->enter(rs, clos);
	if (clos == NULL)
		return gu_null_variant;

	PgfExpr expr = gu_null_variant;
	size_t n_args = 0;
	PgfClosure** args;

	if (clos->code == rs->eval_gates->evaluate_value) {
		PgfValue* val = (PgfValue*) clos;
		PgfAbsFun* absfun = gu_container(val->con, PgfAbsFun, closure);

		expr   = absfun->ep.expr;
		n_args = absfun->arity;
		args   = val->args;
	} else if (clos->code == rs->eval_gates->evaluate_value_lit) {
		PgfValueLit* val = (PgfValueLit*) clos;

		PgfExprLit *elit =
			gu_new_variant(PGF_EXPR_LIT,
						   PgfExprLit,
						   &expr, rs->out_pool);

		GuVariantInfo i = gu_variant_open(val->lit);
		switch (i.tag) {
		case PGF_LITERAL_STR: {
			PgfLiteralStr* lstr = i.data;

			PgfLiteralStr* new_lstr =
				gu_new_flex_variant(PGF_LITERAL_STR,
									PgfLiteralStr,
									val, strlen(lstr->val)+1,
									&elit->lit, rs->out_pool);
			strcpy(new_lstr->val, lstr->val);
			break;
		}
		case PGF_LITERAL_INT: {
			PgfLiteralInt* lint = i.data;

			PgfLiteralInt* new_lint =
				gu_new_variant(PGF_LITERAL_INT,
							   PgfLiteralInt,
							   &elit->lit, rs->out_pool);
			new_lint->val = lint->val;
			break;
		}
		case PGF_LITERAL_FLT: {
			PgfLiteralFlt* lflt = i.data;

			PgfLiteralFlt* new_lflt =
				gu_new_variant(PGF_LITERAL_FLT,
							   PgfLiteralFlt,
							   &elit->lit, rs->out_pool);
			new_lflt->val = lflt->val;
			break;
		}
		default:
			gu_impossible();
		}
	} else if (clos->code == rs->eval_gates->evaluate_value_pap) {
		PgfValuePAP *pap = (PgfValuePAP*) clos;

		PgfValueGen* gen =
			gu_new(PgfValueGen, rs->pool);
		gen->header.code = rs->eval_gates->evaluate_gen;
		gen->level  = level;

		size_t n_args = pap->n_args/sizeof(PgfClosure*);
		PgfValuePAP* new_pap = gu_new_flex(rs->pool, PgfValuePAP, args, n_args+1);
		new_pap->header.code = rs->eval_gates->evaluate_value_pap;
		new_pap->fun         = pap->fun;
		new_pap->n_args      = pap->n_args+sizeof(PgfClosure*);
		new_pap->args[0]     = &gen->header;
		for (size_t i = 0; i < n_args; i++) {
			new_pap->args[i+1] = pap->args[i];
		}

		PgfExprAbs *eabs =
			gu_new_variant(PGF_EXPR_ABS,
						   PgfExprAbs,
						   &expr, rs->out_pool);
		eabs->bind_type = PGF_BIND_TYPE_EXPLICIT;
		eabs->id = gu_format_string(rs->out_pool, "v%d", level);
		eabs->body = pgf_value2expr(rs, level+1, &new_pap->header);
	} else if (clos->code == rs->eval_gates->evaluate_value_const) {
		PgfValuePAP* val = (PgfValuePAP*) clos;
		
		if (val->fun->code == rs->eval_gates->evaluate_meta) {
			PgfValueMeta* fun = (PgfValueMeta*) val->fun;

			PgfExprMeta *emeta =
				gu_new_variant(PGF_EXPR_META,
				               PgfExprMeta,
				               &expr, rs->out_pool);
			emeta->id = fun->id;
		} else if (val->fun->code == rs->eval_gates->evaluate_gen) {
			PgfValueGen* fun = (PgfValueGen*) val->fun;

			PgfExprVar *evar =
				gu_new_variant(PGF_EXPR_VAR,
				               PgfExprVar,
				               &expr, rs->out_pool);
			evar->var = level - fun->level - 1;
		} else if (val->fun->code == rs->eval_gates->evaluate_sum) {
			PgfValueSum* sum = (PgfValueSum*) val->fun;

			PgfExpr e1,e2;
			PgfExprFun *efun =
				gu_new_flex_variant(PGF_EXPR_FUN,
				                    PgfExprFun,
				                    fun, 2,
				                    &e1, rs->out_pool);
			strcpy(efun->fun, "+");

			PgfExprLit *elit =
				gu_new_variant(PGF_EXPR_LIT,
				               PgfExprLit,
				               &e2, rs->out_pool);
			elit->lit = sum->lit;
			
			PgfExprApp* eapp =
				gu_new_variant(PGF_EXPR_APP,
				               PgfExprApp,
				               &expr, rs->out_pool);
			eapp->fun = e1;
			eapp->arg = e2;
	
			size_t n_consts = gu_buf_length(sum->consts);
			for (size_t i = 0; i < n_consts; i++) {
				PgfClosure* con =
					gu_buf_get(sum->consts, PgfClosure*, i);

				PgfExpr fun = expr;
				PgfExpr arg = 
					pgf_value2expr(rs, level, con);
				if (gu_variant_is_null(arg))
					return gu_null_variant;

				PgfExprApp* e =
					gu_new_variant(PGF_EXPR_APP,
					               PgfExprApp,
					               &expr, rs->out_pool);
				e->fun = fun;
				e->arg = arg;
			}
		} else {
예제 #8
0
파일: reader.c 프로젝트: k0001/GF
static void
pgf_read_tag_error(PgfReader* rdr)
{
	gu_impossible();
}