Skip to content

Commit

Permalink
Implement uxntal lambdas.
Browse files Browse the repository at this point in the history
  • Loading branch information
zzo38 committed Aug 1, 2023
1 parent ae3b5b5 commit feba063
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
6 changes: 6 additions & 0 deletions asm.doc
Expand Up @@ -88,6 +88,12 @@ The following standard tokens are available:
characters without any opcodes or delimiters. (If you need spaces, then
you must use separate tokens such as 20 for spaces.)

{ and } can be used around a lambda block (they can also be used for
macros as described above). The { represents a JSI to the matching } and
the } represents a STH2r instruction. In this way, the { } block is
skipped and the address of the beginning of the block (after the JSI
instruction) will be stored on the stack.

An instruction opcode consists of three uppercase letters, optionally
followed by any combination of instruction flags which can be "2" for
16-bit operands, "r" to work with the other stack, and/or "k" to keep
Expand Down
16 changes: 16 additions & 0 deletions uxnasm.c
Expand Up @@ -59,13 +59,15 @@ typedef struct {

typedef struct {
Uint8 data[LENGTH];
Uint8 lambda_stack[256], lambda_ptr, lambda_count;
unsigned int ptr, length;
Uint16 llen, mlen, rlen, xlen;
Label labels[MAXLABELS];
Macro macros[MAXMACROS];
Reference refs[MAXREFS];
ExpItem exps[MAXEXPS];
char scope[0x40];
char lambda[0x10];
Uint32 total;
} Program;

Expand Down Expand Up @@ -228,6 +230,13 @@ makereference(char *scope, char *label, Uint16 addr)
return 1;
}

static char*makelambda(int id) {
scpy("?lambda", p.lambda, 8);
p.lambda[7] = '0' + (id >> 0x4);
p.lambda[8] = '0' + (id & 0xf);
return p.lambda;
}

static int makeexp(Uint8 kind,char*name,Uint32 len,Uint8 misc) {
ExpItem*e;
if(p.xlen==MAXEXPS) return error("Expansion limit exceeded","");
Expand Down Expand Up @@ -548,6 +557,13 @@ parse(char *w, FILE *f)
if(!makeexp('^',w+1,0,0)) return 0;
p.exps[p.xlen-1].len=p.ptr;
break;
case '{': /* lambda start */
p.lambda_stack[p.lambda_ptr++] = p.lambda_count;
makereference(p.scope, makelambda(p.lambda_count++), p.ptr + 1);
return writebyte(0x60) && writeshort(0xffff, 0);
case '}': /* lambda end */
if(!makelabel(makelambda(p.lambda_stack[--p.lambda_ptr])+1)) return error("Invalid label", w);
return writebyte(0x6f);
case '[':
case ']':
if(slen(w) == 1) break;
Expand Down

0 comments on commit feba063

Please sign in to comment.