forked from GitHub/gf-core
hash function for abstract syntax trees
This commit is contained in:
@@ -367,15 +367,15 @@ gu_string_is_prefix(GuString s1, GuString s2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GuWord
|
GuHash
|
||||||
gu_string_hash(GuString s)
|
gu_string_hash(GuHash h, GuString s)
|
||||||
{
|
{
|
||||||
if (s.w_ & 1) {
|
if (s.w_ & 1) {
|
||||||
return s.w_;
|
return h*101 + s.w_;
|
||||||
}
|
}
|
||||||
size_t len = gu_string_length(s);
|
size_t len = gu_string_length(s);
|
||||||
uint8_t* data = gu_string_long_data(s);
|
uint8_t* data = gu_string_long_data(s);
|
||||||
return gu_hash_bytes(0, data, len);
|
return gu_hash_bytes(h, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -403,7 +403,7 @@ gu_string_hasher_hash(GuHasher* self, const void* p)
|
|||||||
{
|
{
|
||||||
(void) self;
|
(void) self;
|
||||||
const GuString* sp = p;
|
const GuString* sp = p;
|
||||||
return gu_string_hash(*sp);
|
return gu_string_hash(0, *sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ gu_string_is_prefix(GuString s1, GuString s2);
|
|||||||
#if defined(GU_HASH_H_) && !defined(GU_STRING_H_HASH_)
|
#if defined(GU_HASH_H_) && !defined(GU_STRING_H_HASH_)
|
||||||
#define GU_STRING_H_HASH_
|
#define GU_STRING_H_HASH_
|
||||||
|
|
||||||
uintptr_t
|
GuHash
|
||||||
gu_string_hash(GuString s);
|
gu_string_hash(GuHash h, GuString s);
|
||||||
|
|
||||||
extern GuHasher gu_string_hasher[1];
|
extern GuHasher gu_string_hasher[1];
|
||||||
|
|
||||||
|
|||||||
@@ -830,6 +830,86 @@ pgf_expr_eq(PgfExpr e1, PgfExpr e2)
|
|||||||
return false;
|
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
|
void
|
||||||
pgf_print_literal(PgfLiteral lit,
|
pgf_print_literal(PgfLiteral lit,
|
||||||
GuWriter* wtr, GuExn* err)
|
GuWriter* wtr, GuExn* err)
|
||||||
|
|||||||
@@ -166,6 +166,12 @@ pgf_expr_eq(PgfExpr e1, PgfExpr e2);
|
|||||||
bool
|
bool
|
||||||
pgf_type_eq(PgfType* t1, PgfType* t2);
|
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;
|
typedef struct PgfPrintContext PgfPrintContext;
|
||||||
|
|
||||||
struct PgfPrintContext {
|
struct PgfPrintContext {
|
||||||
|
|||||||
Reference in New Issue
Block a user