1
0
forked from GitHub/gf-core

hash function for abstract syntax trees

This commit is contained in:
kr.angelov
2013-07-02 19:12:53 +00:00
parent c0a0859566
commit 2948231e0f
4 changed files with 93 additions and 7 deletions

View File

@@ -367,15 +367,15 @@ gu_string_is_prefix(GuString s1, GuString s2)
return true;
}
GuWord
gu_string_hash(GuString s)
GuHash
gu_string_hash(GuHash h, GuString s)
{
if (s.w_ & 1) {
return s.w_;
return h*101 + s.w_;
}
size_t len = gu_string_length(s);
uint8_t* data = gu_string_long_data(s);
return gu_hash_bytes(0, data, len);
return gu_hash_bytes(h, data, len);
}
bool
@@ -403,7 +403,7 @@ gu_string_hasher_hash(GuHasher* self, const void* p)
{
(void) self;
const GuString* sp = p;
return gu_string_hash(*sp);
return gu_string_hash(0, *sp);
}
static bool

View File

@@ -78,8 +78,8 @@ gu_string_is_prefix(GuString s1, GuString s2);
#if defined(GU_HASH_H_) && !defined(GU_STRING_H_HASH_)
#define GU_STRING_H_HASH_
uintptr_t
gu_string_hash(GuString s);
GuHash
gu_string_hash(GuHash h, GuString s);
extern GuHasher gu_string_hasher[1];

View File

@@ -830,6 +830,86 @@ pgf_expr_eq(PgfExpr e1, PgfExpr e2)
return false;
}
GuHash
pgf_literal_hash(GuHash h, PgfLiteral lit)
{
GuVariantInfo i = gu_variant_open(lit);
switch (i.tag) {
case PGF_LITERAL_STR: {
PgfLiteralStr* lit = i.data;
h = gu_string_hash(h, lit->val);
break;
}
case PGF_LITERAL_INT: {
PgfLiteralInt* lit = i.data;
h = gu_hash_byte(h, lit->val);
break;
}
case PGF_LITERAL_FLT: {
PgfLiteralFlt* lit = i.data;
h = gu_hash_byte(h, lit->val);
break;
}
default:
gu_impossible();
}
return h;
}
GuHash
pgf_expr_hash(GuHash h, PgfExpr e)
{
GuVariantInfo ei = gu_variant_open(e);
switch (ei.tag) {
case PGF_EXPR_ABS: {
PgfExprAbs* abs = ei.data;
h = gu_string_hash(h, abs->id);
h = pgf_expr_hash(h, abs->body);
break;
}
case PGF_EXPR_APP: {
PgfExprApp* app = ei.data;
h = pgf_expr_hash(h, app->fun);
h = pgf_expr_hash(h, app->arg);
break;
}
case PGF_EXPR_LIT: {
PgfExprLit* lit = ei.data;
h = pgf_literal_hash(h, lit->lit);
break;
}
case PGF_EXPR_META:
h = gu_hash_byte(h, '?');
break;
case PGF_EXPR_FUN: {
PgfExprFun* fun = ei.data;
h = gu_string_hash(h, fun->fun);
break;
}
case PGF_EXPR_VAR: {
PgfExprVar* evar = ei.data;
h = gu_hash_byte(h, evar->var);
break;
}
case PGF_EXPR_TYPED: {
PgfExprTyped* typed = ei.data;
h = pgf_expr_hash(h, typed->expr);
break;
}
case PGF_EXPR_IMPL_ARG: {
PgfExprImplArg* impl = ei.data;
h = pgf_expr_hash(h, impl->expr);
break;
}
default:
gu_impossible();
}
return h;
}
void
pgf_print_literal(PgfLiteral lit,
GuWriter* wtr, GuExn* err)

View File

@@ -166,6 +166,12 @@ pgf_expr_eq(PgfExpr e1, PgfExpr e2);
bool
pgf_type_eq(PgfType* t1, PgfType* t2);
GuHash
pgf_literal_hash(GuHash h, PgfLiteral lit);
GuHash
pgf_expr_hash(GuHash h, PgfExpr e);
typedef struct PgfPrintContext PgfPrintContext;
struct PgfPrintContext {