diff options
Diffstat (limited to 'src/parse.cff')
| -rw-r--r-- | src/parse.cff | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/src/parse.cff b/src/parse.cff index 7afec96..1b5fba3 100644 --- a/src/parse.cff +++ b/src/parse.cff @@ -730,23 +730,13 @@ fn isdecltokt(t TokT) bool { struct BloomFilt { bits [4]u32, - fn _hash(x u32) u32 { - // https://nullprogram.com/blog/2018/07/31/ - x ^= x >> 16; - x *= 0x7feb352dU; - x ^= x >> 15; - x *= 0x846ca68bU; - x ^= x >> 16; - return x; - } - def NHASH = 4; def NBITS = 8 * sizeof BloomFilt; fn add(this *BloomFilt, s *const u8) void { let h u32 = as(uptrint)s; for let i = 0; i < NHASH; ++i { - h = _hash(h); + h = cwhash32(h); let idx = h % NBITS; this.bits[idx/32] |= 1u32 << (idx%32); } @@ -755,7 +745,7 @@ struct BloomFilt { fn matches(this *const BloomFilt, s *const u8) bool { let h u32 = as(uptrint)s; for let i = 0; i < NHASH; ++i { - h = _hash(h); + h = cwhash32(h); let idx = h % NBITS; if this.bits[idx/32] & (1u64 << (idx%32)) == 0 { return #f; @@ -840,6 +830,11 @@ fn parseagg(P *Parser, loc Loc, kind AggKind, name *const u8, retdecl **Decl) *c ty.size = size; ty.align = align; agg.flds = flds.dat[0::flds.len]; + if agg.flds.#len >= IDXMAP_MIN_WORTHIT { + agg.idxmap->init(agg.flds.#len, agg.flds.#ptr, sizeof AggField); + } else { + agg.idxmap = {}; + } *constty = *ty; constty.konst = #t; if kind == :EUnion { @@ -890,7 +885,10 @@ fn parseagg(P *Parser, loc Loc, kind AggKind, name *const u8, retdecl **Decl) *c } fn findaggfield(ty *const Type, name *const u8) *AggField { - foreach_ptr(fld, i, ty.u.Agg.flds) { + if ty.u.Agg.idxmap.idxs { + return ty.u.Agg.idxmap->find(name, ty.u.Agg.flds.#ptr, sizeof AggField); + } + foreach_ptr(fld, _, ty.u.Agg.flds) { if fld.name == name { return fld; } @@ -899,7 +897,10 @@ fn findaggfield(ty *const Type, name *const u8) *AggField { } fn findbitffield(ty *const Type, name *const u8) *BitFField { - foreach_ptr(fld, i, ty.u.BitF.flds) { + if ty.u.BitF.idxmap.idxs { + return ty.u.BitF.idxmap->find(name, ty.u.BitF.flds.#ptr, sizeof BitFField); + } + foreach_ptr(fld, _, ty.u.BitF.flds) { if fld.name == name { return fld; } @@ -987,6 +988,11 @@ fn parsebitfield(P *Parser, name *const u8) *const Type { } bitf.flds = flds->move(P.alloc); + if bitf.flds.#len >= IDXMAP_MIN_WORTHIT { + bitf.idxmap->init(bitf.flds.#len, bitf.flds.#ptr, sizeof BitFField); + } else { + bitf.idxmap = {}; + } return interntype(&ty); } @@ -2303,11 +2309,12 @@ fn pexassign(P *Parser) Expr { switch { case !islvalue(&ex); err(P, ex.loc, "left operand to assignment is not lvalue"); - case (typeof2(ex.ty, rhs.ty) == #null) - and !((ex.ty->is(:Ptr) and rhs.ty->is(:Int) - and (tok.t == '+=' or tok.t == '-='))); + case ex.ty->is(:Ptr) and rhs.ty->is(:Int) and (tok.t == '+=' or tok.t == '-='); + // pass + case typeof2(ex.ty, rhs.ty) == #null; err(P, tok.loc, "invalid operands %t and %t for assignment operator %qT", ex.ty, rhs.ty, &tok); + case okind == :IntFlo and (!isnumtype(ex.ty) or !isnumtype(rhs.ty)); err(P, tok.loc, "invalid operands %t and %t for assignment operator %qT", ex.ty, rhs.ty, &tok); @@ -2957,7 +2964,7 @@ fn doimport(P *Parser, loc Loc, path *const u8) [#]*Decl { return d0.decls; } rpath = strcpy(malloc(strlen(rpath) + 1), rpath); - let e = seen->put(rpath, { {}, #t }); + seen->put(rpath, { {}, #t }); let P2 Parser #?; parser_init(&P2, rpath); P2.is_header = #t; @@ -2965,7 +2972,7 @@ fn doimport(P *Parser, loc Loc, path *const u8) [#]*Decl { P2.alloc = P.alloc; let decls = parse4import(&P2); - *e = { decls, #f }; + seen->put(rpath, { decls, #f }); return decls; } |