commit 0301ad9

zzo38  ·  2023-08-01 18:59:07 +0000 UTC
parent cabc34a
Implement uxntal lambdas.
2 files changed,  +22, -0
+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
+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;