Advertisement
Guest User

Lisp.zh

a guest
Feb 4th, 2016
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 82.84 KB | None | 0 0
  1. import "std.zh"
  2. import "string.zh"
  3.  
  4. ////////////////////////////////////////////////////////////////
  5. // Characters
  6.  
  7. const int CHAR_QUOTE = 39; // '
  8. const int CHAR_TAB = 9;
  9. const int CHAR_NEWLINE = 10;
  10.  
  11. bool Lisp_Char_IsWhitespace(int c) {
  12.   return c == CHAR_TAB || c == CHAR_NEWLINE || c == ' ';}
  13.  
  14. bool Lisp_Char_IsSymbol(int c) {
  15.   return !Lisp_Char_IsWhitespace(c) && c
  16.     && c != '(' && c != ')' && c != CHAR_QUOTE;}
  17.  
  18. bool Lisp_Char_IsSymbolStart(int c) {
  19.   return Lisp_Char_IsSymbol(c) && !isNumber(c);}
  20.  
  21. ////////////////////////////////////////////////////////////////
  22. // Strings
  23.  
  24. // Computes a hash code for a string.  Implementation of djb2. Not sure if
  25. // it'll have problems because it's not a "long".
  26. int Lisp_StringHash(int string_array, int string_offset) {
  27.   int hash = 5381;
  28.   int i = string_offset;
  29.   while (0 != string_array[i]) {
  30.     hash = (hash << 5) + hash + string_array[string_offset + i];
  31.     ++i;}
  32.   return hash;}
  33.  
  34. // Write a string into an array, returning the new end index.
  35. int Lisp_WriteString(int array, int offset, int string) {
  36.   return Lisp_WriteString(array, offset, string, 0);}
  37. int Lisp_WriteString(int array, int offset, int string, int string_offset) {
  38.   int i;
  39.   for (i = string_offset; string[i] != 0 && i < SizeOfArray(string); ++i) {
  40.     array[offset] = string[i];
  41.     ++offset;}
  42.   return offset;}
  43.  
  44. ////////////////////////////////////////////////////////////////
  45. // Data Types
  46.  
  47. // Denotes one of the builtin values.
  48. const int LISP_TYPE_BUILTIN = 0x20000;
  49. // Denotes an object in the main memory array.
  50. const int LISP_TYPE_OBJECT  = 0x10000;
  51. // Denotes a symbol.
  52. const int LISP_TYPE_SYMBOL  = 0x08000;
  53.  
  54. // Pointer Screen Indices.
  55. const int LISP_TYPE_POINTER       = 0x24000;
  56. const int LISP_POINTER_TYPE_MASK  = 0x00300;
  57. const int LISP_POINTER_INDEX_MASK = 0x000FF;
  58. const int LISP_TYPE_NPC           = 0x00000;
  59. const int LISP_TYPE_ITEM          = 0x00100;
  60. const int LISP_TYPE_LWEAPON       = 0x00200;
  61. const int LISP_TYPE_EWEAPON       = 0x00300;
  62.  
  63. //// These flags are for the memory info array.
  64. // Indicates a cell object.
  65. const int LISP_MEMORY_CELL     = 0x10000;
  66. // For reference counting.
  67. const int LISP_MEMORY_REF_MASK  = 0x0000F;
  68. const int LISP_MEMORY_MAX_REF   = 0x0000F;
  69. // Marks an object as being permanent.
  70. const int LISP_MEMORY_PERMANENT = 0x00010;
  71.  
  72.  
  73. // If a given value references an object.
  74. bool Lisp_IsObject(int x) {return x & LISP_TYPE_OBJECT;}
  75.  
  76. bool Lisp_IsPointer(int x) {return LISP_LINK == x || (x & LISP_TYPE_POINTER) == LISP_TYPE_POINTER;}
  77.  
  78. // If a given value is a number.
  79. bool Lisp_IsNumber(int x) {
  80.   if (x < 0) {return true;}
  81.   if (Lisp_IsObject(x)) {return false;}
  82.   if (Lisp_IsSymbol(x)) {return false;}
  83.   if (Lisp_IsPointer(x)) {return false;}
  84.   return true;}
  85.  
  86. ////////////////////////////////////////////////////////////////
  87. // Memory
  88.  
  89. // The size of the memory.
  90. const int LISP_MEMORY_SIZE = 65536;
  91. // Holds flags about the info at the given index.
  92. int Lisp_Memory_Info[65536];
  93. // Holds the actual memory. Object type determines the interpretation.
  94. int Lisp_Memory_A[65536];
  95. int Lisp_Memory_B[65536];
  96. // Last index used in memory.
  97. int Lisp_Memory_LastAddress = -1;
  98.  
  99. // Return true if the memory address is free.
  100. bool Lisp_Memory_IsFree(int address) {
  101.   if (0 == address) {return false;}
  102.     if (LISP_MEMORY_PERMANENT & Lisp_Memory_Info[address]) {return false;}
  103.   return 0 == (Lisp_Memory_Info[address] & LISP_MEMORY_REF_MASK);}
  104.  
  105. // Return the number of memory addresses in use.
  106. int Lisp_Memory_InUseCount() {
  107.     int count = 0;
  108.     for (int i = 0; i < LISP_MEMORY_SIZE; ++i) {
  109.         if (!Lisp_Memory_IsFree(i)) {++count;}}
  110.     return count;}
  111.  
  112. // Increment the ref count for the object. If the object is increased from 0 references
  113. void Lisp_Memory_IncRefCount(int object) {
  114.   if (!Lisp_IsObject(object)) {return;}
  115.   int address = object & ~LISP_TYPE_OBJECT;
  116.   // Don't increment past the max value.
  117.     int refcount = Lisp_Memory_Info[address] & LISP_MEMORY_REF_MASK;
  118.     if (refcount < LISP_MEMORY_MAX_REF) {
  119.         ++Lisp_Memory_Info[address];}}
  120.  
  121. // Decrement the ref count for the object. If the object is reduced
  122. // to 0 references, will also reduce the ref counts of its references.
  123. void Lisp_Memory_DecRefCount(int object) {
  124.     if (!Lisp_IsObject(object)) {return;}
  125.     int address = object & ~LISP_TYPE_OBJECT;
  126.     int refcount = Lisp_Memory_Info[address] & LISP_MEMORY_REF_MASK;
  127.   // If it's at the max value, we don't know how many there are.
  128.     if (LISP_MEMORY_MAX_REF == refcount) {return;}
  129.     // Don't decrement past 0.
  130.     if (refcount > 0) {--Lisp_Memory_Info[address];}}
  131.  
  132. // Attempt to garbage collect a single object and its references by using
  133. // refcounts.
  134. void Lisp_Memory_GC(int object) {
  135.     while (true) {
  136.         if (!Lisp_IsObject(object)) {return;}
  137.         int address = object & ~LISP_TYPE_OBJECT;
  138.         // Don't gc permanent objects.
  139.         if (LISP_MEMORY_PERMANENT & Lisp_Memory_Info[address]) {return;}
  140.         // Make sure the refcount is 0.
  141.         if ((Lisp_Memory_Info[address] & LISP_MEMORY_REF_MASK) > 0) {return;}
  142.  
  143.         // If it's a cell.
  144.         if (Lisp_IsCell(object)) {
  145.             // Decrease children's ref counts.
  146.             Lisp_Memory_DecRefCount(Lisp_Memory_A[address]);
  147.             Lisp_Memory_DecRefCount(Lisp_Memory_B[address]);
  148.             // Attempt to GC children. Tail is done in-loop as an optimization for lists.
  149.             Lisp_Memory_GC(Lisp_Memory_A[address]);
  150.             object = Lisp_Memory_B[address];}}}
  151.  
  152. // List of all permanent objects.
  153. int Lisp_Memory_Permanents[100];
  154. int Lisp_Memory_PermanentCount = 0;
  155.  
  156. bool Lisp_Memory_Permanent(int object) {
  157.   if (!Lisp_IsObject(object)) {return false;}
  158.     return Lisp_Memory_Info[object & ~LISP_TYPE_OBJECT] & LISP_MEMORY_PERMANENT;}
  159. void Lisp_Memory_Permanent(int object, bool value) {
  160.   if (!Lisp_IsObject(object)) {return;}
  161.     bool current  = Lisp_Memory_Permanent(object);
  162.     if (current == value) {return;}
  163.     if (value) {
  164.         // Mark as permanent.
  165.         Lisp_Memory_Info[object & ~LISP_TYPE_OBJECT] |= LISP_MEMORY_PERMANENT;
  166.         // Add to permanent list.
  167.         Lisp_Memory_Permanents[Lisp_Memory_PermanentCount] = object;
  168.         ++Lisp_Memory_PermanentCount;}
  169.     else {
  170.         // Mark as not permanent.
  171.         Lisp_Memory_Info[object & ~LISP_TYPE_OBJECT] &= ~LISP_MEMORY_PERMANENT;
  172.         // Remove from the permanent list.
  173.         int i;
  174.         for (i = 0; i < Lisp_Memory_PermanentCount; ++i) {
  175.             if (object == Lisp_Memory_Permanents[i]) {break;}}
  176.         for (; i < Lisp_Memory_PermanentCount - 1; ++i) {
  177.             Lisp_Memory_Permanents[i] = Lisp_Memory_Permanents[i + 1];}
  178.         --Lisp_Memory_PermanentCount;}}
  179.  
  180. // Garbage collect (mark & sweep).
  181. void Lisp_Memory_GC() {
  182.     bool mark[65536];
  183.     int queue[65536];
  184.  
  185.     // Initialize queue with permanents.
  186.     memcpy(queue, 0, Lisp_Memory_Permanents, 0, Lisp_Memory_PermanentCount);
  187.     int queue_size = Lisp_Memory_PermanentCount;
  188.  
  189.     // Start marking things.
  190.     int queue_index = 0;
  191.     while (queue_index < queue_size) {
  192.         int object = queue[queue_index];
  193.         if (Lisp_IsObject(object)) {
  194.             int mark_index = object & ~LISP_TYPE_OBJECT;
  195.             if (!mark[mark_index]) {
  196.                 mark[mark_index] = true;
  197.  
  198.                 if (Lisp_IsCell(object)) {
  199.                     int head = Lisp_Cell_Head(object);
  200.                     if (head) {
  201.                         queue[queue_size] = head;
  202.                         ++queue_size;}
  203.                     int tail = Lisp_Cell_Tail(object);
  204.                     if (tail) {
  205.                         queue[queue_size] = tail;
  206.                         ++queue_size;}}}}
  207.         ++queue_index;
  208.     }
  209.  
  210.     // Free everything that doesn't have a mark.
  211.     for (int i = 0; i < LISP_MEMORY_SIZE; ++i)  {
  212.         if (!mark[i] && i < 520) {
  213.             Lisp_Memory_Info[i] &= ~LISP_MEMORY_REF_MASK;}}
  214. }
  215.  
  216. ////////////////////////////////////////////////////////////////
  217. // Cells
  218.  
  219. // If a given value indicates a cell.
  220. bool Lisp_IsCell(int x) {return LISP_NIL == x || x & LISP_TYPE_OBJECT;}
  221.  
  222. // Creates a new cell in memory.
  223. int Lisp_Cell() {
  224.   // Advance until we find a free cell.
  225.   int address = (Lisp_Memory_LastAddress + 1) % LISP_MEMORY_SIZE;
  226.   while (!Lisp_Memory_IsFree(address) && address != Lisp_Memory_LastAddress) {
  227.     address = (address + 1) % LISP_MEMORY_SIZE;}
  228.  
  229.   // If we failed, complain.
  230.   if (Lisp_Memory_LastAddress == address) {
  231.     Lisp_Cell_OutOfMemory();
  232.     return 0;}
  233.  
  234.   // Save last used address
  235.   Lisp_Memory_LastAddress = address;
  236.  
  237.   // Initialize that address as being a cell.
  238.   Lisp_Memory_Info[address] = LISP_MEMORY_CELL;
  239.  
  240.   // Clear the data.
  241.   Lisp_Memory_A[address] = LISP_NIL;
  242.   Lisp_Memory_B[address] = LISP_NIL;
  243.  
  244.   // Return pointer.
  245.   return LISP_TYPE_OBJECT | address;}
  246. void Lisp_Cell_OutOfMemory() {
  247.   int msg[]="ERROR - Lisp_Cell() - Out of Memory.\n";
  248.   printf(msg);}
  249.  
  250. // Get the head of a cell.
  251. int Lisp_Cell_Head(int cell) {
  252.   if (cell == LISP_NIL) {return LISP_NIL;}
  253.   if (!Lisp_IsCell(cell)) {
  254.     Lisp_Cell_Head_Error(cell);
  255.     return LISP_NIL;}
  256.   int address = cell & ~LISP_TYPE_OBJECT;
  257.   return Lisp_Memory_A[address];}
  258. void Lisp_Cell_Head_Error(int value) {
  259.   int msg[] = "ERROR: Attempted to get head of <%d>.\n";
  260.   printf(msg, value);}
  261. // Get the tail of a cell.
  262. int Lisp_Cell_Tail(int cell) {
  263.   if (cell == LISP_NIL) {return LISP_NIL;}
  264.   if (!Lisp_IsCell(cell)) {
  265.     Lisp_Cell_Tail_Error(cell);
  266.     return LISP_NIL;}
  267.   int address = cell & ~LISP_TYPE_OBJECT;
  268.   return Lisp_Memory_B[address];}
  269. void Lisp_Cell_Tail_Error(int value) {
  270.   int msg[] = "ERROR: Attempted to get tail of <%d>.\n";
  271.   printf(msg, value);}
  272. // Set the head of a cell. Returns the cell.
  273. int Lisp_Cell_Head(int cell, int value) {
  274.   int address = cell & ~LISP_TYPE_OBJECT;
  275.   Lisp_Memory_IncRefCount(value);
  276.   Lisp_Memory_DecRefCount(Lisp_Memory_A[address]);
  277.   Lisp_Memory_A[address] = value;
  278.   return cell;}
  279. // Set the tail of a cell. Returns the cell.
  280. int Lisp_Cell_Tail(int cell, int value) {
  281.   int address = cell & ~LISP_TYPE_OBJECT;
  282.   Lisp_Memory_IncRefCount(value);
  283.   Lisp_Memory_DecRefCount(Lisp_Memory_B[address]);
  284.   Lisp_Memory_B[address] = value;
  285.   return cell;}
  286.  
  287. // Convenience method for creating a cell.
  288. int Lisp_Cell(int head, int tail) {
  289.   int cell = Lisp_Cell();
  290.   Lisp_Cell_Head(cell, head);
  291.   Lisp_Cell_Tail(cell, tail);
  292.   return cell;}
  293.  
  294. // Convenience method for creating a list.
  295. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  296.               int a8, int a9, int aa, int ab, int ac, int ad, int ae, int af) {
  297.   int args[0x10];
  298.   arrayset(args, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af);
  299.   int head = Lisp_Cell(a0, LISP_NIL);
  300.   int cell = head;
  301.   for (int i = 1; i < 0x10 && args[i] != 0; ++i) {
  302.     int tmp = Lisp_Cell(args[i], LISP_NIL);
  303.     Lisp_Cell_Tail(cell, tmp);
  304.     cell = tmp;}
  305.   return head;}
  306.  
  307. ////////////////////////////////////////////////////////////////
  308. // Symbols
  309.  
  310. // Holds each symbol string consecutively.
  311. int Lisp_Symbol_Data[214747];
  312. // Next open spot in Lisp_Symbol_Data.
  313. int Lisp_Symbol_NextIndex = 0;
  314. // Index into Lisp_SymbolStrings for a given symbol.
  315. int Lisp_Symbol_Indices[32768];
  316. // Maximum number of symbols.
  317. const int LISP_SYMBOL_COUNT = 0x08000;
  318.  
  319. bool Lisp_IsSymbol(int symbol) {
  320.   return (symbol & LISP_TYPE_SYMBOL) && (symbol & ~LISP_TYPE_OBJECT);}
  321.  
  322. // Get the symbol for a given string, creating it if needed.
  323. int Lisp_Symbol_Get(int array) {return Lisp_Symbol_Get(array, 0);}
  324. int Lisp_Symbol_Get(int array, int offset) {
  325.   int symbol; int i;
  326.   int index = Floor(Lisp_StringHash(array, offset)) % LISP_SYMBOL_COUNT;
  327.   if (index < 0) {index += LISP_SYMBOL_COUNT;}
  328.   int end_index = (LISP_SYMBOL_COUNT + index - 1) % LISP_SYMBOL_COUNT;
  329.   while (index != end_index) {
  330.     int string_index = Lisp_Symbol_Indices[index] - 1;
  331.     // If we hit an empty space, the symbol is unknown and we need to make it.
  332.     if (-1 == string_index) {
  333.       // Save the string's start.
  334.       Lisp_Symbol_Indices[index] = Lisp_Symbol_NextIndex + 1;
  335.       // Copy over the string.
  336.       for (i = 0; array[offset + i] != 0; ++i) {
  337.         Lisp_Symbol_Data[Lisp_Symbol_NextIndex + i] = array[offset + i];}
  338.       Lisp_Symbol_Data[Lisp_Symbol_NextIndex + i] = 0;
  339.       Lisp_Symbol_NextIndex += i + 1;
  340.       // Return the symbol.
  341.       return LISP_TYPE_SYMBOL | index;}
  342.     // If we hit a filled space, return if it's the right symbol.
  343.     else if (0 == strcmp(Lisp_Symbol_Data, string_index, array, offset)) {
  344.       return LISP_TYPE_SYMBOL | index;}
  345.     // Advance to the next index.
  346.     index = (index + 1) % LISP_SYMBOL_COUNT;}
  347.   // Failure. OOM.
  348.   return -1;}
  349.  
  350. ////////////////////////////////////////////////////////////////
  351. // Bultin Values
  352.  
  353. const int LISP_FALSE       = 0x20000;
  354. const int LISP_TRUE        = 0x20001;
  355. const int LISP_ENV         = 0x20002;
  356. const int LISP_FUNCTION    = 0x20003;
  357. const int LISP_MACRO       = 0x20004;
  358. const int LISP_HEAD        = 0x20005;
  359. const int LISP_TAIL        = 0x20006;
  360. const int LISP_LIST        = 0x20007;
  361. const int LISP_ADD         = 0x20008;
  362. const int LISP_SUBTRACT    = 0x20009;
  363. const int LISP_MULTIPLY    = 0x2000A;
  364. const int LISP_DIVIDE      = 0x2000B;
  365. const int LISP_SET         = 0x2000C;
  366. const int LISP_LET         = 0x2000D;
  367. const int LISP_DO          = 0x2000E;
  368. const int LISP_QUOTE       = 0x2000F;
  369. const int LISP_NIL         = 0x20010;
  370. const int LISP_IF          = 0x20011;
  371. const int LISP_CELL        = 0x20012;
  372. const int LISP_WHILE       = 0x20013;
  373. const int LISP_PRINT       = 0x20014;
  374. const int LISP_DEFINE      = 0x20015;
  375. const int LISP_VARARG      = 0x20016;
  376. const int LISP_NOT         = 0x20017;
  377. const int LISP_LT          = 0x20018;
  378. const int LISP_GT          = 0x20019;
  379. const int LISP_EQ          = 0x2001A;
  380. const int LISP_LTE         = 0x2001B;
  381. const int LISP_GTE         = 0x2001C;
  382. const int LISP_NPC         = 0x2001D;
  383. const int LISP_ITEM        = 0x2001E;
  384. const int LISP_LWEAPON     = 0x2001F;
  385. const int LISP_EWEAPON     = 0x20020;
  386. const int LISP_LINK        = 0x20021;
  387. const int LISP_NPC_P       = 0x20022;
  388. const int LISP_ITEM_P      = 0x20023;
  389. const int LISP_LWEAPON_P   = 0x20024;
  390. const int LISP_EWEAPON_P   = 0x20025;
  391. const int LISP_LINK_P      = 0x20026;
  392. const int LISP_VALID       = 0x20027;
  393. const int LISP_X           = 0x20028;
  394. const int LISP_Y           = 0x20029;
  395. const int LISP_Z           = 0x2002A;
  396. const int LISP_WAITDRAW    = 0x2002B;
  397. const int LISP_WAITFRAME   = 0x2002C;
  398. const int LISP_INPUT_START = 0x2002D;
  399. const int LISP_INPUT_MAP   = 0x2002E;
  400. const int LISP_INPUT_UP    = 0x2002F;
  401. const int LISP_INPUT_DOWN  = 0x20030;
  402. const int LISP_INPUT_LEFT  = 0x20031;
  403. const int LISP_INPUT_RIGHT = 0x20032;
  404. const int LISP_INPUT_L     = 0x20033;
  405. const int LISP_INPUT_R     = 0x20034;
  406. const int LISP_INPUT_EX1   = 0x20035;
  407. const int LISP_INPUT_EX2   = 0x20036;
  408. const int LISP_INPUT_EX3   = 0x20037;
  409. const int LISP_INPUT_EX4   = 0x20038;
  410. const int LISP_PRESS_START = 0x20039;
  411. const int LISP_PRESS_MAP   = 0x2003A;
  412. const int LISP_PRESS_UP    = 0x2003B;
  413. const int LISP_PRESS_DOWN  = 0x2003C;
  414. const int LISP_PRESS_LEFT  = 0x2003D;
  415. const int LISP_PRESS_RIGHT = 0x2003E;
  416. const int LISP_PRESS_L     = 0x2003F;
  417. const int LISP_PRESS_R     = 0x20040;
  418. const int LISP_PRESS_EX1   = 0x20041;
  419. const int LISP_PRESS_EX2   = 0x20042;
  420. const int LISP_PRESS_EX3   = 0x20043;
  421. const int LISP_PRESS_EX4   = 0x20044;
  422. const int LISP_DIR         = 0x20045;
  423. const int LISP_HP          = 0x20046;
  424. const int LISP_NPC_COUNT      = 0x20047;
  425. const int LISP_ITEM_COUNT     = 0x20048;
  426. const int LISP_LWEAPON_COUNT  = 0x20049;
  427. const int LISP_EWEAPON_COUNT  = 0x2004A;
  428. const int LISP_CUR_SCREEN     = 0x2004B;
  429. const int LISP_CUR_DSCREEN    = 0x2004C;
  430. const int LISP_CUR_LEVEL      = 0x2004D;
  431. const int LISP_CUR_MAP        = 0x2004E;
  432. const int LISP_CUR_DMAP       = 0x2004F;
  433. const int LISP_SCREEN_CHANGED = 0x20050;
  434. const int LISP_ACTIVE_WAITFRAME = 0x20051;
  435. const int LISP_MEMORY_IN_USE = 0x20052;
  436.  
  437. bool Lisp_IsBuiltin(int x) {return x & LISP_TYPE_BUILTIN && x < LISP_TYPE_POINTER;}
  438.  
  439. ////////////////////////////////////////////////////////////////
  440. // Standard Symbols
  441.  
  442. // Report whether or not a symbol matches the given value.
  443. void Lisp_Symbol_Check(int string, int target) {
  444.   int value = Lisp_Symbol_Get(string);
  445.   if (target != value) {Lisp_Symbol_Check_Fail(string, value);}}
  446. void Lisp_Symbol_Check_Fail(int string, int value) {
  447.   int msg[] = "ERROR: Symbol <%s> needs to be value <%d>.\n";
  448.   printf(msg, string, value);}
  449.  
  450. const int LISP_SYM_FALSE = 43152;
  451. const int LISP_SYM_TRUE = 46093;
  452. const int LISP_SYM_ENV = 49859;
  453. const int LISP_SYM_FUNCTION = 40645;
  454. const int LISP_SYM_MACRO = 39720;
  455. const int LISP_SYM_HEAD = 62296;
  456. const int LISP_SYM_TAIL = 59959;
  457. const int LISP_SYM_LIST = 47170;
  458. const int LISP_SYM_ADD = 46544;
  459. const int LISP_SYM_SUBTRACT = 46546;
  460. const int LISP_SYM_MULTIPLY = 46543;
  461. const int LISP_SYM_DIVIDE = 46548;
  462. const int LISP_SYM_SET = 64806;
  463. const int LISP_SYM_LET = 57183;
  464. const int LISP_SYM_DO = 46973;
  465. const int LISP_SYM_QUOTE = 33651;
  466. const int LISP_SYM_NIL = 59485;
  467. const int LISP_SYM_IF = 47129;
  468. const int LISP_SYM_CELL = 50311;
  469. const int LISP_SYM_WHILE = 65362;
  470. const int LISP_SYM_PRINT = 54460;
  471. const int LISP_SYM_DEFINE = 53246;
  472. const int LISP_SYM_VARARG = 46539;
  473. const int LISP_SYM_NOT = 59691;
  474. const int LISP_SYM_LT = 46561;
  475. const int LISP_SYM_GT = 46563;
  476. const int LISP_SYM_EQ = 46562;
  477. const int LISP_SYM_LTE = 45603;
  478. const int LISP_SYM_GTE = 45669;
  479. const int LISP_SYM_NPC = 59707;
  480. const int LISP_SYM_ITEM = 49173;
  481. const int LISP_SYM_LWEAPON = 40325;
  482. const int LISP_SYM_EWEAPON = 41464;
  483. const int LISP_SYM_LINK = 46996;
  484. const int LISP_SYM_NPC_P = 60550;
  485. const int LISP_SYM_ITEM_P = 46395;
  486. const int LISP_SYM_LWEAPON_P = 42298;
  487. const int LISP_SYM_EWEAPON_P = 34304;
  488. const int LISP_SYM_LINK_P = 44756;
  489. const int LISP_SYM_VALID = 48268;
  490. const int LISP_SYM_X = 46621;
  491. const int LISP_SYM_Y = 46622;
  492. const int LISP_SYM_Z = 46623;
  493. const int LISP_SYM_WAITDRAW    = 33074;
  494. const int LISP_SYM_WAITFRAME   = 46975;
  495. const int LISP_SYM_INPUT_START = 40578;
  496. const int LISP_SYM_INPUT_MAP   = 62184;
  497. const int LISP_SYM_INPUT_UP    = 53687;
  498. const int LISP_SYM_INPUT_DOWN  = 33265;
  499. const int LISP_SYM_INPUT_LEFT  = 47172;
  500. const int LISP_SYM_INPUT_RIGHT = 52469;
  501. const int LISP_SYM_INPUT_L     = 51228;
  502. const int LISP_SYM_INPUT_R     = 51234;
  503. const int LISP_SYM_INPUT_EX1   = 54168;
  504. const int LISP_SYM_INPUT_EX2   = 54169;
  505. const int LISP_SYM_INPUT_EX3   = 54170;
  506. const int LISP_SYM_INPUT_EX4   = 54171;
  507. const int LISP_SYM_PRESS_START = 52024;
  508. const int LISP_SYM_PRESS_MAP   = 51277;
  509. const int LISP_SYM_PRESS_UP    = 50450;
  510. const int LISP_SYM_PRESS_DOWN  = 54889;
  511. const int LISP_SYM_PRESS_LEFT  = 36028;
  512. const int LISP_SYM_PRESS_RIGHT = 63915;
  513. const int LISP_SYM_PRESS_L     = 43468;
  514. const int LISP_SYM_PRESS_R     = 43474;
  515. const int LISP_SYM_PRESS_EX1   = 43261;
  516. const int LISP_SYM_PRESS_EX2   = 43262;
  517. const int LISP_SYM_PRESS_EX3   = 43263;
  518. const int LISP_SYM_PRESS_EX4   = 43264;
  519. const int LISP_SYM_DIR         = 48601;
  520. const int LISP_SYM_HP          = 47106;
  521. const int LISP_SYM_NPC_COUNT     = 63203;
  522. const int LISP_SYM_ITEM_COUNT    = 35825;
  523. const int LISP_SYM_LWEAPON_COUNT = 41457;
  524. const int LISP_SYM_EWEAPON_COUNT = 44517;
  525. const int LISP_SYM_CUR_SCREEN     = 61272;
  526. const int LISP_SYM_CUR_DSCREEN    = 64781;
  527. const int LISP_SYM_CUR_LEVEL      = 57704;
  528. const int LISP_SYM_CUR_MAP        = 60024;
  529. const int LISP_SYM_CUR_DMAP       = 37548;
  530. const int LISP_SYM_SCREEN_CHANGED = 35692;
  531. const int LISP_SYM_ACTIVE_WAITFRAME = 44930;
  532. const int LISP_SYM_MEMORY_IN_USE    = 62240;
  533.  
  534. // Initialize the standard symbols.
  535. int Lisp_Symbol_Init() {
  536.   int _false[]    = "false";    Lisp_Symbol_Check(_false,    LISP_SYM_FALSE);
  537.   int _true[]     = "true";     Lisp_Symbol_Check(_true,     LISP_SYM_TRUE);
  538.   int env[]       = "env";      Lisp_Symbol_Check(env,       LISP_SYM_ENV);
  539.   int _function[] = "function"; Lisp_Symbol_Check(_function, LISP_SYM_FUNCTION);
  540.   int macro[]     = "macro";    Lisp_Symbol_Check(macro,     LISP_SYM_MACRO);
  541.   int head[]      = "head";     Lisp_Symbol_Check(head,      LISP_SYM_HEAD);
  542.   int tail[]      = "tail";     Lisp_Symbol_Check(tail,      LISP_SYM_TAIL);
  543.   int list[]      = "list";     Lisp_Symbol_Check(list,      LISP_SYM_LIST);
  544.   int add[]       = "+";        Lisp_Symbol_Check(add,       LISP_SYM_ADD);
  545.   int subtract[]  = "-";        Lisp_Symbol_Check(subtract,  LISP_SYM_SUBTRACT);
  546.   int multiply[]  = "*";        Lisp_Symbol_Check(multiply,  LISP_SYM_MULTIPLY);
  547.   int divide[]    = "/";        Lisp_Symbol_Check(divide,    LISP_SYM_DIVIDE);
  548.   int set[]       = "set";      Lisp_Symbol_Check(set,       LISP_SYM_SET);
  549.   int let[]       = "let";      Lisp_Symbol_Check(let,       LISP_SYM_LET);
  550.   int _do[]       = "do";       Lisp_Symbol_Check(_do,       LISP_SYM_DO);
  551.   int quote[]     = "quote";    Lisp_Symbol_Check(quote,     LISP_SYM_QUOTE);
  552.   int nil[]       = "nil";      Lisp_Symbol_Check(nil,       LISP_SYM_NIL);
  553.   int _if[]       = "if";       Lisp_Symbol_Check(_if,       LISP_SYM_IF);
  554.   int cell[]      = "cell";     Lisp_Symbol_Check(cell,      LISP_SYM_CELL);
  555.   int _while[]    = "while";    Lisp_Symbol_Check(_while,    LISP_SYM_WHILE);
  556.   int print[]     = "print";    Lisp_Symbol_Check(print,     LISP_SYM_PRINT);
  557.   int define[]    = "define";   Lisp_Symbol_Check(define,    LISP_SYM_DEFINE);
  558.   int vararg[]    = "&";        Lisp_Symbol_Check(vararg,    LISP_SYM_VARARG);
  559.   int not[]       = "not";      Lisp_Symbol_Check(not,       LISP_SYM_NOT);
  560.   int lt[]        = "<";        Lisp_Symbol_Check(lt,        LISP_SYM_LT);
  561.   int gt[]        = ">";        Lisp_Symbol_Check(gt,        LISP_SYM_GT);
  562.   int eq[]        = "=";        Lisp_Symbol_Check(eq,        LISP_SYM_EQ);
  563.   int lte[]       = "<=";       Lisp_Symbol_Check(lte,       LISP_SYM_LTE);
  564.   int gte[]       = ">=";       Lisp_Symbol_Check(gte,       LISP_SYM_GTE);
  565.   int _npc[]      = "npc";      Lisp_Symbol_Check(_npc,      LISP_SYM_NPC);
  566.   int _item[]     = "item";     Lisp_Symbol_Check(_item,     LISP_SYM_ITEM);
  567.   int _lweapon[]  = "lweapon";  Lisp_Symbol_Check(_lweapon,  LISP_SYM_LWEAPON);
  568.   int _eweapon[]  = "eweapon";  Lisp_Symbol_Check(_eweapon,  LISP_SYM_EWEAPON);
  569.   int _link[]     = "link";     Lisp_Symbol_Check(_link,     LISP_SYM_LINK);
  570.   int npc_p[]     = "npc?";     Lisp_Symbol_Check(npc_p,     LISP_SYM_NPC_P);
  571.   int item_p[]    = "item?";    Lisp_Symbol_Check(item_p,    LISP_SYM_ITEM_P);
  572.   int lweapon_p[] = "lweapon?"; Lisp_Symbol_Check(lweapon_p, LISP_SYM_LWEAPON_P);
  573.   int eweapon_p[] = "eweapon?"; Lisp_Symbol_Check(eweapon_p, LISP_SYM_EWEAPON_P);
  574.   int link_p[]    = "link?";    Lisp_Symbol_Check(link_p,    LISP_SYM_LINK_P);
  575.   int valid[]     = "valid?";   Lisp_Symbol_Check(valid,     LISP_SYM_VALID);
  576.   int x[]         = "x";        Lisp_Symbol_Check(x,         LISP_SYM_X);
  577.   int y[]         = "y";        Lisp_Symbol_Check(y,         LISP_SYM_Y);
  578.   int z[]         = "z";        Lisp_Symbol_Check(z,         LISP_SYM_Z);
  579.   int waitdraw[]    = "waitdraw";    Lisp_Symbol_Check(waitdraw,    LISP_SYM_WAITDRAW);
  580.   int waitframe[]   = "waitframe";   Lisp_Symbol_Check(waitframe,   LISP_SYM_WAITFRAME);
  581.   int input_start[] = "input-start"; Lisp_Symbol_Check(input_start, LISP_SYM_INPUT_START);
  582.   int input_map[]   = "input-map";   Lisp_Symbol_Check(input_map  , LISP_SYM_INPUT_MAP);
  583.   int input_up[]    = "input-up";    Lisp_Symbol_Check(input_up   , LISP_SYM_INPUT_UP);
  584.   int input_down[]  = "input-down";  Lisp_Symbol_Check(input_down , LISP_SYM_INPUT_DOWN);
  585.   int input_left[]  = "input-left";  Lisp_Symbol_Check(input_left , LISP_SYM_INPUT_LEFT);
  586.   int input_right[] = "input-right"; Lisp_Symbol_Check(input_right, LISP_SYM_INPUT_RIGHT);
  587.   int input_l[]     = "input-l";     Lisp_Symbol_Check(input_l    , LISP_SYM_INPUT_L);
  588.   int input_r[]     = "input-r";     Lisp_Symbol_Check(input_r    , LISP_SYM_INPUT_R);
  589.   int input_ex1[]   = "input-ex1";   Lisp_Symbol_Check(input_ex1  , LISP_SYM_INPUT_EX1);
  590.   int input_ex2[]   = "input-ex2";   Lisp_Symbol_Check(input_ex2  , LISP_SYM_INPUT_EX2);
  591.   int input_ex3[]   = "input-ex3";   Lisp_Symbol_Check(input_ex3  , LISP_SYM_INPUT_EX3);
  592.   int input_ex4[]   = "input-ex4";   Lisp_Symbol_Check(input_ex4  , LISP_SYM_INPUT_EX4);
  593.   int press_start[] = "press-start"; Lisp_Symbol_Check(press_start, LISP_SYM_PRESS_START);
  594.   int press_map[]   = "press-map";   Lisp_Symbol_Check(press_map  , LISP_SYM_PRESS_MAP);
  595.   int press_up[]    = "press-up";    Lisp_Symbol_Check(press_up   , LISP_SYM_PRESS_UP);
  596.   int press_down[]  = "press-down";  Lisp_Symbol_Check(press_down , LISP_SYM_PRESS_DOWN);
  597.   int press_left[]  = "press-left";  Lisp_Symbol_Check(press_left , LISP_SYM_PRESS_LEFT);
  598.   int press_right[] = "press-right"; Lisp_Symbol_Check(press_right, LISP_SYM_PRESS_RIGHT);
  599.   int press_l[]     = "press-l";     Lisp_Symbol_Check(press_l    , LISP_SYM_PRESS_L);
  600.   int press_r[]     = "press-r";     Lisp_Symbol_Check(press_r    , LISP_SYM_PRESS_R);
  601.   int press_ex1[]   = "press-ex1";   Lisp_Symbol_Check(press_ex1  , LISP_SYM_PRESS_EX1);
  602.   int press_ex2[]   = "press-ex2";   Lisp_Symbol_Check(press_ex2  , LISP_SYM_PRESS_EX2);
  603.   int press_ex3[]   = "press-ex3";   Lisp_Symbol_Check(press_ex3  , LISP_SYM_PRESS_EX3);
  604.   int press_ex4[]   = "press-ex4";   Lisp_Symbol_Check(press_ex4  , LISP_SYM_PRESS_EX4);
  605.   int dir[]         = "dir";         Lisp_Symbol_Check(dir,         LISP_SYM_DIR);
  606.   int hp[]          = "hp";          Lisp_Symbol_Check(hp,          LISP_SYM_HP);
  607.   int npc_count[]     = "npc-count";     Lisp_Symbol_Check(npc_count,     LISP_SYM_NPC_COUNT);
  608.   int item_count[]    = "item-count";    Lisp_Symbol_Check(item_count,    LISP_SYM_ITEM_COUNT);
  609.   int lweapon_count[] = "lweapon-count"; Lisp_Symbol_Check(lweapon_count, LISP_SYM_LWEAPON_COUNT);
  610.   int eweapon_count[] = "eweapon-count"; Lisp_Symbol_Check(eweapon_count, LISP_SYM_EWEAPON_COUNT);
  611.   int cur_screen[]    = "current-screen";  Lisp_Symbol_Check(cur_screen,  LISP_SYM_CUR_SCREEN);
  612.   int cur_dscreen[]   = "current-dscreen"; Lisp_Symbol_Check(cur_dscreen, LISP_SYM_CUR_DSCREEN);
  613.   int cur_level[]     = "current-level";   Lisp_Symbol_Check(cur_level,   LISP_SYM_CUR_LEVEL);
  614.   int cur_map[]       = "current-map";     Lisp_Symbol_Check(cur_map,     LISP_SYM_CUR_MAP);
  615.   int cur_dmap[]       = "current-dmap";    Lisp_Symbol_Check(cur_dmap,    LISP_SYM_CUR_DMAP);
  616.   int screen_changed[] = "screen-changed";  Lisp_Symbol_Check(screen_changed, LISP_SYM_SCREEN_CHANGED);
  617.   int active_waitframe[]   = "active-waitframe";   Lisp_Symbol_Check(active_waitframe,   LISP_SYM_ACTIVE_WAITFRAME);
  618.     int memory_in_use[] = "memory-in-use"; Lisp_Symbol_Check(memory_in_use, LISP_SYM_MEMORY_IN_USE);
  619. }
  620.  
  621. ////////////////////////////////////////////////////////////////
  622. // Environment
  623.  
  624. // The default environment to use.
  625. int Lisp_Env_Root;
  626.  
  627. // Create a new environment.
  628. int Lisp_Env() {return Lisp_Env(LISP_NIL);}
  629. int Lisp_Env(int parent) {return Lisp_Cell(LISP_SYM_ENV, parent);}
  630.  
  631. // Get an entry in an environment.
  632. // env - the environment to search
  633. // key - the key to look for
  634. // local - if we ignore parent environments
  635. int Lisp_Env_GetEntry(int env, int key) {return Lisp_Env_Get(env, key, false);}
  636. int Lisp_Env_GetEntry(int env, int key, bool local) {
  637.   while (true) {
  638.     // Advance to the next entry.
  639.     env = Lisp_Cell_Tail(env);
  640.     // Quit if we've failed.
  641.     if (LISP_NIL == env) {return LISP_NIL;}
  642.  
  643.     int cell = Lisp_Cell_Head(env);
  644.     // If we've hit <env> again, it means we've reached a parent environment.
  645.     if (LISP_SYM_ENV == cell) {
  646.       // If we're restricted to local, fail.
  647.       if (local) {return LISP_NIL;}
  648.       // Otherwise skip this element.
  649.       continue;}
  650.  
  651.     // If we found the key, return the entry.
  652.     if (key == Lisp_Cell_Head(cell)) {return cell;}}}
  653.  
  654. // This is the actual get call.
  655. int Lisp_Env_Get(int env, int key) {return Lisp_Env_Get(env, key, false);}
  656. int Lisp_Env_Get(int env, int key, bool local) {
  657.   int entry = Lisp_Env_GetEntry(env, key, local);
  658.   if (LISP_NIL == entry) {return LISP_NIL;}
  659.   return Lisp_Cell_Tail(entry);}
  660.  
  661. // Set an environment value.
  662. // env - the environment to update.
  663. // key - the key to set.
  664. // value - the value to use.
  665. // local - if true, will force a new value in the immediate environment if it
  666. //     doesn't exist. Otherwise it will use a parent entry if available.
  667. void Lisp_Env_Set(int env, int key, int value) {Lisp_Env_Set(env, key, value, false);}
  668. void Lisp_Env_Set(int env, int key, int value, bool local) {
  669.   int entry = Lisp_Env_GetEntry(env, key, local);
  670.   // If there's no existing entry, stick it at the front of the environment.
  671.   if (LISP_NIL == entry) {
  672.     Lisp_Cell_Tail(env, Lisp_Cell(Lisp_Cell(key, value), Lisp_Cell_Tail(env)));}
  673.   // If there is an existing entry, update it.
  674.   else {
  675.     Lisp_Cell_Tail(entry, value);}}
  676.  
  677. // Create a new default environment.
  678. int Lisp_Env_Default() {
  679.   int env = Lisp_Env();
  680.   Lisp_Env_Set(env, LISP_SYM_FALSE,     LISP_FALSE);
  681.   Lisp_Env_Set(env, LISP_SYM_TRUE,      LISP_TRUE);
  682.   Lisp_Env_Set(env, LISP_SYM_ENV,       LISP_ENV);
  683.   Lisp_Env_Set(env, LISP_SYM_FUNCTION,  LISP_FUNCTION);
  684.   Lisp_Env_Set(env, LISP_SYM_MACRO,     LISP_MACRO);
  685.   Lisp_Env_Set(env, LISP_SYM_HEAD,      LISP_HEAD);
  686.   Lisp_Env_Set(env, LISP_SYM_TAIL,      LISP_TAIL);
  687.   Lisp_Env_Set(env, LISP_SYM_LIST,      LISP_LIST);
  688.   Lisp_Env_Set(env, LISP_SYM_ADD,       LISP_ADD);
  689.   Lisp_Env_Set(env, LISP_SYM_SUBTRACT,  LISP_SUBTRACT);
  690.   Lisp_Env_Set(env, LISP_SYM_MULTIPLY,  LISP_MULTIPLY);
  691.   Lisp_Env_Set(env, LISP_SYM_DIVIDE,    LISP_DIVIDE);
  692.   Lisp_Env_Set(env, LISP_SYM_SET,       LISP_SET);
  693.   Lisp_Env_Set(env, LISP_SYM_LET,       LISP_LET);
  694.   Lisp_Env_Set(env, LISP_SYM_DO,        LISP_DO);
  695.   Lisp_Env_Set(env, LISP_SYM_QUOTE,     LISP_QUOTE);
  696.   Lisp_Env_Set(env, LISP_SYM_NIL,       LISP_NIL);
  697.   Lisp_Env_Set(env, LISP_SYM_IF,        LISP_IF);
  698.   Lisp_Env_Set(env, LISP_SYM_CELL,      LISP_CELL);
  699.   Lisp_Env_Set(env, LISP_SYM_WHILE,     LISP_WHILE);
  700.   Lisp_Env_Set(env, LISP_SYM_PRINT,     LISP_PRINT);
  701.   Lisp_Env_Set(env, LISP_SYM_DEFINE,    LISP_DEFINE);
  702.   Lisp_Env_Set(env, LISP_SYM_VARARG,    LISP_VARARG);
  703.   Lisp_Env_Set(env, LISP_SYM_NOT,       LISP_NOT);
  704.   Lisp_Env_Set(env, LISP_SYM_LT,        LISP_LT);
  705.   Lisp_Env_Set(env, LISP_SYM_GT,        LISP_GT);
  706.   Lisp_Env_Set(env, LISP_SYM_EQ,        LISP_EQ);
  707.   Lisp_Env_Set(env, LISP_SYM_LTE,       LISP_LTE);
  708.   Lisp_Env_Set(env, LISP_SYM_GTE,       LISP_GTE);
  709.   Lisp_Env_Set(env, LISP_SYM_NPC,       LISP_NPC);
  710.   Lisp_Env_Set(env, LISP_SYM_ITEM,      LISP_ITEM);
  711.   Lisp_Env_Set(env, LISP_SYM_LWEAPON,   LISP_LWEAPON);
  712.   Lisp_Env_Set(env, LISP_SYM_EWEAPON,   LISP_EWEAPON);
  713.   Lisp_Env_Set(env, LISP_SYM_LINK,      LISP_LINK);
  714.   Lisp_Env_Set(env, LISP_SYM_NPC_P,     LISP_NPC_P);
  715.   Lisp_Env_Set(env, LISP_SYM_ITEM_P,    LISP_ITEM_P);
  716.   Lisp_Env_Set(env, LISP_SYM_LWEAPON_P, LISP_LWEAPON_P);
  717.   Lisp_Env_Set(env, LISP_SYM_EWEAPON_P, LISP_EWEAPON_P);
  718.   Lisp_Env_Set(env, LISP_SYM_LINK_P,    LISP_LINK_P);
  719.   Lisp_Env_Set(env, LISP_SYM_VALID,     LISP_VALID);
  720.   Lisp_Env_Set(env, LISP_SYM_X,         LISP_X);
  721.   Lisp_Env_Set(env, LISP_SYM_Y,         LISP_Y);
  722.   Lisp_Env_Set(env, LISP_SYM_Z,         LISP_Z);
  723.   Lisp_Env_Set(env, LISP_SYM_WAITDRAW,    LISP_WAITDRAW);
  724.   Lisp_Env_Set(env, LISP_SYM_WAITFRAME,   LISP_WAITFRAME);
  725.   Lisp_Env_Set(env, LISP_SYM_INPUT_START, LISP_INPUT_START);
  726.   Lisp_Env_Set(env, LISP_SYM_INPUT_MAP,   LISP_INPUT_MAP);
  727.   Lisp_Env_Set(env, LISP_SYM_INPUT_UP,    LISP_INPUT_UP);
  728.   Lisp_Env_Set(env, LISP_SYM_INPUT_DOWN,  LISP_INPUT_DOWN);
  729.   Lisp_Env_Set(env, LISP_SYM_INPUT_LEFT,  LISP_INPUT_LEFT);
  730.   Lisp_Env_Set(env, LISP_SYM_INPUT_RIGHT, LISP_INPUT_RIGHT);
  731.   Lisp_Env_Set(env, LISP_SYM_INPUT_L,     LISP_INPUT_L);
  732.   Lisp_Env_Set(env, LISP_SYM_INPUT_R,     LISP_INPUT_R);
  733.   Lisp_Env_Set(env, LISP_SYM_INPUT_EX1,   LISP_INPUT_EX1);
  734.   Lisp_Env_Set(env, LISP_SYM_INPUT_EX2,   LISP_INPUT_EX2);
  735.   Lisp_Env_Set(env, LISP_SYM_INPUT_EX3,   LISP_INPUT_EX3);
  736.   Lisp_Env_Set(env, LISP_SYM_INPUT_EX4,   LISP_INPUT_EX4);
  737.   Lisp_Env_Set(env, LISP_SYM_PRESS_START, LISP_PRESS_START);
  738.   Lisp_Env_Set(env, LISP_SYM_PRESS_MAP,   LISP_PRESS_MAP);
  739.   Lisp_Env_Set(env, LISP_SYM_PRESS_UP,    LISP_PRESS_UP);
  740.   Lisp_Env_Set(env, LISP_SYM_PRESS_DOWN,  LISP_PRESS_DOWN);
  741.   Lisp_Env_Set(env, LISP_SYM_PRESS_LEFT,  LISP_PRESS_LEFT);
  742.   Lisp_Env_Set(env, LISP_SYM_PRESS_RIGHT, LISP_PRESS_RIGHT);
  743.   Lisp_Env_Set(env, LISP_SYM_PRESS_L,     LISP_PRESS_L);
  744.   Lisp_Env_Set(env, LISP_SYM_PRESS_R,     LISP_PRESS_R);
  745.   Lisp_Env_Set(env, LISP_SYM_PRESS_EX1,   LISP_PRESS_EX1);
  746.   Lisp_Env_Set(env, LISP_SYM_PRESS_EX2,   LISP_PRESS_EX2);
  747.   Lisp_Env_Set(env, LISP_SYM_PRESS_EX3,   LISP_PRESS_EX3);
  748.   Lisp_Env_Set(env, LISP_SYM_PRESS_EX4,   LISP_PRESS_EX4);
  749.   Lisp_Env_Set(env, LISP_SYM_DIR,         LISP_DIR);
  750.   Lisp_Env_Set(env, LISP_SYM_HP,          LISP_HP);
  751.   Lisp_Env_Set(env, LISP_SYM_NPC_COUNT,      LISP_NPC_COUNT);
  752.   Lisp_Env_Set(env, LISP_SYM_ITEM_COUNT,     LISP_ITEM_COUNT);
  753.   Lisp_Env_Set(env, LISP_SYM_LWEAPON_COUNT,  LISP_LWEAPON_COUNT);
  754.   Lisp_Env_Set(env, LISP_SYM_EWEAPON_COUNT,  LISP_EWEAPON_COUNT);
  755.   Lisp_Env_Set(env, LISP_SYM_CUR_SCREEN,     LISP_CUR_SCREEN);
  756.   Lisp_Env_Set(env, LISP_SYM_CUR_DSCREEN,    LISP_CUR_DSCREEN);
  757.   Lisp_Env_Set(env, LISP_SYM_CUR_LEVEL,      LISP_CUR_LEVEL);
  758.   Lisp_Env_Set(env, LISP_SYM_CUR_MAP,        LISP_CUR_MAP);
  759.   Lisp_Env_Set(env, LISP_SYM_CUR_DMAP,       LISP_CUR_DMAP);
  760.   Lisp_Env_Set(env, LISP_SYM_SCREEN_CHANGED, LISP_SCREEN_CHANGED);
  761.   Lisp_Env_Set(env, LISP_SYM_ACTIVE_WAITFRAME, LISP_ACTIVE_WAITFRAME);
  762.   Lisp_Env_Set(env, LISP_SYM_MEMORY_IN_USE, LISP_MEMORY_IN_USE);
  763.   return env;}
  764.  
  765. ////////////////////////////////////////////////////////////////
  766. // Lists
  767.  
  768. // Get the nth value in a list.
  769. int Lisp_List_Nth(int list, int n) {
  770.   while (n > 0) {
  771.     list = Lisp_Cell_Tail(list);
  772.     if (!list) {return LISP_NIL;}
  773.     --n;}
  774.   return Lisp_Cell_Head(list);}
  775.  
  776. ////////////////////////////////////////////////////////////////
  777. // Initalization
  778.  
  779. void Lisp_Init() {
  780.   Lisp_Symbol_Init();
  781.   Lisp_Env_Root = Lisp_Env_Default();
  782.     Lisp_Memory_Permanent(Lisp_Env_Root, true);
  783.   int source[] = "
  784. (define defmacro
  785.  (macro (name & spec)
  786.    (list 'define name
  787.      (cell 'macro spec))))
  788. (defmacro defn (name & spec)
  789.  (list 'define name
  790.    (cell 'function spec)))
  791. (defmacro when (test & body)
  792.  (list 'if test (cell 'do body) nil))
  793. (defmacro unless (test & body)
  794.  (list 'if test (cell nil body)))
  795. (defn reverse (list)
  796.  (let (result nil)
  797.    (while list
  798.      (set result (cell (head list) result))
  799.      (set list (tail list)))
  800.    result))
  801. (defn nth (list n)
  802.  (while n
  803.    (set list (tail list))
  804.    (- n 1))
  805.  (head list))
  806. (defn map (f list)
  807.  (let (result nil)
  808.    (while list
  809.      (set result (cell (f (head list)) result))
  810.      (set list (tail list)))
  811.    (reverse result)))
  812. (defn range (count)
  813.  (let (result nil)
  814.    (while count
  815.      (set count (- count 1))
  816.      (set result (cell count result)))
  817.    result))
  818.  
  819. ;; Pointers
  820. (defn items ()
  821.  (map item (range (item-count))))
  822. (defn npcs ()
  823.  (map item (range (npc-count))))
  824. (defn lweapons ()
  825.  (map item (range (lweapon-count))))
  826. (defn eweapons ()
  827.  (map item (range (eweapon-count))))
  828. ";
  829.   Lisp_Eval(Lisp_Parse(source));
  830. }
  831.  
  832. ////////////////////////////////////////////////////////////////
  833. // Printing
  834.  
  835. // Write a lisp value into a string. Returns the new last offset.
  836. int Lisp_WriteValue(int array, int offset, int value) {
  837.   int index;
  838.  
  839.   // Several important builtins.
  840.   if (LISP_FALSE == value) {
  841.     index = Lisp_Symbol_Indices[LISP_SYM_FALSE & ~LISP_TYPE_SYMBOL] - 1;
  842.     offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}
  843.   else if (LISP_TRUE == value) {
  844.     index = Lisp_Symbol_Indices[LISP_SYM_TRUE & ~LISP_TYPE_SYMBOL] - 1;
  845.     offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}
  846.   else if (LISP_NIL == value) {
  847.     index = Lisp_Symbol_Indices[LISP_SYM_NIL & ~LISP_TYPE_SYMBOL] - 1;
  848.     offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}
  849.   else if (LISP_LINK == value) {
  850.     index = Lisp_Symbol_Indices[LISP_SYM_LINK & ~LISP_TYPE_SYMBOL] - 1;
  851.     array[offset] = '[';
  852.     offset = Lisp_WriteString(array, offset + 1, Lisp_Symbol_Data, index);
  853.     array[offset] = ']';
  854.     ++offset;}
  855.  
  856.   // A list.
  857.   else if (Lisp_IsCell(value)) {
  858.     array[offset] = '(';
  859.     offset += 1;
  860.     while (LISP_NIL != value) {
  861.       offset = Lisp_WriteValue(array, offset, Lisp_Cell_Head(value));
  862.       value = Lisp_Cell_Tail(value);
  863.       // If we reached the end of the list, quit.
  864.       if (LISP_NIL == value) {
  865.         array[offset] = ')';
  866.         offset = offset + 1;
  867.         break;}
  868.       // If we don't end on a null, do the special . form.
  869.       if (!Lisp_IsCell(value)) {
  870.         array[offset] = ' ';
  871.         array[offset + 1] = '.';
  872.         array[offset + 2] = ' ';
  873.         offset = Lisp_WriteValue(array, offset + 3, value);
  874.         array[offset] = ')';
  875.         offset = offset + 1;
  876.         break;}
  877.       array[offset] = ' ';
  878.       ++offset;}}
  879.  
  880.   // A symbol.
  881.   else if (Lisp_IsSymbol(value)) {
  882.     // Strip symbol marker.
  883.     value = value & ~LISP_TYPE_SYMBOL;
  884.     index = Lisp_Symbol_Indices[value] - 1;
  885.     if (-1 == index) {offset = Lisp_WriteValue_UnknownSymbol(array, offset);}
  886.     else {offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}}
  887.  
  888.   else if (Lisp_IsPointer(value)) {
  889.     array[offset] = '['; ++offset;
  890.     int type = LISP_POINTER_TYPE_MASK & value;
  891.     if (LISP_TYPE_NPC == type) {
  892.       index = Lisp_Symbol_Indices[LISP_SYM_NPC & ~LISP_TYPE_SYMBOL] - 1;
  893.       offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}
  894.     if (LISP_TYPE_ITEM == type) {
  895.       index = Lisp_Symbol_Indices[LISP_SYM_ITEM & ~LISP_TYPE_SYMBOL] - 1;
  896.       offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}
  897.     if (LISP_TYPE_LWEAPON == type) {
  898.       index = Lisp_Symbol_Indices[LISP_SYM_LWEAPON & ~LISP_TYPE_SYMBOL] - 1;
  899.       offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}
  900.     if (LISP_TYPE_EWEAPON == type) {
  901.       index = Lisp_Symbol_Indices[LISP_SYM_EWEAPON & ~LISP_TYPE_SYMBOL] - 1;
  902.       offset = Lisp_WriteString(array, offset, Lisp_Symbol_Data, index);}
  903.     array[offset] = ' '; ++offset;
  904.     offset += itoa(array, offset, (LISP_POINTER_INDEX_MASK & value) + 1);
  905.     array[offset] = ']'; ++offset;}
  906.  
  907.   // 0.
  908.   else if (0 == value) {
  909.     array[offset] = '0';
  910.     offset += 1;}
  911.  
  912.   // A number.
  913.   else {offset += ftoa(array, offset, value, true);}
  914.  
  915.   return offset;}
  916.  
  917. int Lisp_WriteValue_UnknownSymbol(int array, int offset) {
  918.   int msg[] = "unknown-symbol";
  919.   return Lisp_WriteString(array, offset, msg);}
  920.  
  921. // Create a formatted string.
  922. int Lisp_Format(int target, int format,
  923.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  924.                 int a8, int a9, int aa, int ab, int ac, int ad, int ae, int af) {
  925.   int args[0x10];
  926.   arrayset(args, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af);
  927.  
  928.   int target_i = 0; int format_i = 0; int args_i = 0;
  929.   while (0 != format[format_i] && target_i < SizeOfArray(target) - 1) {
  930.     int c = format[format_i];
  931.  
  932.     if ('~' == c) {
  933.       ++format_i;
  934.       c = format[format_i];
  935.  
  936.       if ('~' == c) {
  937.         target[target_i] = '~';
  938.         ++format_i;
  939.         ++target_i;
  940.         continue;}
  941.  
  942.       if ('%' == c) {
  943.         target[target_i] = 10; // newline
  944.         ++format_i;
  945.         ++target_i;
  946.         continue;}
  947.  
  948.       if ('D' == c) {
  949.         target_i += itoa(target, target_i, args[args_i]);
  950.         ++format_i;
  951.         ++args_i;
  952.         continue;}
  953.  
  954.       if ('X' == c) {
  955.         target_i += xtoa(target, target_i, args[args_i], true);
  956.         ++format_i;
  957.         ++args_i;
  958.         continue;}
  959.  
  960.       if ('A' == c) {
  961.         target_i = Lisp_WriteValue(target, target_i, args[args_i]);
  962.         ++format_i;
  963.         ++args_i;
  964.         continue;}}
  965.  
  966.     target[target_i] = format[format_i];
  967.     ++target_i;
  968.     ++format_i;}
  969.  
  970.   target[target_i] = 0;
  971.   return target_i;}
  972.  
  973. // Trace a long string.
  974. void TraceS_Long(int string) {
  975.   int buffer[0x200];
  976.   int buffer_index = 0;
  977.   int string_index = 0;
  978.   while (string[string_index] != 0) {
  979.     buffer[buffer_index] = string[string_index];
  980.     if (0x1FE == buffer_index) {
  981.       buffer_index = 0;
  982.       TraceS(buffer);}
  983.     ++buffer_index;
  984.     ++string_index;}
  985.   buffer[buffer_index] = 0;
  986.   TraceS(buffer);}
  987.  
  988. void Lisp_Print(int format,
  989.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  990.                 int a8, int a9, int aa, int ab, int ac, int ad, int ae, int af) {
  991.   int buffer[0x2000];
  992.   Lisp_Format(buffer, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af);
  993.   TraceS_Long(buffer);}
  994.  
  995. ////////////////////////////////////////////////////////////////
  996.  
  997. int Lisp_Bool(bool value) {
  998.   if (value) {return LISP_TRUE;}
  999.   return LISP_FALSE;}
  1000.  
  1001. bool Lisp_IsTruthy(int value) {
  1002.   if (0 == value) {return false;}
  1003.   if (LISP_FALSE == value) {return false;}
  1004.   if (LISP_NIL == value) {return false;}
  1005.   return true;}
  1006.  
  1007. int Lisp_Eval(int x) {return Lisp_Eval(Lisp_Env_Root, x);}
  1008. int Lisp_Eval(int env, int x) {
  1009.   // Symbol
  1010.   if (Lisp_IsSymbol(x)) {return Lisp_Env_Get(env, x, false);}
  1011.  
  1012.   // Builtin.
  1013.   if (Lisp_IsBuiltin(x)) {return x;}
  1014.  
  1015.   // List.
  1016.   if (Lisp_IsCell(x)) {return Lisp_Eval_List(env, x);}
  1017.  
  1018.   // Number.
  1019.   if (Lisp_IsNumber(x)) {return x;}
  1020.  
  1021. }
  1022.  
  1023. // Evaluate a list.
  1024. int Lisp_Eval_List(int env, int list) {
  1025.   int f = Lisp_Eval(env, Lisp_Cell_Head(list));
  1026.  
  1027.   // Check for a function or macro.
  1028.   if (Lisp_IsCell(f) && f != LISP_NIL) {
  1029.     int g = Lisp_Cell_Head(f);
  1030.     if (g == LISP_SYM_FUNCTION) {return Lisp_Eval_Function_Call(env, f, Lisp_Cell_Tail(list));}
  1031.     if (g == LISP_SYM_MACRO) {return Lisp_Eval_Macro_Call(env, f, Lisp_Cell_Tail(list));}}
  1032.  
  1033.   // Builtin command.
  1034.   if (Lisp_IsBuiltin(f)) {
  1035.     if (LISP_ENV == f) {return env;}
  1036.     if (LISP_FUNCTION == f) {return list;}
  1037.     if (LISP_MACRO == f) {return list;}
  1038.     list = Lisp_Cell_Tail(list);
  1039.     if (LISP_HEAD == f) {return Lisp_Eval_Builtin_Head(env, list);}
  1040.     if (LISP_TAIL == f) {return Lisp_Eval_Builtin_Tail(env, list);}
  1041.     if (LISP_LIST == f) {return Lisp_Eval_Builtin_List(env, list);}
  1042.     if (LISP_ADD == f) {return Lisp_Eval_Builtin_Add(env, list);}
  1043.     if (LISP_SUBTRACT == f) {return Lisp_Eval_Builtin_Subtract(env, list);}
  1044.     if (LISP_MULTIPLY == f) {return Lisp_Eval_Builtin_Multiply(env, list);}
  1045.     if (LISP_DIVIDE == f) {return Lisp_Eval_Builtin_Divide(env, list);}
  1046.     if (LISP_SET == f) {return Lisp_Eval_Builtin_Set(env, list);}
  1047.     if (LISP_LET == f) {return Lisp_Eval_Builtin_Let(env, list);}
  1048.     if (LISP_DO == f) {return Lisp_Eval_Builtin_Do(env, list);}
  1049.     if (LISP_QUOTE == f) {return Lisp_Eval_Builtin_Quote(env, list);}
  1050.     if (LISP_IF == f) {return Lisp_Eval_Builtin_If(env, list);}
  1051.     if (LISP_CELL == f) {return Lisp_Eval_Builtin_Cell(env, list);}
  1052.     if (LISP_WHILE == f) {return Lisp_Eval_Builtin_While(env, list);}
  1053.     if (LISP_PRINT == f) {return Lisp_Eval_Builtin_Print(env, list);}
  1054.     if (LISP_DEFINE == f) {return Lisp_Eval_Builtin_Define(env, list);}
  1055.     if (LISP_NOT == f) {return Lisp_Eval_Builtin_Not(env, list);}
  1056.     if (LISP_LT == f) {return Lisp_Eval_Builtin_LT(env, list);}
  1057.     if (LISP_GT == f) {return Lisp_Eval_Builtin_GT(env, list);}
  1058.     if (LISP_EQ == f) {return Lisp_Eval_Builtin_EQ(env, list);}
  1059.     if (LISP_LTE == f) {return Lisp_Eval_Builtin_LTE(env, list);}
  1060.     if (LISP_GTE == f) {return Lisp_Eval_Builtin_GTE(env, list);}
  1061.     if (LISP_NPC == f) {return Lisp_Eval_Builtin_Npc(env, list);}
  1062.     if (LISP_ITEM == f) {return Lisp_Eval_Builtin_Item(env, list);}
  1063.     if (LISP_LWEAPON == f) {return Lisp_Eval_Builtin_LWeapon(env, list);}
  1064.     if (LISP_EWEAPON == f) {return Lisp_Eval_Builtin_EWeapon(env, list);}
  1065.     if (LISP_NPC_P == f) {return Lisp_Eval_Builtin_Npc_P(env, list);}
  1066.     if (LISP_ITEM_P == f) {return Lisp_Eval_Builtin_Item_P(env, list);}
  1067.     if (LISP_LWEAPON_P == f) {return Lisp_Eval_Builtin_LWeapon_P(env, list);}
  1068.     if (LISP_EWEAPON_P == f) {return Lisp_Eval_Builtin_EWeapon_P(env, list);}
  1069.     if (LISP_VALID == f) {return Lisp_Eval_Builtin_Valid(env, list);}
  1070.     if (LISP_X == f) {return Lisp_Eval_Builtin_X(env, list);}
  1071.     if (LISP_Y == f) {return Lisp_Eval_Builtin_Y(env, list);}
  1072.     if (LISP_Z == f) {return Lisp_Eval_Builtin_Z(env, list);}
  1073.     if (LISP_WAITDRAW == f) {return Lisp_Eval_Builtin_Waitdraw(env, list);}
  1074.     if (LISP_WAITFRAME == f) {return Lisp_Eval_Builtin_Waitframe(env, list);}
  1075.     if (LISP_INPUT_START == f) {return Lisp_Eval_Builtin_Input_Start(env, list);}
  1076.     if (LISP_INPUT_MAP == f) {return Lisp_Eval_Builtin_Input_Map(env, list);}
  1077.     if (LISP_INPUT_UP == f) {return Lisp_Eval_Builtin_Input_Up(env, list);}
  1078.     if (LISP_INPUT_DOWN == f) {return Lisp_Eval_Builtin_Input_Down(env, list);}
  1079.     if (LISP_INPUT_LEFT == f) {return Lisp_Eval_Builtin_Input_Left(env, list);}
  1080.     if (LISP_INPUT_RIGHT == f) {return Lisp_Eval_Builtin_Input_Right(env, list);}
  1081.     if (LISP_INPUT_L == f) {return Lisp_Eval_Builtin_Input_L(env, list);}
  1082.     if (LISP_INPUT_R == f) {return Lisp_Eval_Builtin_Input_L(env, list);}
  1083.     if (LISP_INPUT_EX1 == f) {return Lisp_Eval_Builtin_Input_Ex1(env, list);}
  1084.     if (LISP_INPUT_EX2 == f) {return Lisp_Eval_Builtin_Input_Ex2(env, list);}
  1085.     if (LISP_INPUT_EX3 == f) {return Lisp_Eval_Builtin_Input_Ex3(env, list);}
  1086.     if (LISP_INPUT_EX4 == f) {return Lisp_Eval_Builtin_Input_Ex4(env, list);}
  1087.     if (LISP_PRESS_START == f) {return Lisp_Eval_Builtin_Press_Start(env, list);}
  1088.     if (LISP_PRESS_MAP == f) {return Lisp_Eval_Builtin_Press_Map(env, list);}
  1089.     if (LISP_PRESS_UP == f) {return Lisp_Eval_Builtin_Press_Up(env, list);}
  1090.     if (LISP_PRESS_DOWN == f) {return Lisp_Eval_Builtin_Press_Down(env, list);}
  1091.     if (LISP_PRESS_LEFT == f) {return Lisp_Eval_Builtin_Press_Left(env, list);}
  1092.     if (LISP_PRESS_RIGHT == f) {return Lisp_Eval_Builtin_Press_Right(env, list);}
  1093.     if (LISP_PRESS_L == f) {return Lisp_Eval_Builtin_Press_L(env, list);}
  1094.     if (LISP_PRESS_R == f) {return Lisp_Eval_Builtin_Press_L(env, list);}
  1095.     if (LISP_PRESS_EX1 == f) {return Lisp_Eval_Builtin_Press_Ex1(env, list);}
  1096.     if (LISP_PRESS_EX2 == f) {return Lisp_Eval_Builtin_Press_Ex2(env, list);}
  1097.     if (LISP_PRESS_EX3 == f) {return Lisp_Eval_Builtin_Press_Ex3(env, list);}
  1098.     if (LISP_PRESS_EX4 == f) {return Lisp_Eval_Builtin_Press_Ex4(env, list);}
  1099.     if (LISP_DIR == f) {return Lisp_Eval_Builtin_Dir(env, list);}
  1100.     if (LISP_HP == f) {return Lisp_Eval_Builtin_Hp(env, list);}
  1101.     if (LISP_NPC_COUNT == f) {return Screen->NumNPCs();}
  1102.     if (LISP_ITEM_COUNT == f) {return Screen->NumItems();}
  1103.     if (LISP_LWEAPON_COUNT == f) {return Screen->NumLWeapons();}
  1104.     if (LISP_EWEAPON_COUNT == f) {return Screen->NumEWeapons();}
  1105.         if (LISP_CUR_SCREEN == f) {return Game->GetCurScreen();}
  1106.         if (LISP_CUR_DSCREEN == f) {return Game->GetCurDMapScreen();}
  1107.         if (LISP_CUR_LEVEL == f) {return Game->GetCurLevel();}
  1108.         if (LISP_CUR_MAP == f) {return Game->GetCurMap();}
  1109.         if (LISP_CUR_DMAP == f) {return Game->GetCurDMap();}
  1110.         if (LISP_SCREEN_CHANGED == f) {return Lisp_State_ScreenChanged;}
  1111.     if (LISP_ACTIVE_WAITFRAME == f) {return Lisp_Eval_Builtin_Active_Waitframe(env, list);}
  1112.     if (LISP_MEMORY_IN_USE == f) {return Lisp_Memory_InUseCount();}
  1113.   }
  1114.  
  1115.   Lisp_Eval_List_CannotCall(f);
  1116.   return 0;}
  1117. void Lisp_Eval_List_CannotCall(int x) {
  1118.   int msg[] = "ERROR: Cannot call value ~A.~%";
  1119.   Lisp_Print(msg, x);}
  1120.  
  1121. void Lisp_Eval_IncorrectArgCount(int f_sym) {
  1122.   int msg[] = "ERROR (~A): Illegal argument count.~%";
  1123.   Lisp_Print(msg, f_sym);}
  1124. void Lisp_Eval_ArgsNotList(int f_sym) {
  1125.   int msg[] = "ERROR (~A): Malformed arguments.~%";
  1126.   Lisp_Print(msg, f_sym);}
  1127.  
  1128. int Lisp_Eval_Builtin_Head(int env, int list) {
  1129.   if (LISP_NIL == list) {
  1130.     Lisp_Eval_IncorrectArgCount(LISP_SYM_HEAD);
  1131.     return LISP_NIL;}
  1132.   int value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1133.   if (LISP_NIL != Lisp_Cell_Tail(list)) {
  1134.     Lisp_Eval_IncorrectArgCount(LISP_SYM_HEAD);
  1135.     return LISP_NIL;}
  1136.   return Lisp_Cell_Head(value);}
  1137.  
  1138. int Lisp_Eval_Builtin_Tail(int env, int list) {
  1139.   if (LISP_NIL == list) {
  1140.     Lisp_Eval_IncorrectArgCount(LISP_SYM_TAIL);
  1141.     return LISP_NIL;}
  1142.   int value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1143.   if (LISP_NIL != Lisp_Cell_Tail(list)) {
  1144.     Lisp_Eval_IncorrectArgCount(LISP_SYM_TAIL);
  1145.     return LISP_NIL;}
  1146.   return Lisp_Cell_Tail(value);}
  1147.  
  1148. int Lisp_Eval_Builtin_List(int env, int list) {
  1149.   if (LISP_NIL == list) {return LISP_NIL;}
  1150.   int head = LISP_NIL;
  1151.   int current = head;
  1152.   while (list != LISP_NIL) {
  1153.     int tmp = Lisp_Cell(Lisp_Eval(env, Lisp_Cell_Head(list)), LISP_NIL);
  1154.     if (LISP_NIL == head) {head = tmp;}
  1155.     else {Lisp_Cell_Tail(current, tmp);}
  1156.     current = tmp;
  1157.     list = Lisp_Cell_Tail(list);
  1158.     if (!Lisp_IsCell(list)) {
  1159.       Lisp_Eval_ArgsNotList(LISP_SYM_LIST);
  1160.       return LISP_NIL;}}
  1161.   return head;}
  1162.  
  1163. int Lisp_Eval_Builtin_Add(int env, int list) {
  1164.   int value = 0;
  1165.   while (LISP_NIL != list) {
  1166.     if (!Lisp_IsCell(list)) {
  1167.       Lisp_Eval_ArgsNotList(LISP_SYM_ADD);
  1168.       return LISP_NIL;}
  1169.     int head = Lisp_Eval(env, Lisp_Cell_Head(list));
  1170.     if (!Lisp_IsNumber(head)) {
  1171.       Lisp_Eval_Builtin_Add_NotNumber(head);
  1172.       return LISP_NIL;}
  1173.     value += head;
  1174.     list = Lisp_Cell_Tail(list);}
  1175.   return value;}
  1176. void Lisp_Eval_Builtin_Add_NotNumber(int value) {
  1177.   int msg[] = "ERROR (+): Argument <~A> is not a number.~%";
  1178.   Lisp_Print(msg, value);}
  1179.  
  1180. int Lisp_Eval_Builtin_Subtract(int env, int list) {
  1181.   int value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1182.   if (!Lisp_IsNumber(value)) {
  1183.     Lisp_Eval_Builtin_Subtract_NotNumber(value);
  1184.     return LISP_NIL;}
  1185.   list = Lisp_Cell_Tail(list);
  1186.   while (LISP_NIL != list) {
  1187.     int head = Lisp_Eval(env, Lisp_Cell_Head(list));
  1188.     if (!Lisp_IsNumber(head)) {
  1189.       Lisp_Eval_Builtin_Subtract_NotNumber(head);
  1190.       return LISP_NIL;}
  1191.     value -= head;
  1192.     list = Lisp_Cell_Tail(list);
  1193.     if (!Lisp_IsCell(list)) {
  1194.       Lisp_Eval_ArgsNotList(LISP_SYM_SUBTRACT);
  1195.       return LISP_NIL;}}
  1196.   return value;}
  1197. void Lisp_Eval_Builtin_Subtract_NotNumber(int value) {
  1198.   int msg[] = "ERROR (-): Argument <~A> is not a number.~%";
  1199.   Lisp_Print(msg, value);}
  1200.  
  1201. int Lisp_Eval_Builtin_Multiply(int env, int list) {
  1202.   int value = 1;
  1203.   while (LISP_NIL != list) {
  1204.     if (!Lisp_IsCell(list)) {
  1205.       Lisp_Eval_ArgsNotList(LISP_SYM_MULTIPLY);
  1206.       return LISP_NIL;}
  1207.     int head = Lisp_Eval(env, Lisp_Cell_Head(list));
  1208.     if (!Lisp_IsNumber(head)) {
  1209.       Lisp_Eval_Builtin_Multiply_NotNumber(head);
  1210.       return LISP_NIL;}
  1211.     value *= head;
  1212.     list = Lisp_Cell_Tail(list);}
  1213.   return value;}
  1214. void Lisp_Eval_Builtin_Multiply_NotNumber(int value) {
  1215.   int msg[] = "ERROR (*): Argument <~A> is not a number.~%";
  1216.   Lisp_Print(msg, value);}
  1217.  
  1218. int Lisp_Eval_Builtin_Divide(int env, int list) {
  1219.   int value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1220.   if (!Lisp_IsNumber(value)) {
  1221.     Lisp_Eval_Builtin_Divide_NotNumber(value);
  1222.     return 0;}
  1223.   list = Lisp_Cell_Tail(list);
  1224.   while (LISP_NIL != list) {
  1225.     int head = Lisp_Eval(env, Lisp_Cell_Head(list));
  1226.     if (!Lisp_IsNumber(head)) {
  1227.       Lisp_Eval_Builtin_Divide_NotNumber(head);
  1228.       return LISP_NIL;}
  1229.     value /= head;
  1230.     list = Lisp_Cell_Tail(list);
  1231.     if (!Lisp_IsCell(list)) {
  1232.       Lisp_Eval_ArgsNotList(LISP_SYM_DIVIDE);
  1233.       return LISP_NIL;}}
  1234.   return value;}
  1235. void Lisp_Eval_Builtin_Divide_NotNumber(int value) {
  1236.   int msg[] = "ERROR (/): Argument <~A> is not a number.~%";
  1237.   Lisp_Print(msg, value);}
  1238.  
  1239. int Lisp_Eval_Builtin_Set(int env, int list) {
  1240.   int key; int value;
  1241.   while (LISP_NIL != list) {
  1242.     key = Lisp_Cell_Head(list);
  1243.     if (!Lisp_IsSymbol(key)) {
  1244.       Lisp_Eval_Builtin_Set_NotSymbol(key);
  1245.       return LISP_NIL;}
  1246.     list = Lisp_Cell_Tail(list);
  1247.     value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1248.     Lisp_Env_Set(env, key, value);
  1249.     list = Lisp_Cell_Tail(list);}
  1250.   return value;}
  1251. void Lisp_Eval_Builtin_Set_NotSymbol(int key) {
  1252.   int msg[] = "ERROR (set): <~A> is not a symbol.~%";
  1253.   Lisp_Print(msg);}
  1254.  
  1255. int Lisp_Eval_Builtin_Let(int env, int list) {
  1256.   int new_env = Lisp_Env(env);
  1257.   int bindings = Lisp_Cell_Head(list);
  1258.   list = Lisp_Cell_Tail(list);
  1259.   while (LISP_NIL != bindings) {
  1260.     int key = Lisp_Cell_Head(bindings);
  1261.     if (!Lisp_IsSymbol(key)) {
  1262.       Lisp_Eval_Builtin_Let_NotSymbol(key);
  1263.       return LISP_NIL;}
  1264.     bindings = Lisp_Cell_Tail(bindings);
  1265.     int value = Lisp_Eval(env, Lisp_Cell_Head(bindings));
  1266.     Lisp_Env_Set(new_env, key, value, true);
  1267.     bindings = Lisp_Cell_Tail(bindings);}
  1268.     int result = Lisp_Eval_Builtin_Do(new_env, list);
  1269.     Lisp_Memory_GC(new_env);
  1270.   return result;}
  1271. void Lisp_Eval_Builtin_Let_NotSymbol(int key) {
  1272.   int msg[] = "ERROR (let): <~A> is not a symbol.~%";
  1273.   Lisp_Print(msg);}
  1274.  
  1275. int Lisp_Eval_Builtin_Do(int env, int list) {
  1276.   int result = LISP_NIL;
  1277.   while (LISP_NIL != list) {
  1278.     result = Lisp_Eval(env, Lisp_Cell_Head(list));
  1279.     list = Lisp_Cell_Tail(list);}
  1280.   return result;}
  1281.  
  1282. int Lisp_Eval_Builtin_Quote(int env, int list) {
  1283.   if (LISP_NIL != Lisp_Cell_Tail(list)) {Lisp_Eval_Builtin_Quote_TooManyArgs();}
  1284.   return Lisp_Cell_Head(list);}
  1285. void Lisp_Eval_Builtin_Quote_TooManyArgs() {
  1286.   int msg[] = "ERROR (quote): Too many arguments.~%";
  1287.   Lisp_Print(msg);}
  1288.  
  1289. int Lisp_Eval_Builtin_If(int env, int list) {
  1290.   int test = Lisp_Eval(env, Lisp_Cell_Head(list));
  1291.   list = Lisp_Cell_Tail(list);
  1292.   if (Lisp_IsTruthy(test)) {
  1293.     return Lisp_Eval(env, Lisp_Cell_Head(list));}
  1294.   else {
  1295.     list = Lisp_Cell_Tail(list);
  1296.     return Lisp_Eval_Builtin_Do(env, list);}}
  1297.  
  1298. int Lisp_Eval_Builtin_Cell(int env, int list) {
  1299.   int head = Lisp_Eval(env, Lisp_Cell_Head(list));
  1300.   list = Lisp_Cell_Tail(list);
  1301.   int tail = Lisp_Eval(env, Lisp_Cell_Head(list));
  1302.   return Lisp_Cell(head, tail);}
  1303.  
  1304. int Lisp_Eval_Builtin_While(int env, int list) {
  1305.   int result = LISP_NIL;
  1306.   int test_code = Lisp_Cell_Head(list);
  1307.   list = Lisp_Cell_Tail(list);
  1308.   while (Lisp_IsTruthy(Lisp_Eval(env, test_code))) {
  1309.     result = Lisp_Eval_Builtin_Do(env, list);}
  1310.   return result;}
  1311.  
  1312. int Lisp_Eval_Builtin_Print(int env, int list) {
  1313.   int result = Lisp_Eval(env, Lisp_Cell_Head(list));
  1314.   int msg[] = "~A~%";
  1315.   Lisp_Print(msg, result);
  1316.   return result;}
  1317.  
  1318. int Lisp_Eval_Builtin_Define(int env, int list) {
  1319.   int key = Lisp_Cell_Head(list);
  1320.   if (!Lisp_IsSymbol(key)) {
  1321.     Lisp_Eval_Builtin_Define_NotSymbol(key);
  1322.     return LISP_NIL;}
  1323.   list = Lisp_Cell_Tail(list);
  1324.   int value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1325.   Lisp_Env_Set(Lisp_Env_Root, key, value);
  1326.   return value;}
  1327. void Lisp_Eval_Builtin_Define_NotSymbol(int key) {
  1328.   int msg[] = "ERROR (define): <~A> is not a symbol.~%";
  1329.   Lisp_Print(msg);}
  1330.  
  1331. int Lisp_Eval_Builtin_Not(int env, int list) {
  1332.   if (LISP_NIL != Lisp_Cell_Tail(list)) {
  1333.     Lisp_Eval_IncorrectArgCount(LISP_SYM_NOT);
  1334.     return LISP_NIL;}
  1335.   int x = Lisp_Eval(env, Lisp_Cell_Head(list));
  1336.   if (Lisp_IsTruthy(x)) {return LISP_FALSE;}
  1337.   else {return LISP_TRUE;}}
  1338.  
  1339. int Lisp_Eval_Builtin_LT(int env, int list) {
  1340.   int previous = Lisp_Eval(env, Lisp_Cell_Head(list));
  1341.   list = Lisp_Cell_Tail(list);
  1342.   int current = Lisp_Eval(env, Lisp_Cell_Head(list));
  1343.   while (LISP_NIL != list) {
  1344.     if (previous >= current) {return LISP_FALSE;}
  1345.     previous = current;
  1346.     list = Lisp_Cell_Tail(list);
  1347.     current = Lisp_Eval(env, Lisp_Cell_Head(list));}
  1348.   return LISP_TRUE;}
  1349.  
  1350. int Lisp_Eval_Builtin_GT(int env, int list) {
  1351.   int previous = Lisp_Eval(env, Lisp_Cell_Head(list));
  1352.   list = Lisp_Cell_Tail(list);
  1353.   int current = Lisp_Eval(env, Lisp_Cell_Head(list));
  1354.   while (LISP_NIL != list) {
  1355.     if (previous <= current) {return LISP_FALSE;}
  1356.     previous = current;
  1357.     list = Lisp_Cell_Tail(list);
  1358.     current = Lisp_Eval(env, Lisp_Cell_Head(list));}
  1359.   return LISP_TRUE;}
  1360.  
  1361. int Lisp_Eval_Builtin_EQ(int env, int list) {
  1362.   int previous = Lisp_Eval(env, Lisp_Cell_Head(list));
  1363.   list = Lisp_Cell_Tail(list);
  1364.   int current = Lisp_Eval(env, Lisp_Cell_Head(list));
  1365.   while (LISP_NIL != list) {
  1366.     if (previous != current) {return LISP_FALSE;}
  1367.     previous = current;
  1368.     list = Lisp_Cell_Tail(list);
  1369.     current = Lisp_Eval(env, Lisp_Cell_Head(list));}
  1370.   return LISP_TRUE;}
  1371.  
  1372. int Lisp_Eval_Builtin_LTE(int env, int list) {
  1373.   int previous = Lisp_Eval(env, Lisp_Cell_Head(list));
  1374.   list = Lisp_Cell_Tail(list);
  1375.   int current = Lisp_Eval(env, Lisp_Cell_Head(list));
  1376.   while (LISP_NIL != list) {
  1377.     if (previous > current) {return LISP_FALSE;}
  1378.     previous = current;
  1379.     list = Lisp_Cell_Tail(list);
  1380.     current = Lisp_Eval(env, Lisp_Cell_Head(list));}
  1381.   return LISP_TRUE;}
  1382.  
  1383. int Lisp_Eval_Builtin_GTE(int env, int list) {
  1384.   int previous = Lisp_Eval(env, Lisp_Cell_Head(list));
  1385.   list = Lisp_Cell_Tail(list);
  1386.   int current = Lisp_Eval(env, Lisp_Cell_Head(list));
  1387.   while (LISP_NIL != list) {
  1388.     if (previous < current) {return LISP_FALSE;}
  1389.     previous = current;
  1390.     list = Lisp_Cell_Tail(list);
  1391.     current = Lisp_Eval(env, Lisp_Cell_Head(list));}
  1392.   return LISP_TRUE;}
  1393.  
  1394. int Lisp_Eval_Builtin_Npc(int env, int list) {
  1395.   return Lisp_Eval(env, Lisp_Cell_Head(list)) | LISP_TYPE_NPC | LISP_TYPE_POINTER;}
  1396. int Lisp_Eval_Builtin_Item(int env, int list) {
  1397.   return Lisp_Eval(env, Lisp_Cell_Head(list)) | LISP_TYPE_ITEM | LISP_TYPE_POINTER;}
  1398. int Lisp_Eval_Builtin_LWeapon(int env, int list) {
  1399.   return Lisp_Eval(env, Lisp_Cell_Head(list)) | LISP_TYPE_LWEAPON | LISP_TYPE_POINTER;}
  1400. int Lisp_Eval_Builtin_EWeapon(int env, int list) {
  1401.   return Lisp_Eval(env, Lisp_Cell_Head(list)) | LISP_TYPE_EWEAPON | LISP_TYPE_POINTER;}
  1402.  
  1403. int Lisp_Eval_Builtin_Npc_P(int env, int list) {
  1404.   int x = Lisp_Eval(env, Lisp_Cell_Head(list));
  1405.   return Lisp_Bool(x & LISP_TYPE_POINTER && (LISP_POINTER_TYPE_MASK & x) == LISP_TYPE_NPC);}
  1406. int Lisp_Eval_Builtin_Item_P(int env, int list) {
  1407.   int x = Lisp_Eval(env, Lisp_Cell_Head(list));
  1408.   return Lisp_Bool(x & LISP_TYPE_POINTER && (LISP_POINTER_TYPE_MASK & x) == LISP_TYPE_ITEM);}
  1409. int Lisp_Eval_Builtin_LWeapon_P(int env, int list) {
  1410.   int x = Lisp_Eval(env, Lisp_Cell_Head(list));
  1411.   return Lisp_Bool(x & LISP_TYPE_POINTER && (LISP_POINTER_TYPE_MASK & x) == LISP_TYPE_LWEAPON);}
  1412. int Lisp_Eval_Builtin_EWeapon_P(int env, int list) {
  1413.   int x = Lisp_Eval(env, Lisp_Cell_Head(list));
  1414.   return Lisp_Bool(x & LISP_TYPE_POINTER && (LISP_POINTER_TYPE_MASK & x) == LISP_TYPE_EWEAPON);}
  1415. int Lisp_Eval_Builtin_Link_P(int env, int list) {
  1416.   int x = Lisp_Eval(env, Lisp_Cell_Head(list));
  1417.   return Lisp_Bool(x == LISP_LINK);}
  1418.  
  1419. int Lisp_Eval_Builtin_Valid(int env, int list) {
  1420.   int x = Lisp_Eval(env, Lisp_Cell_Head(list));
  1421.   if (LISP_LINK == x) {return LISP_TRUE;}
  1422.   if (!(LISP_TYPE_POINTER & x)) {return LISP_FALSE;}
  1423.   int type = x & LISP_POINTER_TYPE_MASK;
  1424.   int index = (x & LISP_POINTER_INDEX_MASK) + 1;
  1425.   if (type == LISP_TYPE_NPC) {
  1426.     npc o = Screen->LoadNPC(index);
  1427.     return Lisp_Bool(o->isValid());}
  1428.   if (type == LISP_TYPE_ITEM) {
  1429.     item o = Screen->LoadItem(index);
  1430.     return Lisp_Bool(o->isValid());}
  1431.   if (type == LISP_TYPE_LWEAPON) {
  1432.     lweapon o = Screen->LoadLWeapon(index);
  1433.     return Lisp_Bool(o->isValid());}
  1434.   if (type == LISP_TYPE_ITEM) {
  1435.     eweapon o = Screen->LoadEWeapon(index);
  1436.     return Lisp_Bool(o->isValid());}
  1437.   return LISP_NIL;}
  1438.  
  1439. int Lisp_Eval_NotPointer(int f_sym, int value) {
  1440.   int msg[] = "ERROR (~A): ~A is not a pointer.~%";
  1441.   Lisp_Print(msg, f_sym, value);}
  1442.  
  1443. int Lisp_Eval_NotNumber(int f_sym, int value) {
  1444.   int msg[] = "ERROR (~A): ~A is not a number.~%";
  1445.   Lisp_Print(msg, f_sym, value);}
  1446.  
  1447. int Lisp_Eval_Builtin_X(int env, int list) {
  1448.   int pointer = Lisp_Eval(env, Lisp_Cell_Head(list));
  1449.   if (!Lisp_IsPointer(pointer)) {
  1450.     Lisp_Eval_NotPointer(LISP_SYM_X, pointer);
  1451.     return LISP_NIL;}
  1452.   list = Lisp_Cell_Tail(list);
  1453.   bool set = false;
  1454.   int value;
  1455.   if (LISP_NIL != list) {
  1456.     set = true;
  1457.     value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1458.     if (!Lisp_IsNumber(value)) {
  1459.       Lisp_Eval_NotNumber(LISP_SYM_X, value);
  1460.       return LISP_NIL;}}
  1461.   if (LISP_LINK == pointer) {
  1462.     if (set) {Link->X = value;}
  1463.     return Link->X;}
  1464.   int type = pointer & LISP_POINTER_TYPE_MASK;
  1465.   int index = (pointer & LISP_POINTER_INDEX_MASK) + 1;
  1466.   if (LISP_TYPE_NPC == type) {
  1467.     npc o = Screen->LoadNPC(index);
  1468.     if (set) {o->X = value;}
  1469.     return o->X;}
  1470.   if (LISP_TYPE_ITEM == type) {
  1471.     item o = Screen->LoadItem(index);
  1472.     if (set) {o->X = value;}
  1473.     return o->X;}
  1474.   if (LISP_TYPE_LWEAPON == type) {
  1475.     lweapon o = Screen->LoadLWeapon(index);
  1476.     if (set) {o->X = value;}
  1477.     return o->X;}
  1478.   if (LISP_TYPE_EWEAPON == type) {
  1479.     eweapon o = Screen->LoadEWeapon(index);
  1480.     if (set) {o->X = value;}
  1481.     return o->X;}
  1482.   return LISP_NIL;}
  1483.  
  1484. int Lisp_Eval_Builtin_Y(int env, int list) {
  1485.   int pointer = Lisp_Eval(env, Lisp_Cell_Head(list));
  1486.   if (!Lisp_IsPointer(pointer)) {
  1487.     Lisp_Eval_NotPointer(LISP_SYM_Y, pointer);
  1488.     return LISP_NIL;}
  1489.   list = Lisp_Cell_Tail(list);
  1490.   bool set = false;
  1491.   int value;
  1492.   if (LISP_NIL != list) {
  1493.     set = true;
  1494.     value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1495.     if (!Lisp_IsNumber(value)) {
  1496.       Lisp_Eval_NotNumber(LISP_SYM_Y, value);
  1497.       return LISP_NIL;}}
  1498.   if (LISP_LINK == pointer) {
  1499.     if (set) {Link->Y = value;}
  1500.     return Link->Y;}
  1501.   int type = pointer & LISP_POINTER_TYPE_MASK;
  1502.   int index = (pointer & LISP_POINTER_INDEX_MASK) + 1;
  1503.   if (LISP_TYPE_NPC == type) {
  1504.     npc o = Screen->LoadNPC(index);
  1505.     if (set) {o->Y = value;}
  1506.     return o->Y;}
  1507.   if (LISP_TYPE_ITEM == type) {
  1508.     item o = Screen->LoadItem(index);
  1509.     if (set) {o->Y = value;}
  1510.     return o->Y;}
  1511.   if (LISP_TYPE_LWEAPON == type) {
  1512.     lweapon o = Screen->LoadLWeapon(index);
  1513.     if (set) {o->Y = value;}
  1514.     return o->Y;}
  1515.   if (LISP_TYPE_EWEAPON == type) {
  1516.     eweapon o = Screen->LoadEWeapon(index);
  1517.     if (set) {o->Y = value;}
  1518.     return o->Y;}
  1519.   return LISP_NIL;}
  1520.  
  1521. int Lisp_Eval_Builtin_Z(int env, int list) {
  1522.   int pointer = Lisp_Eval(env, Lisp_Cell_Head(list));
  1523.   if (!Lisp_IsPointer(pointer)) {
  1524.     Lisp_Eval_NotPointer(LISP_SYM_Z, pointer);
  1525.     return LISP_NIL;}
  1526.   list = Lisp_Cell_Tail(list);
  1527.   bool set = false;
  1528.   int value;
  1529.   if (LISP_NIL != list) {
  1530.     set = true;
  1531.     value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1532.     if (!Lisp_IsNumber(value)) {
  1533.       Lisp_Eval_NotNumber(LISP_SYM_Z, value);
  1534.       return LISP_NIL;}}
  1535.   if (LISP_LINK == pointer) {
  1536.     if (set) {Link->Z = value;}
  1537.     return Link->Z;}
  1538.   int type = pointer & LISP_POINTER_TYPE_MASK;
  1539.   int index = (pointer & LISP_POINTER_INDEX_MASK) + 1;
  1540.   if (LISP_TYPE_NPC == type) {
  1541.     npc o = Screen->LoadNPC(index);
  1542.     if (set) {o->Z = value;}
  1543.     return o->Z;}
  1544.   if (LISP_TYPE_ITEM == type) {
  1545.     item o = Screen->LoadItem(index);
  1546.     if (set) {o->Z = value;}
  1547.     return o->Z;}
  1548.   if (LISP_TYPE_LWEAPON == type) {
  1549.     lweapon o = Screen->LoadLWeapon(index);
  1550.     if (set) {o->Z = value;}
  1551.     return o->Z;}
  1552.   if (LISP_TYPE_EWEAPON == type) {
  1553.     eweapon o = Screen->LoadEWeapon(index);
  1554.     if (set) {o->Z = value;}
  1555.     return o->Z;}
  1556.   return LISP_NIL;}
  1557.  
  1558. int Lisp_Eval_Builtin_Waitdraw(int env, int list) {Waitdraw();}
  1559. int Lisp_Eval_Builtin_Waitframe(int env, int list) {Waitframe();}
  1560.  
  1561. int Lisp_State_ScreenChanged = 0;
  1562. int Lisp_State_LastScreen = -1;
  1563. int Lisp_Eval_Builtin_Active_Waitframe(int env, int list) {
  1564.     Waitframe();
  1565.     int screen = (Game->GetCurDMap() << 8) + Game->GetCurDMapScreen();
  1566.     Lisp_State_ScreenChanged = Cond(screen != Lisp_State_LastScreen, 1, 0);
  1567.     Lisp_State_LastScreen = screen;
  1568.  
  1569.     //int msg[] = "Memory: %d\n"; printf(msg, Lisp_Memory_InUseCount());
  1570.  
  1571.     if (Lisp_State_ScreenChanged) {
  1572.         int memory_start = Lisp_Memory_InUseCount();
  1573.         Lisp_Memory_GC();
  1574.         int memory_end = Lisp_Memory_InUseCount();
  1575.         int msg[] = "Garbage Collection: %d -> %d\n";
  1576.         printf(msg, memory_start, memory_end);
  1577.     }
  1578. }
  1579.  
  1580. int Lisp_Eval_Builtin_Input_Start(int env, int list) {
  1581.   if (LISP_NIL != list) {
  1582.     Link->InputStart = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1583.   return Lisp_Bool(Link->InputStart);}
  1584. int Lisp_Eval_Builtin_Input_Map(int env, int list) {
  1585.   if (LISP_NIL != list) {
  1586.     Link->InputMap = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1587.   return Lisp_Bool(Link->InputMap);}
  1588. int Lisp_Eval_Builtin_Input_Up(int env, int list) {
  1589.   if (LISP_NIL != list) {
  1590.     Link->InputUp = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1591.   return Lisp_Bool(Link->InputUp);}
  1592. int Lisp_Eval_Builtin_Input_Down(int env, int list) {
  1593.   if (LISP_NIL != list) {
  1594.     Link->InputDown = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1595.   return Lisp_Bool(Link->InputDown);}
  1596. int Lisp_Eval_Builtin_Input_Left(int env, int list) {
  1597.   if (LISP_NIL != list) {
  1598.     Link->InputLeft = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1599.   return Lisp_Bool(Link->InputLeft);}
  1600. int Lisp_Eval_Builtin_Input_Right(int env, int list) {
  1601.   if (LISP_NIL != list) {
  1602.     Link->InputRight = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1603.   return Lisp_Bool(Link->InputRight);}
  1604. int Lisp_Eval_Builtin_Input_L(int env, int list) {
  1605.   if (LISP_NIL != list) {
  1606.     Link->InputL = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1607.   return Lisp_Bool(Link->InputL);}
  1608. int Lisp_Eval_Builtin_Input_R(int env, int list) {
  1609.   if (LISP_NIL != list) {
  1610.     Link->InputR = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1611.   return Lisp_Bool(Link->InputR);}
  1612. int Lisp_Eval_Builtin_Input_Ex1(int env, int list) {
  1613.   if (LISP_NIL != list) {
  1614.     Link->InputEx1 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1615.   return Lisp_Bool(Link->InputEx1);}
  1616. int Lisp_Eval_Builtin_Input_Ex2(int env, int list) {
  1617.   if (LISP_NIL != list) {
  1618.     Link->InputEx2 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1619.   return Lisp_Bool(Link->InputEx2);}
  1620. int Lisp_Eval_Builtin_Input_Ex3(int env, int list) {
  1621.   if (LISP_NIL != list) {
  1622.     Link->InputEx3 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1623.   return Lisp_Bool(Link->InputEx3);}
  1624. int Lisp_Eval_Builtin_Input_Ex4(int env, int list) {
  1625.   if (LISP_NIL != list) {
  1626.     Link->InputEx4 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1627.   return Lisp_Bool(Link->InputEx4);}
  1628. int Lisp_Eval_Builtin_Press_Start(int env, int list) {
  1629.   if (LISP_NIL != list) {
  1630.     Link->PressStart = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1631.   return Lisp_Bool(Link->PressStart);}
  1632. int Lisp_Eval_Builtin_Press_Map(int env, int list) {
  1633.   if (LISP_NIL != list) {
  1634.     Link->PressMap = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1635.   return Lisp_Bool(Link->PressMap);}
  1636. int Lisp_Eval_Builtin_Press_Up(int env, int list) {
  1637.   if (LISP_NIL != list) {
  1638.     Link->PressUp = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1639.   return Lisp_Bool(Link->PressUp);}
  1640. int Lisp_Eval_Builtin_Press_Down(int env, int list) {
  1641.   if (LISP_NIL != list) {
  1642.     Link->PressDown = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1643.   return Lisp_Bool(Link->PressDown);}
  1644. int Lisp_Eval_Builtin_Press_Left(int env, int list) {
  1645.   if (LISP_NIL != list) {
  1646.     Link->PressLeft = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1647.   return Lisp_Bool(Link->PressLeft);}
  1648. int Lisp_Eval_Builtin_Press_Right(int env, int list) {
  1649.   if (LISP_NIL != list) {
  1650.     Link->PressRight = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1651.   return Lisp_Bool(Link->PressRight);}
  1652. int Lisp_Eval_Builtin_Press_L(int env, int list) {
  1653.   if (LISP_NIL != list) {
  1654.     Link->PressL = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1655.   return Lisp_Bool(Link->PressL);}
  1656. int Lisp_Eval_Builtin_Press_R(int env, int list) {
  1657.   if (LISP_NIL != list) {
  1658.     Link->PressR = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1659.   return Lisp_Bool(Link->PressR);}
  1660. int Lisp_Eval_Builtin_Press_Ex1(int env, int list) {
  1661.   if (LISP_NIL != list) {
  1662.     Link->PressEx1 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1663.   return Lisp_Bool(Link->PressEx1);}
  1664. int Lisp_Eval_Builtin_Press_Ex2(int env, int list) {
  1665.   if (LISP_NIL != list) {
  1666.     Link->PressEx2 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1667.   return Lisp_Bool(Link->PressEx2);}
  1668. int Lisp_Eval_Builtin_Press_Ex3(int env, int list) {
  1669.   if (LISP_NIL != list) {
  1670.     Link->PressEx3 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1671.   return Lisp_Bool(Link->PressEx3);}
  1672. int Lisp_Eval_Builtin_Press_Ex4(int env, int list) {
  1673.   if (LISP_NIL != list) {
  1674.     Link->PressEx4 = Lisp_IsTruthy(Lisp_Eval(env, Lisp_Cell_Head(list)));}
  1675.   return Lisp_Bool(Link->PressEx4);}
  1676.  
  1677. int Lisp_Eval_Builtin_Dir(int env, int list) {
  1678.   int pointer = Lisp_Eval(env, Lisp_Cell_Head(list));
  1679.   if (!Lisp_IsPointer(pointer)) {
  1680.     Lisp_Eval_NotPointer(LISP_SYM_DIR, pointer);
  1681.     return LISP_NIL;}
  1682.   list = Lisp_Cell_Tail(list);
  1683.   bool set = false;
  1684.   int value;
  1685.   if (LISP_NIL != list) {
  1686.     set = true;
  1687.     value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1688.     if (!Lisp_IsNumber(value)) {
  1689.       Lisp_Eval_NotNumber(LISP_SYM_DIR, value);
  1690.       return LISP_NIL;}}
  1691.   if (LISP_LINK == pointer) {
  1692.     if (set) {Link->Dir = value;}
  1693.     return Link->Dir;}
  1694.   int type = pointer & LISP_POINTER_TYPE_MASK;
  1695.   int index = (pointer & LISP_POINTER_INDEX_MASK) + 1;
  1696.   if (LISP_TYPE_NPC == type) {
  1697.     npc o = Screen->LoadNPC(index);
  1698.     if (set) {o->Dir = value;}
  1699.     return o->Dir;}
  1700.   if (LISP_TYPE_LWEAPON == type) {
  1701.     lweapon o = Screen->LoadLWeapon(index);
  1702.     if (set) {o->Dir = value;}
  1703.     return o->Dir;}
  1704.   if (LISP_TYPE_EWEAPON == type) {
  1705.     eweapon o = Screen->LoadEWeapon(index);
  1706.     if (set) {o->Dir = value;}
  1707.     return o->Dir;}
  1708.   return LISP_NIL;}
  1709.  
  1710. int Lisp_Eval_Builtin_Hp(int env, int list) {
  1711.   int pointer = Lisp_Eval(env, Lisp_Cell_Head(list));
  1712.   if (!Lisp_IsPointer(pointer)) {
  1713.     Lisp_Eval_NotPointer(LISP_SYM_HP, pointer);
  1714.     return LISP_NIL;}
  1715.   list = Lisp_Cell_Tail(list);
  1716.   bool set = false;
  1717.   int value;
  1718.   if (LISP_NIL != list) {
  1719.     set = true;
  1720.     value = Lisp_Eval(env, Lisp_Cell_Head(list));
  1721.     if (!Lisp_IsNumber(value)) {
  1722.       Lisp_Eval_NotNumber(LISP_SYM_HP, value);
  1723.       return LISP_NIL;}}
  1724.   if (LISP_LINK == pointer) {
  1725.     if (set) {Link->HP = value;}
  1726.     return Link->HP;}
  1727.   int type = pointer & LISP_POINTER_TYPE_MASK;
  1728.   int index = (pointer & LISP_POINTER_INDEX_MASK) + 1;
  1729.   if (LISP_TYPE_NPC == type) {
  1730.     npc o = Screen->LoadNPC(index);
  1731.     if (set) {o->HP = value;}
  1732.     return o->HP;}
  1733.   return LISP_NIL;}
  1734.  
  1735. int Lisp_Eval_Function_Call(int env, int f, int args) {
  1736.   f = Lisp_Cell_Tail(f);
  1737.   int arg_spec = Lisp_Cell_Head(f);
  1738.   int f_body = Lisp_Cell_Tail(f);
  1739.  
  1740.   int new_env = Lisp_Env(env);
  1741.   while (LISP_NIL != arg_spec && LISP_NIL != args) {
  1742.     int spec = Lisp_Cell_Head(arg_spec);
  1743.     if (LISP_SYM_VARARG == spec) {
  1744.       spec = Lisp_Cell_Head(Lisp_Cell_Tail(arg_spec));
  1745.       Lisp_Env_Set(new_env, spec, args, true);
  1746.       break;}
  1747.     int arg = Lisp_Eval(env, Lisp_Cell_Head(args));
  1748.     Lisp_Env_Set(new_env, spec, arg, true);
  1749.     arg_spec = Lisp_Cell_Tail(arg_spec);
  1750.     args = Lisp_Cell_Tail(args);}
  1751.  
  1752.     int result = Lisp_Eval_Builtin_Do(new_env, f_body);
  1753.     Lisp_Memory_GC(new_env);
  1754.   return result;}
  1755.  
  1756. int Lisp_Eval_Macro_Call(int env, int macro, int args) {
  1757.   int m = Lisp_Cell_Tail(macro);
  1758.   int arg_spec = Lisp_Cell_Head(m);
  1759.   int m_body = Lisp_Cell_Tail(m);
  1760.  
  1761.   int new_env = Lisp_Env(env);
  1762.   while (LISP_NIL != arg_spec && LISP_NIL != args) {
  1763.     int spec = Lisp_Cell_Head(arg_spec);
  1764.     if (LISP_SYM_VARARG == spec) {
  1765.       spec = Lisp_Cell_Head(Lisp_Cell_Tail(arg_spec));
  1766.       Lisp_Env_Set(new_env, spec, args, true);
  1767.       break;}
  1768.     int arg = Lisp_Cell_Head(args);
  1769.     Lisp_Env_Set(new_env, spec, arg, true);
  1770.     arg_spec = Lisp_Cell_Tail(arg_spec);
  1771.     args = Lisp_Cell_Tail(args);}
  1772.  
  1773.   int expansion = Lisp_Eval_Builtin_Do(new_env, m_body);
  1774.   int result = Lisp_Eval(env, expansion);
  1775.     Lisp_Memory_GC(new_env);
  1776.     Lisp_Memory_GC(expansion);
  1777.     return result;}
  1778.  
  1779. ////////////////////////////////////////////////////////////////
  1780. // Parse
  1781.  
  1782. int Lisp_Parse_Index = 0;
  1783. int Lisp_Parse(int string) {
  1784.   int head = Lisp_Cell(LISP_SYM_DO, LISP_NIL);
  1785.   int cell = head;
  1786.   Lisp_Parse_Index = 0;
  1787.   while (0 != string[Lisp_Parse_Index]) {
  1788.     int _item = Lisp_Cell(Lisp_Parse_Item(string), LISP_NIL);
  1789.     Lisp_Cell_Tail(cell, _item);
  1790.     cell = _item;}
  1791.   return head;}
  1792.  
  1793. void Lisp_Parse_Skip(int string) {
  1794.   int last_index = Lisp_Parse_Index - 1;
  1795.   while (Lisp_Parse_Index != last_index) {
  1796.     last_index = Lisp_Parse_Index;
  1797.     if (Lisp_Char_IsWhitespace(string[Lisp_Parse_Index])) {++Lisp_Parse_Index;}
  1798.     if (';' == string[Lisp_Parse_Index]) {
  1799.       while (CHAR_NEWLINE != string[Lisp_Parse_Index]) {++Lisp_Parse_Index;}
  1800.       ++Lisp_Parse_Index;}}}
  1801.  
  1802. int Lisp_Parse_Item(int string) {
  1803.   Lisp_Parse_Skip(string);
  1804.  
  1805.   int result = LISP_NIL;
  1806.  
  1807.   if ('(' == string[Lisp_Parse_Index]) {
  1808.     result = Lisp_Parse_List(string);}
  1809.  
  1810.   else if (Lisp_Char_IsSymbolStart(string[Lisp_Parse_Index])) {
  1811.     result = Lisp_Parse_Symbol(string);}
  1812.  
  1813.   else if (isNumber(string[Lisp_Parse_Index])) {
  1814.     result = Lisp_Parse_Number(string);}
  1815.  
  1816.   // quote
  1817.   else if (CHAR_QUOTE == string[Lisp_Parse_Index]) {
  1818.     ++Lisp_Parse_Index;
  1819.     result = Lisp_List(LISP_SYM_QUOTE, Lisp_Parse_Item(string));}
  1820.  
  1821.   else {++Lisp_Parse_Index;}
  1822.  
  1823.   Lisp_Parse_Skip(string);
  1824.   return result;}
  1825.  
  1826. int Lisp_Parse_List(int string) {
  1827.   ++Lisp_Parse_Index;
  1828.  
  1829.   int list = LISP_NIL;
  1830.   int cell = LISP_NIL;
  1831.   while (')' != string[Lisp_Parse_Index]) {
  1832.     if ('.' == string[Lisp_Parse_Index]) {
  1833.       Lisp_Parse_Skip(string);
  1834.       Lisp_Cell_Tail(cell, Lisp_Parse_Item(string));
  1835.       break;}
  1836.  
  1837.     int _item = Lisp_Parse_Item(string);
  1838.     if (LISP_NIL == list) {
  1839.       list = Lisp_Cell(_item, LISP_NIL);
  1840.       cell = list;}
  1841.     else {
  1842.       int swap = Lisp_Cell(_item, LISP_NIL);
  1843.       Lisp_Cell_Tail(cell, swap);
  1844.       cell = swap;}}
  1845.   ++Lisp_Parse_Index;
  1846.   return list;}
  1847.  
  1848. int Lisp_Parse_Symbol(int string) {
  1849.   int buffer[0x100];
  1850.   int index = 0;
  1851.   while (Lisp_Char_IsSymbol(string[Lisp_Parse_Index])) {
  1852.     buffer[index] = string[Lisp_Parse_Index];
  1853.     ++index;
  1854.     ++Lisp_Parse_Index;}
  1855.   return Lisp_Symbol_Get(buffer);}
  1856.  
  1857. int Lisp_Parse_Number(int string) {
  1858.   int value = 0;
  1859.  
  1860.   if (string[Lisp_Parse_Index] == '0' && string[Lisp_Parse_Index + 1] == 'x') {
  1861.     Lisp_Parse_Index += 2;
  1862.     while (isHex(string[Lisp_Parse_Index])) {
  1863.       int c = string[Lisp_Parse_Index];
  1864.       value *= 16;
  1865.       if (isNumber(c)) {value += c - '0';}
  1866.       if ('A' <= c && c <= 'F') {value += 10 + c - 'A';}
  1867.       if ('a' <= c && c <= 'f') {value += 10 + c - 'a';}
  1868.       ++Lisp_Parse_Index;}
  1869.     return value;}
  1870.  
  1871.   while (isNumber(string[Lisp_Parse_Index])) {
  1872.     value *= 10;
  1873.     value += string[Lisp_Parse_Index] - '0';
  1874.     ++Lisp_Parse_Index;}
  1875.  
  1876.   if ('.' == string[Lisp_Parse_Index]) {
  1877.     ++Lisp_Parse_Index;
  1878.     for (int mult = 0.1;
  1879.          mult >= 0.0001 && isNumber(string[Lisp_Parse_Index]);
  1880.          mult *= 0.1) {
  1881.       value += mult * (string[Lisp_Parse_Index] - '0');
  1882.       ++Lisp_Parse_Index;}}
  1883.  
  1884.   return value;}
  1885.  
  1886. ////////////////////////////////////////////////////////////////
  1887. // Varargs
  1888.  
  1889. int Lisp_Format(int target, int format,
  1890.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1891.                 int a8, int a9, int aa, int ab, int ac, int ad, int ae) {
  1892.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, 0);}
  1893. int Lisp_Format(int target, int format,
  1894.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1895.                 int a8, int a9, int aa, int ab, int ac, int ad) {
  1896.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, 0, 0);}
  1897. int Lisp_Format(int target, int format,
  1898.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1899.                 int a8, int a9, int aa, int ab, int ac) {
  1900.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, 0, 0, 0);}
  1901. int Lisp_Format(int target, int format,
  1902.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1903.                 int a8, int a9, int aa, int ab) {
  1904.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, 0, 0, 0, 0);}
  1905. int Lisp_Format(int target, int format,
  1906.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1907.                 int a8, int a9, int aa) {
  1908.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, 0, 0, 0, 0, 0);}
  1909. int Lisp_Format(int target, int format,
  1910.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1911.                 int a8, int a9) {
  1912.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0, 0, 0, 0, 0, 0);}
  1913. int Lisp_Format(int target, int format,
  1914.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1915.                 int a8) {
  1916.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, 0, 0, 0, 0, 0, 0, 0);}
  1917. int Lisp_Format(int target, int format,
  1918.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
  1919.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, a7, 0, 0, 0, 0, 0, 0, 0, 0);}
  1920. int Lisp_Format(int target, int format,
  1921.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6) {
  1922.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, a6, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1923. int Lisp_Format(int target, int format,
  1924.                 int a0, int a1, int a2, int a3, int a4, int a5) {
  1925.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, a5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1926. int Lisp_Format(int target, int format,
  1927.                 int a0, int a1, int a2, int a3, int a4) {
  1928.   return Lisp_Format(target, format, a0, a1, a2, a3, a4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1929. int Lisp_Format(int target, int format,
  1930.                 int a0, int a1, int a2, int a3) {
  1931.   return Lisp_Format(target, format, a0, a1, a2, a3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1932. int Lisp_Format(int target, int format,
  1933.                 int a0, int a1, int a2) {
  1934.   return Lisp_Format(target, format, a0, a1, a2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1935. int Lisp_Format(int target, int format,
  1936.                 int a0, int a1) {
  1937.   return Lisp_Format(target, format, a0, a1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1938. int Lisp_Format(int target, int format,
  1939.                 int a0) {
  1940.   return Lisp_Format(target, format, a0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1941. int Lisp_Format(int target, int format) {
  1942.   return Lisp_Format(target, format, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1943.  
  1944. void Lisp_Print(int format,
  1945.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1946.                 int a8, int a9, int aa, int ab, int ac, int ad, int ae) {
  1947.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, 0);}
  1948. void Lisp_Print(int format,
  1949.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1950.                 int a8, int a9, int aa, int ab, int ac, int ad) {
  1951.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, 0, 0);}
  1952. void Lisp_Print(int format,
  1953.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1954.                 int a8, int a9, int aa, int ab, int ac) {
  1955.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, 0, 0, 0);}
  1956. void Lisp_Print(int format,
  1957.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1958.                 int a8, int a9, int aa, int ab) {
  1959.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, 0, 0, 0, 0);}
  1960. void Lisp_Print(int format,
  1961.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1962.                 int a8, int a9, int aa) {
  1963.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, 0, 0, 0, 0, 0);}
  1964. void Lisp_Print(int format,
  1965.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1966.                 int a8, int a9) {
  1967.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0, 0, 0, 0, 0, 0);}
  1968. void Lisp_Print(int format,
  1969.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  1970.                 int a8) {
  1971.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, a8, 0, 0, 0, 0, 0, 0, 0);}
  1972. void Lisp_Print(int format,
  1973.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
  1974.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, a7, 0, 0, 0, 0, 0, 0, 0, 0);}
  1975. void Lisp_Print(int format,
  1976.                 int a0, int a1, int a2, int a3, int a4, int a5, int a6) {
  1977.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, a6, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1978. void Lisp_Print(int format,
  1979.                 int a0, int a1, int a2, int a3, int a4, int a5) {
  1980.   Lisp_Print(format, a0, a1, a2, a3, a4, a5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1981. void Lisp_Print(int format,
  1982.                 int a0, int a1, int a2, int a3, int a4) {
  1983.   Lisp_Print(format, a0, a1, a2, a3, a4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1984. void Lisp_Print(int format,
  1985.                 int a0, int a1, int a2, int a3) {
  1986.   Lisp_Print(format, a0, a1, a2, a3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1987. void Lisp_Print(int format,
  1988.                 int a0, int a1, int a2) {
  1989.   Lisp_Print(format, a0, a1, a2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1990. void Lisp_Print(int format,
  1991.                 int a0, int a1) {
  1992.   Lisp_Print(format, a0, a1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1993. void Lisp_Print(int format,
  1994.                 int a0) {
  1995.   Lisp_Print(format, a0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1996. void Lisp_Print(int format) {
  1997.   Lisp_Print(format, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  1998.  
  1999. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  2000.               int a8, int a9, int aa, int ab, int ac, int ad, int ae) {
  2001.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, 0);}
  2002. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  2003.               int a8, int a9, int aa, int ab, int ac, int ad) {
  2004.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, 0, 0);}
  2005. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  2006.               int a8, int a9, int aa, int ab, int ac) {
  2007.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, 0, 0, 0);}
  2008. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  2009.               int a8, int a9, int aa, int ab) {
  2010.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, 0, 0, 0, 0);}
  2011. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  2012.               int a8, int a9, int aa) {
  2013.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, 0, 0, 0, 0, 0);}
  2014. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  2015.               int a8, int a9) {
  2016.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0, 0, 0, 0, 0, 0);}
  2017. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
  2018.               int a8) {
  2019.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, a8, 0, 0, 0, 0, 0, 0, 0);}
  2020. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
  2021.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, a7, 0, 0, 0, 0, 0, 0, 0, 0);}
  2022. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5, int a6) {
  2023.   return Lisp_List(a0, a1, a2, a3, a4, a5, a6, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  2024. int Lisp_List(int a0, int a1, int a2, int a3, int a4, int a5) {
  2025.   return Lisp_List(a0, a1, a2, a3, a4, a5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  2026. int Lisp_List(int a0, int a1, int a2, int a3, int a4) {
  2027.   return Lisp_List(a0, a1, a2, a3, a4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  2028. int Lisp_List(int a0, int a1, int a2, int a3) {
  2029.   return Lisp_List(a0, a1, a2, a3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  2030. int Lisp_List(int a0, int a1, int a2) {
  2031.   return Lisp_List(a0, a1, a2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  2032. int Lisp_List(int a0, int a1) {
  2033.   return Lisp_List(a0, a1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
  2034. int Lisp_List(int a0) {
  2035.   return Lisp_List(a0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement