aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/code.c
diff options
context:
space:
mode:
authorNicholas Noll <nnoll523@gmail.com>2021-10-26 12:35:22 -0700
committerNicholas Noll <nnoll523@gmail.com>2021-10-26 12:35:22 -0700
commit2416a8654e3c1a4b74fcc0379dac5294670a1f46 (patch)
treeeb63703a92b035752674b9ab97a310fe58b2862a /sys/cmd/rc/code.c
parent47e1e78da8eba4d755179d61a16f2c7920d2da39 (diff)
feat(rc): keywords now recognized. for and while loop
Prototypes for loops sketched. This required recognizing keywords and returning from yylex. Debugging/testing will be required.
Diffstat (limited to 'sys/cmd/rc/code.c')
-rw-r--r--sys/cmd/rc/code.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sys/cmd/rc/code.c b/sys/cmd/rc/code.c
index 0723279..786f284 100644
--- a/sys/cmd/rc/code.c
+++ b/sys/cmd/rc/code.c
@@ -163,6 +163,43 @@ walk(Tree *node)
}
node = n;
break;
+ /* control structures */
+ case Twhile:
+ addr1 = interpreter.i; // head of loop
+ walk(node->child[0]);
+ if(addr1 == interpreter.i)
+ fatal("TODO");
+ emitf(Xtrue);
+ addr2 = emiti(0); // goto end of loop
+
+ walk(node->child[1]);
+ emitf(Xgoto);
+ emiti(addr1); // goto top of loop
+ storepc(addr2);
+ break;
+
+ case Tfor:
+ emitf(Xmark);
+ if(node->child[1]){ // for( x in X )
+ walk(node->child[1]);
+ // emitf(Xglob)
+ }else{ // for(X)
+ fatal("TODO");
+ }
+ emitf(Xmark); // null initial value for Xlocal
+ emitf(Xmark);
+ walk(node->child[0]);
+ emitf(Xlocal);
+
+ addr1 = emitf(Xfor);
+ addr2 = emiti(0);
+
+ walk(node->child[2]);
+ emitf(Xgoto);
+ emiti(addr1);
+ storepc(addr2);
+ emitf(Xunlocal);
+ break;
/* forks */
case '&':