about summary refs log blame commit diff stats
path: root/config.def.h
blob: 83a8c183c3d72ee5d8b6849949d9976d4fb49f60 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                                         
 
                






                                                                        



                                                                
 
             
                                                                               
 
                
                                                                         

                                                                   
  
 
               
                              
                                                                                          
 
                    


                                                                              

  
                     
                       





                                                                          
              
                                                                              

                                                                                                                                                                                         
                                                                          
                                                                          
                                                                          

                                                                                       
                                                                          
                                                                          
                                                                          


                                                                          
                                                                                    
                                                                                    








                                                                                      
                                                                          
  
/* See LICENSE file for copyright and license details. */

/* appearance */
#define FONT            "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"
#define NORMBORDERCOLOR "#cccccc"
#define NORMBGCOLOR     "#cccccc"
#define NORMFGCOLOR     "#000000"
#define SELBORDERCOLOR  "#0066ff"
#define SELBGCOLOR      "#0066ff"
#define SELFGCOLOR      "#ffffff"
unsigned int borderpx  = 1;        /* border pixel of windows */
unsigned int snap      = 32;       /* snap pixel */
Bool showbar           = True;     /* False means no bar */
Bool topbar            = True;     /* False means bottom bar */

/* tagging */
const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };

Rule rules[] = {
	/* class      instance    title       tags ref      isfloating */
	{ "Gimp",     NULL,       NULL,       0,            True },
	{ "Firefox",  NULL,       NULL,       1 << 8,       True },
};

/* layout(s) */
double mfact           = 0.55;
Bool resizehints       = False;     /* False means respect size hints in tiled resizals */

Layout layouts[] = {
	/* symbol     arrange function */
	{ "[]=",      tile }, /* first entry is default */
	{ "><>",      NULL }, /* no layout function means floating behavior */
};

/* key definitions */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
        { MODKEY,                       KEY,      view,           TAG }, \
        { MODKEY|ControlMask,           KEY,      toggleview,     TAG }, \
        { MODKEY|ShiftMask,             KEY,      tag,            TAG }, \
        { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      TAG },

Key keys[] = {
	/* modifier                     key        function        argument */
	{ MODKEY,                       XK_p,      spawn,          (char *)"exec dmenu_run -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"' -sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"'" },
	{ MODKEY|ShiftMask,             XK_Return, spawn,          (char *)"exec uxterm" },
	{ MODKEY,                       XK_b,      togglebar,      NULL },
	{ MODKEY,                       XK_j,      focusnext,      NULL },
	{ MODKEY,                       XK_k,      focusprev,      NULL },
	{ MODKEY,                       XK_h,      setmfact,       (double[]){-0.05} },
	{ MODKEY,                       XK_l,      setmfact,       (double[]){+0.05} },
	{ MODKEY,                       XK_m,      togglemax,      NULL },
	{ MODKEY,                       XK_Return, zoom,           NULL },
	{ MODKEY,                       XK_Tab,    view,           NULL },
	{ MODKEY|ShiftMask,             XK_c,      killclient,     NULL },
	{ MODKEY,                       XK_space,  togglelayout,   NULL },
	{ MODKEY|ShiftMask,             XK_space,  togglefloating, NULL },
	{ MODKEY,                       XK_0,      view,           (uint[]){ ~0 } },
	{ MODKEY|ShiftMask,             XK_0,      tag,            (uint[]){ ~0 } },
	TAGKEYS(                        XK_1,                      (uint[]){ 1 << 0} )
	TAGKEYS(                        XK_2,                      (uint[]){ 1 << 1} )
	TAGKEYS(                        XK_3,                      (uint[]){ 1 << 2} )
	TAGKEYS(                        XK_4,                      (uint[]){ 1 << 3} )
	TAGKEYS(                        XK_5,                      (uint[]){ 1 << 4} )
	TAGKEYS(                        XK_6,                      (uint[]){ 1 << 5} )
	TAGKEYS(                        XK_7,                      (uint[]){ 1 << 6} )
	TAGKEYS(                        XK_8,                      (uint[]){ 1 << 7} )
	TAGKEYS(                        XK_9,                      (uint[]){ 1 << 8} )
	{ MODKEY|ShiftMask,             XK_q,      quit,           NULL },
};
an>" ": 0= 0 = ;\n" ": 0< 0 < ;\n" ": 0> 0 > ;\n" ": <> = 0= ;\n" ": <= > 0= ;\n" ": >= < 0= ;\n" ": 0<= 0 <= ;\n" ": 0>= 0 >= ;\n" ": 1+ 1 + ;\n" ": 1- 1 - ;\n" ": 2+ 2 + ;\n" ": 2- 2 - ;\n" ": 2/ 2 / ;\n" ": 2* 2 * ;\n" ": D2/ 2. D/ ;\n" ": +! DUP @ ROT + SWAP ! ;\n" ": [COMPILE] WORD FIND >CFA , ; IMMEDIATE\n" ": [CHAR] key ' LIT , , ; IMMEDIATE\n" ": RECURSE LATEST @ >CFA , ; IMMEDIATE\n" ": DOCOL 0 ;\n" ": CONSTANT CREATE DOCOL , ' LIT , , ' EXIT , ;\n" ": 2CONSTANT SWAP CREATE DOCOL , ' LIT , , ' LIT , , ' EXIT , ;\n" ": VARIABLE HERE @ CELL ALLOT CREATE DOCOL , ' LIT , , ' EXIT , ;\n" /* TODO: Allot AFTER the code, not before */ ": 2VARIABLE HERE @ 2 CELLS ALLOT CREATE DOCOL , ' LIT , , ' EXIT , ;\n" /* TODO: Allot AFTER the code, not before */ ": IF ' 0BRANCH , HERE @ 0 , ; IMMEDIATE\n" ": THEN DUP HERE @ SWAP - SWAP ! ; IMMEDIATE\n" ": ELSE ' BRANCH , HERE @ 0 , SWAP DUP HERE @ SWAP - SWAP ! ; IMMEDIATE\n" ": BEGIN HERE @ ; IMMEDIATE\n" ": UNTIL ' 0BRANCH , HERE @ - , ; IMMEDIATE\n" ": AGAIN ' BRANCH , HERE @ - , ; IMMEDIATE\n" ": WHILE ' 0BRANCH , HERE @ 0 , ; IMMEDIATE\n" ": REPEAT ' BRANCH , SWAP HERE @ - , DUP HERE @ SWAP - SWAP ! ; IMMEDIATE\n" ": UNLESS ' 0= , [COMPILE] IF ; IMMEDIATE\n" ": DO HERE @ ' SWAP , ' >R , ' >R , ; IMMEDIATE\n" ": LOOP ' R> , ' R> , ' SWAP , ' 1+ , ' 2DUP , ' = , ' 0BRANCH , HERE @ - , ' 2DROP , ; IMMEDIATE\n" ": +LOOP ' R> , ' R> , ' SWAP , ' ROT , ' + , ' 2DUP , ' <= , ' 0BRANCH , HERE @ - , ' 2DROP , ; IMMEDIATE\n" ": I ' R@ , ; IMMEDIATE\n" ": SPACES DUP 0> IF 0 DO SPACE LOOP ELSE DROP THEN ;\n" ": ABS DUP 0< IF NEGATE THEN ;\n" ": DABS 2DUP 0. D< IF DNEGATE THEN ;\n" ": .DIGIT DUP 9 > IF 55 ELSE 48 THEN + EMIT ;\n" ": .SIGN DUP 0< IF 45 EMIT NEGATE THEN ;\n" /* BUG: 10000000000... will be shown wrong */ ": .POS BASE @ /MOD ?DUP IF RECURSE THEN .DIGIT ;\n" ": . .SIGN DUP IF .POS ELSE .DIGIT THEN ;\n" ": COUNTPOS SWAP 1 + SWAP BASE @ / ?DUP IF RECURSE THEN ;\n" ": DIGITS DUP 0< IF 1 ELSE 0 THEN SWAP COUNTPOS ;\n" ": .R OVER DIGITS - SPACES . ;\n" ": . . SPACE ;\n" ": ? @ . ;\n" ": .S DSP@ BEGIN DUP S0@ > WHILE DUP ? CELL - REPEAT DROP ;\n" ": TYPE 0 DO DUP C@ EMIT 1 + LOOP DROP ;\n" ": ALIGN BEGIN HERE @ CELL MOD WHILE 0 C, REPEAT ;\n" ": s\" ' LITSTRING , HERE @ 0 , BEGIN KEY DUP 34 <> WHILE C, REPEAT DROP DUP HERE @ SWAP - CELL - SWAP ! ALIGN ; IMMEDIATE\n" ": .\" [COMPILE] s\" ' TYPE , ; IMMEDIATE\n" ": ( BEGIN KEY [CHAR] ) = UNTIL ; IMMEDIATE\n" ": COUNT DUP 1+ SWAP C@ ;\n" ": MIN 2DUP < IF DROP ELSE NIP THEN ;\n" ": MAX 2DUP > IF DROP ELSE NIP THEN ;\n" ": D0= OR 0= ;\n" ": DMIN 2OVER 2OVER D< IF 2DROP ELSE 2NIP THEN ;\n" ": DMAX 2OVER 2OVER D> IF 2DROP ELSE 2NIP THEN ;\n" ; /******************************************************************************/ /* The primary data output function. This is the place to change if you want * to e.g. output data on a microcontroller via a serial interface. */ void putkey(char c) { putchar(c); } /* The primary data input function. This is where you place the code to e.g. * read from a serial line. */ int llkey() { if (*initscript_pos) return *(initscript_pos++); return getchar(); } /* Anything waiting in the keyboard buffer? */ int keyWaiting() { return positionInLineBuffer < charsInLineBuffer ? -1 : 0; } /* Line buffered character input. We're duplicating the functionality of the * stdio library here to make the code easier to port to other input sources */ int getkey() { int c; if (keyWaiting()) return lineBuffer[positionInLineBuffer++]; charsInLineBuffer = 0; while ((c = llkey()) != EOF) { if (charsInLineBuffer == sizeof(lineBuffer)) break; lineBuffer[charsInLineBuffer++] = c; if (c == '\n') break; } positionInLineBuffer = 1; return lineBuffer[0]; } /* C string output */ void tell(const char *str) { while (*str) putkey(*str++); } /* The basic (data) stack operations */ cell pop() { if (*sp == 1) { tell("? Stack underflow\n"); errorFlag = 1; return 0; } return stack[--(*sp)]; } cell tos() { if (*sp == 1) { tell("? Stack underflow\n"); errorFlag = 1; return 0; } return stack[(*sp)-1]; } void push(cell data) { if (*sp >= STACK_SIZE) { tell("? Stack overflow\n"); errorFlag = 1; return; } stack[(*sp)++] = data; } dcell dpop() { cell tmp[2]; tmp[1] = pop(); tmp[0] = pop(); return *((dcell*)tmp); } void dpush(dcell data) { cell tmp[2]; *((dcell*)tmp) = data; push(tmp[0]); push(tmp[1]); } /* The basic return stack operations */ cell rpop() { if (*rsp == 1) { tell("? RStack underflow\n"); errorFlag = 1; return 0; } return rstack[--(*rsp)]; } void rpush(cell data) { if (*rsp >= RSTACK_SIZE) { tell("? RStack overflow\n"); errorFlag = 1; return; } rstack[(*rsp)++] = data; } /* Secure memory access */ cell readMem(cell address) { if (address > MEM_SIZE) { tell("Internal error in readMem: Invalid addres\n"); errorFlag = 1; return 0; } return *((cell*)(memory + address)); } void writeMem(cell address, cell value) { if (address > MEM_SIZE) { tell("Internal error in writeMem: Invalid address\n"); errorFlag = 1; return; } *((cell*)(memory + address)) = value; } /* Reading a word into the input line buffer */ byte readWord() { char *line = (char*)memory; byte len = 0; int c; while ((c = getkey()) != EOF) { if (c == ' ') continue; if (c == '\n') continue; if (c != '\\') break; while ((c = getkey()) != EOF) if (c == '\n') break; } while (c != ' ' && c != '\n' && c != EOF) { if (len >= (INPUT_LINE_SIZE - 1)) break; line[++len] = c; c = getkey(); } line[0] = len; return len; } /* toupper() clone so we don't have to pull in ctype.h */ char up(char c) { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } /* Dictionary lookup */ cell findWord(cell address, cell len) { cell ret = *latest; char *name = (char*)&memory[address]; cell i; int found; for (ret = *latest; ret; ret = readMem(ret)) { if ((memory[ret + CELL_SIZE] & MASK_NAMELENGTH) != len) continue; if (memory[ret + CELL_SIZE] & FLAG_HIDDEN) continue; found = 1; for (i = 0; i < len; i++) { if (up(memory[ret + i + 1 + CELL_SIZE]) != up(name[i])) { found = 0; break; } } if (found) break; } return ret; } /* Basic number parsing, base <= 36 only atm */ void parseNumber(byte *word, cell len, dcell *number, cell *notRead, byte *isDouble) { int negative = 0; cell i; char c; cell current; *number = 0; *isDouble = 0; if (len == 0) { *notRead = 0; return; } if (word[0] == '-') { negative = 1; len--; word++; } else if (word[0] == '+') { len--; word++; } for (i = 0; i < len; i++) { c = *word; word++; if (c == '.') { *isDouble = 1; continue; } else if (c >= '0' && c <= '9') current = c - '0'; else if (c >= 'A' && c <= 'Z') current = 10 + c - 'A'; else if (c >= 'a' && c <= 'z') current = 10 + c - 'a'; else break; if (current >= *base) break; *number = *number * *base + current; } *notRead = len - i; if (negative) *number = (-((scell)*number)); } /******************************************************************************* * * Builtin definitions * *******************************************************************************/ BUILTIN(0, "RUNDOCOL", docol, 0) { rpush(lastIp); next = commandAddress + CELL_SIZE; } /* The first few builtins are very simple, not need to waste vertical space here */ BUILTIN( 1, "CELL", doCellSize, 0) { push(CELL_SIZE); } BUILTIN( 2, "@", memRead, 0) { push(readMem(pop())); } BUILTIN( 3, "C@", memReadByte, 0) { push(memory[pop()]); } BUILTIN( 4, "KEY", key, 0) { push(getkey()); } BUILTIN( 5, "EMIT", emit, 0) { putkey(pop() & 255); } BUILTIN( 6, "DROP", drop, 0) { pop(); } BUILTIN( 7, "EXIT", doExit, 0) { next = rpop(); } BUILTIN( 8, "BYE", bye, 0) { exitReq = 1; } BUILTIN( 9, "LATEST", doLatest, 0) { push(LATEST_POSITION); } BUILTIN(10, "HERE", doHere, 0) { push(HERE_POSITION); } BUILTIN(11, "BASE", doBase, 0) { push(BASE_POSITION); } BUILTIN(12, "STATE", doState, 0) { push(STATE_POSITION); } BUILTIN(13, "[", gotoInterpreter, FLAG_IMMEDIATE) { *state = 0; } BUILTIN(14, "]", gotoCompiler, 0) { *state = 1; } BUILTIN(15, "HIDE", hide, 0) { memory[*latest + CELL_SIZE] ^= FLAG_HIDDEN; } BUILTIN(16, "R>", rtos, 0) { push(rpop()); } BUILTIN(17, ">R", stor, 0) { rpush(pop()); } BUILTIN(18, "KEY?", key_p, 0) { push(keyWaiting()); } BUILTIN(19, "BRANCH", branch, 0) { next += readMem(next); } BUILTIN(20, "0BRANCH", zbranch, 0) { next += pop() ? CELL_SIZE : readMem(next); } BUILTIN(21, "IMMEDIATE", toggleImmediate, FLAG_IMMEDIATE) { memory[*latest + CELL_SIZE] ^= FLAG_IMMEDIATE; } BUILTIN(22, "FREE", doFree, 0) { push(MEM_SIZE - *here); } BUILTIN(23, "S0@", s0_r, 0) { push(STACK_POSITION + CELL_SIZE); } BUILTIN(24, "DSP@", dsp_r, 0) { push(STACK_POSITION + *sp * CELL_SIZE); } BUILTIN(25, "NOT", not, 0) { push(~pop()); } BUILTIN(26, "DUP", dup, 0) { push(tos()); } BUILTIN(27, "!", memWrite, 0) { cell address = pop(); cell value = pop(); writeMem(address, value); } BUILTIN(28, "C!", memWriteByte, 0) { cell address = pop(); cell value = pop(); memory[address] = value & 255; } BUILTIN(29, "SWAP", swap, 0) { cell a = pop(); cell b = pop(); push(a); push(b); } BUILTIN(30, "OVER", over, 0) { cell a = pop(); cell b = tos(); push(a); push(b); } BUILTIN(31, ",", comma, 0) { push(*here); memWrite(); *here += CELL_SIZE; } BUILTIN(32, "C,", commaByte, 0) { push(*here); memWriteByte(); *here += sizeof(byte); } BUILTIN(33, "WORD", word, 0) { byte len = readWord(); push(1); push(len); } BUILTIN(34, "FIND", find, 0) { cell len = pop(); cell address = pop(); cell ret = findWord(address, len); push(ret); } cell getCfa(cell address) { byte len = (memory[address + CELL_SIZE] & MASK_NAMELENGTH) + 1; while ((len & (CELL_SIZE-1)) != 0) len++; return address + CELL_SIZE + len; } BUILTIN(35, ">CFA", cfa, 0) { cell address = pop(); cell ret = getCfa(address); if (ret < maxBuiltinAddress) push(readMem(ret)); else push(ret); } BUILTIN(36, "NUMBER", number, 0) { dcell num; cell notRead; byte isDouble; cell len = pop(); byte* address = &memory[pop()]; parseNumber(address, len, &num, &notRead, &isDouble); if (isDouble) dpush(num); else push((cell)num); push(notRead); } BUILTIN(37, "LIT", lit, 0) { push(readMem(next)); next += CELL_SIZE; } /* Outer and inner interpreter, TODO split up */ BUILTIN(38, "QUIT", quit, 0) { cell address; dcell number; cell notRead; cell command; int i; byte isDouble; cell tmp[2]; int immediate; for (exitReq = 0; exitReq == 0;) { lastIp = next = quit_address; errorFlag = 0; word(); find(); address = pop(); if (address) { immediate = (memory[address + CELL_SIZE] & FLAG_IMMEDIATE); commandAddress = getCfa(address); command = readMem(commandAddress); if (*state && !immediate) { if (command < MAX_BUILTIN_ID && command != docol_id) push(command); else push(commandAddress); comma(); } else { while (!errorFlag && !exitReq) { if (command == quit_id) break; else if (command < MAX_BUILTIN_ID) builtins[command](); else { lastIp = next; next = command; } commandAddress = next; command = readMem(commandAddress); next += CELL_SIZE; } } } else { parseNumber(&memory[1], memory[0], &number, &notRead, &isDouble); if (notRead) { tell("Unknown word: "); for (i=0; i<memory[0]; i++) putkey(memory[i+1]); putkey('\n'); *sp = *rsp = 1; continue; } else { if (*state) { *((dcell*)tmp) = number; push(lit_id); comma(); if (isDouble) { push(tmp[0]); comma(); push(lit_id); comma(); push(tmp[1]); comma(); } else { push((cell)number); comma(); } } else { if (isDouble) dpush(number); else push((cell)number); } } } if (errorFlag) *sp = *rsp = 1; else if (!keyWaiting() && !(*initscript_pos)) tell(" OK\n"); } } BUILTIN(39, "+", plus, 0) { scell n1 = pop(); scell n2 = pop(); push(n1 + n2); } BUILTIN(40, "-", minus, 0) { scell n1 = pop(); scell n2 = pop(); push(n2 - n1); } BUILTIN(41, "*", mul, 0) { scell n1 = pop(); scell n2 = pop(); push(n1 * n2); } BUILTIN(42, "/MOD", divmod, 0) { scell n1 = pop(); scell n2 = pop(); push(n2 % n1); push(n2 / n1); } BUILTIN(43, "ROT", rot, 0) { cell a = pop(); cell b = pop(); cell c = pop(); push(b); push(a); push(c); } void createWord(const char* name, byte len, byte flags); BUILTIN(44, "CREATE", doCreate, 0) { byte len; cell address; word(); len = pop() & 255; address = pop(); createWord((char*)&memory[address], len, 0); } BUILTIN(45, ":", colon, 0) { doCreate(); push(docol_id); comma(); hide(); *state = 1; } BUILTIN(46, ";", semicolon, FLAG_IMMEDIATE) { push(doExit_id); comma(); hide(); *state = 0; } BUILTIN(47, "R@", rget, 0) { cell tmp = rpop(); rpush(tmp); push(tmp); } BUILTIN(48, "J", doJ, 0) { cell tmp1 = rpop(); cell tmp2 = rpop(); cell tmp3 = rpop(); rpush(tmp3); rpush(tmp2); rpush(tmp1); push(tmp3); } BUILTIN(49, "'", tick, FLAG_IMMEDIATE) { word(); find(); cfa(); if (*state) { push(lit_id); comma(); comma(); } } BUILTIN(50, "=", equals, 0) { cell a1 = pop(); cell a2 = pop(); push(a2 == a1 ? -1 : 0); } BUILTIN(51, "<", smaller, 0) { scell a1 = pop(); scell a2 = pop(); push(a2 < a1 ? -1 : 0); } BUILTIN(52, ">", larger, 0) { scell a1 = pop(); scell a2 = pop(); push(a2 > a1 ? -1 : 0); } BUILTIN(53, "AND", doAnd, 0) { cell a1 = pop(); cell a2 = pop(); push(a2 & a1); } BUILTIN(54, "OR", doOr, 0) { cell a1 = pop(); cell a2 = pop(); push(a2 | a1); } BUILTIN(55, "?DUP", p_dup, 0) { cell a = tos(); if (a) push(a); } BUILTIN(56, "LITSTRING", litstring, 0) { cell length = readMem(next); next += CELL_SIZE; push(next); push(length); next += length; while (next & (CELL_SIZE-1)) next++; } BUILTIN(57, "XOR", xor, 0) { cell a = pop(); cell b = pop(); push(a ^ b); } BUILTIN(58, "*/", timesDivide, 0) { cell n3 = pop(); dcell n2 = pop(); dcell n1 = pop(); dcell r = (n1 * n2) / n3; push((cell)r); if ((cell)r != r) { tell("Arithmetic overflow\n"); errorFlag = 1; } } BUILTIN(59, "*/MOD", timesDivideMod, 0) { cell n3 = pop(); dcell n2 = pop(); dcell n1 = pop(); dcell r = (n1 * n2) / n3; dcell m = (n1 * n2) % n3; push((cell)m); push((cell)r); if ((cell)r != r) { tell("Arithmetic overflow\n"); errorFlag = 1; } } BUILTIN(60, "D=", dequals, 0) { dcell a1 = dpop(); dcell a2 = dpop(); push(a2 == a1 ? -1 : 0); } BUILTIN(61, "D<", dsmaller, 0) { dscell a1 = dpop(); dscell a2 = dpop(); push(a2 < a1 ? -1 : 0); } BUILTIN(62, "D>", dlarger, 0) { dscell a1 = dpop(); dscell a2 = dpop(); push(a2 > a1 ? -1 : 0); } BUILTIN(63, "DU<", dusmaller, 0) { dcell a1 = dpop(); dcell a2 = dpop(); push(a2 < a1 ? -1 : 0); } BUILTIN(64, "D+", dplus, 0) { dscell n1 = dpop(); dscell n2 = dpop(); dpush(n1 + n2); } BUILTIN(65, "D-", dminus, 0) { dscell n1 = dpop(); dscell n2 = dpop(); dpush(n2 - n1); } BUILTIN(66, "D*", dmul, 0) { dscell n1 = dpop(); dscell n2 = dpop(); dpush(n1 * n2); } BUILTIN(67, "D/", ddiv, 0) { dscell n1 = dpop(); dscell n2 = dpop(); dpush(n2 / n1); } BUILTIN(68, "2SWAP", dswap, 0) { dcell a = dpop(); dcell b = dpop(); dpush(a); dpush(b); } BUILTIN(69, "2OVER", dover, 0) { dcell a = dpop(); dcell b = dpop(); dpush(b); dpush(a); dpush(b); } BUILTIN(70, "2ROT", drot, 0) { dcell a = dpop(); dcell b = dpop(); dcell c = dpop(); dpush(b); dpush(a); dpush(c); } /******************************************************************************* * * Loose ends * *******************************************************************************/ /* Create a word in the dictionary */ void createWord(const char* name, byte len, byte flags) { cell newLatest = *here; push(*latest); comma(); push(len | flags); commaByte(); while (len--) { push(*name); commaByte(); name++; } while (*here & (CELL_SIZE-1)) { push(0); commaByte(); } *latest = newLatest; } /* A simple strlen clone so we don't have to pull in string.h */ byte slen(const char *str) { byte ret = 0; while (*str++) ret++; return ret; } /* Add a builtin to the dictionary */ void addBuiltin(cell code, const char* name, const byte flags, builtin f) { if (errorFlag) return; if (code >= MAX_BUILTIN_ID) { tell("Error adding builtin "); tell(name); tell(": Out of builtin IDs\n"); errorFlag = 1; return; } if (builtins[code] != 0) { tell("Error adding builtin "); tell(name); tell(": ID given twice\n"); errorFlag = 1; return; } builtins[code] = f; createWord(name, slen(name), flags); push(code); comma(); push(doExit_id); comma(); } /* Program setup and jump to outer interpreter */ int main() { errorFlag = 0; if (DCELL_SIZE != 2*CELL_SIZE) { tell("Configuration error: DCELL_SIZE != 2*CELL_SIZE\n"); return 1; } state = (cell*)&memory[STATE_POSITION]; base = (cell*)&memory[BASE_POSITION]; latest = (cell*)&memory[LATEST_POSITION]; here = (cell*)&memory[HERE_POSITION]; sp = (cell*)&memory[STACK_POSITION]; stack = (cell*)&memory[STACK_POSITION + CELL_SIZE]; rsp = (cell*)&memory[RSTACK_POSITION]; rstack = (cell*)&memory[RSTACK_POSITION + CELL_SIZE]; *sp = *rsp = 1; *state = 0; *base = 10; *latest = 0; *here = HERE_START; ADD_BUILTIN(docol); ADD_BUILTIN(doCellSize); ADD_BUILTIN(memRead); ADD_BUILTIN(memWrite); ADD_BUILTIN(memReadByte); ADD_BUILTIN(memWriteByte); ADD_BUILTIN(key); ADD_BUILTIN(emit); ADD_BUILTIN(swap); ADD_BUILTIN(dup); ADD_BUILTIN(drop); ADD_BUILTIN(over); ADD_BUILTIN(comma); ADD_BUILTIN(commaByte); ADD_BUILTIN(word); ADD_BUILTIN(find); ADD_BUILTIN(cfa); ADD_BUILTIN(doExit); ADD_BUILTIN(quit); quit_address = getCfa(*latest); ADD_BUILTIN(number); ADD_BUILTIN(bye); ADD_BUILTIN(doLatest); ADD_BUILTIN(doHere); ADD_BUILTIN(doBase); ADD_BUILTIN(doState); ADD_BUILTIN(plus); ADD_BUILTIN(minus); ADD_BUILTIN(mul); ADD_BUILTIN(divmod); ADD_BUILTIN(rot); ADD_BUILTIN(gotoInterpreter); ADD_BUILTIN(gotoCompiler); ADD_BUILTIN(doCreate); ADD_BUILTIN(hide); ADD_BUILTIN(lit); ADD_BUILTIN(colon); ADD_BUILTIN(semicolon); ADD_BUILTIN(rtos); ADD_BUILTIN(stor); ADD_BUILTIN(rget); ADD_BUILTIN(doJ); ADD_BUILTIN(tick); ADD_BUILTIN(key_p); ADD_BUILTIN(equals); ADD_BUILTIN(smaller); ADD_BUILTIN(larger); ADD_BUILTIN(doAnd); ADD_BUILTIN(doOr); ADD_BUILTIN(branch); ADD_BUILTIN(zbranch); ADD_BUILTIN(toggleImmediate); ADD_BUILTIN(doFree); ADD_BUILTIN(p_dup); ADD_BUILTIN(s0_r); ADD_BUILTIN(dsp_r); ADD_BUILTIN(litstring); ADD_BUILTIN(not); ADD_BUILTIN(xor); ADD_BUILTIN(timesDivide); ADD_BUILTIN(timesDivideMod); ADD_BUILTIN(dequals); ADD_BUILTIN(dsmaller); ADD_BUILTIN(dlarger); ADD_BUILTIN(dusmaller); ADD_BUILTIN(dplus); ADD_BUILTIN(dminus); ADD_BUILTIN(dmul); ADD_BUILTIN(ddiv); ADD_BUILTIN(dswap); ADD_BUILTIN(dover); ADD_BUILTIN(drot); maxBuiltinAddress = (*here) - 1; if (errorFlag) return 1; initscript_pos = (char*)initScript; quit(); return 0; }