commit 0301ad9
zzo38
·
2023-08-01 18:59:07 +0000 UTC
parent cabc34a
Implement uxntal lambdas.
M
asm.doc
+6,
-0
1@@ -88,6 +88,12 @@ The following standard tokens are available:
2 characters without any opcodes or delimiters. (If you need spaces, then
3 you must use separate tokens such as 20 for spaces.)
4
5+ { and } can be used around a lambda block (they can also be used for
6+ macros as described above). The { represents a JSI to the matching } and
7+ the } represents a STH2r instruction. In this way, the { } block is
8+ skipped and the address of the beginning of the block (after the JSI
9+ instruction) will be stored on the stack.
10+
11 An instruction opcode consists of three uppercase letters, optionally
12 followed by any combination of instruction flags which can be "2" for
13 16-bit operands, "r" to work with the other stack, and/or "k" to keep
M
uxnasm.c
+16,
-0
1@@ -59,6 +59,7 @@ typedef struct {
2
3 typedef struct {
4 Uint8 data[LENGTH];
5+ Uint8 lambda_stack[256], lambda_ptr, lambda_count;
6 unsigned int ptr, length;
7 Uint16 llen, mlen, rlen, xlen;
8 Label labels[MAXLABELS];
9@@ -66,6 +67,7 @@ typedef struct {
10 Reference refs[MAXREFS];
11 ExpItem exps[MAXEXPS];
12 char scope[0x40];
13+ char lambda[0x10];
14 Uint32 total;
15 } Program;
16
17@@ -228,6 +230,13 @@ makereference(char *scope, char *label, Uint16 addr)
18 return 1;
19 }
20
21+static char*makelambda(int id) {
22+ scpy("?lambda", p.lambda, 8);
23+ p.lambda[7] = '0' + (id >> 0x4);
24+ p.lambda[8] = '0' + (id & 0xf);
25+ return p.lambda;
26+}
27+
28 static int makeexp(Uint8 kind,char*name,Uint32 len,Uint8 misc) {
29 ExpItem*e;
30 if(p.xlen==MAXEXPS) return error("Expansion limit exceeded","");
31@@ -548,6 +557,13 @@ parse(char *w, FILE *f)
32 if(!makeexp('^',w+1,0,0)) return 0;
33 p.exps[p.xlen-1].len=p.ptr;
34 break;
35+ case '{': /* lambda start */
36+ p.lambda_stack[p.lambda_ptr++] = p.lambda_count;
37+ makereference(p.scope, makelambda(p.lambda_count++), p.ptr + 1);
38+ return writebyte(0x60) && writeshort(0xffff, 0);
39+ case '}': /* lambda end */
40+ if(!makelabel(makelambda(p.lambda_stack[--p.lambda_ptr])+1)) return error("Invalid label", w);
41+ return writebyte(0x6f);
42 case '[':
43 case ']':
44 if(slen(w) == 1) break;