ONAME, ONONAME,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
ODCLFUNC, ODCLFIELD, ODCLARG,
- OLIST, OCMP, OPTR, OARRAY,
+ OLIST, OCMP, OPTR, OARRAY, ORANGE,
ORETURN, OFOR, OIF, OSWITCH,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
OGOTO, OPROC, ONEW, OEMPTY, OSELECT,
Node* convas(Node*);
void arrayconv(Type*, Node*);
Node* colas(Node*, Node*);
-Node* dorange(Node*, Node*, Node*, int);
+Node* dorange(Node*);
Node* reorder1(Node*);
Node* reorder2(Node*);
Node* reorder3(Node*);
%type <node> Astmt Bstmt
%type <node> for_stmt for_body for_header
%type <node> if_stmt if_body if_header select_stmt
-%type <node> simple_stmt osimple_stmt semi_stmt
+%type <node> simple_stmt osimple_stmt orange_stmt semi_stmt
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
%type <node> exprsym3_list_r exprsym3
%type <node> name onew_name new_name new_name_list_r new_field
{
if(addtop != N)
fatal("exprsym3_list_r LCOLAS expr_list");
-
$$ = rev($1);
$$ = colas($$, $3);
$$ = nod(OAS, $$, $3);
popdcl();
}
+ocolas:
+| LCOLAS
+
+orange_stmt:
+ osimple_stmt
+| exprsym3_list_r '=' LRANGE expr
+ {
+ $$ = nod(ORANGE, $1, $4);
+ $$->etype = 0; // := flag
+ }
+| exprsym3 ':' exprsym3 '=' LRANGE expr
+ {
+ $$ = nod(OLIST, $1, $3);
+ $$ = nod(ORANGE, $$, $6);
+ $$->etype = 0;
+ }
+| exprsym3_list_r ocolas LRANGE expr
+ {
+ $$ = nod(ORANGE, $1, $4);
+ $$->etype = 1;
+ }
+| exprsym3 ':' exprsym3 ocolas LRANGE expr
+ {
+ $$ = nod(OLIST, $1, $3);
+ $$ = nod(ORANGE, $$, $6);
+ $$->etype = 1;
+ }
+
for_header:
- osimple_stmt ';' osimple_stmt ';' osimple_stmt
+ osimple_stmt ';' orange_stmt ';' osimple_stmt
{
+ if($3 != N && $3->op == ORANGE) {
+ $$ = dorange($3);
+ $$->ninit = list($$->ninit, $1);
+ $$->nincr = list($$->nincr, $5);
+ break;
+ }
// init ; test ; incr
$$ = nod(OFOR, N, N);
$$->ninit = $1;
$$->ntest = $3;
$$->nincr = $5;
}
-| osimple_stmt
+| orange_stmt
{
- // test
+ // range
+ if($1 != N && $1->op == ORANGE) {
+ $$ = dorange($1);
+ break;
+ }
+ // normal test
$$ = nod(OFOR, N, N);
$$->ninit = N;
$$->ntest = $1;
$$->nincr = N;
}
-| new_name ':' new_name LRANGE expr
- {
- $$ = dorange($1, $3, $5, 1);
- }
-| new_name LRANGE expr
- {
- $$ = dorange($1, N, $3, 1);
- }
for_body:
for_header compound_stmt
[OREGISTER] = "REGISTER",
[OINDREG] = "INDREG",
[OSEND] = "SEND",
+ [ORANGE] = "RANGE",
[ORECV] = "RECV",
[OPTR] = "PTR",
[ORETURN] = "RETURN",
return nl;
}
+/*
+ * rewrite a range statement
+ * k and v are names/new_names
+ * m is an array or map
+ * local is =/0 or :=/1
+ */
Node*
-dorange(Node *k, Node *v, Node *m, int local)
+dorange(Node *nn)
{
+ Node *k, *v, *m;
Node *n, *hk, *on, *r, *a;
Type *t, *th;
+ int local;
- if(!local)
- fatal("only local varables now");
+ if(nn->op != ORANGE)
+ fatal("dorange not ORANGE");
+
+ k = nn->left;
+ m = nn->right;
+ local = nn->etype;
+
+ v = N;
+ if(k->op == OLIST) {
+ v = k->right;
+ k = k->left;
+ }
n = nod(OFOR, N, N);
n->nincr = nod(OASOP, hk, literal(1));
n->nincr->etype = OADD;
- k = old2new(k, hk->type);
+ if(local)
+ k = old2new(k, hk->type);
n->nbody = nod(OAS, k, hk);
if(v != N) {
- v = old2new(v, t->type);
+ if(local)
+ v = old2new(v, t->type);
n->nbody = list(n->nbody,
nod(OAS, v, nod(OINDEX, m, hk)) );
}
r = nod(OCALL, on, r);
n->nincr = r;
- k = old2new(k, t->down);
+ if(local)
+ k = old2new(k, t->down);
if(v == N) {
on = syslook("mapiter1", 1);
argtype(on, th);
n->nbody = nod(OAS, k, r);
goto out;
}
- v = old2new(v, t->type);
+ if(local)
+ v = old2new(v, t->type);
on = syslook("mapiter2", 1);
argtype(on, th);
argtype(on, t->down);