Index: class.c ================================================================== --- class.c +++ class.c @@ -749,22 +749,22 @@ case MAC_ADD: n=0; for(;;) { nxttok(); if(tokent==TF_MACRO+TF_CLOSE) break; - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n+=tokenv; } tokent=TF_INT; tokenv=n; break; case MAC_SUB: nxttok(); - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n=tokenv; nxttok(); - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n-=tokenv; nxttok(); if(tokent!=TF_MACRO+TF_CLOSE) ParseError("Too many macro arguments\n"); tokent=TF_INT; tokenv=n; @@ -772,35 +772,35 @@ case MAC_MUL: n=1; for(;;) { nxttok(); if(tokent==TF_MACRO+TF_CLOSE) break; - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n*=tokenv; } tokent=TF_INT; tokenv=n; break; case MAC_DIV: nxttok(); - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n=tokenv; nxttok(); - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); if(!tokenv) ParseError("Division by zero\n"); n/=tokenv; nxttok(); if(tokent!=TF_MACRO+TF_CLOSE) ParseError("Too many macro arguments\n"); tokent=TF_INT; tokenv=n; break; case MAC_MOD: nxttok(); - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n=tokenv; nxttok(); - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); if(!tokenv) ParseError("Division by zero\n"); n%=tokenv; nxttok(); if(tokent!=TF_MACRO+TF_CLOSE) ParseError("Too many macro arguments\n"); tokent=TF_INT; @@ -809,11 +809,11 @@ case MAC_BAND: n=-1; for(;;) { nxttok(); if(tokent==TF_MACRO+TF_CLOSE) break; - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n&=tokenv; } tokent=TF_INT; tokenv=n; break; @@ -820,11 +820,11 @@ case MAC_BOR: n=0; for(;;) { nxttok(); if(tokent==TF_MACRO+TF_CLOSE) break; - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n|=tokenv; } tokent=TF_INT; tokenv=n; break; @@ -831,19 +831,19 @@ case MAC_BXOR: n=0; for(;;) { nxttok(); if(tokent==TF_MACRO+TF_CLOSE) break; - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n^=tokenv; } tokent=TF_INT; tokenv=n; break; case MAC_BNOT: nxttok(); - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); n=~tokenv; nxttok(); if(tokent!=TF_MACRO+TF_CLOSE) ParseError("Too many macro arguments\n"); tokent=TF_INT; tokenv=n; @@ -875,11 +875,11 @@ case MAC_BIT: n=0; for(;;) { nxttok(); if(tokent==TF_MACRO+TF_CLOSE) break; - if(tokent!=TF_INT) ParseError("Number expected\n"); + if(tokent!=TF_INT && tokent!=TF_NAME+TF_DIR && tokent!=TF_NAME+TF_KEY) ParseError("Number expected\n"); if(tokenv<32) n|=1<n<=n || !macstack->args[n]) ParseError("Cannot edit nonexistent argument %u\n",n+1); + if(macstack->args[n]->t&(TF_MACRO|TF_EOF)) ParseError("Invalid edit token\n"); macstack->args[n]->t=tokent; macstack->args[n]->v=tokenv; macstack->args[n]->str=0; if(*tokenstr) { macstack->args[n]->str=strdup(tokenstr); Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -209,10 +209,13 @@ Modulo. {version } Expands into nothing. The number must be zero, otherwise it is an error. Future versions of Free Hero Mesh may change this. + +All arithmetic/bitwise macros also allow their arguments to be directions +and keys, in which case they are treated as the corresponding numbers. It is possible to implement a tag system in this preprocessor, which makes it Turing complete. For example: {define "skip" {call \2}}