node chktype2(node e,scope v){ node f, ftype; f = chk(e,v); if (f == bad__K) return bad_or_undefined_T; if (equal(f,type__K)) return type__T; ftype = type(f); if (ftype != type__T) { node sym; if (ftype != deferred__T) { errorpos(e,"not valid type"); return NULL; } sym = unpos(f); assert(issym(sym)); if (sym->body.symbol.value == NULL) { node t = newtype(f,NULL,FALSE); t->body.type.flags = deferred_F; assert(issym(sym)); sym->body.symbol.value = t; t->body.type.name = sym; } return sym->body.symbol.value; } return f; /* was totype(f) */ }
void internsymbol(node s, scope v){ assertpos(issym(s),s); push(complete_symbol_list,s); if (s->body.symbol.flags & intern_F) { errorpos(s,"symbol defined again ... "); return; } s->body.symbol.flags |= intern_F; if (v != NULL) reinternsymbol(s,v); /* if ( 0 == strcmp("x",tostring(s)) ) trap(); */ if (s->body.symbol.type!=keyword_T) { char *Cname; assertpos(issym(s),s); if (s->body.symbol.flags & literal_F) { Cname = tostring(s); /* no totoken here? */ if (!(s->body.symbol.flags & nouniquify_F)) Cname = uniquify(Cname); } else { Cname = totoken(tostring(s)); if (s->body.symbol.flags & (export_F | import_F)) Cname = prefixify(s->body.symbol.package,Cname); if (!(s->body.symbol.flags & nouniquify_F)) Cname = uniquify(Cname); else if (s->body.symbol.name->body.unique_string.seqno == 0) s->body.symbol.name->body.unique_string.seqno++; } s->body.symbol.Cname = Cname; } if (s->body.symbol.flags & (export_F|import_F)) exportit(s,v); }
void checkfordeferredsymbols(){ node p; for (p = complete_symbol_list; p != NULL; p = CDR(p)) { node s = CAR(p); assertpos(s->tag == symbol_tag,s); if (s->body.symbol.flags & errmsg_given_F) continue; bool def = !!(s->body.symbol.flags & (defined_F|import_F)); bool dec = type(s) != deferred__T; if (!def && !dec) errorpos(s,"symbol never defined nor declared"); else if (!def) errorpos(s,"symbol never defined"); else if (!dec) errorpos(s,"symbol never declared"); } }
node chktype(node ee,scope v){ node e = chktype2(ee,v); if (e==type__T) { errorpos(ee,"not valid type"); return bad_or_undefined_T; } return e; }
bool forwardtype(node old,node newn){ assert(istype(old)); assert(istype(newn)); assert(old->body.type.flags & deferred_F); assert(old != deferred__T); old->body.type.flags &= ~deferred_F; if ((old->body.type.flags & should_be_pointer_F) && !ispointertype(newn)) { errorpos(newn,"expected a pointer type"); return FALSE; } old->body.type.flags &= ~should_be_pointer_F; if ((old->body.type.flags & should_be_tagged_F) && !istaggedtype(newn)) { errorpos(newn,"expected a tagged pointer type"); return FALSE; } old->body.type.flags &= ~should_be_tagged_F; old->body.type.forward = typeforward(newn); return TRUE; }
node newsymbol(node p, node ptype, scope v, int flags){ node name; node s; struct POS *ppos = NULL; assertpos(istype(ptype),ptype); if (issym(p)) { /* defined previously so the Cname can be set by the translator */ return p; } if (isstr(p)) { name = p; p = NULL; } else if (isstrpos(p)) { ppos = &p->body.position.pos; name = p->body.position.contents; assertpos(name->tag == unique_string_tag,name); } else { errorpos(p,"defining a nonsymbol"); return NULL; } s = newnode(SYMBOL,symbol_tag); /* newnode clears the memory */ assert(s->body.symbol.flags == 0); s->body.symbol.name = name; s->body.symbol.type = ptype; s->body.symbol.pos = ppos==NULL ? empty_pos : *ppos; if (!inside_defun(v) && !(flags & tmp_F)) flags |= global_F; s->body.symbol.flags = flags & ~intern_F; if (v!=NULL && v->previous != NULL) { scope w = v->previous; assert(w->current_package==NULL || issym(w->current_package)); s->body.symbol.package = w->current_package; } if (flags & intern_F) internsymbol(s,v); return s; }
node notimpl(node e){ errorpos(e,"not implemented yet"); return bad__K; }
node badnumargs(node e,int n){ errorpos(e,"should have %d argument%s",n,n==1?"":"s"); return bad__K; }
node typemismatch(node e){ errorpos(e,"type mismatch"); return bad__K; }
bool Reed_Solomon::decode(const bvec &coded_bits, const ivec &erasure_positions, bvec &decoded_message, bvec &cw_isvalid) { bool decoderfailure, no_dec_failure; int j, i, kk, l, L, foundzeros, iterations = floor_i(static_cast<double>(coded_bits.length()) / (n * m)); bvec mbit(m * k); decoded_message.set_size(iterations * k * m, false); cw_isvalid.set_length(iterations); GFX rx(q, n - 1), cx(q, n - 1), mx(q, k - 1), ex(q, n - 1), S(q, 2 * t), Xi(q, 2 * t), Gamma(q), Lambda(q), Psiprime(q), OldLambda(q), T(q), Omega(q); GFX dummy(q), One(q, (char*)"0"), Omegatemp(q); GF delta(q), tempsum(q), rtemp(q), temp(q), Xk(q), Xkinv(q); ivec errorpos; if ( erasure_positions.length() ) { it_assert(max(erasure_positions) < iterations*n, "Reed_Solomon::decode: erasure position is invalid."); } no_dec_failure = true; for (i = 0; i < iterations; i++) { decoderfailure = false; //Fix the received polynomial r(x) for (j = 0; j < n; j++) { rtemp.set(q, coded_bits.mid(i * n * m + j * m, m)); rx[j] = rtemp; } // Fix the Erasure polynomial Gamma(x) // and replace erased coordinates with zeros rtemp.set(q, -1); ivec alphapow = - ones_i(2); Gamma = One; for (j = 0; j < erasure_positions.length(); j++) { rx[erasure_positions(j)] = rtemp; alphapow(1) = erasure_positions(j); Gamma *= (One - GFX(q, alphapow)); } //Fix the syndrome polynomial S(x). S.clear(); for (j = 1; j <= 2 * t; j++) { S[j] = rx(GF(q, b + j - 1)); } // calculate the modified syndrome polynomial Xi(x) = Gamma * (1+S) - 1 Xi = Gamma * (One + S) - One; // Apply Berlekam-Massey algorithm if (Xi.get_true_degree() >= 1) { //Errors in the received word // Iterate to find Lambda(x), which hold all error locations kk = 0; Lambda = One; L = 0; T = GFX(q, (char*)"-1 0"); while (kk < 2 * t) { kk = kk + 1; tempsum = GF(q, -1); for (l = 1; l <= L; l++) { tempsum += Lambda[l] * Xi[kk - l]; } delta = Xi[kk] - tempsum; if (delta != GF(q, -1)) { OldLambda = Lambda; Lambda -= delta * T; if (2 * L < kk) { L = kk - L; T = OldLambda / delta; } } T = GFX(q, (char*)"-1 0") * T; } // Find the zeros to Lambda(x) errorpos.set_size(Lambda.get_true_degree()); foundzeros = 0; for (j = q - 2; j >= 0; j--) { if (Lambda(GF(q, j)) == GF(q, -1)) { errorpos(foundzeros) = (n - j) % n; foundzeros += 1; if (foundzeros >= Lambda.get_true_degree()) { break; } } } if (foundzeros != Lambda.get_true_degree()) { decoderfailure = true; } else { // Forney algorithm... //Compute Omega(x) using the key equation for RS-decoding Omega.set_degree(2 * t); Omegatemp = Lambda * (One + Xi); for (j = 0; j <= 2 * t; j++) { Omega[j] = Omegatemp[j]; } //Find the error/erasure magnitude polynomial by treating them the same Psiprime = formal_derivate(Lambda*Gamma); errorpos = concat(errorpos, erasure_positions); ex.clear(); for (j = 0; j < errorpos.length(); j++) { Xk = GF(q, errorpos(j)); Xkinv = GF(q, 0) / Xk; // we calculate ex = - error polynomial, in order to avoid the // subtraction when recunstructing the corrected codeword ex[errorpos(j)] = (Xk * Omega(Xkinv)) / Psiprime(Xkinv); if (b != 1) { // non-narrow-sense code needs corrected error magnitudes int correction_exp = ( errorpos(j)*(1-b) ) % n; ex[errorpos(j)] *= GF(q, correction_exp + ( (correction_exp < 0) ? n : 0 )); } } //Reconstruct the corrected codeword. // instead of subtracting the error/erasures, we calculated // the negative error with 'ex' above cx = rx + ex; //Code word validation S.clear(); for (j = 1; j <= 2 * t; j++) { S[j] = cx(GF(q, b + j - 1)); } if (S.get_true_degree() >= 1) { decoderfailure = true; } } } else { cx = rx; decoderfailure = false; } //Find the message polynomial mbit.clear(); if (decoderfailure == false) { if (cx.get_true_degree() >= 1) { // A nonzero codeword was transmitted if (systematic) { for (j = 0; j < k; j++) { mx[j] = cx[j]; } } else { mx = divgfx(cx, g); } for (j = 0; j <= mx.get_true_degree(); j++) { mbit.replace_mid(j * m, mx[j].get_vectorspace()); } } } else { //Decoder failure. // for a systematic code it is better to extract the undecoded message // from the received code word, i.e. obtaining a bit error // prob. p_b << 1/2, than setting all-zero (p_b = 1/2) if (systematic) { mbit = coded_bits.mid(i * n * m, k * m); } else { mbit = zeros_b(k); } no_dec_failure = false; } decoded_message.replace_mid(i * m * k, mbit); cw_isvalid(i) = (!decoderfailure); } return no_dec_failure; }