static void arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init) { Node *r, *a; NodeList *l; Node *index, *value; for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("arraylit: rhs not OKEY: %N", r); index = r->left; value = r->right; switch(value->op) { case OARRAYLIT: if(value->type->bound < 0) { if(pass == 1 && ctxt != 0) { a = nod(OINDEX, var, index); slicelit(ctxt, value, a, init); } else if(pass == 2 && ctxt == 0) { a = nod(OINDEX, var, index); slicelit(ctxt, value, a, init); } else if(pass == 3) break; continue; } a = nod(OINDEX, var, index); arraylit(ctxt, pass, value, a, init); continue; case OSTRUCTLIT: a = nod(OINDEX, var, index); structlit(ctxt, pass, value, a, init); continue; } if(isliteral(index) && isliteral(value)) { if(pass == 2) continue; } else if(pass == 1) continue; // build list of var[index] = value a = nod(OINDEX, var, index); a = nod(OAS, a, value); typecheck(&a, Etop); walkexpr(&a, init); // add any assignments in r to top if(pass == 1) { if(a->op != OAS) fatal("structlit: not as"); a->dodata = 2; } *init = list(*init, a); } }
static int getdyn(Node *n, int top) { NodeList *nl; Node *value; int mode; mode = 0; switch(n->op) { default: if(isliteral(n)) return MODECONST; return MODEDYNAM; case OARRAYLIT: if(!top && n->type->bound < 0) return MODEDYNAM; case OSTRUCTLIT: break; } for(nl=n->list; nl; nl=nl->next) { value = nl->n->right; mode |= getdyn(value, 0); if(mode == (MODEDYNAM|MODECONST)) break; } return mode; }
static void structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init) { Node *r, *a; NodeList *nl; Node *index, *value; for(nl=n->list; nl; nl=nl->next) { r = nl->n; if(r->op != OKEY) fatal("structlit: rhs not OKEY: %N", r); index = r->left; value = r->right; switch(value->op) { case OARRAYLIT: if(value->type->bound < 0) { if(pass == 1 && ctxt != 0) { a = nod(ODOT, var, newname(index->sym)); slicelit(ctxt, value, a, init); } else if(pass == 2 && ctxt == 0) { a = nod(ODOT, var, newname(index->sym)); slicelit(ctxt, value, a, init); } else if(pass == 3) break; continue; } a = nod(ODOT, var, newname(index->sym)); arraylit(ctxt, pass, value, a, init); continue; case OSTRUCTLIT: a = nod(ODOT, var, newname(index->sym)); structlit(ctxt, pass, value, a, init); continue; } if(isliteral(value)) { if(pass == 2) continue; } else if(pass == 1) continue; // build list of var.field = expr a = nod(ODOT, var, newname(index->sym)); a = nod(OAS, a, value); typecheck(&a, Etop); walkexpr(&a, init); if(pass == 1) { if(a->op != OAS) fatal("structlit: not as"); a->dodata = 2; } *init = list(*init, a); } }
// Return FALSE when compilation has finished bool compiler::compile_token(const std::string& s, parser& p) { if ( s.empty() ) { m.load_halt(); resolve_forwards(); return false; } else if ( ishalt(s) ) m.load_halt(); else if ( iscomment(s) ) p.skip_line(); else if ( isliteral(s) ) compile_literal(s); else if ( islabel(s) ) m.addlabel(s.c_str(), m.pos()); else { Op op = tok2op(s); if ( op == NOP_END ) error("Unknown operation: " + s); m.load(op); } return true; }
static void maplit(int ctxt, Node *n, Node *var, NodeList **init) { Node *r, *a; NodeList *l; int nerr, b; Type *t, *tk, *tv, *t1; Node *vstat, *index, *value; Sym *syma, *symb; ctxt = 0; // make the map var nerr = nerrors; a = nod(OMAKE, N, N); a->list = list1(typenod(n->type)); litas(var, a, init); // count the initializers b = 0; for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("slicelit: rhs not OKEY: %N", r); index = r->left; value = r->right; if(isliteral(index) && isliteral(value)) b++; } t = T; if(b != 0) { // build type [count]struct { a Tindex, b Tvalue } t = n->type; tk = t->down; tv = t->type; symb = lookup("b"); t = typ(TFIELD); t->type = tv; t->sym = symb; syma = lookup("a"); t1 = t; t = typ(TFIELD); t->type = tk; t->sym = syma; t->down = t1; t1 = t; t = typ(TSTRUCT); t->type = t1; t1 = t; t = typ(TARRAY); t->bound = b; t->type = t1; dowidth(t); // make and initialize static array vstat = staticname(t, ctxt); b = 0; for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("slicelit: rhs not OKEY: %N", r); index = r->left; value = r->right; if(isliteral(index) && isliteral(value)) { // build vstat[b].a = key; a = nodintconst(b); a = nod(OINDEX, vstat, a); a = nod(ODOT, a, newname(syma)); a = nod(OAS, a, index); typecheck(&a, Etop); walkexpr(&a, init); a->dodata = 2; *init = list(*init, a); // build vstat[b].b = value; a = nodintconst(b); a = nod(OINDEX, vstat, a); a = nod(ODOT, a, newname(symb)); a = nod(OAS, a, value); typecheck(&a, Etop); walkexpr(&a, init); a->dodata = 2; *init = list(*init, a); b++; } } // loop adding structure elements to map // for i = 0; i < len(vstat); i++ { // map[vstat[i].a] = vstat[i].b // } index = nod(OXXX, N, N); tempname(index, types[TINT]); a = nod(OINDEX, vstat, index); a->etype = 1; // no bounds checking a = nod(ODOT, a, newname(symb)); r = nod(OINDEX, vstat, index); r->etype = 1; // no bounds checking r = nod(ODOT, r, newname(syma)); r = nod(OINDEX, var, r); r = nod(OAS, r, a); a = nod(OFOR, N, N); a->nbody = list1(r); a->ninit = list1(nod(OAS, index, nodintconst(0))); a->ntest = nod(OLT, index, nodintconst(t->bound)); a->nincr = nod(OASOP, index, nodintconst(1)); a->nincr->etype = OADD; typecheck(&a, Etop); walkstmt(&a); *init = list(*init, a); } // put in dynamic entries one-at-a-time for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("slicelit: rhs not OKEY: %N", r); index = r->left; value = r->right; if(isliteral(index) && isliteral(value)) continue; // build list of var[c] = expr a = nod(OINDEX, var, r->left); a = nod(OAS, a, r->right); typecheck(&a, Etop); walkexpr(&a, init); if(nerr != nerrors) break; *init = list(*init, a); } }
static void slicelit(int ctxt, Node *n, Node *var, NodeList **init) { Node *r, *a; NodeList *l; Type *t; Node *vstat, *vauto; Node *index, *value; int mode; // make an array type t = shallow(n->type); t->bound = mpgetfix(n->right->val.u.xval); t->width = 0; t->sym = nil; dowidth(t); if(ctxt != 0) { // put everything into static array vstat = staticname(t, ctxt); arraylit(ctxt, 1, n, vstat, init); arraylit(ctxt, 2, n, vstat, init); // copy static to slice a = nod(OSLICE, vstat, nod(OKEY, N, N)); a = nod(OAS, var, a); typecheck(&a, Etop); a->dodata = 2; *init = list(*init, a); return; } // recipe for var = []t{...} // 1. make a static array // var vstat [...]t // 2. assign (data statements) the constant part // vstat = constpart{} // 3. make an auto pointer to array and allocate heap to it // var vauto *[...]t = new([...]t) // 4. copy the static array to the auto array // *vauto = vstat // 5. assign slice of allocated heap to var // var = [0:]*auto // 6. for each dynamic part assign to the slice // var[i] = dynamic part // // an optimization is done if there is no constant part // 3. var vauto *[...]t = new([...]t) // 5. var = [0:]*auto // 6. var[i] = dynamic part // if the literal contains constants, // make static initialized array (1),(2) vstat = N; mode = getdyn(n, 1); if(mode & MODECONST) { vstat = staticname(t, ctxt); arraylit(ctxt, 1, n, vstat, init); } // make new auto *array (3 declare) vauto = nod(OXXX, N, N); tempname(vauto, ptrto(t)); // set auto to point at new heap (3 assign) a = nod(ONEW, N, N); a->list = list1(typenod(t)); a = nod(OAS, vauto, a); typecheck(&a, Etop); walkexpr(&a, init); *init = list(*init, a); if(vstat != N) { // copy static to heap (4) a = nod(OIND, vauto, N); a = nod(OAS, a, vstat); typecheck(&a, Etop); walkexpr(&a, init); *init = list(*init, a); } // make slice out of heap (5) a = nod(OAS, var, nod(OSLICE, vauto, nod(OKEY, N, N))); typecheck(&a, Etop); walkexpr(&a, init); *init = list(*init, a); // put dynamics into slice (6) for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) fatal("slicelit: rhs not OKEY: %N", r); index = r->left; value = r->right; a = nod(OINDEX, var, index); a->etype = 1; // no bounds checking // TODO need to check bounds? switch(value->op) { case OARRAYLIT: if(value->type->bound < 0) break; arraylit(ctxt, 2, value, a, init); continue; case OSTRUCTLIT: structlit(ctxt, 2, value, a, init); continue; } if(isliteral(index) && isliteral(value)) continue; // build list of var[c] = expr a = nod(OAS, a, value); typecheck(&a, Etop); walkexpr(&a, init); *init = list(*init, a); } }