15dfecf96Smrg/* 25dfecf96Smrg * Copyright (c) 2001 by The XFree86 Project, Inc. 35dfecf96Smrg * 45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a 55dfecf96Smrg * copy of this software and associated documentation files (the "Software"), 65dfecf96Smrg * to deal in the Software without restriction, including without limitation 75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the 95dfecf96Smrg * Software is furnished to do so, subject to the following conditions: 105dfecf96Smrg * 115dfecf96Smrg * The above copyright notice and this permission notice shall be included in 125dfecf96Smrg * all copies or substantial portions of the Software. 135dfecf96Smrg * 145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 205dfecf96Smrg * SOFTWARE. 215dfecf96Smrg * 225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall 235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other 245dfecf96Smrg * dealings in this Software without prior written authorization from the 255dfecf96Smrg * XFree86 Project. 265dfecf96Smrg * 275dfecf96Smrg * Author: Paulo César Pereira de Andrade 285dfecf96Smrg */ 295dfecf96Smrg 305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/lisp.c,v 1.87tsi Exp $ */ 315dfecf96Smrg 32f765521fSmrg#ifdef HAVE_CONFIG_H 33f765521fSmrg# include "config.h" 34f765521fSmrg#endif 35f765521fSmrg 365dfecf96Smrg#include <stdlib.h> 375dfecf96Smrg#include <string.h> 385dfecf96Smrg#ifdef sun 395dfecf96Smrg#include <strings.h> 405dfecf96Smrg#endif 415dfecf96Smrg#include <ctype.h> 425dfecf96Smrg#include <errno.h> 435dfecf96Smrg#include <fcntl.h> 445dfecf96Smrg#include <stdarg.h> 455dfecf96Smrg#include <signal.h> 465dfecf96Smrg#include <sys/wait.h> 475dfecf96Smrg 485dfecf96Smrg#ifndef X_NOT_POSIX 495dfecf96Smrg#include <unistd.h> /* for sysconf(), and getpagesize() */ 505dfecf96Smrg#endif 515dfecf96Smrg 525dfecf96Smrg#include "lisp/bytecode.h" 535dfecf96Smrg 545dfecf96Smrg#include "lisp/read.h" 555dfecf96Smrg#include "lisp/format.h" 565dfecf96Smrg#include "lisp/math.h" 575dfecf96Smrg#include "lisp/hash.h" 585dfecf96Smrg#include "lisp/package.h" 595dfecf96Smrg#include "lisp/pathname.h" 605dfecf96Smrg#include "lisp/regex.h" 615dfecf96Smrg#include "lisp/require.h" 625dfecf96Smrg#include "lisp/stream.h" 635dfecf96Smrg#include "lisp/struct.h" 645dfecf96Smrg#include "lisp/time.h" 655dfecf96Smrg#include "lisp/write.h" 665dfecf96Smrg#include <math.h> 675dfecf96Smrg 685dfecf96Smrgtypedef struct { 695dfecf96Smrg LispObj **objects; 705dfecf96Smrg LispObj *freeobj; 715dfecf96Smrg int nsegs; 725dfecf96Smrg int nobjs; 735dfecf96Smrg int nfree; 745dfecf96Smrg} LispObjSeg; 755dfecf96Smrg 765dfecf96Smrg/* 775dfecf96Smrg * Prototypes 785dfecf96Smrg */ 795dfecf96Smrgstatic void Lisp__GC(LispObj*, LispObj*); 805dfecf96Smrgstatic LispObj *Lisp__New(LispObj*, LispObj*); 815dfecf96Smrg 825dfecf96Smrg/* run a user function, to be called only by LispEval */ 835dfecf96Smrgstatic LispObj *LispRunFunMac(LispObj*, LispObj*, int, int); 845dfecf96Smrg 855dfecf96Smrg/* expands and executes a setf method, to be called only by Lisp_Setf */ 865dfecf96SmrgLispObj *LispRunSetf(LispArgList*, LispObj*, LispObj*, LispObj*); 875dfecf96SmrgLispObj *LispRunSetfMacro(LispAtom*, LispObj*, LispObj*); 885dfecf96Smrg 895dfecf96Smrg/* increases storage size for environment */ 905dfecf96Smrgvoid LispMoreEnvironment(void); 915dfecf96Smrg 925dfecf96Smrg/* increases storage size for stack of builtin arguments */ 935dfecf96Smrgvoid LispMoreStack(void); 945dfecf96Smrg 955dfecf96Smrg/* increases storage size for global variables */ 965dfecf96Smrgvoid LispMoreGlobals(LispPackage*); 975dfecf96Smrg 985dfecf96Smrg#ifdef __GNUC__ 995dfecf96Smrgstatic INLINE LispObj *LispDoGetVar(LispObj*); 1005dfecf96Smrg#endif 1015dfecf96Smrgstatic INLINE void LispDoAddVar(LispObj*, LispObj*); 1025dfecf96Smrg 1035dfecf96Smrg/* Helper for importing symbol(s) functions, 1045dfecf96Smrg * Search for the specified object in the current package */ 1055dfecf96Smrgstatic INLINE LispObj *LispGetVarPack(LispObj*); 1065dfecf96Smrg 1075dfecf96Smrg/* create environment for function call */ 1085dfecf96Smrgstatic int LispMakeEnvironment(LispArgList*, LispObj*, LispObj*, int, int); 1095dfecf96Smrg 1105dfecf96Smrg /* if not already in keyword package, move atom to keyword package */ 1115dfecf96Smrgstatic LispObj *LispCheckKeyword(LispObj*); 1125dfecf96Smrg 1135dfecf96Smrg /* builtin backquote parsing */ 1145dfecf96Smrgstatic LispObj *LispEvalBackquoteObject(LispObj*, int, int); 1155dfecf96Smrg /* used also by the bytecode compiler */ 1165dfecf96SmrgLispObj *LispEvalBackquote(LispObj*, int); 1175dfecf96Smrg 1185dfecf96Smrg /* create or change object property */ 1195dfecf96Smrgvoid LispSetAtomObjectProperty(LispAtom*, LispObj*); 1205dfecf96Smrg /* remove object property */ 1215dfecf96Smrgstatic void LispRemAtomObjectProperty(LispAtom*); 1225dfecf96Smrg 1235dfecf96Smrg /* allocates a new LispProperty for the given atom */ 1245dfecf96Smrgstatic void LispAllocAtomProperty(LispAtom*); 1255dfecf96Smrg /* Increment reference count of atom property */ 1265dfecf96Smrgstatic void LispIncrementAtomReference(LispAtom*); 1275dfecf96Smrg /* Decrement reference count of atom property */ 1285dfecf96Smrgstatic void LispDecrementAtomReference(LispAtom*); 1295dfecf96Smrg /* Removes all atom properties */ 1305dfecf96Smrgstatic void LispRemAtomAllProperties(LispAtom*); 1315dfecf96Smrg 1325dfecf96Smrgstatic LispObj *LispAtomPropertyFunction(LispAtom*, LispObj*, int); 1335dfecf96Smrg 1345dfecf96Smrgstatic INLINE void LispCheckMemLevel(void); 1355dfecf96Smrg 1365dfecf96Smrgvoid LispAllocSeg(LispObjSeg*, int); 1375dfecf96Smrgstatic INLINE void LispMark(LispObj*); 1385dfecf96Smrg 1395dfecf96Smrg/* functions, macros, setf methods, and structure definitions */ 1405dfecf96Smrgstatic INLINE void LispProt(LispObj*); 1415dfecf96Smrg 1425dfecf96Smrgstatic LispObj *LispCheckNeedProtect(LispObj*); 1435dfecf96Smrg 144f765521fSmrgstatic void LispSignalHandler(int); 1455dfecf96Smrg 1465dfecf96Smrg/* 1475dfecf96Smrg * Initialization 1485dfecf96Smrg */ 1495dfecf96SmrgLispMac lisp__data; 1505dfecf96Smrg 1515dfecf96Smrgstatic LispObj lispunbound = {LispNil_t}; 1525dfecf96SmrgLispObj *UNBOUND = &lispunbound; 1535dfecf96Smrg 1545dfecf96Smrgstatic volatile int lisp__disable_int; 1555dfecf96Smrgstatic volatile int lisp__interrupted; 1565dfecf96Smrg 1575dfecf96SmrgLispObj *Okey, *Orest, *Ooptional, *Oaux, *Olambda; 1585dfecf96Smrg 1595dfecf96SmrgAtom_id Snil, St; 1605dfecf96SmrgAtom_id Saux, Skey, Soptional, Srest; 1615dfecf96SmrgAtom_id Satom, Ssymbol, Sinteger, Scharacter, Sstring, Slist, 1625dfecf96Smrg Scons, Svector, Sarray, Sstruct, Skeyword, Sfunction, Spathname, 1635dfecf96Smrg Srational, Sfloat, Scomplex, Sopaque, Sdefault; 1645dfecf96Smrg 1655dfecf96SmrgLispObj *Oformat, *Kunspecific; 1665dfecf96SmrgLispObj *Oexpand_setf_method; 1675dfecf96Smrg 1685dfecf96Smrgstatic LispProperty noproperty; 1695dfecf96SmrgLispProperty *NOPROPERTY = &noproperty; 1705dfecf96Smrgstatic int segsize, minfree; 1715dfecf96Smrgint pagesize, gcpro; 1725dfecf96Smrg 1735dfecf96Smrgstatic LispObjSeg objseg = {NULL, NIL}; 1745dfecf96Smrgstatic LispObjSeg atomseg = {NULL, NIL}; 1755dfecf96Smrg 1765dfecf96Smrgint LispArgList_t; 1775dfecf96Smrg 1785dfecf96SmrgLispFile *Stdout, *Stdin, *Stderr; 1795dfecf96Smrg 1805dfecf96Smrgstatic LispBuiltin lispbuiltins[] = { 1815dfecf96Smrg {LispFunction, Lisp_Mul, "* &rest numbers"}, 1825dfecf96Smrg {LispFunction, Lisp_Plus, "+ &rest numbers"}, 1835dfecf96Smrg {LispFunction, Lisp_Minus, "- number &rest more-numbers"}, 1845dfecf96Smrg {LispFunction, Lisp_Div, "/ number &rest more-numbers"}, 1855dfecf96Smrg {LispFunction, Lisp_OnePlus, "1+ number"}, 1865dfecf96Smrg {LispFunction, Lisp_OneMinus, "1- number"}, 1875dfecf96Smrg {LispFunction, Lisp_Less, "< number &rest more-numbers"}, 1885dfecf96Smrg {LispFunction, Lisp_LessEqual, "<= number &rest more-numbers"}, 1895dfecf96Smrg {LispFunction, Lisp_Equal_, "= number &rest more-numbers"}, 1905dfecf96Smrg {LispFunction, Lisp_Greater, "> number &rest more-numbers"}, 1915dfecf96Smrg {LispFunction, Lisp_GreaterEqual, ">= number &rest more-numbers"}, 1925dfecf96Smrg {LispFunction, Lisp_NotEqual, "/= number &rest more-numbers"}, 1935dfecf96Smrg {LispFunction, Lisp_Max, "max number &rest more-numbers"}, 1945dfecf96Smrg {LispFunction, Lisp_Min, "min number &rest more-numbers"}, 1955dfecf96Smrg {LispFunction, Lisp_Abs, "abs number"}, 1965dfecf96Smrg {LispFunction, Lisp_Acons, "acons key datum alist"}, 1975dfecf96Smrg {LispFunction, Lisp_Adjoin, "adjoin item list &key key test test-not"}, 1985dfecf96Smrg {LispFunction, Lisp_AlphaCharP, "alpha-char-p char"}, 1995dfecf96Smrg {LispMacro, Lisp_And, "and &rest args", 1, 0, Com_And}, 2005dfecf96Smrg {LispFunction, Lisp_Append, "append &rest lists"}, 2015dfecf96Smrg {LispFunction, Lisp_Apply, "apply function arg &rest more-args", 1}, 2025dfecf96Smrg {LispFunction, Lisp_Aref, "aref array &rest subscripts"}, 2035dfecf96Smrg {LispFunction, Lisp_Assoc, "assoc item list &key test test-not key"}, 2045dfecf96Smrg {LispFunction, Lisp_AssocIf, "assoc-if predicate list &key key"}, 2055dfecf96Smrg {LispFunction, Lisp_AssocIfNot, "assoc-if-not predicate list &key key"}, 2065dfecf96Smrg {LispFunction, Lisp_Atom, "atom object"}, 2075dfecf96Smrg {LispMacro, Lisp_Block, "block name &rest body", 1, 0, Com_Block}, 2085dfecf96Smrg {LispFunction, Lisp_BothCaseP, "both-case-p character"}, 2095dfecf96Smrg {LispFunction, Lisp_Boundp, "boundp symbol"}, 2105dfecf96Smrg {LispFunction, Lisp_Butlast, "butlast list &optional count"}, 2115dfecf96Smrg {LispFunction, Lisp_Nbutlast, "nbutlast list &optional count"}, 2125dfecf96Smrg {LispFunction, Lisp_Car, "car list", 0, 0, Com_C_r}, 2135dfecf96Smrg {LispFunction, Lisp_Car, "first list", 0, 0, Com_C_r}, 2145dfecf96Smrg {LispMacro, Lisp_Case, "case keyform &rest body"}, 2155dfecf96Smrg {LispMacro, Lisp_Catch, "catch tag &rest body", 1}, 2165dfecf96Smrg {LispFunction, Lisp_Cdr, "cdr list", 0, 0, Com_C_r}, 2175dfecf96Smrg {LispFunction, Lisp_Cdr, "rest list", 0, 0, Com_C_r}, 2185dfecf96Smrg {LispFunction, Lisp_Ceiling, "ceiling number &optional divisor", 1}, 2195dfecf96Smrg {LispFunction, Lisp_Fceiling, "fceiling number &optional divisor", 1}, 2205dfecf96Smrg {LispFunction, Lisp_Char, "char string index"}, 2215dfecf96Smrg {LispFunction, Lisp_Char, "schar simple-string index"}, 2225dfecf96Smrg {LispFunction, Lisp_CharLess, "char< character &rest more-characters"}, 2235dfecf96Smrg {LispFunction, Lisp_CharLessEqual, "char<= character &rest more-characters"}, 2245dfecf96Smrg {LispFunction, Lisp_CharEqual_, "char= character &rest more-characters"}, 2255dfecf96Smrg {LispFunction, Lisp_CharGreater, "char> character &rest more-characters"}, 2265dfecf96Smrg {LispFunction, Lisp_CharGreaterEqual, "char>= character &rest more-characters"}, 2275dfecf96Smrg {LispFunction, Lisp_CharNotEqual_, "char/= character &rest more-characters"}, 2285dfecf96Smrg {LispFunction, Lisp_CharLessp, "char-lessp character &rest more-characters"}, 2295dfecf96Smrg {LispFunction, Lisp_CharNotGreaterp, "char-not-greaterp character &rest more-characters"}, 2305dfecf96Smrg {LispFunction, Lisp_CharEqual, "char-equal character &rest more-characters"}, 2315dfecf96Smrg {LispFunction, Lisp_CharGreaterp, "char-greaterp character &rest more-characters"}, 2325dfecf96Smrg {LispFunction, Lisp_CharNotLessp, "char-not-lessp character &rest more-characters"}, 2335dfecf96Smrg {LispFunction, Lisp_CharNotEqual, "char-not-equal character &rest more-characters"}, 2345dfecf96Smrg {LispFunction, Lisp_CharDowncase, "char-downcase character"}, 2355dfecf96Smrg {LispFunction, Lisp_CharInt, "char-code character"}, 2365dfecf96Smrg {LispFunction, Lisp_CharInt, "char-int character"}, 2375dfecf96Smrg {LispFunction, Lisp_CharUpcase, "char-upcase character"}, 2385dfecf96Smrg {LispFunction, Lisp_Character, "character object"}, 2395dfecf96Smrg {LispFunction, Lisp_Characterp, "characterp object"}, 2405dfecf96Smrg {LispFunction, Lisp_Clrhash, "clrhash hash-table"}, 2415dfecf96Smrg {LispFunction, Lisp_IntChar, "code-char integer"}, 2425dfecf96Smrg {LispFunction, Lisp_Coerce, "coerce object result-type"}, 2435dfecf96Smrg {LispFunction, Lisp_Compile, "compile name &optional definition", 1}, 2445dfecf96Smrg {LispFunction, Lisp_Complex, "complex realpart &optional imagpart"}, 2455dfecf96Smrg {LispMacro, Lisp_Cond, "cond &rest body", 0, 0, Com_Cond}, 2465dfecf96Smrg {LispFunction, Lisp_Cons, "cons car cdr", 0, 0, Com_Cons}, 2475dfecf96Smrg {LispFunction, Lisp_Consp, "consp object", 0, 0, Com_Consp}, 2485dfecf96Smrg {LispFunction, Lisp_Constantp, "constantp form &optional environment"}, 2495dfecf96Smrg {LispFunction, Lisp_Conjugate, "conjugate number"}, 2505dfecf96Smrg {LispFunction, Lisp_Complexp, "complexp object"}, 2515dfecf96Smrg {LispFunction, Lisp_CopyAlist, "copy-alist list"}, 2525dfecf96Smrg {LispFunction, Lisp_CopyList, "copy-list list"}, 2535dfecf96Smrg {LispFunction, Lisp_CopyTree, "copy-tree list"}, 2545dfecf96Smrg {LispFunction, Lisp_Close, "close stream &key abort"}, 2555dfecf96Smrg {LispFunction, Lisp_C_r, "caar list", 0, 0, Com_C_r}, 2565dfecf96Smrg {LispFunction, Lisp_C_r, "cadr list", 0, 0, Com_C_r}, 2575dfecf96Smrg {LispFunction, Lisp_C_r, "cdar list", 0, 0, Com_C_r}, 2585dfecf96Smrg {LispFunction, Lisp_C_r, "cddr list", 0, 0, Com_C_r}, 2595dfecf96Smrg {LispFunction, Lisp_C_r, "caaar list", 0, 0, Com_C_r}, 2605dfecf96Smrg {LispFunction, Lisp_C_r, "caadr list", 0, 0, Com_C_r}, 2615dfecf96Smrg {LispFunction, Lisp_C_r, "cadar list", 0, 0, Com_C_r}, 2625dfecf96Smrg {LispFunction, Lisp_C_r, "caddr list", 0, 0, Com_C_r}, 2635dfecf96Smrg {LispFunction, Lisp_C_r, "cdaar list", 0, 0, Com_C_r}, 2645dfecf96Smrg {LispFunction, Lisp_C_r, "cdadr list", 0, 0, Com_C_r}, 2655dfecf96Smrg {LispFunction, Lisp_C_r, "cddar list", 0, 0, Com_C_r}, 2665dfecf96Smrg {LispFunction, Lisp_C_r, "cdddr list", 0, 0, Com_C_r}, 2675dfecf96Smrg {LispFunction, Lisp_C_r, "caaaar list", 0, 0, Com_C_r}, 2685dfecf96Smrg {LispFunction, Lisp_C_r, "caaadr list", 0, 0, Com_C_r}, 2695dfecf96Smrg {LispFunction, Lisp_C_r, "caadar list", 0, 0, Com_C_r}, 2705dfecf96Smrg {LispFunction, Lisp_C_r, "caaddr list", 0, 0, Com_C_r}, 2715dfecf96Smrg {LispFunction, Lisp_C_r, "cadaar list", 0, 0, Com_C_r}, 2725dfecf96Smrg {LispFunction, Lisp_C_r, "cadadr list", 0, 0, Com_C_r}, 2735dfecf96Smrg {LispFunction, Lisp_C_r, "caddar list", 0, 0, Com_C_r}, 2745dfecf96Smrg {LispFunction, Lisp_C_r, "cadddr list", 0, 0, Com_C_r}, 2755dfecf96Smrg {LispFunction, Lisp_C_r, "cdaaar list", 0, 0, Com_C_r}, 2765dfecf96Smrg {LispFunction, Lisp_C_r, "cdaadr list", 0, 0, Com_C_r}, 2775dfecf96Smrg {LispFunction, Lisp_C_r, "cdadar list", 0, 0, Com_C_r}, 2785dfecf96Smrg {LispFunction, Lisp_C_r, "cdaddr list", 0, 0, Com_C_r}, 2795dfecf96Smrg {LispFunction, Lisp_C_r, "cddaar list", 0, 0, Com_C_r}, 2805dfecf96Smrg {LispFunction, Lisp_C_r, "cddadr list", 0, 0, Com_C_r}, 2815dfecf96Smrg {LispFunction, Lisp_C_r, "cdddar list", 0, 0, Com_C_r}, 2825dfecf96Smrg {LispFunction, Lisp_C_r, "cddddr list", 0, 0, Com_C_r}, 2835dfecf96Smrg {LispMacro, Lisp_Decf, "decf place &optional delta"}, 2845dfecf96Smrg {LispMacro, Lisp_Defconstant, "defconstant name initial-value &optional documentation"}, 2855dfecf96Smrg {LispMacro, Lisp_Defmacro, "defmacro name lambda-list &rest body"}, 2865dfecf96Smrg {LispMacro, Lisp_Defstruct, "defstruct name &rest description"}, 2875dfecf96Smrg {LispMacro, Lisp_Defun, "defun name lambda-list &rest body"}, 2885dfecf96Smrg {LispMacro, Lisp_Defsetf, "defsetf function lambda-list &rest body"}, 2895dfecf96Smrg {LispMacro, Lisp_Defparameter, "defparameter name initial-value &optional documentation"}, 2905dfecf96Smrg {LispMacro, Lisp_Defvar, "defvar name &optional initial-value documentation"}, 2915dfecf96Smrg {LispFunction, Lisp_Delete, "delete item sequence &key from-end test test-not start end count key"}, 2925dfecf96Smrg {LispFunction, Lisp_DeleteDuplicates, "delete-duplicates sequence &key from-end test test-not start end key"}, 2935dfecf96Smrg {LispFunction, Lisp_DeleteIf, "delete-if predicate sequence &key from-end start end count key"}, 2945dfecf96Smrg {LispFunction, Lisp_DeleteIfNot, "delete-if-not predicate sequence &key from-end start end count key"}, 2955dfecf96Smrg {LispFunction, Lisp_DeleteFile, "delete-file filename"}, 2965dfecf96Smrg {LispFunction, Lisp_Denominator, "denominator rational"}, 2975dfecf96Smrg {LispFunction, Lisp_DigitChar, "digit-char weight &optional radix"}, 2985dfecf96Smrg {LispFunction, Lisp_DigitCharP, "digit-char-p character &optional radix"}, 2995dfecf96Smrg {LispFunction, Lisp_Directory, "directory pathname &key all if-cannot-read"}, 3005dfecf96Smrg {LispFunction, Lisp_DirectoryNamestring, "directory-namestring pathname"}, 3015dfecf96Smrg {LispFunction, Lisp_Disassemble, "disassemble function"}, 3025dfecf96Smrg {LispMacro, Lisp_Do, "do init test &rest body"}, 3035dfecf96Smrg {LispMacro, Lisp_DoP, "do* init test &rest body"}, 3045dfecf96Smrg {LispFunction, Lisp_Documentation, "documentation symbol type"}, 3055dfecf96Smrg {LispMacro, Lisp_DoList, "dolist init &rest body", 0, 0, Com_Dolist}, 3065dfecf96Smrg {LispMacro, Lisp_DoTimes, "dotimes init &rest body"}, 3075dfecf96Smrg {LispMacro, Lisp_DoAllSymbols, "do-all-symbols init &rest body"}, 3085dfecf96Smrg {LispMacro, Lisp_DoExternalSymbols, "do-external-symbols init &rest body"}, 3095dfecf96Smrg {LispMacro, Lisp_DoSymbols, "do-symbols init &rest body"}, 3105dfecf96Smrg {LispFunction, Lisp_Elt, "elt sequence index"}, 3115dfecf96Smrg {LispFunction, Lisp_Endp, "endp object"}, 3125dfecf96Smrg {LispFunction, Lisp_EnoughNamestring, "enough-namestring pathname &optional defaults"}, 3135dfecf96Smrg {LispFunction, Lisp_Eq, "eq left right", 0, 0, Com_Eq}, 3145dfecf96Smrg {LispFunction, Lisp_Eql, "eql left right", 0, 0, Com_Eq}, 3155dfecf96Smrg {LispFunction, Lisp_Equal, "equal left right", 0, 0, Com_Eq}, 3165dfecf96Smrg {LispFunction, Lisp_Equalp, "equalp left right", 0, 0, Com_Eq}, 3175dfecf96Smrg {LispFunction, Lisp_Error, "error control-string &rest arguments"}, 3185dfecf96Smrg {LispFunction, Lisp_Evenp, "evenp integer"}, 3195dfecf96Smrg {LispFunction, Lisp_Export, "export symbols &optional package"}, 3205dfecf96Smrg {LispFunction, Lisp_Eval, "eval form"}, 3215dfecf96Smrg {LispFunction, Lisp_Every, "every predicate sequence &rest more-sequences"}, 3225dfecf96Smrg {LispFunction, Lisp_Some, "some predicate sequence &rest more-sequences"}, 3235dfecf96Smrg {LispFunction, Lisp_Notevery, "notevery predicate sequence &rest more-sequences"}, 3245dfecf96Smrg {LispFunction, Lisp_Notany, "notany predicate sequence &rest more-sequences"}, 3255dfecf96Smrg {LispFunction, Lisp_Fboundp, "fboundp symbol"}, 3265dfecf96Smrg {LispFunction, Lisp_Find, "find item sequence &key from-end test test-not start end key"}, 3275dfecf96Smrg {LispFunction, Lisp_FindIf, "find-if predicate sequence &key from-end start end key"}, 3285dfecf96Smrg {LispFunction, Lisp_FindIfNot, "find-if-not predicate sequence &key from-end start end key"}, 3295dfecf96Smrg {LispFunction, Lisp_FileNamestring, "file-namestring pathname"}, 3305dfecf96Smrg {LispFunction, Lisp_Fill, "fill sequence item &key start end"}, 3315dfecf96Smrg {LispFunction, Lisp_FindAllSymbols, "find-all-symbols string-or-symbol"}, 3325dfecf96Smrg {LispFunction, Lisp_FindSymbol, "find-symbol string &optional package", 1}, 3335dfecf96Smrg {LispFunction, Lisp_FindPackage, "find-package name"}, 3345dfecf96Smrg {LispFunction, Lisp_Float, "float number &optional other"}, 3355dfecf96Smrg {LispFunction, Lisp_Floatp, "floatp object"}, 3365dfecf96Smrg {LispFunction, Lisp_Floor, "floor number &optional divisor", 1}, 3375dfecf96Smrg {LispFunction, Lisp_Ffloor, "ffloor number &optional divisor", 1}, 3385dfecf96Smrg {LispFunction, Lisp_Fmakunbound, "fmakunbound symbol"}, 3395dfecf96Smrg {LispFunction, Lisp_Format, "format destination control-string &rest arguments"}, 3405dfecf96Smrg {LispFunction, Lisp_FreshLine, "fresh-line &optional output-stream"}, 3415dfecf96Smrg {LispFunction, Lisp_Funcall, "funcall function &rest arguments", 1}, 3425dfecf96Smrg {LispFunction, Lisp_Functionp, "functionp object"}, 3435dfecf96Smrg {LispFunction, Lisp_Gc, "gc &optional car cdr"}, 3445dfecf96Smrg {LispFunction, Lisp_Gcd, "gcd &rest integers"}, 3455dfecf96Smrg {LispFunction, Lisp_Gensym, "gensym &optional arg"}, 3465dfecf96Smrg {LispFunction, Lisp_Get, "get symbol indicator &optional default"}, 3475dfecf96Smrg {LispFunction, Lisp_Gethash, "gethash key hash-table &optional default", 1}, 3485dfecf96Smrg {LispMacro, Lisp_Go, "go tag", 0, 0, Com_Go}, 3495dfecf96Smrg {LispFunction, Lisp_GraphicCharP, "graphic-char-p char"}, 3505dfecf96Smrg {LispFunction, Lisp_HashTableP, "hash-table-p object"}, 3515dfecf96Smrg {LispFunction, Lisp_HashTableCount, "hash-table-count hash-table"}, 3525dfecf96Smrg {LispFunction, Lisp_HashTableRehashSize, "hash-table-rehash-size hash-table"}, 3535dfecf96Smrg {LispFunction, Lisp_HashTableRehashThreshold, "hash-table-rehash-threshold hash-table"}, 3545dfecf96Smrg {LispFunction, Lisp_HashTableSize, "hash-table-size hash-table"}, 3555dfecf96Smrg {LispFunction, Lisp_HashTableTest, "hash-table-test hash-table"}, 3565dfecf96Smrg {LispFunction, Lisp_HostNamestring, "host-namestring pathname"}, 3575dfecf96Smrg {LispMacro, Lisp_If, "if test then &optional else", 0, 0, Com_If}, 3585dfecf96Smrg {LispMacro, Lisp_IgnoreErrors, "ignore-errors &rest body", 1}, 3595dfecf96Smrg {LispFunction, Lisp_Imagpart, "imagpart number"}, 3605dfecf96Smrg {LispMacro, Lisp_InPackage, "in-package name"}, 3615dfecf96Smrg {LispMacro, Lisp_Incf, "incf place &optional delta"}, 3625dfecf96Smrg {LispFunction, Lisp_Import, "import symbols &optional package"}, 3635dfecf96Smrg {LispFunction, Lisp_InputStreamP, "input-stream-p stream"}, 3645dfecf96Smrg {LispFunction, Lisp_IntChar, "int-char integer"}, 3655dfecf96Smrg {LispFunction, Lisp_Integerp, "integerp object"}, 3665dfecf96Smrg {LispFunction, Lisp_Intern, "intern string &optional package", 1}, 3675dfecf96Smrg {LispFunction, Lisp_Intersection, "intersection list1 list2 &key test test-not key"}, 3685dfecf96Smrg {LispFunction, Lisp_Nintersection, "nintersection list1 list2 &key test test-not key"}, 3695dfecf96Smrg {LispFunction, Lisp_Isqrt, "isqrt natural"}, 3705dfecf96Smrg {LispFunction, Lisp_Keywordp, "keywordp object"}, 3715dfecf96Smrg {LispFunction, Lisp_Last, "last list &optional count", 0, 0, Com_Last}, 3725dfecf96Smrg {LispMacro, Lisp_Lambda, "lambda lambda-list &rest body"}, 3735dfecf96Smrg {LispFunction, Lisp_Lcm, "lcm &rest integers"}, 3745dfecf96Smrg {LispFunction, Lisp_Length, "length sequence", 0, 0, Com_Length}, 3755dfecf96Smrg {LispMacro, Lisp_Let, "let init &rest body", 1, 0, Com_Let}, 3765dfecf96Smrg {LispMacro, Lisp_LetP, "let* init &rest body", 1, 0, Com_Letx}, 3775dfecf96Smrg {LispFunction, Lisp_ListP, "list* object &rest more-objects"}, 3785dfecf96Smrg {LispFunction, Lisp_ListAllPackages, "list-all-packages"}, 3795dfecf96Smrg {LispFunction, Lisp_List, "list &rest args"}, 3805dfecf96Smrg {LispFunction, Lisp_ListLength, "list-length list"}, 3815dfecf96Smrg {LispFunction, Lisp_Listp, "listp object", 0, 0, Com_Listp}, 3825dfecf96Smrg {LispFunction, Lisp_Listen, "listen &optional input-stream"}, 3835dfecf96Smrg {LispFunction, Lisp_Load, "load filename &key verbose print if-does-not-exist"}, 3845dfecf96Smrg {LispFunction, Lisp_Logand, "logand &rest integers"}, 3855dfecf96Smrg {LispFunction, Lisp_Logeqv, "logeqv &rest integers"}, 3865dfecf96Smrg {LispFunction, Lisp_Logior, "logior &rest integers"}, 3875dfecf96Smrg {LispFunction, Lisp_Lognot, "lognot integer"}, 3885dfecf96Smrg {LispFunction, Lisp_Logxor, "logxor &rest integers"}, 3895dfecf96Smrg {LispMacro, Lisp_Loop, "loop &rest body", 0, 0, Com_Loop}, 3905dfecf96Smrg {LispFunction, Lisp_LowerCaseP, "lower-case-p character"}, 3915dfecf96Smrg {LispFunction, Lisp_MakeArray, "make-array dimensions &key element-type initial-element initial-contents adjustable fill-pointer displaced-to displaced-index-offset"}, 3925dfecf96Smrg {LispFunction, Lisp_MakeHashTable, "make-hash-table &key test size rehash-size rehash-threshold initial-contents"}, 3935dfecf96Smrg {LispFunction, Lisp_MakeList, "make-list size &key initial-element"}, 3945dfecf96Smrg {LispFunction, Lisp_MakePackage, "make-package package-name &key nicknames use"}, 3955dfecf96Smrg {LispFunction, Lisp_MakePathname, "make-pathname &key host device directory name type version defaults"}, 3965dfecf96Smrg {LispFunction, Lisp_MakeString, "make-string size &key initial-element element-type"}, 3975dfecf96Smrg {LispFunction, Lisp_MakeSymbol, "make-symbol name"}, 3985dfecf96Smrg {LispFunction, Lisp_MakeStringInputStream, "make-string-input-stream string &optional start end"}, 3995dfecf96Smrg {LispFunction, Lisp_MakeStringOutputStream, "make-string-output-stream &key element-type"}, 4005dfecf96Smrg {LispFunction, Lisp_GetOutputStreamString, "get-output-stream-string string-output-stream"}, 4015dfecf96Smrg {LispFunction, Lisp_Makunbound, "makunbound symbol"}, 4025dfecf96Smrg {LispFunction, Lisp_Mapc, "mapc function list &rest more-lists"}, 4035dfecf96Smrg {LispFunction, Lisp_Mapcar, "mapcar function list &rest more-lists"}, 4045dfecf96Smrg {LispFunction, Lisp_Mapcan, "mapcan function list &rest more-lists"}, 4055dfecf96Smrg {LispFunction, Lisp_Maphash, "maphash function hash-table"}, 4065dfecf96Smrg {LispFunction, Lisp_Mapl, "mapl function list &rest more-lists"}, 4075dfecf96Smrg {LispFunction, Lisp_Maplist, "maplist function list &rest more-lists"}, 4085dfecf96Smrg {LispFunction, Lisp_Mapcon, "mapcon function list &rest more-lists"}, 4095dfecf96Smrg {LispFunction, Lisp_Member, "member item list &key test test-not key"}, 4105dfecf96Smrg {LispFunction, Lisp_MemberIf, "member-if predicate list &key key"}, 4115dfecf96Smrg {LispFunction, Lisp_MemberIfNot, "member-if-not predicate list &key key"}, 4125dfecf96Smrg {LispFunction, Lisp_Minusp, "minusp number"}, 4135dfecf96Smrg {LispFunction, Lisp_Mod, "mod number divisor"}, 4145dfecf96Smrg {LispMacro, Lisp_MultipleValueBind, "multiple-value-bind symbols values &rest body"}, 4155dfecf96Smrg {LispMacro, Lisp_MultipleValueCall, "multiple-value-call function &rest form", 1}, 4165dfecf96Smrg {LispMacro, Lisp_MultipleValueProg1, "multiple-value-prog1 first-form &rest form", 1}, 4175dfecf96Smrg {LispMacro, Lisp_MultipleValueList, "multiple-value-list form"}, 4185dfecf96Smrg {LispMacro, Lisp_MultipleValueSetq, "multiple-value-setq symbols form"}, 4195dfecf96Smrg {LispFunction, Lisp_Nconc, "nconc &rest lists"}, 4205dfecf96Smrg {LispFunction, Lisp_Nreverse, "nreverse sequence"}, 4215dfecf96Smrg {LispFunction, Lisp_NsetDifference, "nset-difference list1 list2 &key test test-not key"}, 4225dfecf96Smrg {LispFunction, Lisp_Nsubstitute, "nsubstitute newitem olditem sequence &key from-end test test-not start end count key"}, 4235dfecf96Smrg {LispFunction, Lisp_NsubstituteIf, "nsubstitute-if newitem test sequence &key from-end start end count key"}, 4245dfecf96Smrg {LispFunction, Lisp_NsubstituteIfNot, "nsubstitute-if-not newitem test sequence &key from-end start end count key"}, 4255dfecf96Smrg {LispFunction, Lisp_Nth, "nth index list"}, 4265dfecf96Smrg {LispFunction, Lisp_Nthcdr, "nthcdr index list", 0, 0, Com_Nthcdr}, 4275dfecf96Smrg {LispMacro, Lisp_NthValue, "nth-value index form"}, 4285dfecf96Smrg {LispFunction, Lisp_Numerator, "numerator rational"}, 4295dfecf96Smrg {LispFunction, Lisp_Namestring, "namestring pathname"}, 4305dfecf96Smrg {LispFunction, Lisp_Null, "not arg", 0, 0, Com_Null}, 4315dfecf96Smrg {LispFunction, Lisp_Null, "null list", 0, 0, Com_Null}, 4325dfecf96Smrg {LispFunction, Lisp_Numberp, "numberp object", 0, 0, Com_Numberp}, 4335dfecf96Smrg {LispFunction, Lisp_Oddp, "oddp integer"}, 4345dfecf96Smrg {LispFunction, Lisp_Open, "open filename &key direction element-type if-exists if-does-not-exist external-format"}, 4355dfecf96Smrg {LispFunction, Lisp_OpenStreamP, "open-stream-p stream"}, 4365dfecf96Smrg {LispMacro, Lisp_Or, "or &rest args", 1, 0, Com_Or}, 4375dfecf96Smrg {LispFunction, Lisp_OutputStreamP, "output-stream-p stream"}, 4385dfecf96Smrg {LispFunction, Lisp_Packagep, "packagep object"}, 4395dfecf96Smrg {LispFunction, Lisp_PackageName, "package-name package"}, 4405dfecf96Smrg {LispFunction, Lisp_PackageNicknames, "package-nicknames package"}, 4415dfecf96Smrg {LispFunction, Lisp_PackageUseList, "package-use-list package"}, 4425dfecf96Smrg {LispFunction, Lisp_PackageUsedByList, "package-used-by-list package"}, 4435dfecf96Smrg {LispFunction, Lisp_Pairlis, "pairlis key data &optional alist"}, 4445dfecf96Smrg {LispFunction, Lisp_ParseInteger, "parse-integer string &key start end radix junk-allowed", 1}, 4455dfecf96Smrg {LispFunction, Lisp_ParseNamestring, "parse-namestring object &optional host defaults &key start end junk-allowed", 1}, 4465dfecf96Smrg {LispFunction, Lisp_PathnameHost, "pathname-host pathname"}, 4475dfecf96Smrg {LispFunction, Lisp_PathnameDevice, "pathname-device pathname"}, 4485dfecf96Smrg {LispFunction, Lisp_PathnameDirectory, "pathname-directory pathname"}, 4495dfecf96Smrg {LispFunction, Lisp_PathnameName, "pathname-name pathname"}, 4505dfecf96Smrg {LispFunction, Lisp_PathnameType, "pathname-type pathname"}, 4515dfecf96Smrg {LispFunction, Lisp_PathnameVersion, "pathname-version pathname"}, 4525dfecf96Smrg {LispFunction, Lisp_Pathnamep, "pathnamep object"}, 4535dfecf96Smrg {LispFunction, Lisp_Plusp, "plusp number"}, 4545dfecf96Smrg {LispMacro, Lisp_Pop, "pop place"}, 4555dfecf96Smrg {LispFunction, Lisp_Position, "position item sequence &key from-end test test-not start end key"}, 4565dfecf96Smrg {LispFunction, Lisp_PositionIf, "position-if predicate sequence &key from-end start end key"}, 4575dfecf96Smrg {LispFunction, Lisp_PositionIfNot, "position-if-not predicate sequence &key from-end start end key"}, 4585dfecf96Smrg {LispFunction, Lisp_Prin1, "prin1 object &optional output-stream"}, 4595dfecf96Smrg {LispFunction, Lisp_Princ, "princ object &optional output-stream"}, 4605dfecf96Smrg {LispFunction, Lisp_Print, "print object &optional output-stream"}, 4615dfecf96Smrg {LispFunction, Lisp_ProbeFile, "probe-file pathname"}, 4625dfecf96Smrg {LispFunction, Lisp_Proclaim, "proclaim declaration"}, 4635dfecf96Smrg {LispMacro, Lisp_Prog1, "prog1 first &rest body"}, 4645dfecf96Smrg {LispMacro, Lisp_Prog2, "prog2 first second &rest body"}, 4655dfecf96Smrg {LispMacro, Lisp_Progn, "progn &rest body", 1, 0, Com_Progn}, 4665dfecf96Smrg {LispMacro, Lisp_Progv, "progv symbols values &rest body", 1}, 4675dfecf96Smrg {LispFunction, Lisp_Provide, "provide module"}, 4685dfecf96Smrg {LispMacro, Lisp_Push, "push item place"}, 4695dfecf96Smrg {LispMacro, Lisp_Pushnew, "pushnew item place &key key test test-not"}, 4705dfecf96Smrg {LispFunction, Lisp_Quit, "quit &optional status"}, 4715dfecf96Smrg {LispMacro, Lisp_Quote, "quote object"}, 4725dfecf96Smrg {LispFunction, Lisp_Rational, "rational number"}, 4735dfecf96Smrg {LispFunction, Lisp_Rationalp, "rationalp object"}, 4745dfecf96Smrg {LispFunction, Lisp_Read, "read &optional input-stream eof-error-p eof-value recursive-p"}, 4755dfecf96Smrg {LispFunction, Lisp_ReadChar, "read-char &optional input-stream eof-error-p eof-value recursive-p"}, 4765dfecf96Smrg {LispFunction, Lisp_ReadCharNoHang, "read-char-no-hang &optional input-stream eof-error-p eof-value recursive-p"}, 4775dfecf96Smrg {LispFunction, Lisp_ReadLine, "read-line &optional input-stream eof-error-p eof-value recursive-p", 1}, 4785dfecf96Smrg {LispFunction, Lisp_Realpart, "realpart number"}, 4795dfecf96Smrg {LispFunction, Lisp_Replace, "replace sequence1 sequence2 &key start1 end1 start2 end2"}, 4805dfecf96Smrg {LispFunction, Lisp_ReadFromString, "read-from-string string &optional eof-error-p eof-value &key start end preserve-whitespace", 1}, 4815dfecf96Smrg {LispFunction, Lisp_Require, "require module &optional pathname"}, 4825dfecf96Smrg {LispFunction, Lisp_Rem, "rem number divisor"}, 4835dfecf96Smrg {LispFunction, Lisp_Remhash, "remhash key hash-table"}, 4845dfecf96Smrg {LispFunction, Lisp_Remove, "remove item sequence &key from-end test test-not start end count key"}, 4855dfecf96Smrg {LispFunction, Lisp_RemoveDuplicates, "remove-duplicates sequence &key from-end test test-not start end key"}, 4865dfecf96Smrg {LispFunction, Lisp_RemoveIf, "remove-if predicate sequence &key from-end start end count key"}, 4875dfecf96Smrg {LispFunction, Lisp_RemoveIfNot, "remove-if-not predicate sequence &key from-end start end count key"}, 4885dfecf96Smrg {LispFunction, Lisp_Remprop, "remprop symbol indicator"}, 4895dfecf96Smrg {LispFunction, Lisp_RenameFile, "rename-file filename new-name", 1}, 4905dfecf96Smrg {LispMacro, Lisp_Return, "return &optional result", 1, 0, Com_Return}, 4915dfecf96Smrg {LispMacro, Lisp_ReturnFrom, "return-from name &optional result", 1, 0, Com_ReturnFrom}, 4925dfecf96Smrg {LispFunction, Lisp_Reverse, "reverse sequence"}, 4935dfecf96Smrg {LispFunction, Lisp_Round, "round number &optional divisor", 1}, 4945dfecf96Smrg {LispFunction, Lisp_Fround, "fround number &optional divisor", 1}, 4955dfecf96Smrg {LispFunction, Lisp_Rplaca, "rplaca place value", 0, 0, Com_Rplac_}, 4965dfecf96Smrg {LispFunction, Lisp_Rplacd, "rplacd place value", 0, 0, Com_Rplac_}, 4975dfecf96Smrg {LispFunction, Lisp_Search, "search sequence1 sequence2 &key from-end test test-not key start1 start2 end1 end2"}, 4985dfecf96Smrg {LispFunction, Lisp_Set, "set symbol value"}, 4995dfecf96Smrg {LispFunction, Lisp_SetDifference, "set-difference list1 list2 &key test test-not key"}, 5005dfecf96Smrg {LispFunction, Lisp_SetExclusiveOr, "set-exclusive-or list1 list2 &key test test-not key"}, 5015dfecf96Smrg {LispFunction, Lisp_NsetExclusiveOr, "nset-exclusive-or list1 list2 &key test test-not key"}, 5025dfecf96Smrg {LispMacro, Lisp_Setf, "setf &rest form"}, 5035dfecf96Smrg {LispMacro, Lisp_Psetf, "psetf &rest form"}, 5045dfecf96Smrg {LispMacro, Lisp_SetQ, "setq &rest form", 0, 0, Com_Setq}, 5055dfecf96Smrg {LispMacro, Lisp_Psetq, "psetq &rest form"}, 5065dfecf96Smrg {LispFunction, Lisp_Sleep, "sleep seconds"}, 5075dfecf96Smrg {LispFunction, Lisp_Sort, "sort sequence predicate &key key"}, 5085dfecf96Smrg {LispFunction, Lisp_Sqrt, "sqrt number"}, 5095dfecf96Smrg {LispFunction, Lisp_Elt, "svref sequence index"}, 5105dfecf96Smrg {LispFunction, Lisp_Sort, "stable-sort sequence predicate &key key"}, 5115dfecf96Smrg {LispFunction, Lisp_Streamp, "streamp object"}, 5125dfecf96Smrg {LispFunction, Lisp_String, "string object"}, 5135dfecf96Smrg {LispFunction, Lisp_Stringp, "stringp object"}, 5145dfecf96Smrg {LispFunction, Lisp_StringEqual_, "string= string1 string2 &key start1 end1 start2 end2"}, 5155dfecf96Smrg {LispFunction, Lisp_StringLess, "string< string1 string2 &key start1 end1 start2 end2"}, 5165dfecf96Smrg {LispFunction, Lisp_StringGreater, "string> string1 string2 &key start1 end1 start2 end2"}, 5175dfecf96Smrg {LispFunction, Lisp_StringLessEqual, "string<= string1 string2 &key start1 end1 start2 end2"}, 5185dfecf96Smrg {LispFunction, Lisp_StringGreaterEqual, "string>= string1 string2 &key start1 end1 start2 end2"}, 5195dfecf96Smrg {LispFunction, Lisp_StringNotEqual_, "string/= string1 string2 &key start1 end1 start2 end2"}, 5205dfecf96Smrg {LispFunction, Lisp_StringConcat, "string-concat &rest strings"}, 5215dfecf96Smrg {LispFunction, Lisp_StringEqual, "string-equal string1 string2 &key start1 end1 start2 end2"}, 5225dfecf96Smrg {LispFunction, Lisp_StringGreaterp, "string-greaterp string1 string2 &key start1 end1 start2 end2"}, 5235dfecf96Smrg {LispFunction, Lisp_StringNotEqual, "string-not-equal string1 string2 &key start1 end1 start2 end2"}, 5245dfecf96Smrg {LispFunction, Lisp_StringNotGreaterp, "string-not-greaterp string1 string2 &key start1 end1 start2 end2"}, 5255dfecf96Smrg {LispFunction, Lisp_StringNotLessp, "string-not-lessp string1 string2 &key start1 end1 start2 end2"}, 5265dfecf96Smrg {LispFunction, Lisp_StringLessp, "string-lessp string1 string2 &key start1 end1 start2 end2"}, 5275dfecf96Smrg {LispFunction, Lisp_StringTrim, "string-trim character-bag string"}, 5285dfecf96Smrg {LispFunction, Lisp_StringLeftTrim, "string-left-trim character-bag string"}, 5295dfecf96Smrg {LispFunction, Lisp_StringRightTrim, "string-right-trim character-bag string"}, 5305dfecf96Smrg {LispFunction, Lisp_StringUpcase, "string-upcase string &key start end"}, 5315dfecf96Smrg {LispFunction, Lisp_NstringUpcase, "nstring-upcase string &key start end"}, 5325dfecf96Smrg {LispFunction, Lisp_StringDowncase, "string-downcase string &key start end"}, 5335dfecf96Smrg {LispFunction, Lisp_NstringDowncase, "nstring-downcase string &key start end"}, 5345dfecf96Smrg {LispFunction, Lisp_StringCapitalize, "string-capitalize string &key start end"}, 5355dfecf96Smrg {LispFunction, Lisp_NstringCapitalize, "nstring-capitalize string &key start end"}, 5365dfecf96Smrg {LispFunction, Lisp_Subseq, "subseq sequence start &optional end"}, 5375dfecf96Smrg {LispFunction, Lisp_Subsetp, "subsetp list1 list2 &key test test-not key"}, 5385dfecf96Smrg {LispFunction, Lisp_Substitute, "substitute newitem olditem sequence &key from-end test test-not start end count key"}, 5395dfecf96Smrg {LispFunction, Lisp_SubstituteIf, "substitute-if newitem test sequence &key from-end start end count key"}, 5405dfecf96Smrg {LispFunction, Lisp_SubstituteIfNot, "substitute-if-not newitem test sequence &key from-end start end count key"}, 5415dfecf96Smrg {LispFunction, Lisp_SymbolFunction, "symbol-function symbol"}, 5425dfecf96Smrg {LispFunction, Lisp_SymbolName, "symbol-name symbol"}, 5435dfecf96Smrg {LispFunction, Lisp_Symbolp, "symbolp object"}, 5445dfecf96Smrg {LispFunction, Lisp_SymbolPlist, "symbol-plist symbol"}, 5455dfecf96Smrg {LispFunction, Lisp_SymbolPackage, "symbol-package symbol"}, 5465dfecf96Smrg {LispFunction, Lisp_SymbolValue, "symbol-value symbol"}, 5475dfecf96Smrg {LispMacro, Lisp_Tagbody, "tagbody &rest body", 0, 0, Com_Tagbody}, 5485dfecf96Smrg {LispFunction, Lisp_Terpri, "terpri &optional output-stream"}, 5495dfecf96Smrg {LispFunction, Lisp_Typep, "typep object type"}, 5505dfecf96Smrg {LispMacro, Lisp_The, "the value-type form"}, 5515dfecf96Smrg {LispMacro, Lisp_Throw, "throw tag result", 1}, 5525dfecf96Smrg {LispMacro, Lisp_Time, "time form"}, 5535dfecf96Smrg {LispFunction, Lisp_Truename, "truename pathname"}, 5545dfecf96Smrg {LispFunction, Lisp_TreeEqual, "tree-equal tree-1 tree-2 &key test test-not"}, 5555dfecf96Smrg {LispFunction, Lisp_Truncate, "truncate number &optional divisor", 1}, 5565dfecf96Smrg {LispFunction, Lisp_Ftruncate, "ftruncate number &optional divisor", 1}, 5575dfecf96Smrg {LispFunction, Lisp_Unexport, "unexport symbols &optional package"}, 5585dfecf96Smrg {LispFunction, Lisp_Union, "union list1 list2 &key test test-not key"}, 5595dfecf96Smrg {LispFunction, Lisp_Nunion, "nunion list1 list2 &key test test-not key"}, 5605dfecf96Smrg {LispMacro, Lisp_Unless, "unless test &rest body", 1, 0, Com_Unless}, 5615dfecf96Smrg {LispFunction, Lisp_UserHomedirPathname, "user-homedir-pathname &optional host"}, 5625dfecf96Smrg {LispMacro, Lisp_UnwindProtect, "unwind-protect protect &rest cleanup"}, 5635dfecf96Smrg {LispFunction, Lisp_UpperCaseP, "upper-case-p character"}, 5645dfecf96Smrg {LispFunction, Lisp_Values, "values &rest objects", 1}, 5655dfecf96Smrg {LispFunction, Lisp_ValuesList, "values-list list", 1}, 5665dfecf96Smrg {LispFunction, Lisp_Vector, "vector &rest objects"}, 5675dfecf96Smrg {LispMacro, Lisp_When, "when test &rest body", 1, 0, Com_When}, 5685dfecf96Smrg {LispFunction, Lisp_Write, " write object &key case circle escape length level lines pretty readably right-margin stream"}, 5695dfecf96Smrg {LispFunction, Lisp_WriteChar, "write-char string &optional output-stream"}, 5705dfecf96Smrg {LispFunction, Lisp_WriteLine, "write-line string &optional output-stream &key start end"}, 5715dfecf96Smrg {LispFunction, Lisp_WriteString, "write-string string &optional output-stream &key start end"}, 5725dfecf96Smrg {LispFunction, Lisp_XeditCharStore, "lisp::char-store string index value", 0, 1}, 5735dfecf96Smrg {LispFunction, Lisp_XeditEltStore, "lisp::elt-store sequence index value", 0, 1}, 5745dfecf96Smrg {LispFunction, Lisp_XeditMakeStruct, "lisp::make-struct atom &rest init", 0, 1}, 5755dfecf96Smrg {LispFunction, Lisp_XeditPut, " lisp::put symbol indicator value", 0, 1}, 5765dfecf96Smrg {LispFunction, Lisp_XeditPuthash, "lisp::puthash key hash-table value", 0, 1}, 5775dfecf96Smrg {LispFunction, Lisp_XeditSetSymbolPlist, "lisp::set-symbol-plist symbol list", 0, 1}, 5785dfecf96Smrg {LispFunction, Lisp_XeditStructAccess, "lisp::struct-access atom struct", 0, 1}, 5795dfecf96Smrg {LispFunction, Lisp_XeditStructType, "lisp::struct-type atom struct", 0, 1}, 5805dfecf96Smrg {LispFunction, Lisp_XeditStructStore, "lisp::struct-store atom struct value", 0, 1}, 5815dfecf96Smrg {LispFunction, Lisp_XeditVectorStore, "lisp::vector-store array &rest values", 0, 1}, 5825dfecf96Smrg {LispFunction, Lisp_XeditDocumentationStore, "lisp::documentation-store symbol type string", 0, 1}, 5835dfecf96Smrg {LispFunction, Lisp_Zerop, "zerop number"}, 5845dfecf96Smrg}; 5855dfecf96Smrg 5865dfecf96Smrgstatic LispBuiltin extbuiltins[] = { 5875dfecf96Smrg {LispFunction, Lisp_Getenv, "getenv name"}, 5885dfecf96Smrg {LispFunction, Lisp_MakePipe, "make-pipe command-line &key direction element-type external-format"}, 5895dfecf96Smrg {LispFunction, Lisp_PipeBroken, "pipe-broken pipe-stream"}, 5905dfecf96Smrg {LispFunction, Lisp_PipeErrorStream, "pipe-error-stream pipe-stream"}, 5915dfecf96Smrg {LispFunction, Lisp_PipeInputDescriptor, "pipe-input-descriptor pipe-stream"}, 5925dfecf96Smrg {LispFunction, Lisp_PipeErrorDescriptor, "pipe-error-descriptor pipe-stream"}, 5935dfecf96Smrg {LispFunction, Lisp_Recomp, "re-comp pattern &key nospec icase nosub newline"}, 5945dfecf96Smrg {LispFunction, Lisp_Reexec, "re-exec regex string &key count start end notbol noteol"}, 5955dfecf96Smrg {LispFunction, Lisp_Rep, "re-p object"}, 5965dfecf96Smrg {LispFunction, Lisp_Setenv, "setenv name value &optional overwrite"}, 5975dfecf96Smrg {LispFunction, Lisp_Unsetenv, "unsetenv name"}, 5985dfecf96Smrg {LispFunction, Lisp_NstringTrim, "nstring-trim character-bag string"}, 5995dfecf96Smrg {LispFunction, Lisp_NstringLeftTrim, "nstring-left-trim character-bag string"}, 6005dfecf96Smrg {LispFunction, Lisp_NstringRightTrim, "nstring-right-trim character-bag string"}, 6015dfecf96Smrg {LispMacro, Lisp_Until, "until test &rest body", 0, 0, Com_Until}, 6025dfecf96Smrg {LispMacro, Lisp_While, "while test &rest body", 0, 0, Com_While}, 6035dfecf96Smrg}; 6045dfecf96Smrg 6055dfecf96Smrg/* byte code function argument list for functions that don't change it's 6065dfecf96Smrg * &REST argument list. */ 6075dfecf96Smrgextern LispObj x_cons[8]; 6085dfecf96Smrg 6095dfecf96Smrg/* 6105dfecf96Smrg * Implementation 6115dfecf96Smrg */ 6125dfecf96Smrgstatic int 6135dfecf96SmrgLispGetPageSize(void) 6145dfecf96Smrg{ 6155dfecf96Smrg static int pagesize = -1; 6165dfecf96Smrg 6175dfecf96Smrg if (pagesize != -1) 6185dfecf96Smrg return pagesize; 6195dfecf96Smrg 6205dfecf96Smrg /* Try each supported method in the preferred order */ 6215dfecf96Smrg 622f765521fSmrg#if defined(_SC_PAGESIZE) || defined(HAVE_DECL__SC_PAGESIZE) 6235dfecf96Smrg pagesize = sysconf(_SC_PAGESIZE); 6245dfecf96Smrg#endif 6255dfecf96Smrg 6265dfecf96Smrg#ifdef _SC_PAGE_SIZE 6275dfecf96Smrg if (pagesize == -1) 6285dfecf96Smrg pagesize = sysconf(_SC_PAGE_SIZE); 6295dfecf96Smrg#endif 6305dfecf96Smrg 631f765521fSmrg#ifdef HAVE_GETPAGESIZE 6325dfecf96Smrg if (pagesize == -1) 6335dfecf96Smrg pagesize = getpagesize(); 6345dfecf96Smrg#endif 6355dfecf96Smrg 6365dfecf96Smrg#ifdef PAGE_SIZE 6375dfecf96Smrg if (pagesize == -1) 6385dfecf96Smrg pagesize = PAGE_SIZE; 6395dfecf96Smrg#endif 6405dfecf96Smrg 6415dfecf96Smrg if (pagesize < sizeof(LispObj) * 16) 6425dfecf96Smrg pagesize = sizeof(LispObj) * 16; /* need a reasonable sane size */ 6435dfecf96Smrg 6445dfecf96Smrg return pagesize; 6455dfecf96Smrg} 6465dfecf96Smrg 6475dfecf96Smrgvoid 648f765521fSmrgLispDestroy(const char *fmt, ...) 6495dfecf96Smrg{ 6505dfecf96Smrg static char Error[] = "*** "; 6515dfecf96Smrg 6525dfecf96Smrg if (!lisp__data.destroyed) { 6535dfecf96Smrg char string[128]; 6545dfecf96Smrg va_list ap; 6555dfecf96Smrg 6565dfecf96Smrg va_start(ap, fmt); 6575dfecf96Smrg vsnprintf(string, sizeof(string), fmt, ap); 6585dfecf96Smrg va_end(ap); 6595dfecf96Smrg 6605dfecf96Smrg if (!lisp__data.ignore_errors) { 6615dfecf96Smrg if (Stderr->column) 6625dfecf96Smrg LispFputc(Stderr, '\n'); 6635dfecf96Smrg LispFputs(Stderr, Error); 6645dfecf96Smrg LispFputs(Stderr, string); 6655dfecf96Smrg LispFputc(Stderr, '\n'); 6665dfecf96Smrg LispFflush(Stderr); 6675dfecf96Smrg } 6685dfecf96Smrg else 6695dfecf96Smrg lisp__data.error_condition = STRING(string); 6705dfecf96Smrg 6715dfecf96Smrg#ifdef DEBUGGER 6725dfecf96Smrg if (lisp__data.debugging) { 6735dfecf96Smrg LispDebugger(LispDebugCallWatch, NIL, NIL); 6745dfecf96Smrg LispDebugger(LispDebugCallFatal, NIL, NIL); 6755dfecf96Smrg } 6765dfecf96Smrg#endif 6775dfecf96Smrg 6785dfecf96Smrg lisp__data.destroyed = 1; 6795dfecf96Smrg LispBlockUnwind(NULL); 6805dfecf96Smrg if (lisp__data.errexit) 6815dfecf96Smrg exit(1); 6825dfecf96Smrg } 6835dfecf96Smrg 6845dfecf96Smrg#ifdef DEBUGGER 6855dfecf96Smrg if (lisp__data.debugging) { 6865dfecf96Smrg /* when stack variables could be changed, this must be also changed! */ 6875dfecf96Smrg lisp__data.debug_level = -1; 6885dfecf96Smrg lisp__data.debug = LispDebugUnspec; 6895dfecf96Smrg } 6905dfecf96Smrg#endif 6915dfecf96Smrg 6925dfecf96Smrg while (lisp__data.mem.level) { 6935dfecf96Smrg --lisp__data.mem.level; 6945dfecf96Smrg if (lisp__data.mem.mem[lisp__data.mem.level]) 6955dfecf96Smrg free(lisp__data.mem.mem[lisp__data.mem.level]); 6965dfecf96Smrg } 6975dfecf96Smrg lisp__data.mem.index = 0; 6985dfecf96Smrg 6995dfecf96Smrg /* If the package was changed and an error happened */ 700c2cbb186Smrg if (lisp__data.savepackage != NULL) 701c2cbb186Smrg PACKAGE = lisp__data.savepackage; 7025dfecf96Smrg lisp__data.pack = lisp__data.savepack; 7035dfecf96Smrg 7045dfecf96Smrg LispTopLevel(); 7055dfecf96Smrg 7065dfecf96Smrg if (!lisp__data.running) { 707f765521fSmrg static const char *Fatal = "*** Fatal: nowhere to longjmp.\n"; 7085dfecf96Smrg 7095dfecf96Smrg LispFputs(Stderr, Fatal); 7105dfecf96Smrg LispFflush(Stderr); 7115dfecf96Smrg abort(); 7125dfecf96Smrg } 7135dfecf96Smrg 7145dfecf96Smrg siglongjmp(lisp__data.jmp, 1); 7155dfecf96Smrg} 7165dfecf96Smrg 7175dfecf96Smrgvoid 718f765521fSmrgLispContinuable(const char *fmt, ...) 7195dfecf96Smrg{ 7205dfecf96Smrg va_list ap; 7215dfecf96Smrg char string[128]; 722f765521fSmrg static const char *Error = "*** Error: "; 7235dfecf96Smrg 7245dfecf96Smrg if (Stderr->column) 7255dfecf96Smrg LispFputc(Stderr, '\n'); 7265dfecf96Smrg LispFputs(Stderr, Error); 7275dfecf96Smrg va_start(ap, fmt); 7285dfecf96Smrg vsnprintf(string, sizeof(string), fmt, ap); 7295dfecf96Smrg va_end(ap); 7305dfecf96Smrg LispFputs(Stderr, string); 7315dfecf96Smrg LispFputc(Stderr, '\n'); 7325dfecf96Smrg LispFputs(Stderr, "Type 'continue' if you want to proceed: "); 7335dfecf96Smrg LispFflush(Stderr); 7345dfecf96Smrg 7355dfecf96Smrg /* NOTE: does not check if stdin is a tty */ 7365dfecf96Smrg if (LispFgets(Stdin, string, sizeof(string)) && 7375dfecf96Smrg strcmp(string, "continue\n") == 0) 7385dfecf96Smrg return; 7395dfecf96Smrg 7405dfecf96Smrg LispDestroy("aborted on continuable error"); 7415dfecf96Smrg} 7425dfecf96Smrg 7435dfecf96Smrgvoid 744f765521fSmrgLispMessage(const char *fmt, ...) 7455dfecf96Smrg{ 7465dfecf96Smrg va_list ap; 7475dfecf96Smrg char string[128]; 7485dfecf96Smrg 7495dfecf96Smrg if (Stderr->column) 7505dfecf96Smrg LispFputc(Stderr, '\n'); 7515dfecf96Smrg va_start(ap, fmt); 7525dfecf96Smrg vsnprintf(string, sizeof(string), fmt, ap); 7535dfecf96Smrg va_end(ap); 7545dfecf96Smrg LispFputs(Stderr, string); 7555dfecf96Smrg LispFputc(Stderr, '\n'); 7565dfecf96Smrg LispFflush(Stderr); 7575dfecf96Smrg} 7585dfecf96Smrg 7595dfecf96Smrgvoid 760f765521fSmrgLispWarning(const char *fmt, ...) 7615dfecf96Smrg{ 7625dfecf96Smrg va_list ap; 7635dfecf96Smrg char string[128]; 764f765521fSmrg static const char *Warning = "*** Warning: "; 7655dfecf96Smrg 7665dfecf96Smrg if (Stderr->column) 7675dfecf96Smrg LispFputc(Stderr, '\n'); 7685dfecf96Smrg LispFputs(Stderr, Warning); 7695dfecf96Smrg va_start(ap, fmt); 7705dfecf96Smrg vsnprintf(string, sizeof(string), fmt, ap); 7715dfecf96Smrg va_end(ap); 7725dfecf96Smrg LispFputs(Stderr, string); 7735dfecf96Smrg LispFputc(Stderr, '\n'); 7745dfecf96Smrg LispFflush(Stderr); 7755dfecf96Smrg} 7765dfecf96Smrg 7775dfecf96Smrgvoid 7785dfecf96SmrgLispTopLevel(void) 7795dfecf96Smrg{ 7805dfecf96Smrg int count; 7815dfecf96Smrg 7825dfecf96Smrg COD = NIL; 7835dfecf96Smrg#ifdef DEBUGGER 7845dfecf96Smrg if (lisp__data.debugging) { 7855dfecf96Smrg DBG = NIL; 7865dfecf96Smrg if (lisp__data.debug == LispDebugFinish) 7875dfecf96Smrg lisp__data.debug = LispDebugUnspec; 7885dfecf96Smrg lisp__data.debug_level = -1; 7895dfecf96Smrg lisp__data.debug_step = 0; 7905dfecf96Smrg } 7915dfecf96Smrg#endif 7925dfecf96Smrg gcpro = 0; 7935dfecf96Smrg lisp__data.block.block_level = 0; 7945dfecf96Smrg if (lisp__data.block.block_size) { 7955dfecf96Smrg while (lisp__data.block.block_size) 7965dfecf96Smrg free(lisp__data.block.block[--lisp__data.block.block_size]); 7975dfecf96Smrg free(lisp__data.block.block); 7985dfecf96Smrg lisp__data.block.block = NULL; 7995dfecf96Smrg } 8005dfecf96Smrg 8015dfecf96Smrg lisp__data.destroyed = lisp__data.ignore_errors = 0; 8025dfecf96Smrg 8035dfecf96Smrg if (CONSP(lisp__data.input_list)) { 8045dfecf96Smrg LispUngetInfo **info, *unget = lisp__data.unget[0]; 8055dfecf96Smrg 8065dfecf96Smrg while (CONSP(lisp__data.input_list)) 8075dfecf96Smrg lisp__data.input_list = CDR(lisp__data.input_list); 8085dfecf96Smrg SINPUT = lisp__data.input_list; 8095dfecf96Smrg while (lisp__data.nunget > 1) 8105dfecf96Smrg free(lisp__data.unget[--lisp__data.nunget]); 8115dfecf96Smrg if ((info = realloc(lisp__data.unget, sizeof(LispUngetInfo*))) != NULL) 8125dfecf96Smrg lisp__data.unget = info; 8135dfecf96Smrg lisp__data.unget[0] = unget; 8145dfecf96Smrg lisp__data.iunget = 0; 8155dfecf96Smrg lisp__data.eof = 0; 8165dfecf96Smrg } 8175dfecf96Smrg 8185dfecf96Smrg for (count = 0; lisp__data.mem.level;) { 8195dfecf96Smrg --lisp__data.mem.level; 8205dfecf96Smrg if (lisp__data.mem.mem[lisp__data.mem.level]) { 8215dfecf96Smrg ++count; 8225dfecf96Smrg#if 0 8235dfecf96Smrg printf("LEAK: %p\n", lisp__data.mem.mem[lisp__data.mem.level]); 8245dfecf96Smrg#endif 8255dfecf96Smrg } 8265dfecf96Smrg } 8275dfecf96Smrg lisp__data.mem.index = 0; 8285dfecf96Smrg if (count) 8295dfecf96Smrg LispWarning("%d raw memory pointer(s) left. Probably a leak.", count); 8305dfecf96Smrg 8315dfecf96Smrg lisp__data.stack.base = lisp__data.stack.length = 8325dfecf96Smrg lisp__data.env.lex = lisp__data.env.length = lisp__data.env.head = 0; 8335dfecf96Smrg RETURN_COUNT = 0; 8345dfecf96Smrg lisp__data.protect.length = 0; 8355dfecf96Smrg 8365dfecf96Smrg lisp__data.savepackage = PACKAGE; 8375dfecf96Smrg lisp__data.savepack = lisp__data.pack; 8385dfecf96Smrg 8395dfecf96Smrg lisp__disable_int = lisp__interrupted = 0; 8405dfecf96Smrg} 8415dfecf96Smrg 8425dfecf96Smrgvoid 8435dfecf96SmrgLispGC(LispObj *car, LispObj *cdr) 8445dfecf96Smrg{ 8455dfecf96Smrg Lisp__GC(car, cdr); 8465dfecf96Smrg} 8475dfecf96Smrg 8485dfecf96Smrgstatic void 8495dfecf96SmrgLisp__GC(LispObj *car, LispObj *cdr) 8505dfecf96Smrg{ 8515dfecf96Smrg register LispObj *entry, *last, *freeobj, **pentry, **eentry; 8525dfecf96Smrg register int nfree; 8535dfecf96Smrg unsigned i, j; 8545dfecf96Smrg LispAtom *atom; 8555dfecf96Smrg struct timeval start, end; 8565dfecf96Smrg#ifdef DEBUG 8575dfecf96Smrg long sec, msec; 8585dfecf96Smrg int count = objseg.nfree; 8595dfecf96Smrg#else 8605dfecf96Smrg long msec; 8615dfecf96Smrg#endif 8625dfecf96Smrg 8635dfecf96Smrg if (gcpro) 8645dfecf96Smrg return; 8655dfecf96Smrg 8665dfecf96Smrg DISABLE_INTERRUPTS(); 8675dfecf96Smrg 8685dfecf96Smrg nfree = 0; 8695dfecf96Smrg freeobj = NIL; 8705dfecf96Smrg 8715dfecf96Smrg ++lisp__data.gc.count; 8725dfecf96Smrg 8735dfecf96Smrg#ifdef DEBUG 8745dfecf96Smrg gettimeofday(&start, NULL); 8755dfecf96Smrg#else 8765dfecf96Smrg if (lisp__data.gc.timebits) 8775dfecf96Smrg gettimeofday(&start, NULL); 8785dfecf96Smrg#endif 8795dfecf96Smrg 8805dfecf96Smrg /* Need to measure timings again to check if it is not better/faster 8815dfecf96Smrg * to just mark these fields as any other data, as the interface was 8825dfecf96Smrg * changed to properly handle circular lists in the function body itself. 8835dfecf96Smrg */ 8845dfecf96Smrg if (lisp__data.gc.immutablebits) { 8855dfecf96Smrg for (j = 0; j < objseg.nsegs; j++) { 8865dfecf96Smrg for (entry = objseg.objects[j], last = entry + segsize; 8875dfecf96Smrg entry < last; entry++) 8885dfecf96Smrg entry->prot = 0; 8895dfecf96Smrg } 8905dfecf96Smrg } 8915dfecf96Smrg 8925dfecf96Smrg /* Protect all packages */ 8935dfecf96Smrg for (entry = PACK; CONSP(entry); entry = CDR(entry)) { 8945dfecf96Smrg LispObj *package = CAR(entry); 8955dfecf96Smrg LispPackage *pack = package->data.package.package; 8965dfecf96Smrg 8975dfecf96Smrg /* Protect cons cell */ 8985dfecf96Smrg entry->mark = 1; 8995dfecf96Smrg 9005dfecf96Smrg /* Protect the package cell */ 9015dfecf96Smrg package->mark = 1; 9025dfecf96Smrg 9035dfecf96Smrg /* Protect package name */ 9045dfecf96Smrg package->data.package.name->mark = 1; 9055dfecf96Smrg 9065dfecf96Smrg /* Protect package nicknames */ 9075dfecf96Smrg LispMark(package->data.package.nicknames); 9085dfecf96Smrg 9095dfecf96Smrg /* Protect global symbols */ 9105dfecf96Smrg for (pentry = pack->glb.pairs, eentry = pentry + pack->glb.length; 9115dfecf96Smrg pentry < eentry; pentry++) 9125dfecf96Smrg LispMark((*pentry)->data.atom->property->value); 9135dfecf96Smrg 9145dfecf96Smrg /* Traverse atom list, protecting properties, and function/structure 9155dfecf96Smrg * definitions if lisp__data.gc.immutablebits set */ 916f14f4646Smrg for (atom = (LispAtom *)hash_iter_first(pack->atoms); 917f14f4646Smrg atom; 918f14f4646Smrg atom = (LispAtom *)hash_iter_next(pack->atoms)) { 919f14f4646Smrg if (atom->property != NOPROPERTY) { 920f14f4646Smrg if (atom->a_property) 921f14f4646Smrg LispMark(atom->property->properties); 922f14f4646Smrg if (lisp__data.gc.immutablebits) { 923f14f4646Smrg if (atom->a_function || atom->a_compiled) 924f14f4646Smrg LispProt(atom->property->fun.function); 925f14f4646Smrg if (atom->a_defsetf) 926f14f4646Smrg LispProt(atom->property->setf); 927f14f4646Smrg if (atom->a_defstruct) 928f14f4646Smrg LispProt(atom->property->structure.definition); 9295dfecf96Smrg } 9305dfecf96Smrg } 9315dfecf96Smrg } 9325dfecf96Smrg } 9335dfecf96Smrg 9345dfecf96Smrg /* protect environment */ 9355dfecf96Smrg for (pentry = lisp__data.env.values, 9365dfecf96Smrg eentry = pentry + lisp__data.env.length; 9375dfecf96Smrg pentry < eentry; pentry++) 9385dfecf96Smrg LispMark(*pentry); 9395dfecf96Smrg 9405dfecf96Smrg /* protect multiple return values */ 9415dfecf96Smrg for (pentry = lisp__data.returns.values, 9425dfecf96Smrg eentry = pentry + lisp__data.returns.count; 9435dfecf96Smrg pentry < eentry; pentry++) 9445dfecf96Smrg LispMark(*pentry); 9455dfecf96Smrg 9465dfecf96Smrg /* protect stack of arguments to builtin functions */ 9475dfecf96Smrg for (pentry = lisp__data.stack.values, 9485dfecf96Smrg eentry = pentry + lisp__data.stack.length; 9495dfecf96Smrg pentry < eentry; pentry++) 9505dfecf96Smrg LispMark(*pentry); 9515dfecf96Smrg 9525dfecf96Smrg /* protect temporary data used by builtin functions */ 9535dfecf96Smrg for (pentry = lisp__data.protect.objects, 9545dfecf96Smrg eentry = pentry + lisp__data.protect.length; 9555dfecf96Smrg pentry < eentry; pentry++) 9565dfecf96Smrg LispMark(*pentry); 9575dfecf96Smrg 9585dfecf96Smrg for (i = 0; i < sizeof(x_cons) / sizeof(x_cons[0]); i++) 9595dfecf96Smrg x_cons[i].mark = 0; 9605dfecf96Smrg 9615dfecf96Smrg LispMark(COD); 9625dfecf96Smrg#ifdef DEBUGGER 9635dfecf96Smrg LispMark(DBG); 9645dfecf96Smrg LispMark(BRK); 9655dfecf96Smrg#endif 9665dfecf96Smrg LispMark(PRO); 9675dfecf96Smrg LispMark(lisp__data.input_list); 9685dfecf96Smrg LispMark(lisp__data.output_list); 9695dfecf96Smrg LispMark(car); 9705dfecf96Smrg LispMark(cdr); 9715dfecf96Smrg 9725dfecf96Smrg for (j = 0; j < objseg.nsegs; j++) { 9735dfecf96Smrg for (entry = objseg.objects[j], last = entry + segsize; 9745dfecf96Smrg entry < last; entry++) { 9755dfecf96Smrg if (entry->prot) 9765dfecf96Smrg continue; 9775dfecf96Smrg else if (entry->mark) 9785dfecf96Smrg entry->mark = 0; 9795dfecf96Smrg else { 9805dfecf96Smrg switch (XOBJECT_TYPE(entry)) { 9815dfecf96Smrg case LispString_t: 9825dfecf96Smrg free(THESTR(entry)); 9835dfecf96Smrg entry->type = LispCons_t; 9845dfecf96Smrg break; 9855dfecf96Smrg case LispStream_t: 9865dfecf96Smrg switch (entry->data.stream.type) { 9875dfecf96Smrg case LispStreamString: 9885dfecf96Smrg free(SSTREAMP(entry)->string); 9895dfecf96Smrg free(SSTREAMP(entry)); 9905dfecf96Smrg break; 9915dfecf96Smrg case LispStreamFile: 9925dfecf96Smrg if (FSTREAMP(entry)) 9935dfecf96Smrg LispFclose(FSTREAMP(entry)); 9945dfecf96Smrg break; 9955dfecf96Smrg case LispStreamPipe: 9965dfecf96Smrg /* XXX may need special handling if child hangs */ 9975dfecf96Smrg if (PSTREAMP(entry)) { 9985dfecf96Smrg if (IPSTREAMP(entry)) 9995dfecf96Smrg LispFclose(IPSTREAMP(entry)); 10005dfecf96Smrg if (OPSTREAMP(entry)) 10015dfecf96Smrg LispFclose(OPSTREAMP(entry)); 10025dfecf96Smrg /* don't bother with error stream, will also 10035dfecf96Smrg * freed in this GC call, maybe just out 10045dfecf96Smrg * of order */ 10055dfecf96Smrg if (PIDPSTREAMP(entry) > 0) { 10065dfecf96Smrg kill(PIDPSTREAMP(entry), SIGTERM); 10075dfecf96Smrg waitpid(PIDPSTREAMP(entry), NULL, 0); 10085dfecf96Smrg } 10095dfecf96Smrg free(PSTREAMP(entry)); 10105dfecf96Smrg } 10115dfecf96Smrg break; 10125dfecf96Smrg default: 10135dfecf96Smrg break; 10145dfecf96Smrg } 10155dfecf96Smrg entry->type = LispCons_t; 10165dfecf96Smrg break; 10175dfecf96Smrg case LispBignum_t: 10185dfecf96Smrg mpi_clear(entry->data.mp.integer); 10195dfecf96Smrg free(entry->data.mp.integer); 10205dfecf96Smrg entry->type = LispCons_t; 10215dfecf96Smrg break; 10225dfecf96Smrg case LispBigratio_t: 10235dfecf96Smrg mpr_clear(entry->data.mp.ratio); 10245dfecf96Smrg free(entry->data.mp.ratio); 10255dfecf96Smrg entry->type = LispCons_t; 10265dfecf96Smrg break; 10275dfecf96Smrg case LispLambda_t: 10285dfecf96Smrg if (!SYMBOLP(entry->data.lambda.name)) 10295dfecf96Smrg LispFreeArgList((LispArgList*) 10305dfecf96Smrg entry->data.lambda.name->data.opaque.data); 10315dfecf96Smrg entry->type = LispCons_t; 10325dfecf96Smrg break; 10335dfecf96Smrg case LispRegex_t: 10345dfecf96Smrg refree(entry->data.regex.regex); 10355dfecf96Smrg free(entry->data.regex.regex); 10365dfecf96Smrg entry->type = LispCons_t; 10375dfecf96Smrg break; 10385dfecf96Smrg case LispBytecode_t: 10395dfecf96Smrg free(entry->data.bytecode.bytecode->code); 10405dfecf96Smrg free(entry->data.bytecode.bytecode); 10415dfecf96Smrg entry->type = LispCons_t; 10425dfecf96Smrg break; 10435dfecf96Smrg case LispHashTable_t: 10445dfecf96Smrg LispFreeHashTable(entry->data.hash.table); 10455dfecf96Smrg entry->type = LispCons_t; 10465dfecf96Smrg break; 10475dfecf96Smrg case LispCons_t: 10485dfecf96Smrg break; 10495dfecf96Smrg default: 10505dfecf96Smrg entry->type = LispCons_t; 10515dfecf96Smrg break; 10525dfecf96Smrg } 10535dfecf96Smrg CDR(entry) = freeobj; 10545dfecf96Smrg freeobj = entry; 10555dfecf96Smrg ++nfree; 10565dfecf96Smrg } 10575dfecf96Smrg } 10585dfecf96Smrg } 10595dfecf96Smrg 10605dfecf96Smrg objseg.nfree = nfree; 10615dfecf96Smrg objseg.freeobj = freeobj; 10625dfecf96Smrg 10635dfecf96Smrg lisp__data.gc.immutablebits = 0; 10645dfecf96Smrg 10655dfecf96Smrg#ifdef DEBUG 10665dfecf96Smrg gettimeofday(&end, NULL); 10675dfecf96Smrg sec = end.tv_sec - start.tv_sec; 10685dfecf96Smrg msec = end.tv_usec - start.tv_usec; 10695dfecf96Smrg if (msec < 0) { 10705dfecf96Smrg --sec; 10715dfecf96Smrg msec += 1000000; 10725dfecf96Smrg } 10735dfecf96Smrg LispMessage("gc: " 10745dfecf96Smrg "%ld sec, %ld msec, " 10755dfecf96Smrg "%d recovered, %d free, %d protected, %d total", 10765dfecf96Smrg sec, msec, 10775dfecf96Smrg objseg.nfree - count, objseg.nfree, 10785dfecf96Smrg objseg.nobjs - objseg.nfree, objseg.nobjs); 10795dfecf96Smrg#else 10805dfecf96Smrg if (lisp__data.gc.timebits) { 10815dfecf96Smrg gettimeofday(&end, NULL); 10825dfecf96Smrg if ((msec = end.tv_usec - start.tv_usec) < 0) 10835dfecf96Smrg msec += 1000000; 10845dfecf96Smrg lisp__data.gc.gctime += msec; 10855dfecf96Smrg } 10865dfecf96Smrg#endif 10875dfecf96Smrg 10885dfecf96Smrg ENABLE_INTERRUPTS(); 10895dfecf96Smrg} 10905dfecf96Smrg 10915dfecf96Smrgstatic INLINE void 10925dfecf96SmrgLispCheckMemLevel(void) 10935dfecf96Smrg{ 10945dfecf96Smrg int i; 10955dfecf96Smrg 10965dfecf96Smrg /* Check for a free slot before the end. */ 10975dfecf96Smrg for (i = lisp__data.mem.index; i < lisp__data.mem.level; i++) 10985dfecf96Smrg if (lisp__data.mem.mem[i] == NULL) { 10995dfecf96Smrg lisp__data.mem.index = i; 11005dfecf96Smrg return; 11015dfecf96Smrg } 11025dfecf96Smrg 11035dfecf96Smrg /* Check for a free slot in the beginning */ 11045dfecf96Smrg for (i = 0; i < lisp__data.mem.index; i++) 11055dfecf96Smrg if (lisp__data.mem.mem[i] == NULL) { 11065dfecf96Smrg lisp__data.mem.index = i; 11075dfecf96Smrg return; 11085dfecf96Smrg } 11095dfecf96Smrg 11105dfecf96Smrg lisp__data.mem.index = lisp__data.mem.level; 11115dfecf96Smrg ++lisp__data.mem.level; 11125dfecf96Smrg if (lisp__data.mem.index < lisp__data.mem.space) 11135dfecf96Smrg /* There is free space to store pointer. */ 11145dfecf96Smrg return; 11155dfecf96Smrg else { 11165dfecf96Smrg void **ptr = (void**)realloc(lisp__data.mem.mem, 11175dfecf96Smrg (lisp__data.mem.space + 16) * 11185dfecf96Smrg sizeof(void*)); 11195dfecf96Smrg 11205dfecf96Smrg if (ptr == NULL) 11215dfecf96Smrg LispDestroy("out of memory"); 11225dfecf96Smrg lisp__data.mem.mem = ptr; 11235dfecf96Smrg lisp__data.mem.space += 16; 11245dfecf96Smrg } 11255dfecf96Smrg} 11265dfecf96Smrg 11275dfecf96Smrgvoid 11285dfecf96SmrgLispMused(void *pointer) 11295dfecf96Smrg{ 11305dfecf96Smrg int i; 11315dfecf96Smrg 11325dfecf96Smrg DISABLE_INTERRUPTS(); 11335dfecf96Smrg for (i = lisp__data.mem.index; i >= 0; i--) 11345dfecf96Smrg if (lisp__data.mem.mem[i] == pointer) { 11355dfecf96Smrg lisp__data.mem.mem[i] = NULL; 11365dfecf96Smrg lisp__data.mem.index = i; 11375dfecf96Smrg goto mused_done; 11385dfecf96Smrg } 11395dfecf96Smrg 11405dfecf96Smrg for (i = lisp__data.mem.level - 1; i > lisp__data.mem.index; i--) 11415dfecf96Smrg if (lisp__data.mem.mem[i] == pointer) { 11425dfecf96Smrg lisp__data.mem.mem[i] = NULL; 11435dfecf96Smrg lisp__data.mem.index = i; 11445dfecf96Smrg break; 11455dfecf96Smrg } 11465dfecf96Smrg 11475dfecf96Smrgmused_done: 11485dfecf96Smrg ENABLE_INTERRUPTS(); 11495dfecf96Smrg} 11505dfecf96Smrg 11515dfecf96Smrgvoid * 11525dfecf96SmrgLispMalloc(size_t size) 11535dfecf96Smrg{ 11545dfecf96Smrg void *pointer; 11555dfecf96Smrg 11565dfecf96Smrg DISABLE_INTERRUPTS(); 11575dfecf96Smrg LispCheckMemLevel(); 11585dfecf96Smrg if ((pointer = malloc(size)) == NULL) 11595dfecf96Smrg LispDestroy("out of memory, couldn't allocate %lu bytes", 11605dfecf96Smrg (unsigned long)size); 11615dfecf96Smrg 11625dfecf96Smrg lisp__data.mem.mem[lisp__data.mem.index] = pointer; 11635dfecf96Smrg ENABLE_INTERRUPTS(); 11645dfecf96Smrg 11655dfecf96Smrg return (pointer); 11665dfecf96Smrg} 11675dfecf96Smrg 11685dfecf96Smrgvoid * 11695dfecf96SmrgLispCalloc(size_t nmemb, size_t size) 11705dfecf96Smrg{ 11715dfecf96Smrg void *pointer; 11725dfecf96Smrg 11735dfecf96Smrg DISABLE_INTERRUPTS(); 11745dfecf96Smrg LispCheckMemLevel(); 11755dfecf96Smrg if ((pointer = calloc(nmemb, size)) == NULL) 11765dfecf96Smrg LispDestroy("out of memory, couldn't allocate %lu bytes", 11775dfecf96Smrg (unsigned long)size); 11785dfecf96Smrg 11795dfecf96Smrg lisp__data.mem.mem[lisp__data.mem.index] = pointer; 11805dfecf96Smrg ENABLE_INTERRUPTS(); 11815dfecf96Smrg 11825dfecf96Smrg return (pointer); 11835dfecf96Smrg} 11845dfecf96Smrg 11855dfecf96Smrgvoid * 11865dfecf96SmrgLispRealloc(void *pointer, size_t size) 11875dfecf96Smrg{ 11885dfecf96Smrg void *ptr; 11895dfecf96Smrg int i; 11905dfecf96Smrg 11915dfecf96Smrg DISABLE_INTERRUPTS(); 11925dfecf96Smrg if (pointer != NULL) { 11935dfecf96Smrg for (i = lisp__data.mem.index; i >= 0; i--) 11945dfecf96Smrg if (lisp__data.mem.mem[i] == pointer) 11955dfecf96Smrg goto index_found; 11965dfecf96Smrg 11975dfecf96Smrg for (i = lisp__data.mem.index + 1; i < lisp__data.mem.level; i++) 11985dfecf96Smrg if (lisp__data.mem.mem[i] == pointer) 11995dfecf96Smrg goto index_found; 12005dfecf96Smrg 12015dfecf96Smrg } 12025dfecf96Smrg LispCheckMemLevel(); 12035dfecf96Smrg i = lisp__data.mem.index; 12045dfecf96Smrg 12055dfecf96Smrgindex_found: 12065dfecf96Smrg if ((ptr = realloc(pointer, size)) == NULL) 12075dfecf96Smrg LispDestroy("out of memory, couldn't realloc"); 12085dfecf96Smrg 12095dfecf96Smrg lisp__data.mem.mem[i] = ptr; 12105dfecf96Smrg ENABLE_INTERRUPTS(); 12115dfecf96Smrg 12125dfecf96Smrg return (ptr); 12135dfecf96Smrg} 12145dfecf96Smrg 12155dfecf96Smrgchar * 1216f765521fSmrgLispStrdup(const char *str) 12175dfecf96Smrg{ 12185dfecf96Smrg char *ptr = LispMalloc(strlen(str) + 1); 12195dfecf96Smrg 12205dfecf96Smrg strcpy(ptr, str); 12215dfecf96Smrg 12225dfecf96Smrg return (ptr); 12235dfecf96Smrg} 12245dfecf96Smrg 12255dfecf96Smrgvoid 12265dfecf96SmrgLispFree(void *pointer) 12275dfecf96Smrg{ 12285dfecf96Smrg int i; 12295dfecf96Smrg 12305dfecf96Smrg DISABLE_INTERRUPTS(); 12315dfecf96Smrg for (i = lisp__data.mem.index; i >= 0; i--) 12325dfecf96Smrg if (lisp__data.mem.mem[i] == pointer) { 12335dfecf96Smrg lisp__data.mem.mem[i] = NULL; 12345dfecf96Smrg lisp__data.mem.index = i; 12355dfecf96Smrg goto free_done; 12365dfecf96Smrg } 12375dfecf96Smrg 12385dfecf96Smrg for (i = lisp__data.mem.level - 1; i > lisp__data.mem.index; i--) 12395dfecf96Smrg if (lisp__data.mem.mem[i] == pointer) { 12405dfecf96Smrg lisp__data.mem.mem[i] = NULL; 12415dfecf96Smrg lisp__data.mem.index = i; 12425dfecf96Smrg break; 12435dfecf96Smrg } 12445dfecf96Smrg 12455dfecf96Smrgfree_done: 12465dfecf96Smrg free(pointer); 12475dfecf96Smrg ENABLE_INTERRUPTS(); 12485dfecf96Smrg} 12495dfecf96Smrg 12505dfecf96SmrgLispObj * 1251f765521fSmrgLispSetVariable(LispObj *var, LispObj *val, const char *fname, int eval) 12525dfecf96Smrg{ 12535dfecf96Smrg if (!SYMBOLP(var)) 12545dfecf96Smrg LispDestroy("%s: %s is not a symbol", fname, STROBJ(var)); 12555dfecf96Smrg if (eval) 12565dfecf96Smrg val = EVAL(val); 12575dfecf96Smrg 12585dfecf96Smrg return (LispSetVar(var, val)); 12595dfecf96Smrg} 12605dfecf96Smrg 12615dfecf96Smrgint 1262f765521fSmrgLispRegisterOpaqueType(const char *desc) 12635dfecf96Smrg{ 1264f14f4646Smrg int length; 12655dfecf96Smrg LispOpaque *opaque; 12665dfecf96Smrg 1267f14f4646Smrg length = strlen(desc); 1268f14f4646Smrg opaque = (LispOpaque *)hash_check(lisp__data.opqs, desc, length); 1269f14f4646Smrg 1270f14f4646Smrg if (opaque == NULL) { 1271f14f4646Smrg opaque = (LispOpaque*)LispMalloc(sizeof(LispOpaque)); 1272f14f4646Smrg opaque->desc = (hash_key*)LispCalloc(1, sizeof(hash_key)); 1273f14f4646Smrg opaque->desc->value = LispStrdup(desc); 1274f14f4646Smrg opaque->desc->length = length; 1275f14f4646Smrg hash_put(lisp__data.opqs, (hash_entry *)opaque); 1276f14f4646Smrg LispMused(opaque->desc->value); 1277f14f4646Smrg LispMused(opaque->desc); 1278f14f4646Smrg LispMused(opaque); 1279f14f4646Smrg opaque->type = ++lisp__data.opaque; 1280f14f4646Smrg } 12815dfecf96Smrg 1282f14f4646Smrg return (opaque->type); 12835dfecf96Smrg} 12845dfecf96Smrg 12855dfecf96Smrgchar * 12865dfecf96SmrgLispIntToOpaqueType(int type) 12875dfecf96Smrg{ 12885dfecf96Smrg LispOpaque *opaque; 12895dfecf96Smrg 12905dfecf96Smrg if (type) { 1291f14f4646Smrg for (opaque = (LispOpaque *)hash_iter_first(lisp__data.opqs); 1292f14f4646Smrg opaque; 1293f14f4646Smrg opaque = (LispOpaque *)hash_iter_next(lisp__data.opqs)) { 1294f14f4646Smrg if (opaque->type == type) 1295f14f4646Smrg return (opaque->desc->value); 12965dfecf96Smrg } 12975dfecf96Smrg LispDestroy("Opaque type %d not registered", type); 12985dfecf96Smrg } 12995dfecf96Smrg 1300f14f4646Smrg return (Snil->value); 13015dfecf96Smrg} 13025dfecf96Smrg 1303f14f4646Smrghash_key * 1304f765521fSmrgLispGetAtomKey(const char *string, int perm) 13055dfecf96Smrg{ 1306f14f4646Smrg int length; 1307f14f4646Smrg hash_entry *entry; 1308f14f4646Smrg 1309f14f4646Smrg length = strlen(string); 1310f14f4646Smrg entry = hash_check(lisp__data.strings, string, length); 1311f14f4646Smrg if (entry == NULL) { 1312f14f4646Smrg entry = LispCalloc(1, sizeof(hash_entry)); 1313f14f4646Smrg entry->key = LispCalloc(1, sizeof(hash_key)); 1314f14f4646Smrg if (perm) 1315f765521fSmrg entry->key->value = (char *) string; 1316f14f4646Smrg else 1317f14f4646Smrg entry->key->value = LispStrdup(string); 1318f14f4646Smrg entry->key->length = length; 1319f14f4646Smrg 1320f14f4646Smrg hash_put(lisp__data.strings, entry); 1321f14f4646Smrg if (!perm) 1322f14f4646Smrg LispMused(entry->key->value); 1323f14f4646Smrg LispMused(entry->key); 1324f14f4646Smrg LispMused(entry); 1325f14f4646Smrg } 13265dfecf96Smrg 1327f14f4646Smrg return (entry->key); 13285dfecf96Smrg} 13295dfecf96Smrg 13305dfecf96SmrgLispAtom * 1331f765521fSmrgLispDoGetAtom(const char *str, int perm) 13325dfecf96Smrg{ 1333f14f4646Smrg int length; 13345dfecf96Smrg LispAtom *atom; 13355dfecf96Smrg 1336f14f4646Smrg length = strlen(str); 1337f14f4646Smrg atom = (LispAtom *)hash_check(lisp__data.pack->atoms, str, length); 13385dfecf96Smrg 1339f14f4646Smrg if (atom == NULL) { 1340f14f4646Smrg atom = (LispAtom*)LispCalloc(1, sizeof(LispAtom)); 1341f14f4646Smrg atom->key = LispGetAtomKey(str, perm); 1342f14f4646Smrg hash_put(lisp__data.pack->atoms, (hash_entry *)atom); 1343f14f4646Smrg atom->property = NOPROPERTY; 1344f14f4646Smrg LispMused(atom); 1345f14f4646Smrg } 13465dfecf96Smrg 13475dfecf96Smrg return (atom); 13485dfecf96Smrg} 13495dfecf96Smrg 13505dfecf96Smrgstatic void 13515dfecf96SmrgLispAllocAtomProperty(LispAtom *atom) 13525dfecf96Smrg{ 13535dfecf96Smrg LispProperty *property; 13545dfecf96Smrg 13555dfecf96Smrg if (atom->property != NOPROPERTY) 13565dfecf96Smrg LispDestroy("internal error at ALLOC-ATOM-PROPERTY"); 13575dfecf96Smrg 13585dfecf96Smrg property = LispCalloc(1, sizeof(LispProperty)); 13595dfecf96Smrg LispMused(property); 13605dfecf96Smrg atom->property = property; 13615dfecf96Smrg property->package = lisp__data.pack; 13625dfecf96Smrg if (atom->package == NULL) 13635dfecf96Smrg atom->package = PACKAGE; 13645dfecf96Smrg 13655dfecf96Smrg LispIncrementAtomReference(atom); 13665dfecf96Smrg} 13675dfecf96Smrg 13685dfecf96Smrgstatic void 13695dfecf96SmrgLispIncrementAtomReference(LispAtom *atom) 13705dfecf96Smrg{ 13715dfecf96Smrg if (atom->property != NOPROPERTY) 13725dfecf96Smrg /* if atom->property is NOPROPERTY, this is an unbound symbol */ 13735dfecf96Smrg ++atom->property->refcount; 13745dfecf96Smrg} 13755dfecf96Smrg 13765dfecf96Smrg/* Assumes atom property is not NOPROPERTY */ 13775dfecf96Smrgstatic void 13785dfecf96SmrgLispDecrementAtomReference(LispAtom *atom) 13795dfecf96Smrg{ 13805dfecf96Smrg if (atom->property == NOPROPERTY) 13815dfecf96Smrg /* if atom->property is NOPROPERTY, this is an unbound symbol */ 13825dfecf96Smrg return; 13835dfecf96Smrg 13845dfecf96Smrg if (atom->property->refcount <= 0) 13855dfecf96Smrg LispDestroy("internal error at DECREMENT-ATOM-REFERENCE"); 13865dfecf96Smrg 13875dfecf96Smrg --atom->property->refcount; 13885dfecf96Smrg 13895dfecf96Smrg if (atom->property->refcount == 0) { 13905dfecf96Smrg LispRemAtomAllProperties(atom); 13915dfecf96Smrg free(atom->property); 13925dfecf96Smrg atom->property = NOPROPERTY; 13935dfecf96Smrg } 13945dfecf96Smrg} 13955dfecf96Smrg 13965dfecf96Smrgstatic void 13975dfecf96SmrgLispRemAtomAllProperties(LispAtom *atom) 13985dfecf96Smrg{ 13995dfecf96Smrg if (atom->property != NOPROPERTY) { 14005dfecf96Smrg if (atom->a_object) 14015dfecf96Smrg LispRemAtomObjectProperty(atom); 14025dfecf96Smrg if (atom->a_function) { 14035dfecf96Smrg lisp__data.gc.immutablebits = 1; 14045dfecf96Smrg LispRemAtomFunctionProperty(atom); 14055dfecf96Smrg } 14065dfecf96Smrg else if (atom->a_compiled) { 14075dfecf96Smrg lisp__data.gc.immutablebits = 1; 14085dfecf96Smrg LispRemAtomCompiledProperty(atom); 14095dfecf96Smrg } 14105dfecf96Smrg else if (atom->a_builtin) { 14115dfecf96Smrg lisp__data.gc.immutablebits = 1; 14125dfecf96Smrg LispRemAtomBuiltinProperty(atom); 14135dfecf96Smrg } 14145dfecf96Smrg if (atom->a_defsetf) { 14155dfecf96Smrg lisp__data.gc.immutablebits = 1; 14165dfecf96Smrg LispRemAtomSetfProperty(atom); 14175dfecf96Smrg } 14185dfecf96Smrg if (atom->a_defstruct) { 14195dfecf96Smrg lisp__data.gc.immutablebits = 1; 14205dfecf96Smrg LispRemAtomStructProperty(atom); 14215dfecf96Smrg } 14225dfecf96Smrg } 14235dfecf96Smrg} 14245dfecf96Smrg 14255dfecf96Smrgvoid 14265dfecf96SmrgLispSetAtomObjectProperty(LispAtom *atom, LispObj *object) 14275dfecf96Smrg{ 14285dfecf96Smrg if (atom->property == NOPROPERTY) 14295dfecf96Smrg LispAllocAtomProperty(atom); 14305dfecf96Smrg else if (atom->watch) { 14315dfecf96Smrg if (atom->object == lisp__data.package) { 14325dfecf96Smrg if (!PACKAGEP(object)) 14335dfecf96Smrg LispDestroy("Symbol %s must be a package, not %s", 1434f14f4646Smrg ATOMID(lisp__data.package)->value, STROBJ(object)); 14355dfecf96Smrg lisp__data.pack = object->data.package.package; 14365dfecf96Smrg } 14375dfecf96Smrg } 14385dfecf96Smrg 14395dfecf96Smrg atom->a_object = 1; 14405dfecf96Smrg SETVALUE(atom, object); 14415dfecf96Smrg} 14425dfecf96Smrg 14435dfecf96Smrgstatic void 14445dfecf96SmrgLispRemAtomObjectProperty(LispAtom *atom) 14455dfecf96Smrg{ 14465dfecf96Smrg if (atom->a_object) { 14475dfecf96Smrg atom->a_object = 0; 14485dfecf96Smrg atom->property->value = NULL; 14495dfecf96Smrg } 14505dfecf96Smrg} 14515dfecf96Smrg 14525dfecf96Smrgvoid 14535dfecf96SmrgLispSetAtomCompiledProperty(LispAtom *atom, LispObj *bytecode) 14545dfecf96Smrg{ 14555dfecf96Smrg if (atom->property == NOPROPERTY) 14565dfecf96Smrg LispAllocAtomProperty(atom); 14575dfecf96Smrg 14585dfecf96Smrg lisp__data.gc.immutablebits = 1; 14595dfecf96Smrg if (atom->a_builtin) { 14605dfecf96Smrg atom->a_builtin = 0; 14615dfecf96Smrg LispFreeArgList(atom->property->alist); 14625dfecf96Smrg } 14635dfecf96Smrg else 14645dfecf96Smrg atom->a_function = 0; 14655dfecf96Smrg atom->a_compiled = 1; 14665dfecf96Smrg atom->property->fun.function = bytecode; 14675dfecf96Smrg} 14685dfecf96Smrg 14695dfecf96Smrgvoid 14705dfecf96SmrgLispRemAtomCompiledProperty(LispAtom *atom) 14715dfecf96Smrg{ 14725dfecf96Smrg if (atom->a_compiled) { 14735dfecf96Smrg lisp__data.gc.immutablebits = 1; 14745dfecf96Smrg atom->property->fun.function = NULL; 14755dfecf96Smrg atom->a_compiled = 0; 14765dfecf96Smrg LispFreeArgList(atom->property->alist); 14775dfecf96Smrg atom->property->alist = NULL; 14785dfecf96Smrg } 14795dfecf96Smrg} 14805dfecf96Smrg 14815dfecf96Smrgvoid 14825dfecf96SmrgLispSetAtomFunctionProperty(LispAtom *atom, LispObj *function, 14835dfecf96Smrg LispArgList *alist) 14845dfecf96Smrg{ 14855dfecf96Smrg if (atom->property == NOPROPERTY) 14865dfecf96Smrg LispAllocAtomProperty(atom); 14875dfecf96Smrg 14885dfecf96Smrg lisp__data.gc.immutablebits = 1; 14895dfecf96Smrg if (atom->a_function == 0 && atom->a_builtin == 0 && atom->a_compiled == 0) 14905dfecf96Smrg atom->a_function = 1; 14915dfecf96Smrg else { 14925dfecf96Smrg if (atom->a_builtin) { 14935dfecf96Smrg atom->a_builtin = 0; 14945dfecf96Smrg LispFreeArgList(atom->property->alist); 14955dfecf96Smrg } 14965dfecf96Smrg else 14975dfecf96Smrg atom->a_compiled = 0; 14985dfecf96Smrg atom->a_function = 1; 14995dfecf96Smrg } 15005dfecf96Smrg 15015dfecf96Smrg atom->property->fun.function = function; 15025dfecf96Smrg atom->property->alist = alist; 15035dfecf96Smrg} 15045dfecf96Smrg 15055dfecf96Smrgvoid 15065dfecf96SmrgLispRemAtomFunctionProperty(LispAtom *atom) 15075dfecf96Smrg{ 15085dfecf96Smrg if (atom->a_function) { 15095dfecf96Smrg lisp__data.gc.immutablebits = 1; 15105dfecf96Smrg atom->property->fun.function = NULL; 15115dfecf96Smrg atom->a_function = 0; 15125dfecf96Smrg LispFreeArgList(atom->property->alist); 15135dfecf96Smrg atom->property->alist = NULL; 15145dfecf96Smrg } 15155dfecf96Smrg} 15165dfecf96Smrg 15175dfecf96Smrgvoid 15185dfecf96SmrgLispSetAtomBuiltinProperty(LispAtom *atom, LispBuiltin *builtin, 15195dfecf96Smrg LispArgList *alist) 15205dfecf96Smrg{ 15215dfecf96Smrg if (atom->property == NOPROPERTY) 15225dfecf96Smrg LispAllocAtomProperty(atom); 15235dfecf96Smrg 15245dfecf96Smrg lisp__data.gc.immutablebits = 1; 15255dfecf96Smrg if (atom->a_builtin == 0 && atom->a_function == 0) 15265dfecf96Smrg atom->a_builtin = 1; 15275dfecf96Smrg else { 15285dfecf96Smrg if (atom->a_function) { 15295dfecf96Smrg atom->a_function = 0; 15305dfecf96Smrg LispFreeArgList(atom->property->alist); 15315dfecf96Smrg } 15325dfecf96Smrg } 15335dfecf96Smrg 15345dfecf96Smrg atom->property->fun.builtin = builtin; 15355dfecf96Smrg atom->property->alist = alist; 15365dfecf96Smrg} 15375dfecf96Smrg 15385dfecf96Smrgvoid 15395dfecf96SmrgLispRemAtomBuiltinProperty(LispAtom *atom) 15405dfecf96Smrg{ 15415dfecf96Smrg if (atom->a_builtin) { 15425dfecf96Smrg lisp__data.gc.immutablebits = 1; 15435dfecf96Smrg atom->property->fun.function = NULL; 15445dfecf96Smrg atom->a_builtin = 0; 15455dfecf96Smrg LispFreeArgList(atom->property->alist); 15465dfecf96Smrg atom->property->alist = NULL; 15475dfecf96Smrg } 15485dfecf96Smrg} 15495dfecf96Smrg 15505dfecf96Smrgvoid 15515dfecf96SmrgLispSetAtomSetfProperty(LispAtom *atom, LispObj *setf, LispArgList *alist) 15525dfecf96Smrg{ 15535dfecf96Smrg if (atom->property == NOPROPERTY) 15545dfecf96Smrg LispAllocAtomProperty(atom); 15555dfecf96Smrg 15565dfecf96Smrg lisp__data.gc.immutablebits = 1; 15575dfecf96Smrg if (atom->a_defsetf) 15585dfecf96Smrg LispFreeArgList(atom->property->salist); 15595dfecf96Smrg 15605dfecf96Smrg atom->a_defsetf = 1; 15615dfecf96Smrg atom->property->setf = setf; 15625dfecf96Smrg atom->property->salist = alist; 15635dfecf96Smrg} 15645dfecf96Smrg 15655dfecf96Smrgvoid 15665dfecf96SmrgLispRemAtomSetfProperty(LispAtom *atom) 15675dfecf96Smrg{ 15685dfecf96Smrg if (atom->a_defsetf) { 15695dfecf96Smrg lisp__data.gc.immutablebits = 1; 15705dfecf96Smrg atom->property->setf = NULL; 15715dfecf96Smrg atom->a_defsetf = 0; 15725dfecf96Smrg LispFreeArgList(atom->property->salist); 15735dfecf96Smrg atom->property->salist = NULL; 15745dfecf96Smrg } 15755dfecf96Smrg} 15765dfecf96Smrg 15775dfecf96Smrgvoid 15785dfecf96SmrgLispSetAtomStructProperty(LispAtom *atom, LispObj *def, int fun) 15795dfecf96Smrg{ 15805dfecf96Smrg if (fun > 0xff) 15815dfecf96Smrg /* Not suported by the bytecode compiler... */ 15825dfecf96Smrg LispDestroy("SET-ATOM-STRUCT-PROPERTY: " 15835dfecf96Smrg "more than 256 fields not supported"); 15845dfecf96Smrg 15855dfecf96Smrg if (atom->property == NOPROPERTY) 15865dfecf96Smrg LispAllocAtomProperty(atom); 15875dfecf96Smrg 15885dfecf96Smrg lisp__data.gc.immutablebits = 1; 15895dfecf96Smrg atom->a_defstruct = 1; 15905dfecf96Smrg atom->property->structure.definition = def; 15915dfecf96Smrg atom->property->structure.function = fun; 15925dfecf96Smrg} 15935dfecf96Smrg 15945dfecf96Smrgvoid 15955dfecf96SmrgLispRemAtomStructProperty(LispAtom *atom) 15965dfecf96Smrg{ 15975dfecf96Smrg if (atom->a_defstruct) { 15985dfecf96Smrg lisp__data.gc.immutablebits = 1; 15995dfecf96Smrg atom->property->structure.definition = NULL; 16005dfecf96Smrg atom->a_defstruct = 0; 16015dfecf96Smrg } 16025dfecf96Smrg} 16035dfecf96Smrg 16045dfecf96SmrgLispAtom * 1605f765521fSmrgLispGetAtom(const char *str) 16065dfecf96Smrg{ 16075dfecf96Smrg return (LispDoGetAtom(str, 0)); 16085dfecf96Smrg} 16095dfecf96Smrg 16105dfecf96SmrgLispAtom * 1611f765521fSmrgLispGetPermAtom(const char *str) 16125dfecf96Smrg{ 16135dfecf96Smrg return (LispDoGetAtom(str, 1)); 16145dfecf96Smrg} 16155dfecf96Smrg 16165dfecf96Smrg#define GET_PROPERTY 0 16175dfecf96Smrg#define ADD_PROPERTY 1 16185dfecf96Smrg#define REM_PROPERTY 2 16195dfecf96Smrgstatic LispObj * 16205dfecf96SmrgLispAtomPropertyFunction(LispAtom *atom, LispObj *key, int function) 16215dfecf96Smrg{ 16225dfecf96Smrg LispObj *list = NIL, *result = NIL; 16235dfecf96Smrg 16245dfecf96Smrg if (function == ADD_PROPERTY) { 16255dfecf96Smrg if (atom->property == NOPROPERTY) 16265dfecf96Smrg LispAllocAtomProperty(atom); 16275dfecf96Smrg if (atom->property->properties == NULL) { 16285dfecf96Smrg atom->a_property = 1; 16295dfecf96Smrg atom->property->properties = NIL; 16305dfecf96Smrg } 16315dfecf96Smrg } 16325dfecf96Smrg 16335dfecf96Smrg if (atom->a_property) { 16345dfecf96Smrg LispObj *base; 16355dfecf96Smrg 16365dfecf96Smrg for (base = list = atom->property->properties; 16375dfecf96Smrg CONSP(list); 16385dfecf96Smrg list = CDR(list)) { 16395dfecf96Smrg if (key == CAR(list)) { 16405dfecf96Smrg result = CDR(list); 16415dfecf96Smrg break; 16425dfecf96Smrg } 16435dfecf96Smrg base = list; 16445dfecf96Smrg list = CDR(list); 16455dfecf96Smrg if (!CONSP(list)) 16465dfecf96Smrg LispDestroy("%s: %s has an odd property list length", 16475dfecf96Smrg STROBJ(atom->object), 16485dfecf96Smrg function == REM_PROPERTY ? "REMPROP" : "GET"); 16495dfecf96Smrg } 16505dfecf96Smrg if (CONSP(list) && function == REM_PROPERTY) { 16515dfecf96Smrg if (!CONSP(CDR(list))) 16525dfecf96Smrg LispDestroy("REMPROP: %s has an odd property list length", 16535dfecf96Smrg STROBJ(atom->object)); 16545dfecf96Smrg if (base == list) 16555dfecf96Smrg atom->property->properties = CDDR(list); 16565dfecf96Smrg else 16575dfecf96Smrg RPLACD(CDR(base), CDDR(list)); 16585dfecf96Smrg } 16595dfecf96Smrg } 16605dfecf96Smrg 16615dfecf96Smrg if (!CONSP(list)) { 16625dfecf96Smrg if (function == ADD_PROPERTY) { 16635dfecf96Smrg atom->property->properties = 16645dfecf96Smrg CONS(key, CONS(NIL, atom->property->properties)); 16655dfecf96Smrg result = CDR(atom->property->properties); 16665dfecf96Smrg } 16675dfecf96Smrg } 16685dfecf96Smrg else if (function == REM_PROPERTY) 16695dfecf96Smrg result = T; 16705dfecf96Smrg 16715dfecf96Smrg return (result); 16725dfecf96Smrg} 16735dfecf96Smrg 16745dfecf96SmrgLispObj * 16755dfecf96SmrgLispGetAtomProperty(LispAtom *atom, LispObj *key) 16765dfecf96Smrg{ 16775dfecf96Smrg return (LispAtomPropertyFunction(atom, key, GET_PROPERTY)); 16785dfecf96Smrg} 16795dfecf96Smrg 16805dfecf96SmrgLispObj * 16815dfecf96SmrgLispPutAtomProperty(LispAtom *atom, LispObj *key, LispObj *value) 16825dfecf96Smrg{ 16835dfecf96Smrg LispObj *result = LispAtomPropertyFunction(atom, key, ADD_PROPERTY); 16845dfecf96Smrg 16855dfecf96Smrg RPLACA(result, value); 16865dfecf96Smrg 16875dfecf96Smrg return (result); 16885dfecf96Smrg} 16895dfecf96Smrg 16905dfecf96SmrgLispObj * 16915dfecf96SmrgLispRemAtomProperty(LispAtom *atom, LispObj *key) 16925dfecf96Smrg{ 16935dfecf96Smrg return (LispAtomPropertyFunction(atom, key, REM_PROPERTY)); 16945dfecf96Smrg} 16955dfecf96Smrg 16965dfecf96SmrgLispObj * 16975dfecf96SmrgLispReplaceAtomPropertyList(LispAtom *atom, LispObj *list) 16985dfecf96Smrg{ 16995dfecf96Smrg if (atom->property == NOPROPERTY) 17005dfecf96Smrg LispAllocAtomProperty(atom); 17015dfecf96Smrg if (atom->property->properties == NULL) 17025dfecf96Smrg atom->a_property = 1; 17035dfecf96Smrg atom->property->properties = list; 17045dfecf96Smrg 17055dfecf96Smrg return (list); 17065dfecf96Smrg} 17075dfecf96Smrg#undef GET_PROPERTY 17085dfecf96Smrg#undef ADD_PROPERTY 17095dfecf96Smrg#undef REM_PROPERTY 17105dfecf96Smrg 17115dfecf96Smrg 17125dfecf96Smrg/* Used to make sure that when defining a function like: 17135dfecf96Smrg * (defun my-function (... &key key1 key2 key3 ...) 17145dfecf96Smrg * key1, key2, and key3 will be in the keyword package 17155dfecf96Smrg */ 17165dfecf96Smrgstatic LispObj * 17175dfecf96SmrgLispCheckKeyword(LispObj *keyword) 17185dfecf96Smrg{ 17195dfecf96Smrg if (KEYWORDP(keyword)) 17205dfecf96Smrg return (keyword); 17215dfecf96Smrg 1722f14f4646Smrg return (KEYWORD(ATOMID(keyword)->value)); 17235dfecf96Smrg} 17245dfecf96Smrg 17255dfecf96Smrgvoid 17265dfecf96SmrgLispUseArgList(LispArgList *alist) 17275dfecf96Smrg{ 17285dfecf96Smrg if (alist->normals.num_symbols) 17295dfecf96Smrg LispMused(alist->normals.symbols); 17305dfecf96Smrg if (alist->optionals.num_symbols) { 17315dfecf96Smrg LispMused(alist->optionals.symbols); 17325dfecf96Smrg LispMused(alist->optionals.defaults); 17335dfecf96Smrg LispMused(alist->optionals.sforms); 17345dfecf96Smrg } 17355dfecf96Smrg if (alist->keys.num_symbols) { 17365dfecf96Smrg LispMused(alist->keys.symbols); 17375dfecf96Smrg LispMused(alist->keys.defaults); 17385dfecf96Smrg LispMused(alist->keys.sforms); 17395dfecf96Smrg LispMused(alist->keys.keys); 17405dfecf96Smrg } 17415dfecf96Smrg if (alist->auxs.num_symbols) { 17425dfecf96Smrg LispMused(alist->auxs.symbols); 17435dfecf96Smrg LispMused(alist->auxs.initials); 17445dfecf96Smrg } 17455dfecf96Smrg LispMused(alist); 17465dfecf96Smrg} 17475dfecf96Smrg 17485dfecf96Smrgvoid 17495dfecf96SmrgLispFreeArgList(LispArgList *alist) 17505dfecf96Smrg{ 17515dfecf96Smrg if (alist->normals.num_symbols) 17525dfecf96Smrg LispFree(alist->normals.symbols); 17535dfecf96Smrg if (alist->optionals.num_symbols) { 17545dfecf96Smrg LispFree(alist->optionals.symbols); 17555dfecf96Smrg LispFree(alist->optionals.defaults); 17565dfecf96Smrg LispFree(alist->optionals.sforms); 17575dfecf96Smrg } 17585dfecf96Smrg if (alist->keys.num_symbols) { 17595dfecf96Smrg LispFree(alist->keys.symbols); 17605dfecf96Smrg LispFree(alist->keys.defaults); 17615dfecf96Smrg LispFree(alist->keys.sforms); 17625dfecf96Smrg LispFree(alist->keys.keys); 17635dfecf96Smrg } 17645dfecf96Smrg if (alist->auxs.num_symbols) { 17655dfecf96Smrg LispFree(alist->auxs.symbols); 17665dfecf96Smrg LispFree(alist->auxs.initials); 17675dfecf96Smrg } 17685dfecf96Smrg LispFree(alist); 17695dfecf96Smrg} 17705dfecf96Smrg 17715dfecf96Smrgstatic LispObj * 17725dfecf96SmrgLispCheckNeedProtect(LispObj *object) 17735dfecf96Smrg{ 17745dfecf96Smrg if (object) { 17755dfecf96Smrg switch (OBJECT_TYPE(object)) { 17765dfecf96Smrg case LispNil_t: 17775dfecf96Smrg case LispAtom_t: 17785dfecf96Smrg case LispFunction_t: 17795dfecf96Smrg case LispFixnum_t: 17805dfecf96Smrg case LispSChar_t: 17815dfecf96Smrg return (NULL); 17825dfecf96Smrg default: 17835dfecf96Smrg return (object); 17845dfecf96Smrg } 17855dfecf96Smrg } 17865dfecf96Smrg return (NULL); 17875dfecf96Smrg} 17885dfecf96Smrg 17895dfecf96SmrgLispObj * 17905dfecf96SmrgLispListProtectedArguments(LispArgList *alist) 17915dfecf96Smrg{ 17925dfecf96Smrg int i; 17935dfecf96Smrg GC_ENTER(); 17945dfecf96Smrg LispObj *arguments, *cons, *obj, *prev; 17955dfecf96Smrg 17965dfecf96Smrg arguments = cons = prev = NIL; 17975dfecf96Smrg for (i = 0; i < alist->optionals.num_symbols; i++) { 17985dfecf96Smrg if ((obj = LispCheckNeedProtect(alist->optionals.defaults[i])) != NULL) { 17995dfecf96Smrg if (arguments == NIL) { 18005dfecf96Smrg arguments = cons = prev = CONS(obj, NIL); 18015dfecf96Smrg GC_PROTECT(arguments); 18025dfecf96Smrg } 18035dfecf96Smrg else { 18045dfecf96Smrg RPLACD(cons, CONS(obj, NIL)); 18055dfecf96Smrg prev = cons; 18065dfecf96Smrg cons = CDR(cons); 18075dfecf96Smrg } 18085dfecf96Smrg } 18095dfecf96Smrg } 18105dfecf96Smrg for (i = 0; i < alist->keys.num_symbols; i++) { 18115dfecf96Smrg if ((obj = LispCheckNeedProtect(alist->keys.defaults[i])) != NULL) { 18125dfecf96Smrg if (arguments == NIL) { 18135dfecf96Smrg arguments = cons = prev = CONS(obj, NIL); 18145dfecf96Smrg GC_PROTECT(arguments); 18155dfecf96Smrg } 18165dfecf96Smrg else { 18175dfecf96Smrg RPLACD(cons, CONS(obj, NIL)); 18185dfecf96Smrg prev = cons; 18195dfecf96Smrg cons = CDR(cons); 18205dfecf96Smrg } 18215dfecf96Smrg } 18225dfecf96Smrg } 18235dfecf96Smrg for (i = 0; i < alist->auxs.num_symbols; i++) { 18245dfecf96Smrg if ((obj = LispCheckNeedProtect(alist->auxs.initials[i])) != NULL) { 18255dfecf96Smrg if (arguments == NIL) { 18265dfecf96Smrg arguments = cons = prev = CONS(obj, NIL); 18275dfecf96Smrg GC_PROTECT(arguments); 18285dfecf96Smrg } 18295dfecf96Smrg else { 18305dfecf96Smrg RPLACD(cons, CONS(obj, NIL)); 18315dfecf96Smrg prev = cons; 18325dfecf96Smrg cons = CDR(cons); 18335dfecf96Smrg } 18345dfecf96Smrg } 18355dfecf96Smrg } 18365dfecf96Smrg GC_LEAVE(); 18375dfecf96Smrg 18385dfecf96Smrg /* Don't add a NIL cell at the end, to save some space */ 18395dfecf96Smrg if (arguments != NIL) { 18405dfecf96Smrg if (arguments == cons) 18415dfecf96Smrg arguments = CAR(cons); 18425dfecf96Smrg else 18435dfecf96Smrg CDR(prev) = CAR(cons); 18445dfecf96Smrg } 18455dfecf96Smrg 18465dfecf96Smrg return (arguments); 18475dfecf96Smrg} 18485dfecf96Smrg 18495dfecf96SmrgLispArgList * 1850f765521fSmrgLispCheckArguments(LispFunType type, LispObj *list, const char *name, int builtin) 18515dfecf96Smrg{ 1852f765521fSmrg static const char *types[4] = {"LAMBDA-LIST", "FUNCTION", "MACRO", "SETF-METHOD"}; 1853f765521fSmrg static const char *fnames[4] = {"LAMBDA", "DEFUN", "DEFMACRO", "DEFSETF"}; 18545dfecf96Smrg#define IKEY 0 18555dfecf96Smrg#define IOPTIONAL 1 18565dfecf96Smrg#define IREST 2 18575dfecf96Smrg#define IAUX 3 1858f765521fSmrg static const char *keys[4] = {"&KEY", "&OPTIONAL", "&REST", "&AUX"}; 18595dfecf96Smrg int rest, optional, key, aux, count; 18605dfecf96Smrg LispArgList *alist; 18615dfecf96Smrg LispObj *spec, *sform, *defval, *default_value; 18625dfecf96Smrg char description[8], *desc; 18635dfecf96Smrg 18645dfecf96Smrg/* If LispRealloc fails, the previous memory will be released 18655dfecf96Smrg * in LispTopLevel, unless LispMused was called on the pointer */ 18665dfecf96Smrg#define REALLOC_OBJECTS(pointer, count) \ 18675dfecf96Smrg pointer = LispRealloc(pointer, (count) * sizeof(LispObj*)) 18685dfecf96Smrg 18695dfecf96Smrg alist = LispCalloc(1, sizeof(LispArgList)); 18705dfecf96Smrg if (!CONSP(list)) { 18715dfecf96Smrg if (list != NIL) 18725dfecf96Smrg LispDestroy("%s %s: %s cannot be a %s argument list", 18735dfecf96Smrg fnames[type], name, STROBJ(list), types[type]); 1874f14f4646Smrg alist->description = GETATOMID("")->value; 18755dfecf96Smrg 18765dfecf96Smrg return (alist); 18775dfecf96Smrg } 18785dfecf96Smrg 18795dfecf96Smrg default_value = builtin ? UNSPEC : NIL; 18805dfecf96Smrg 18815dfecf96Smrg description[0] = '\0'; 18825dfecf96Smrg desc = description; 18835dfecf96Smrg rest = optional = key = aux = 0; 18845dfecf96Smrg for (; CONSP(list); list = CDR(list)) { 18855dfecf96Smrg spec = CAR(list); 18865dfecf96Smrg 18875dfecf96Smrg if (CONSP(spec)) { 18885dfecf96Smrg if (builtin) 18895dfecf96Smrg LispDestroy("builtin function argument cannot have default value"); 18905dfecf96Smrg if (aux) { 18915dfecf96Smrg if (!SYMBOLP(CAR(spec)) || 18925dfecf96Smrg (CDR(spec) != NIL && CDDR(spec) != NIL)) 18935dfecf96Smrg LispDestroy("%s %s: bad &AUX argument %s", 18945dfecf96Smrg fnames[type], name, STROBJ(spec)); 18955dfecf96Smrg defval = CDR(spec) != NIL ? CADR(spec) : NIL; 18965dfecf96Smrg count = alist->auxs.num_symbols; 18975dfecf96Smrg REALLOC_OBJECTS(alist->auxs.symbols, count + 1); 18985dfecf96Smrg REALLOC_OBJECTS(alist->auxs.initials, count + 1); 18995dfecf96Smrg alist->auxs.symbols[count] = CAR(spec); 19005dfecf96Smrg alist->auxs.initials[count] = defval; 19015dfecf96Smrg ++alist->auxs.num_symbols; 19025dfecf96Smrg if (count == 0) 19035dfecf96Smrg *desc++ = 'a'; 19045dfecf96Smrg ++alist->num_arguments; 19055dfecf96Smrg } 19065dfecf96Smrg else if (rest) 19075dfecf96Smrg LispDestroy("%s %s: syntax error parsing %s", 19085dfecf96Smrg fnames[type], name, keys[IREST]); 19095dfecf96Smrg else if (key) { 19105dfecf96Smrg LispObj *akey = CAR(spec); 19115dfecf96Smrg 19125dfecf96Smrg defval = default_value; 19135dfecf96Smrg sform = NULL; 19145dfecf96Smrg if (CONSP(akey)) { 19155dfecf96Smrg /* check for special case, as in: 19165dfecf96Smrg * (defun a (&key ((key name) 'default-value)) name) 19175dfecf96Smrg * (a 'key 'test) => TEST 19185dfecf96Smrg * (a) => DEFAULT-VALUE 19195dfecf96Smrg */ 19205dfecf96Smrg if (!SYMBOLP(CAR(akey)) || !CONSP(CDR(akey)) || 19215dfecf96Smrg !SYMBOLP(CADR(akey)) || CDDR(akey) != NIL || 19225dfecf96Smrg (CDR(spec) != NIL && CDDR(spec) != NIL)) 19235dfecf96Smrg LispDestroy("%s %s: bad special &KEY %s", 19245dfecf96Smrg fnames[type], name, STROBJ(spec)); 19255dfecf96Smrg if (CDR(spec) != NIL) 19265dfecf96Smrg defval = CADR(spec); 19275dfecf96Smrg spec = CADR(akey); 19285dfecf96Smrg akey = CAR(akey); 19295dfecf96Smrg } 19305dfecf96Smrg else { 19315dfecf96Smrg akey = NULL; 19325dfecf96Smrg 19335dfecf96Smrg if (!SYMBOLP(CAR(spec))) 19345dfecf96Smrg LispDestroy("%s %s: %s cannot be a %s argument name", 19355dfecf96Smrg fnames[type], name, 19365dfecf96Smrg STROBJ(CAR(spec)), types[type]); 19375dfecf96Smrg /* check if default value provided, and optionally a `svar' */ 19385dfecf96Smrg else if (CDR(spec) != NIL && (!CONSP(CDR(spec)) || 19395dfecf96Smrg (CDDR(spec) != NIL && 19405dfecf96Smrg (!SYMBOLP(CAR(CDDR(spec))) || 19415dfecf96Smrg CDR(CDDR(spec)) != NIL)))) 19425dfecf96Smrg LispDestroy("%s %s: bad argument specification %s", 19435dfecf96Smrg fnames[type], name, STROBJ(spec)); 19445dfecf96Smrg if (CONSP(CDR(spec))) { 19455dfecf96Smrg defval = CADR(spec); 19465dfecf96Smrg if (CONSP(CDDR(spec))) 19475dfecf96Smrg sform = CAR(CDDR(spec)); 19485dfecf96Smrg } 19495dfecf96Smrg /* Add to keyword package, and set the keyword in the 19505dfecf96Smrg * argument list, so that a function argument keyword 19515dfecf96Smrg * will reference the same object, and make comparison 19525dfecf96Smrg * simpler. */ 19535dfecf96Smrg spec = LispCheckKeyword(CAR(spec)); 19545dfecf96Smrg } 19555dfecf96Smrg 19565dfecf96Smrg count = alist->keys.num_symbols; 19575dfecf96Smrg REALLOC_OBJECTS(alist->keys.keys, count + 1); 19585dfecf96Smrg REALLOC_OBJECTS(alist->keys.defaults, count + 1); 19595dfecf96Smrg REALLOC_OBJECTS(alist->keys.sforms, count + 1); 19605dfecf96Smrg REALLOC_OBJECTS(alist->keys.symbols, count + 1); 19615dfecf96Smrg alist->keys.symbols[count] = spec; 19625dfecf96Smrg alist->keys.defaults[count] = defval; 19635dfecf96Smrg alist->keys.sforms[count] = sform; 19645dfecf96Smrg alist->keys.keys[count] = akey; 19655dfecf96Smrg ++alist->keys.num_symbols; 19665dfecf96Smrg if (count == 0) 19675dfecf96Smrg *desc++ = 'k'; 19685dfecf96Smrg alist->num_arguments += 1 + (sform != NULL); 19695dfecf96Smrg } 19705dfecf96Smrg else if (optional) { 19715dfecf96Smrg defval = default_value; 19725dfecf96Smrg sform = NULL; 19735dfecf96Smrg 19745dfecf96Smrg if (!SYMBOLP(CAR(spec))) 19755dfecf96Smrg LispDestroy("%s %s: %s cannot be a %s argument name", 19765dfecf96Smrg fnames[type], name, 19775dfecf96Smrg STROBJ(CAR(spec)), types[type]); 19785dfecf96Smrg /* check if default value provided, and optionally a `svar' */ 19795dfecf96Smrg else if (CDR(spec) != NIL && (!CONSP(CDR(spec)) || 19805dfecf96Smrg (CDDR(spec) != NIL && 19815dfecf96Smrg (!SYMBOLP(CAR(CDDR(spec))) || 19825dfecf96Smrg CDR(CDDR(spec)) != NIL)))) 19835dfecf96Smrg LispDestroy("%s %s: bad argument specification %s", 19845dfecf96Smrg fnames[type], name, STROBJ(spec)); 19855dfecf96Smrg if (CONSP(CDR(spec))) { 19865dfecf96Smrg defval = CADR(spec); 19875dfecf96Smrg if (CONSP(CDDR(spec))) 19885dfecf96Smrg sform = CAR(CDDR(spec)); 19895dfecf96Smrg } 19905dfecf96Smrg spec = CAR(spec); 19915dfecf96Smrg 19925dfecf96Smrg count = alist->optionals.num_symbols; 19935dfecf96Smrg REALLOC_OBJECTS(alist->optionals.symbols, count + 1); 19945dfecf96Smrg REALLOC_OBJECTS(alist->optionals.defaults, count + 1); 19955dfecf96Smrg REALLOC_OBJECTS(alist->optionals.sforms, count + 1); 19965dfecf96Smrg alist->optionals.symbols[count] = spec; 19975dfecf96Smrg alist->optionals.defaults[count] = defval; 19985dfecf96Smrg alist->optionals.sforms[count] = sform; 19995dfecf96Smrg ++alist->optionals.num_symbols; 20005dfecf96Smrg if (count == 0) 20015dfecf96Smrg *desc++ = 'o'; 20025dfecf96Smrg alist->num_arguments += 1 + (sform != NULL); 20035dfecf96Smrg } 20045dfecf96Smrg 20055dfecf96Smrg /* Normal arguments cannot have default value */ 20065dfecf96Smrg else 20075dfecf96Smrg LispDestroy("%s %s: syntax error parsing %s", 20085dfecf96Smrg fnames[type], name, STROBJ(spec)); 20095dfecf96Smrg } 20105dfecf96Smrg 20115dfecf96Smrg /* spec must be an atom, excluding keywords */ 20125dfecf96Smrg else if (!SYMBOLP(spec) || KEYWORDP(spec)) 20135dfecf96Smrg LispDestroy("%s %s: %s cannot be a %s argument", 20145dfecf96Smrg fnames[type], name, STROBJ(spec), types[type]); 20155dfecf96Smrg else { 20165dfecf96Smrg Atom_id atom = ATOMID(spec); 20175dfecf96Smrg 2018f14f4646Smrg if (atom->value[0] == '&') { 20195dfecf96Smrg if (atom == Srest) { 20205dfecf96Smrg if (rest || aux || CDR(list) == NIL || !SYMBOLP(CADR(list)) 20215dfecf96Smrg /* only &aux allowed after &rest */ 20225dfecf96Smrg || (CDDR(list) != NIL && !SYMBOLP(CAR(CDDR(list))) && 20235dfecf96Smrg ATOMID(CAR(CDDR(list))) != Saux)) 20245dfecf96Smrg LispDestroy("%s %s: syntax error parsing %s", 2025f14f4646Smrg fnames[type], name, ATOMID(spec)->value); 20265dfecf96Smrg if (key) 20275dfecf96Smrg LispDestroy("%s %s: %s not allowed after %s", 20285dfecf96Smrg fnames[type], name, keys[IREST], keys[IKEY]); 20295dfecf96Smrg rest = 1; 20305dfecf96Smrg continue; 20315dfecf96Smrg } 20325dfecf96Smrg 20335dfecf96Smrg else if (atom == Skey) { 20345dfecf96Smrg if (rest || aux) 20355dfecf96Smrg LispDestroy("%s %s: %s not allowed after %s", 2036f14f4646Smrg fnames[type], name, ATOMID(spec)->value, 20375dfecf96Smrg rest ? keys[IREST] : keys[IAUX]); 20385dfecf96Smrg key = 1; 20395dfecf96Smrg continue; 20405dfecf96Smrg } 20415dfecf96Smrg 20425dfecf96Smrg else if (atom == Soptional) { 20435dfecf96Smrg if (rest || optional || aux || key) 20445dfecf96Smrg LispDestroy("%s %s: %s not allowed after %s", 2045f14f4646Smrg fnames[type], name, ATOMID(spec)->value, 20465dfecf96Smrg rest ? keys[IREST] : 20475dfecf96Smrg optional ? 20485dfecf96Smrg keys[IOPTIONAL] : 20495dfecf96Smrg aux ? keys[IAUX] : keys[IKEY]); 20505dfecf96Smrg optional = 1; 20515dfecf96Smrg continue; 20525dfecf96Smrg } 20535dfecf96Smrg 20545dfecf96Smrg else if (atom == Saux) { 20555dfecf96Smrg /* &AUX must be the last keyword parameter */ 20565dfecf96Smrg if (aux) 20575dfecf96Smrg LispDestroy("%s %s: syntax error parsing %s", 2058f14f4646Smrg fnames[type], name, ATOMID(spec)->value); 20595dfecf96Smrg else if (builtin) 20605dfecf96Smrg LispDestroy("builtin function cannot have &AUX arguments"); 20615dfecf96Smrg aux = 1; 20625dfecf96Smrg continue; 20635dfecf96Smrg } 20645dfecf96Smrg 20655dfecf96Smrg /* Untill more lambda-list keywords supported, don't allow 20665dfecf96Smrg * argument names starting with the '&' character */ 20675dfecf96Smrg else 20685dfecf96Smrg LispDestroy("%s %s: %s not allowed/implemented", 2069f14f4646Smrg fnames[type], name, ATOMID(spec)->value); 20705dfecf96Smrg } 20715dfecf96Smrg 20725dfecf96Smrg /* Add argument to alist */ 20735dfecf96Smrg if (aux) { 20745dfecf96Smrg count = alist->auxs.num_symbols; 20755dfecf96Smrg REALLOC_OBJECTS(alist->auxs.symbols, count + 1); 20765dfecf96Smrg REALLOC_OBJECTS(alist->auxs.initials, count + 1); 20775dfecf96Smrg alist->auxs.symbols[count] = spec; 20785dfecf96Smrg alist->auxs.initials[count] = default_value; 20795dfecf96Smrg ++alist->auxs.num_symbols; 20805dfecf96Smrg if (count == 0) 20815dfecf96Smrg *desc++ = 'a'; 20825dfecf96Smrg ++alist->num_arguments; 20835dfecf96Smrg } 20845dfecf96Smrg else if (rest) { 20855dfecf96Smrg alist->rest = spec; 20865dfecf96Smrg *desc++ = 'r'; 20875dfecf96Smrg ++alist->num_arguments; 20885dfecf96Smrg } 20895dfecf96Smrg else if (key) { 20905dfecf96Smrg /* Add to keyword package, and set the keyword in the 20915dfecf96Smrg * argument list, so that a function argument keyword 20925dfecf96Smrg * will reference the same object, and make comparison 20935dfecf96Smrg * simpler. */ 20945dfecf96Smrg spec = LispCheckKeyword(spec); 20955dfecf96Smrg count = alist->keys.num_symbols; 20965dfecf96Smrg REALLOC_OBJECTS(alist->keys.keys, count + 1); 20975dfecf96Smrg REALLOC_OBJECTS(alist->keys.defaults, count + 1); 20985dfecf96Smrg REALLOC_OBJECTS(alist->keys.sforms, count + 1); 20995dfecf96Smrg REALLOC_OBJECTS(alist->keys.symbols, count + 1); 21005dfecf96Smrg alist->keys.symbols[count] = spec; 21015dfecf96Smrg alist->keys.defaults[count] = default_value; 21025dfecf96Smrg alist->keys.sforms[count] = NULL; 21035dfecf96Smrg alist->keys.keys[count] = NULL; 21045dfecf96Smrg ++alist->keys.num_symbols; 21055dfecf96Smrg if (count == 0) 21065dfecf96Smrg *desc++ = 'k'; 21075dfecf96Smrg ++alist->num_arguments; 21085dfecf96Smrg } 21095dfecf96Smrg else if (optional) { 21105dfecf96Smrg count = alist->optionals.num_symbols; 21115dfecf96Smrg REALLOC_OBJECTS(alist->optionals.symbols, count + 1); 21125dfecf96Smrg REALLOC_OBJECTS(alist->optionals.defaults, count + 1); 21135dfecf96Smrg REALLOC_OBJECTS(alist->optionals.sforms, count + 1); 21145dfecf96Smrg alist->optionals.symbols[count] = spec; 21155dfecf96Smrg alist->optionals.defaults[count] = default_value; 21165dfecf96Smrg alist->optionals.sforms[count] = NULL; 21175dfecf96Smrg ++alist->optionals.num_symbols; 21185dfecf96Smrg if (count == 0) 21195dfecf96Smrg *desc++ = 'o'; 21205dfecf96Smrg ++alist->num_arguments; 21215dfecf96Smrg } 21225dfecf96Smrg else { 21235dfecf96Smrg count = alist->normals.num_symbols; 21245dfecf96Smrg REALLOC_OBJECTS(alist->normals.symbols, count + 1); 21255dfecf96Smrg alist->normals.symbols[count] = spec; 21265dfecf96Smrg ++alist->normals.num_symbols; 21275dfecf96Smrg if (count == 0) 21285dfecf96Smrg *desc++ = '.'; 21295dfecf96Smrg ++alist->num_arguments; 21305dfecf96Smrg } 21315dfecf96Smrg } 21325dfecf96Smrg } 21335dfecf96Smrg 21345dfecf96Smrg /* Check for dotted argument list */ 21355dfecf96Smrg if (list != NIL) 21365dfecf96Smrg LispDestroy("%s %s: %s cannot end %s arguments", 21375dfecf96Smrg fnames[type], name, STROBJ(list), types[type]); 21385dfecf96Smrg 21395dfecf96Smrg *desc = '\0'; 2140f14f4646Smrg alist->description = LispGetAtomKey(description, 0)->value; 21415dfecf96Smrg 21425dfecf96Smrg return (alist); 21435dfecf96Smrg} 21445dfecf96Smrg 21455dfecf96Smrgvoid 21465dfecf96SmrgLispAddBuiltinFunction(LispBuiltin *builtin) 21475dfecf96Smrg{ 21485dfecf96Smrg static LispObj stream; 21495dfecf96Smrg static LispString string; 21505dfecf96Smrg static int first = 1; 21515dfecf96Smrg LispObj *name, *obj, *list, *cons, *code; 21525dfecf96Smrg LispAtom *atom; 21535dfecf96Smrg LispArgList *alist; 21545dfecf96Smrg int length = lisp__data.protect.length; 21555dfecf96Smrg 21565dfecf96Smrg if (first) { 21575dfecf96Smrg stream.type = LispStream_t; 21585dfecf96Smrg stream.data.stream.source.string = &string; 21595dfecf96Smrg stream.data.stream.pathname = NIL; 21605dfecf96Smrg stream.data.stream.type = LispStreamString; 21615dfecf96Smrg stream.data.stream.readable = 1; 21625dfecf96Smrg stream.data.stream.writable = 0; 21635dfecf96Smrg string.output = 0; 21645dfecf96Smrg first = 0; 21655dfecf96Smrg } 21665dfecf96Smrg string.string = builtin->declaration; 21675dfecf96Smrg string.length = strlen(builtin->declaration); 21685dfecf96Smrg string.input = 0; 21695dfecf96Smrg 21705dfecf96Smrg code = COD; 21715dfecf96Smrg LispPushInput(&stream); 21725dfecf96Smrg name = LispRead(); 21735dfecf96Smrg list = cons = CONS(name, NIL); 21745dfecf96Smrg if (length + 1 >= lisp__data.protect.space) 21755dfecf96Smrg LispMoreProtects(); 21765dfecf96Smrg lisp__data.protect.objects[lisp__data.protect.length++] = list; 21775dfecf96Smrg while ((obj = LispRead()) != NULL) { 21785dfecf96Smrg RPLACD(cons, CONS(obj, NIL)); 21795dfecf96Smrg cons = CDR(cons); 21805dfecf96Smrg } 21815dfecf96Smrg LispPopInput(&stream); 21825dfecf96Smrg 21835dfecf96Smrg atom = name->data.atom; 2184f14f4646Smrg alist = LispCheckArguments(builtin->type, CDR(list), atom->key->value, 1); 21855dfecf96Smrg builtin->symbol = CAR(list); 21865dfecf96Smrg LispSetAtomBuiltinProperty(atom, builtin, alist); 21875dfecf96Smrg LispUseArgList(alist); 21885dfecf96Smrg 21895dfecf96Smrg /* Make function a extern symbol, unless told to not do so */ 21905dfecf96Smrg if (!builtin->internal) 21915dfecf96Smrg LispExportSymbol(name); 21925dfecf96Smrg 21935dfecf96Smrg lisp__data.protect.length = length; 21945dfecf96Smrg COD = code; /* LispRead protect data in COD */ 21955dfecf96Smrg} 21965dfecf96Smrg 21975dfecf96Smrgvoid 21985dfecf96SmrgLispAllocSeg(LispObjSeg *seg, int cellcount) 21995dfecf96Smrg{ 22005dfecf96Smrg unsigned int i; 22015dfecf96Smrg LispObj **list, *obj; 22025dfecf96Smrg 22035dfecf96Smrg DISABLE_INTERRUPTS(); 22045dfecf96Smrg while (seg->nfree < cellcount) { 22055dfecf96Smrg if ((obj = (LispObj*)calloc(1, sizeof(LispObj) * segsize)) == NULL) { 22065dfecf96Smrg ENABLE_INTERRUPTS(); 22075dfecf96Smrg LispDestroy("out of memory"); 22085dfecf96Smrg } 22095dfecf96Smrg if ((list = (LispObj**)realloc(seg->objects, 22105dfecf96Smrg sizeof(LispObj*) * (seg->nsegs + 1))) == NULL) { 22115dfecf96Smrg free(obj); 22125dfecf96Smrg ENABLE_INTERRUPTS(); 22135dfecf96Smrg LispDestroy("out of memory"); 22145dfecf96Smrg } 22155dfecf96Smrg seg->objects = list; 22165dfecf96Smrg seg->objects[seg->nsegs] = obj; 22175dfecf96Smrg 22185dfecf96Smrg seg->nfree += segsize; 22195dfecf96Smrg seg->nobjs += segsize; 22205dfecf96Smrg for (i = 1; i < segsize; i++, obj++) { 22215dfecf96Smrg /* Objects of type cons are the most used, save some time 22225dfecf96Smrg * by not setting it's type in LispNewCons. */ 22235dfecf96Smrg obj->type = LispCons_t; 22245dfecf96Smrg CDR(obj) = obj + 1; 22255dfecf96Smrg } 22265dfecf96Smrg obj->type = LispCons_t; 22275dfecf96Smrg CDR(obj) = seg->freeobj; 22285dfecf96Smrg seg->freeobj = seg->objects[seg->nsegs]; 22295dfecf96Smrg ++seg->nsegs; 22305dfecf96Smrg } 22315dfecf96Smrg#ifdef DEBUG 22325dfecf96Smrg LispMessage("gc: %d cell(s) allocated at %d segment(s)", 22335dfecf96Smrg seg->nobjs, seg->nsegs); 22345dfecf96Smrg#endif 22355dfecf96Smrg ENABLE_INTERRUPTS(); 22365dfecf96Smrg} 22375dfecf96Smrg 22385dfecf96Smrgstatic INLINE void 22395dfecf96SmrgLispMark(register LispObj *object) 22405dfecf96Smrg{ 22415dfecf96Smrgmark_again: 22425dfecf96Smrg switch (OBJECT_TYPE(object)) { 22435dfecf96Smrg case LispNil_t: 22445dfecf96Smrg case LispAtom_t: 22455dfecf96Smrg case LispFixnum_t: 22465dfecf96Smrg case LispSChar_t: 22475dfecf96Smrg case LispFunction_t: 22485dfecf96Smrg return; 22495dfecf96Smrg case LispLambda_t: 22505dfecf96Smrg if (OPAQUEP(object->data.lambda.name)) 22515dfecf96Smrg object->data.lambda.name->mark = 1; 22525dfecf96Smrg object->mark = 1; 22535dfecf96Smrg LispMark(object->data.lambda.data); 22545dfecf96Smrg object = object->data.lambda.code; 22555dfecf96Smrg goto mark_cons; 22565dfecf96Smrg case LispQuote_t: 22575dfecf96Smrg case LispBackquote_t: 22585dfecf96Smrg case LispFunctionQuote_t: 22595dfecf96Smrg object->mark = 1; 22605dfecf96Smrg object = object->data.quote; 22615dfecf96Smrg goto mark_again; 22625dfecf96Smrg case LispPathname_t: 22635dfecf96Smrg object->mark = 1; 22645dfecf96Smrg object = object->data.pathname; 22655dfecf96Smrg goto mark_again; 22665dfecf96Smrg case LispComma_t: 22675dfecf96Smrg object->mark = 1; 22685dfecf96Smrg object = object->data.comma.eval; 22695dfecf96Smrg goto mark_again; 22705dfecf96Smrg case LispComplex_t: 22715dfecf96Smrg if (POINTERP(object->data.complex.real)) 22725dfecf96Smrg object->data.complex.real->mark = 1; 22735dfecf96Smrg if (POINTERP(object->data.complex.imag)) 22745dfecf96Smrg object->data.complex.imag->mark = 1; 22755dfecf96Smrg break; 22765dfecf96Smrg case LispCons_t: 22775dfecf96Smrgmark_cons: 22785dfecf96Smrg for (; CONSP(object) && !object->mark; object = CDR(object)) { 22795dfecf96Smrg object->mark = 1; 22805dfecf96Smrg switch (OBJECT_TYPE(CAR(object))) { 22815dfecf96Smrg case LispNil_t: 22825dfecf96Smrg case LispAtom_t: 22835dfecf96Smrg case LispFixnum_t: 22845dfecf96Smrg case LispSChar_t: 22855dfecf96Smrg case LispPackage_t: /* protected in gc */ 22865dfecf96Smrg break; 22875dfecf96Smrg case LispInteger_t: 22885dfecf96Smrg case LispDFloat_t: 22895dfecf96Smrg case LispString_t: 22905dfecf96Smrg case LispRatio_t: 22915dfecf96Smrg case LispOpaque_t: 22925dfecf96Smrg case LispBignum_t: 22935dfecf96Smrg case LispBigratio_t: 22945dfecf96Smrg CAR(object)->mark = 1; 22955dfecf96Smrg break; 22965dfecf96Smrg default: 22975dfecf96Smrg LispMark(CAR(object)); 22985dfecf96Smrg break; 22995dfecf96Smrg } 23005dfecf96Smrg } 23015dfecf96Smrg if (POINTERP(object) && !object->mark) 23025dfecf96Smrg goto mark_again; 23035dfecf96Smrg return; 23045dfecf96Smrg case LispArray_t: 23055dfecf96Smrg LispMark(object->data.array.list); 23065dfecf96Smrg object->mark = 1; 23075dfecf96Smrg object = object->data.array.dim; 23085dfecf96Smrg goto mark_cons; 23095dfecf96Smrg case LispStruct_t: 23105dfecf96Smrg object->mark = 1; 23115dfecf96Smrg object = object->data.struc.fields; 23125dfecf96Smrg goto mark_cons; 23135dfecf96Smrg case LispStream_t: 23145dfecf96Smrgmark_stream: 23155dfecf96Smrg LispMark(object->data.stream.pathname); 23165dfecf96Smrg if (object->data.stream.type == LispStreamPipe) { 23175dfecf96Smrg object->mark = 1; 23185dfecf96Smrg object = object->data.stream.source.program->errorp; 23195dfecf96Smrg goto mark_stream; 23205dfecf96Smrg } 23215dfecf96Smrg break; 23225dfecf96Smrg case LispRegex_t: 23235dfecf96Smrg object->data.regex.pattern->mark = 1; 23245dfecf96Smrg break; 23255dfecf96Smrg case LispBytecode_t: 23265dfecf96Smrg object->mark = 1; 23275dfecf96Smrg object = object->data.bytecode.code; 23285dfecf96Smrg goto mark_again; 23295dfecf96Smrg case LispHashTable_t: { 23305dfecf96Smrg unsigned long i; 23315dfecf96Smrg LispHashEntry *entry = object->data.hash.table->entries, 23325dfecf96Smrg *last = entry + object->data.hash.table->num_entries; 23335dfecf96Smrg 23345dfecf96Smrg if (object->mark) 23355dfecf96Smrg return; 23365dfecf96Smrg object->mark = 1; 23375dfecf96Smrg for (; entry < last; entry++) { 23385dfecf96Smrg for (i = 0; i < entry->count; i++) { 23395dfecf96Smrg switch (OBJECT_TYPE(entry->keys[i])) { 23405dfecf96Smrg case LispNil_t: 23415dfecf96Smrg case LispAtom_t: 23425dfecf96Smrg case LispFixnum_t: 23435dfecf96Smrg case LispSChar_t: 23445dfecf96Smrg case LispFunction_t: 23455dfecf96Smrg case LispPackage_t: 23465dfecf96Smrg break; 23475dfecf96Smrg case LispInteger_t: 23485dfecf96Smrg case LispDFloat_t: 23495dfecf96Smrg case LispString_t: 23505dfecf96Smrg case LispRatio_t: 23515dfecf96Smrg case LispOpaque_t: 23525dfecf96Smrg case LispBignum_t: 23535dfecf96Smrg case LispBigratio_t: 23545dfecf96Smrg entry->keys[i]->mark = 1; 23555dfecf96Smrg break; 23565dfecf96Smrg default: 23575dfecf96Smrg LispMark(entry->keys[i]); 23585dfecf96Smrg break; 23595dfecf96Smrg } 23605dfecf96Smrg switch (OBJECT_TYPE(entry->values[i])) { 23615dfecf96Smrg case LispNil_t: 23625dfecf96Smrg case LispAtom_t: 23635dfecf96Smrg case LispFixnum_t: 23645dfecf96Smrg case LispSChar_t: 23655dfecf96Smrg case LispFunction_t: 23665dfecf96Smrg case LispPackage_t: 23675dfecf96Smrg break; 23685dfecf96Smrg case LispInteger_t: 23695dfecf96Smrg case LispDFloat_t: 23705dfecf96Smrg case LispString_t: 23715dfecf96Smrg case LispRatio_t: 23725dfecf96Smrg case LispOpaque_t: 23735dfecf96Smrg case LispBignum_t: 23745dfecf96Smrg case LispBigratio_t: 23755dfecf96Smrg entry->values[i]->mark = 1; 23765dfecf96Smrg break; 23775dfecf96Smrg default: 23785dfecf96Smrg LispMark(entry->values[i]); 23795dfecf96Smrg break; 23805dfecf96Smrg } 23815dfecf96Smrg } 23825dfecf96Smrg } 23835dfecf96Smrg } return; 23845dfecf96Smrg default: 23855dfecf96Smrg break; 23865dfecf96Smrg } 23875dfecf96Smrg object->mark = 1; 23885dfecf96Smrg} 23895dfecf96Smrg 23905dfecf96Smrgstatic INLINE void 23915dfecf96SmrgLispProt(register LispObj *object) 23925dfecf96Smrg{ 23935dfecf96Smrgprot_again: 23945dfecf96Smrg switch (OBJECT_TYPE(object)) { 23955dfecf96Smrg case LispNil_t: 23965dfecf96Smrg case LispAtom_t: 23975dfecf96Smrg case LispFixnum_t: 23985dfecf96Smrg case LispSChar_t: 23995dfecf96Smrg case LispFunction_t: 24005dfecf96Smrg return; 24015dfecf96Smrg case LispLambda_t: 24025dfecf96Smrg if (OPAQUEP(object->data.lambda.name)) 24035dfecf96Smrg object->data.lambda.name->prot = 1; 24045dfecf96Smrg object->prot = 1; 24055dfecf96Smrg LispProt(object->data.lambda.data); 24065dfecf96Smrg object = object->data.lambda.code; 24075dfecf96Smrg goto prot_cons; 24085dfecf96Smrg case LispQuote_t: 24095dfecf96Smrg case LispBackquote_t: 24105dfecf96Smrg case LispFunctionQuote_t: 24115dfecf96Smrg object->prot = 1; 24125dfecf96Smrg object = object->data.quote; 24135dfecf96Smrg goto prot_again; 24145dfecf96Smrg case LispPathname_t: 24155dfecf96Smrg object->prot = 1; 24165dfecf96Smrg object = object->data.pathname; 24175dfecf96Smrg goto prot_again; 24185dfecf96Smrg case LispComma_t: 24195dfecf96Smrg object->prot = 1; 24205dfecf96Smrg object = object->data.comma.eval; 24215dfecf96Smrg goto prot_again; 24225dfecf96Smrg case LispComplex_t: 24235dfecf96Smrg if (POINTERP(object->data.complex.real)) 24245dfecf96Smrg object->data.complex.real->prot = 1; 24255dfecf96Smrg if (POINTERP(object->data.complex.imag)) 24265dfecf96Smrg object->data.complex.imag->prot = 1; 24275dfecf96Smrg break; 24285dfecf96Smrg case LispCons_t: 24295dfecf96Smrgprot_cons: 24305dfecf96Smrg for (; CONSP(object) && !object->prot; object = CDR(object)) { 24315dfecf96Smrg object->prot = 1; 24325dfecf96Smrg switch (OBJECT_TYPE(CAR(object))) { 24335dfecf96Smrg case LispNil_t: 24345dfecf96Smrg case LispAtom_t: 24355dfecf96Smrg case LispFixnum_t: 24365dfecf96Smrg case LispSChar_t: 24375dfecf96Smrg case LispFunction_t: 24385dfecf96Smrg case LispPackage_t: /* protected in gc */ 24395dfecf96Smrg break; 24405dfecf96Smrg case LispInteger_t: 24415dfecf96Smrg case LispDFloat_t: 24425dfecf96Smrg case LispString_t: 24435dfecf96Smrg case LispRatio_t: 24445dfecf96Smrg case LispOpaque_t: 24455dfecf96Smrg case LispBignum_t: 24465dfecf96Smrg case LispBigratio_t: 24475dfecf96Smrg CAR(object)->prot = 1; 24485dfecf96Smrg break; 24495dfecf96Smrg default: 24505dfecf96Smrg LispProt(CAR(object)); 24515dfecf96Smrg break; 24525dfecf96Smrg } 24535dfecf96Smrg } 24545dfecf96Smrg if (POINTERP(object) && !object->prot) 24555dfecf96Smrg goto prot_again; 24565dfecf96Smrg return; 24575dfecf96Smrg case LispArray_t: 24585dfecf96Smrg LispProt(object->data.array.list); 24595dfecf96Smrg object->prot = 1; 24605dfecf96Smrg object = object->data.array.dim; 24615dfecf96Smrg goto prot_cons; 24625dfecf96Smrg case LispStruct_t: 24635dfecf96Smrg object->prot = 1; 24645dfecf96Smrg object = object->data.struc.fields; 24655dfecf96Smrg goto prot_cons; 24665dfecf96Smrg case LispStream_t: 24675dfecf96Smrgprot_stream: 24685dfecf96Smrg LispProt(object->data.stream.pathname); 24695dfecf96Smrg if (object->data.stream.type == LispStreamPipe) { 24705dfecf96Smrg object->prot = 1; 24715dfecf96Smrg object = object->data.stream.source.program->errorp; 24725dfecf96Smrg goto prot_stream; 24735dfecf96Smrg } 24745dfecf96Smrg break; 24755dfecf96Smrg case LispRegex_t: 24765dfecf96Smrg object->data.regex.pattern->prot = 1; 24775dfecf96Smrg break; 24785dfecf96Smrg case LispBytecode_t: 24795dfecf96Smrg object->prot = 1; 24805dfecf96Smrg object = object->data.bytecode.code; 24815dfecf96Smrg goto prot_again; 24825dfecf96Smrg case LispHashTable_t: { 24835dfecf96Smrg unsigned long i; 24845dfecf96Smrg LispHashEntry *entry = object->data.hash.table->entries, 24855dfecf96Smrg *last = entry + object->data.hash.table->num_entries; 24865dfecf96Smrg 24875dfecf96Smrg if (object->prot) 24885dfecf96Smrg return; 24895dfecf96Smrg object->prot = 1; 24905dfecf96Smrg for (; entry < last; entry++) { 24915dfecf96Smrg for (i = 0; i < entry->count; i++) { 24925dfecf96Smrg switch (OBJECT_TYPE(entry->keys[i])) { 24935dfecf96Smrg case LispNil_t: 24945dfecf96Smrg case LispAtom_t: 24955dfecf96Smrg case LispFixnum_t: 24965dfecf96Smrg case LispSChar_t: 24975dfecf96Smrg case LispFunction_t: 24985dfecf96Smrg case LispPackage_t: 24995dfecf96Smrg break; 25005dfecf96Smrg case LispInteger_t: 25015dfecf96Smrg case LispDFloat_t: 25025dfecf96Smrg case LispString_t: 25035dfecf96Smrg case LispRatio_t: 25045dfecf96Smrg case LispOpaque_t: 25055dfecf96Smrg case LispBignum_t: 25065dfecf96Smrg case LispBigratio_t: 25075dfecf96Smrg entry->keys[i]->prot = 1; 25085dfecf96Smrg break; 25095dfecf96Smrg default: 25105dfecf96Smrg LispProt(entry->keys[i]); 25115dfecf96Smrg break; 25125dfecf96Smrg } 25135dfecf96Smrg switch (OBJECT_TYPE(entry->values[i])) { 25145dfecf96Smrg case LispNil_t: 25155dfecf96Smrg case LispAtom_t: 25165dfecf96Smrg case LispFixnum_t: 25175dfecf96Smrg case LispSChar_t: 25185dfecf96Smrg case LispFunction_t: 25195dfecf96Smrg case LispPackage_t: 25205dfecf96Smrg break; 25215dfecf96Smrg case LispInteger_t: 25225dfecf96Smrg case LispDFloat_t: 25235dfecf96Smrg case LispString_t: 25245dfecf96Smrg case LispRatio_t: 25255dfecf96Smrg case LispOpaque_t: 25265dfecf96Smrg case LispBignum_t: 25275dfecf96Smrg case LispBigratio_t: 25285dfecf96Smrg entry->values[i]->prot = 1; 25295dfecf96Smrg break; 25305dfecf96Smrg default: 25315dfecf96Smrg LispProt(entry->values[i]); 25325dfecf96Smrg break; 25335dfecf96Smrg } 25345dfecf96Smrg } 25355dfecf96Smrg } 25365dfecf96Smrg } return; 25375dfecf96Smrg default: 25385dfecf96Smrg break; 25395dfecf96Smrg } 25405dfecf96Smrg object->prot = 1; 25415dfecf96Smrg} 25425dfecf96Smrg 25435dfecf96Smrgvoid 25445dfecf96SmrgLispProtect(LispObj *key, LispObj *list) 25455dfecf96Smrg{ 25465dfecf96Smrg PRO = CONS(CONS(key, list), PRO); 25475dfecf96Smrg} 25485dfecf96Smrg 25495dfecf96Smrgvoid 25505dfecf96SmrgLispUProtect(LispObj *key, LispObj *list) 25515dfecf96Smrg{ 25525dfecf96Smrg LispObj *prev, *obj; 25535dfecf96Smrg 25545dfecf96Smrg for (prev = obj = PRO; obj != NIL; prev = obj, obj = CDR(obj)) 25555dfecf96Smrg if (CAR(CAR(obj)) == key && CDR(CAR(obj)) == list) { 25565dfecf96Smrg if (obj == PRO) 25575dfecf96Smrg PRO = CDR(PRO); 25585dfecf96Smrg else 25595dfecf96Smrg CDR(prev) = CDR(obj); 25605dfecf96Smrg return; 25615dfecf96Smrg } 25625dfecf96Smrg 25635dfecf96Smrg LispDestroy("no match for %s, at UPROTECT", STROBJ(key)); 25645dfecf96Smrg} 25655dfecf96Smrg 25665dfecf96Smrgstatic LispObj * 25675dfecf96SmrgLisp__New(LispObj *car, LispObj *cdr) 25685dfecf96Smrg{ 25695dfecf96Smrg int cellcount; 25705dfecf96Smrg LispObj *obj; 25715dfecf96Smrg 25725dfecf96Smrg Lisp__GC(car, cdr); 25735dfecf96Smrg#if 0 25745dfecf96Smrg lisp__data.gc.average = (objseg.nfree + lisp__data.gc.average) >> 1; 25755dfecf96Smrg if (lisp__data.gc.average < minfree) { 25765dfecf96Smrg if (lisp__data.gc.expandbits < 6) 25775dfecf96Smrg ++lisp__data.gc.expandbits; 25785dfecf96Smrg } 25795dfecf96Smrg else if (lisp__data.gc.expandbits) 25805dfecf96Smrg --lisp__data.gc.expandbits; 25815dfecf96Smrg /* For 32 bit computers, where sizeof(LispObj) == 16, 25825dfecf96Smrg * minfree is set to 1024, and expandbits limited to 6, 25835dfecf96Smrg * the maximum extra memory requested here should be 1Mb 25845dfecf96Smrg */ 25855dfecf96Smrg cellcount = minfree << lisp__data.gc.expandbits; 25865dfecf96Smrg#else 25875dfecf96Smrg /* Try to keep at least 3 times more free cells than the de number 25885dfecf96Smrg * of used cells in the freelist, to amenize the cost of the gc time, 25895dfecf96Smrg * in the, currently, very simple gc strategy code. */ 25905dfecf96Smrg cellcount = (objseg.nobjs - objseg.nfree) * 3; 25915dfecf96Smrg cellcount = cellcount + (minfree - (cellcount % minfree)); 25925dfecf96Smrg#endif 25935dfecf96Smrg 25945dfecf96Smrg if (objseg.freeobj == NIL || objseg.nfree < cellcount) 25955dfecf96Smrg LispAllocSeg(&objseg, cellcount); 25965dfecf96Smrg 25975dfecf96Smrg obj = objseg.freeobj; 25985dfecf96Smrg objseg.freeobj = CDR(obj); 25995dfecf96Smrg --objseg.nfree; 26005dfecf96Smrg 26015dfecf96Smrg return (obj); 26025dfecf96Smrg} 26035dfecf96Smrg 26045dfecf96SmrgLispObj * 26055dfecf96SmrgLispNew(LispObj *car, LispObj *cdr) 26065dfecf96Smrg{ 26075dfecf96Smrg LispObj *obj = objseg.freeobj; 26085dfecf96Smrg 26095dfecf96Smrg if (obj == NIL) 26105dfecf96Smrg obj = Lisp__New(car, cdr); 26115dfecf96Smrg else { 26125dfecf96Smrg objseg.freeobj = CDR(obj); 26135dfecf96Smrg --objseg.nfree; 26145dfecf96Smrg } 26155dfecf96Smrg 26165dfecf96Smrg return (obj); 26175dfecf96Smrg} 26185dfecf96Smrg 26195dfecf96SmrgLispObj * 2620f765521fSmrgLispNewAtom(const char *str, int intern) 26215dfecf96Smrg{ 26225dfecf96Smrg LispObj *object; 26235dfecf96Smrg LispAtom *atom = LispDoGetAtom(str, 0); 26245dfecf96Smrg 26255dfecf96Smrg if (atom->object) { 26265dfecf96Smrg if (intern && atom->package == NULL) 26275dfecf96Smrg atom->package = PACKAGE; 26285dfecf96Smrg 26295dfecf96Smrg return (atom->object); 26305dfecf96Smrg } 26315dfecf96Smrg 26325dfecf96Smrg if (atomseg.freeobj == NIL) 26335dfecf96Smrg LispAllocSeg(&atomseg, pagesize); 26345dfecf96Smrg object = atomseg.freeobj; 26355dfecf96Smrg atomseg.freeobj = CDR(object); 26365dfecf96Smrg --atomseg.nfree; 26375dfecf96Smrg 26385dfecf96Smrg object->type = LispAtom_t; 26395dfecf96Smrg object->data.atom = atom; 26405dfecf96Smrg atom->object = object; 26415dfecf96Smrg if (intern) 26425dfecf96Smrg atom->package = PACKAGE; 26435dfecf96Smrg 26445dfecf96Smrg return (object); 26455dfecf96Smrg} 26465dfecf96Smrg 26475dfecf96SmrgLispObj * 2648f765521fSmrgLispNewStaticAtom(const char *str) 26495dfecf96Smrg{ 26505dfecf96Smrg LispObj *object; 26515dfecf96Smrg LispAtom *atom = LispDoGetAtom(str, 1); 26525dfecf96Smrg 26535dfecf96Smrg object = LispNewSymbol(atom); 26545dfecf96Smrg 26555dfecf96Smrg return (object); 26565dfecf96Smrg} 26575dfecf96Smrg 26585dfecf96SmrgLispObj * 26595dfecf96SmrgLispNewSymbol(LispAtom *atom) 26605dfecf96Smrg{ 26615dfecf96Smrg if (atom->object) { 26625dfecf96Smrg if (atom->package == NULL) 26635dfecf96Smrg atom->package = PACKAGE; 26645dfecf96Smrg 26655dfecf96Smrg return (atom->object); 26665dfecf96Smrg } 26675dfecf96Smrg else { 26685dfecf96Smrg LispObj *symbol; 26695dfecf96Smrg 26705dfecf96Smrg if (atomseg.freeobj == NIL) 26715dfecf96Smrg LispAllocSeg(&atomseg, pagesize); 26725dfecf96Smrg symbol = atomseg.freeobj; 26735dfecf96Smrg atomseg.freeobj = CDR(symbol); 26745dfecf96Smrg --atomseg.nfree; 26755dfecf96Smrg 26765dfecf96Smrg symbol->type = LispAtom_t; 26775dfecf96Smrg symbol->data.atom = atom; 26785dfecf96Smrg atom->object = symbol; 26795dfecf96Smrg atom->package = PACKAGE; 26805dfecf96Smrg 26815dfecf96Smrg return (symbol); 26825dfecf96Smrg } 26835dfecf96Smrg} 26845dfecf96Smrg 26855dfecf96Smrg/* function representation is created on demand and never released, 26865dfecf96Smrg * even if the function is undefined and never defined again */ 26875dfecf96SmrgLispObj * 26885dfecf96SmrgLispNewFunction(LispObj *symbol) 26895dfecf96Smrg{ 26905dfecf96Smrg LispObj *function; 26915dfecf96Smrg 26925dfecf96Smrg if (symbol->data.atom->function) 26935dfecf96Smrg return (symbol->data.atom->function); 26945dfecf96Smrg 26955dfecf96Smrg if (symbol->data.atom->package == NULL) 26965dfecf96Smrg symbol->data.atom->package = PACKAGE; 26975dfecf96Smrg 26985dfecf96Smrg if (atomseg.freeobj == NIL) 26995dfecf96Smrg LispAllocSeg(&atomseg, pagesize); 27005dfecf96Smrg function = atomseg.freeobj; 27015dfecf96Smrg atomseg.freeobj = CDR(function); 27025dfecf96Smrg --atomseg.nfree; 27035dfecf96Smrg 27045dfecf96Smrg function->type = LispFunction_t; 27055dfecf96Smrg function->data.atom = symbol->data.atom; 27065dfecf96Smrg symbol->data.atom->function = function; 27075dfecf96Smrg 27085dfecf96Smrg return (function); 27095dfecf96Smrg} 27105dfecf96Smrg 27115dfecf96Smrg/* symbol name representation is created on demand and never released */ 27125dfecf96SmrgLispObj * 27135dfecf96SmrgLispSymbolName(LispObj *symbol) 27145dfecf96Smrg{ 27155dfecf96Smrg LispObj *name; 27165dfecf96Smrg LispAtom *atom = symbol->data.atom; 27175dfecf96Smrg 27185dfecf96Smrg if (atom->name) 27195dfecf96Smrg return (atom->name); 27205dfecf96Smrg 27215dfecf96Smrg if (atomseg.freeobj == NIL) 27225dfecf96Smrg LispAllocSeg(&atomseg, pagesize); 27235dfecf96Smrg name = atomseg.freeobj; 27245dfecf96Smrg atomseg.freeobj = CDR(name); 27255dfecf96Smrg --atomseg.nfree; 27265dfecf96Smrg 27275dfecf96Smrg name->type = LispString_t; 2728f14f4646Smrg THESTR(name) = atom->key->value; 2729f14f4646Smrg STRLEN(name) = atom->key->length; 27305dfecf96Smrg name->data.string.writable = 0; 27315dfecf96Smrg atom->name = name; 27325dfecf96Smrg 27335dfecf96Smrg return (name); 27345dfecf96Smrg} 27355dfecf96Smrg 27365dfecf96SmrgLispObj * 27375dfecf96SmrgLispNewFunctionQuote(LispObj *object) 27385dfecf96Smrg{ 27395dfecf96Smrg LispObj *quote = LispNew(object, NIL); 27405dfecf96Smrg 27415dfecf96Smrg quote->type = LispFunctionQuote_t; 27425dfecf96Smrg quote->data.quote = object; 27435dfecf96Smrg 27445dfecf96Smrg return (quote); 27455dfecf96Smrg} 27465dfecf96Smrg 27475dfecf96SmrgLispObj * 27485dfecf96SmrgLispNewDFloat(double value) 27495dfecf96Smrg{ 27505dfecf96Smrg LispObj *dfloat = objseg.freeobj; 27515dfecf96Smrg 27525dfecf96Smrg if (dfloat == NIL) 27535dfecf96Smrg dfloat = Lisp__New(NIL, NIL); 27545dfecf96Smrg else { 27555dfecf96Smrg objseg.freeobj = CDR(dfloat); 27565dfecf96Smrg --objseg.nfree; 27575dfecf96Smrg } 27585dfecf96Smrg dfloat->type = LispDFloat_t; 27595dfecf96Smrg dfloat->data.dfloat = value; 27605dfecf96Smrg 27615dfecf96Smrg return (dfloat); 27625dfecf96Smrg} 27635dfecf96Smrg 27645dfecf96SmrgLispObj * 2765f765521fSmrgLispNewString(const char *str, long length) 2766f765521fSmrg{ 2767f765521fSmrg char *cstring = LispMalloc(length + 1); 2768f765521fSmrg memcpy(cstring, str, length); 2769f765521fSmrg cstring[length] = '\0'; 2770f765521fSmrg return LispNewStringAlloced(cstring, length); 2771f765521fSmrg} 2772f765521fSmrg 2773f765521fSmrgLispObj * 2774f765521fSmrgLispNewStringAlloced(char *cstring, long length) 27755dfecf96Smrg{ 27765dfecf96Smrg LispObj *string = objseg.freeobj; 27775dfecf96Smrg 27785dfecf96Smrg if (string == NIL) 27795dfecf96Smrg string = Lisp__New(NIL, NIL); 27805dfecf96Smrg else { 27815dfecf96Smrg objseg.freeobj = CDR(string); 27825dfecf96Smrg --objseg.nfree; 27835dfecf96Smrg } 27845dfecf96Smrg LispMused(cstring); 27855dfecf96Smrg string->type = LispString_t; 27865dfecf96Smrg THESTR(string) = cstring; 27875dfecf96Smrg STRLEN(string) = length; 27885dfecf96Smrg string->data.string.writable = 1; 27895dfecf96Smrg 27905dfecf96Smrg return (string); 27915dfecf96Smrg} 27925dfecf96Smrg 27935dfecf96SmrgLispObj * 27945dfecf96SmrgLispNewComplex(LispObj *realpart, LispObj *imagpart) 27955dfecf96Smrg{ 27965dfecf96Smrg LispObj *complexp = objseg.freeobj; 27975dfecf96Smrg 27985dfecf96Smrg if (complexp == NIL) 27995dfecf96Smrg complexp = Lisp__New(realpart, imagpart); 28005dfecf96Smrg else { 28015dfecf96Smrg objseg.freeobj = CDR(complexp); 28025dfecf96Smrg --objseg.nfree; 28035dfecf96Smrg } 28045dfecf96Smrg complexp->type = LispComplex_t; 28055dfecf96Smrg complexp->data.complex.real = realpart; 28065dfecf96Smrg complexp->data.complex.imag = imagpart; 28075dfecf96Smrg 28085dfecf96Smrg return (complexp); 28095dfecf96Smrg} 28105dfecf96Smrg 28115dfecf96SmrgLispObj * 28125dfecf96SmrgLispNewInteger(long integer) 28135dfecf96Smrg{ 28145dfecf96Smrg if (integer > MOST_POSITIVE_FIXNUM || integer < MOST_NEGATIVE_FIXNUM) { 28155dfecf96Smrg LispObj *object = objseg.freeobj; 28165dfecf96Smrg 28175dfecf96Smrg if (object == NIL) 28185dfecf96Smrg object = Lisp__New(NIL, NIL); 28195dfecf96Smrg else { 28205dfecf96Smrg objseg.freeobj = CDR(object); 28215dfecf96Smrg --objseg.nfree; 28225dfecf96Smrg } 28235dfecf96Smrg object->type = LispInteger_t; 28245dfecf96Smrg object->data.integer = integer; 28255dfecf96Smrg 28265dfecf96Smrg return (object); 28275dfecf96Smrg } 28285dfecf96Smrg return (FIXNUM(integer)); 28295dfecf96Smrg} 28305dfecf96Smrg 28315dfecf96SmrgLispObj * 28325dfecf96SmrgLispNewRatio(long num, long den) 28335dfecf96Smrg{ 28345dfecf96Smrg LispObj *ratio = objseg.freeobj; 28355dfecf96Smrg 28365dfecf96Smrg if (ratio == NIL) 28375dfecf96Smrg ratio = Lisp__New(NIL, NIL); 28385dfecf96Smrg else { 28395dfecf96Smrg objseg.freeobj = CDR(ratio); 28405dfecf96Smrg --objseg.nfree; 28415dfecf96Smrg } 28425dfecf96Smrg ratio->type = LispRatio_t; 28435dfecf96Smrg ratio->data.ratio.numerator = num; 28445dfecf96Smrg ratio->data.ratio.denominator = den; 28455dfecf96Smrg 28465dfecf96Smrg return (ratio); 28475dfecf96Smrg} 28485dfecf96Smrg 28495dfecf96SmrgLispObj * 28505dfecf96SmrgLispNewVector(LispObj *objects) 28515dfecf96Smrg{ 28525dfecf96Smrg GC_ENTER(); 28535dfecf96Smrg long count; 28545dfecf96Smrg LispObj *array, *dimension; 28555dfecf96Smrg 28565dfecf96Smrg for (count = 0, array = objects; CONSP(array); count++, array = CDR(array)) 28575dfecf96Smrg ; 28585dfecf96Smrg 28595dfecf96Smrg GC_PROTECT(objects); 28605dfecf96Smrg dimension = CONS(FIXNUM(count), NIL); 28615dfecf96Smrg array = LispNew(objects, dimension); 28625dfecf96Smrg array->type = LispArray_t; 28635dfecf96Smrg array->data.array.list = objects; 28645dfecf96Smrg array->data.array.dim = dimension; 28655dfecf96Smrg array->data.array.rank = 1; 28665dfecf96Smrg array->data.array.type = LispNil_t; 28675dfecf96Smrg array->data.array.zero = count == 0; 28685dfecf96Smrg GC_LEAVE(); 28695dfecf96Smrg 28705dfecf96Smrg return (array); 28715dfecf96Smrg} 28725dfecf96Smrg 28735dfecf96SmrgLispObj * 28745dfecf96SmrgLispNewQuote(LispObj *object) 28755dfecf96Smrg{ 28765dfecf96Smrg LispObj *quote = LispNew(object, NIL); 28775dfecf96Smrg 28785dfecf96Smrg quote->type = LispQuote_t; 28795dfecf96Smrg quote->data.quote = object; 28805dfecf96Smrg 28815dfecf96Smrg return (quote); 28825dfecf96Smrg} 28835dfecf96Smrg 28845dfecf96SmrgLispObj * 28855dfecf96SmrgLispNewBackquote(LispObj *object) 28865dfecf96Smrg{ 28875dfecf96Smrg LispObj *backquote = LispNew(object, NIL); 28885dfecf96Smrg 28895dfecf96Smrg backquote->type = LispBackquote_t; 28905dfecf96Smrg backquote->data.quote = object; 28915dfecf96Smrg 28925dfecf96Smrg return (backquote); 28935dfecf96Smrg} 28945dfecf96Smrg 28955dfecf96SmrgLispObj * 28965dfecf96SmrgLispNewComma(LispObj *object, int atlist) 28975dfecf96Smrg{ 28985dfecf96Smrg LispObj *comma = LispNew(object, NIL); 28995dfecf96Smrg 29005dfecf96Smrg comma->type = LispComma_t; 29015dfecf96Smrg comma->data.comma.eval = object; 29025dfecf96Smrg comma->data.comma.atlist = atlist; 29035dfecf96Smrg 29045dfecf96Smrg return (comma); 29055dfecf96Smrg} 29065dfecf96Smrg 29075dfecf96SmrgLispObj * 29085dfecf96SmrgLispNewCons(LispObj *car, LispObj *cdr) 29095dfecf96Smrg{ 29105dfecf96Smrg LispObj *cons = objseg.freeobj; 29115dfecf96Smrg 29125dfecf96Smrg if (cons == NIL) 29135dfecf96Smrg cons = Lisp__New(car, cdr); 29145dfecf96Smrg else { 29155dfecf96Smrg objseg.freeobj = CDR(cons); 29165dfecf96Smrg --objseg.nfree; 29175dfecf96Smrg } 29185dfecf96Smrg CAR(cons) = car; 29195dfecf96Smrg CDR(cons) = cdr; 29205dfecf96Smrg 29215dfecf96Smrg return (cons); 29225dfecf96Smrg} 29235dfecf96Smrg 29245dfecf96SmrgLispObj * 29255dfecf96SmrgLispNewLambda(LispObj *name, LispObj *code, LispObj *data, LispFunType type) 29265dfecf96Smrg{ 29275dfecf96Smrg LispObj *fun = LispNew(data, code); 29285dfecf96Smrg 29295dfecf96Smrg fun->type = LispLambda_t; 29305dfecf96Smrg fun->funtype = type; 29315dfecf96Smrg fun->data.lambda.name = name; 29325dfecf96Smrg fun->data.lambda.code = code; 29335dfecf96Smrg fun->data.lambda.data = data; 29345dfecf96Smrg 29355dfecf96Smrg return (fun); 29365dfecf96Smrg} 29375dfecf96Smrg 29385dfecf96SmrgLispObj * 29395dfecf96SmrgLispNewStruct(LispObj *fields, LispObj *def) 29405dfecf96Smrg{ 29415dfecf96Smrg LispObj *struc = LispNew(fields, def); 29425dfecf96Smrg 29435dfecf96Smrg struc->type = LispStruct_t; 29445dfecf96Smrg struc->data.struc.fields = fields; 29455dfecf96Smrg struc->data.struc.def = def; 29465dfecf96Smrg 29475dfecf96Smrg return (struc); 29485dfecf96Smrg} 29495dfecf96Smrg 29505dfecf96SmrgLispObj * 29515dfecf96SmrgLispNewOpaque(void *data, int type) 29525dfecf96Smrg{ 29535dfecf96Smrg LispObj *opaque = LispNew(NIL, NIL); 29545dfecf96Smrg 29555dfecf96Smrg opaque->type = LispOpaque_t; 29565dfecf96Smrg opaque->data.opaque.data = data; 29575dfecf96Smrg opaque->data.opaque.type = type; 29585dfecf96Smrg 29595dfecf96Smrg return (opaque); 29605dfecf96Smrg} 29615dfecf96Smrg 29625dfecf96Smrg/* string argument must be static, or allocated */ 29635dfecf96SmrgLispObj * 2964f765521fSmrgLispNewKeyword(const char *string) 29655dfecf96Smrg{ 29665dfecf96Smrg LispObj *keyword; 29675dfecf96Smrg 29685dfecf96Smrg if (PACKAGE != lisp__data.keyword) { 29695dfecf96Smrg LispObj *savepackage; 29705dfecf96Smrg LispPackage *savepack; 29715dfecf96Smrg 29725dfecf96Smrg /* Save package environment */ 29735dfecf96Smrg savepackage = PACKAGE; 29745dfecf96Smrg savepack = lisp__data.pack; 29755dfecf96Smrg 29765dfecf96Smrg /* Change package environment */ 29775dfecf96Smrg PACKAGE = lisp__data.keyword; 29785dfecf96Smrg lisp__data.pack = lisp__data.key; 29795dfecf96Smrg 29805dfecf96Smrg /* Create symbol in keyword package */ 29815dfecf96Smrg keyword = LispNewStaticAtom(string); 29825dfecf96Smrg 29835dfecf96Smrg /* Restore package environment */ 29845dfecf96Smrg PACKAGE = savepackage; 29855dfecf96Smrg lisp__data.pack = savepack; 29865dfecf96Smrg } 29875dfecf96Smrg else 29885dfecf96Smrg /* Just create symbol in keyword package */ 29895dfecf96Smrg keyword = LispNewStaticAtom(string); 29905dfecf96Smrg 29915dfecf96Smrg /* Export keyword symbol */ 29925dfecf96Smrg LispExportSymbol(keyword); 29935dfecf96Smrg 29945dfecf96Smrg /* All keywords are constants */ 29955dfecf96Smrg keyword->data.atom->constant = 1; 29965dfecf96Smrg 29975dfecf96Smrg /* XXX maybe should bound the keyword to itself, but that would 29985dfecf96Smrg * require allocating a LispProperty structure for every keyword */ 29995dfecf96Smrg 30005dfecf96Smrg return (keyword); 30015dfecf96Smrg} 30025dfecf96Smrg 30035dfecf96SmrgLispObj * 30045dfecf96SmrgLispNewPathname(LispObj *obj) 30055dfecf96Smrg{ 30065dfecf96Smrg LispObj *path = LispNew(obj, NIL); 30075dfecf96Smrg 30085dfecf96Smrg path->type = LispPathname_t; 30095dfecf96Smrg path->data.pathname = obj; 30105dfecf96Smrg 30115dfecf96Smrg return (path); 30125dfecf96Smrg} 30135dfecf96Smrg 30145dfecf96SmrgLispObj * 3015f765521fSmrgLispNewStringStream(const char *string, int flags, long length) 3016f765521fSmrg{ 3017f765521fSmrg char *newstring = LispMalloc(length + 1); 3018f765521fSmrg memcpy(newstring, string, length); 3019f765521fSmrg newstring[length] = '\0'; 3020f765521fSmrg 3021f765521fSmrg return LispNewStringStreamAlloced(newstring, flags, length); 3022f765521fSmrg} 3023f765521fSmrg 3024f765521fSmrgLispObj * 3025f765521fSmrgLispNewStringStreamAlloced(char *string, int flags, long length) 30265dfecf96Smrg{ 30275dfecf96Smrg LispObj *stream = LispNew(NIL, NIL); 30285dfecf96Smrg 30295dfecf96Smrg SSTREAMP(stream) = LispCalloc(1, sizeof(LispString)); 3030f765521fSmrg SSTREAMP(stream)->string = string; 30315dfecf96Smrg 30325dfecf96Smrg stream->type = LispStream_t; 30335dfecf96Smrg 30345dfecf96Smrg SSTREAMP(stream)->length = length; 30355dfecf96Smrg LispMused(SSTREAMP(stream)); 30365dfecf96Smrg LispMused(SSTREAMP(stream)->string); 30375dfecf96Smrg stream->data.stream.type = LispStreamString; 30385dfecf96Smrg stream->data.stream.readable = (flags & STREAM_READ) != 0; 30395dfecf96Smrg stream->data.stream.writable = (flags & STREAM_WRITE) != 0; 30405dfecf96Smrg SSTREAMP(stream)->space = length + 1; 30415dfecf96Smrg 30425dfecf96Smrg stream->data.stream.pathname = NIL; 30435dfecf96Smrg 30445dfecf96Smrg return (stream); 30455dfecf96Smrg} 30465dfecf96Smrg 30475dfecf96SmrgLispObj * 30485dfecf96SmrgLispNewFileStream(LispFile *file, LispObj *path, int flags) 30495dfecf96Smrg{ 30505dfecf96Smrg LispObj *stream = LispNew(NIL, NIL); 30515dfecf96Smrg 30525dfecf96Smrg stream->type = LispStream_t; 30535dfecf96Smrg FSTREAMP(stream) = file; 30545dfecf96Smrg stream->data.stream.pathname = path; 30555dfecf96Smrg stream->data.stream.type = LispStreamFile; 30565dfecf96Smrg stream->data.stream.readable = (flags & STREAM_READ) != 0; 30575dfecf96Smrg stream->data.stream.writable = (flags & STREAM_WRITE) != 0; 30585dfecf96Smrg 30595dfecf96Smrg return (stream); 30605dfecf96Smrg} 30615dfecf96Smrg 30625dfecf96SmrgLispObj * 30635dfecf96SmrgLispNewPipeStream(LispPipe *program, LispObj *path, int flags) 30645dfecf96Smrg{ 30655dfecf96Smrg LispObj *stream = LispNew(NIL, NIL); 30665dfecf96Smrg 30675dfecf96Smrg stream->type = LispStream_t; 30685dfecf96Smrg PSTREAMP(stream) = program; 30695dfecf96Smrg stream->data.stream.pathname = path; 30705dfecf96Smrg stream->data.stream.type = LispStreamPipe; 30715dfecf96Smrg stream->data.stream.readable = (flags & STREAM_READ) != 0; 30725dfecf96Smrg stream->data.stream.writable = (flags & STREAM_WRITE) != 0; 30735dfecf96Smrg 30745dfecf96Smrg return (stream); 30755dfecf96Smrg} 30765dfecf96Smrg 30775dfecf96SmrgLispObj * 30785dfecf96SmrgLispNewStandardStream(LispFile *file, LispObj *description, int flags) 30795dfecf96Smrg{ 30805dfecf96Smrg LispObj *stream = LispNew(NIL, NIL); 30815dfecf96Smrg 30825dfecf96Smrg stream->type = LispStream_t; 30835dfecf96Smrg FSTREAMP(stream) = file; 30845dfecf96Smrg stream->data.stream.pathname = description; 30855dfecf96Smrg stream->data.stream.type = LispStreamStandard; 30865dfecf96Smrg stream->data.stream.readable = (flags & STREAM_READ) != 0; 30875dfecf96Smrg stream->data.stream.writable = (flags & STREAM_WRITE) != 0; 30885dfecf96Smrg 30895dfecf96Smrg return (stream); 30905dfecf96Smrg} 30915dfecf96Smrg 30925dfecf96SmrgLispObj * 30935dfecf96SmrgLispNewBignum(mpi *bignum) 30945dfecf96Smrg{ 30955dfecf96Smrg LispObj *integer = LispNew(NIL, NIL); 30965dfecf96Smrg 30975dfecf96Smrg integer->type = LispBignum_t; 30985dfecf96Smrg integer->data.mp.integer = bignum; 30995dfecf96Smrg LispMused(bignum->digs); 31005dfecf96Smrg LispMused(bignum); 31015dfecf96Smrg 31025dfecf96Smrg return (integer); 31035dfecf96Smrg} 31045dfecf96Smrg 31055dfecf96SmrgLispObj * 31065dfecf96SmrgLispNewBigratio(mpr *bigratio) 31075dfecf96Smrg{ 31085dfecf96Smrg LispObj *ratio = LispNew(NIL, NIL); 31095dfecf96Smrg 31105dfecf96Smrg ratio->type = LispBigratio_t; 31115dfecf96Smrg ratio->data.mp.ratio = bigratio; 31125dfecf96Smrg LispMused(mpr_num(bigratio)->digs); 31135dfecf96Smrg LispMused(mpr_den(bigratio)->digs); 31145dfecf96Smrg LispMused(bigratio); 31155dfecf96Smrg 31165dfecf96Smrg return (ratio); 31175dfecf96Smrg} 31185dfecf96Smrg 31195dfecf96Smrg/* name must be of type LispString_t */ 31205dfecf96SmrgLispObj * 31215dfecf96SmrgLispNewPackage(LispObj *name, LispObj *nicknames) 31225dfecf96Smrg{ 31235dfecf96Smrg LispObj *package = LispNew(name, nicknames); 31245dfecf96Smrg LispPackage *pack = LispCalloc(1, sizeof(LispPackage)); 31255dfecf96Smrg 31265dfecf96Smrg package->type = LispPackage_t; 31275dfecf96Smrg package->data.package.name = name; 31285dfecf96Smrg package->data.package.nicknames = nicknames; 31295dfecf96Smrg package->data.package.package = pack; 31305dfecf96Smrg 3131f14f4646Smrg package->data.package.package->atoms = hash_new(STRTBLSZ, NULL); 3132f14f4646Smrg 31335dfecf96Smrg LispMused(pack); 31345dfecf96Smrg 31355dfecf96Smrg return (package); 31365dfecf96Smrg} 31375dfecf96Smrg 31385dfecf96SmrgLispObj * 31395dfecf96SmrgLispSymbolFunction(LispObj *symbol) 31405dfecf96Smrg{ 31415dfecf96Smrg LispAtom *atom = symbol->data.atom; 31425dfecf96Smrg 31435dfecf96Smrg if ((atom->a_builtin && 31445dfecf96Smrg atom->property->fun.builtin->type == LispFunction) || 31455dfecf96Smrg (atom->a_function && 31465dfecf96Smrg atom->property->fun.function->funtype == LispFunction) || 31475dfecf96Smrg (atom->a_defstruct && 31485dfecf96Smrg atom->property->structure.function != STRUCT_NAME) || 31495dfecf96Smrg /* XXX currently bytecode is only generated for functions */ 31505dfecf96Smrg atom->a_compiled) 31515dfecf96Smrg symbol = FUNCTION(symbol); 31525dfecf96Smrg else 31535dfecf96Smrg LispDestroy("SYMBOL-FUNCTION: %s is not a function", STROBJ(symbol)); 31545dfecf96Smrg 31555dfecf96Smrg return (symbol); 31565dfecf96Smrg} 31575dfecf96Smrg 31585dfecf96Smrg 31595dfecf96Smrgstatic INLINE LispObj * 31605dfecf96SmrgLispGetVarPack(LispObj *symbol) 31615dfecf96Smrg{ 31625dfecf96Smrg LispAtom *atom; 31635dfecf96Smrg 3164f14f4646Smrg atom = (LispAtom *)hash_get(lisp__data.pack->atoms, 3165f14f4646Smrg symbol->data.atom->key); 31665dfecf96Smrg 3167f14f4646Smrg return (atom ? atom->object : NULL); 31685dfecf96Smrg} 31695dfecf96Smrg 31705dfecf96Smrg/* package must be of type LispPackage_t */ 31715dfecf96Smrgvoid 31725dfecf96SmrgLispUsePackage(LispObj *package) 31735dfecf96Smrg{ 31745dfecf96Smrg LispAtom *atom; 31755dfecf96Smrg LispPackage *pack; 31765dfecf96Smrg LispObj **pentry, **eentry; 31775dfecf96Smrg 31785dfecf96Smrg /* Already using its own symbols... */ 31795dfecf96Smrg if (package == PACKAGE) 31805dfecf96Smrg return; 31815dfecf96Smrg 31825dfecf96Smrg /* Check if package not already in use-package list */ 31835dfecf96Smrg for (pentry = lisp__data.pack->use.pairs, 31845dfecf96Smrg eentry = pentry + lisp__data.pack->use.length; 31855dfecf96Smrg pentry < eentry; pentry++) 31865dfecf96Smrg if (*pentry == package) 31875dfecf96Smrg return; 31885dfecf96Smrg 31895dfecf96Smrg /* Remember this package is in the use-package list */ 31905dfecf96Smrg if (lisp__data.pack->use.length + 1 >= lisp__data.pack->use.space) { 31915dfecf96Smrg LispObj **pairs = realloc(lisp__data.pack->use.pairs, 31925dfecf96Smrg (lisp__data.pack->use.space + 1) * 31935dfecf96Smrg sizeof(LispObj*)); 31945dfecf96Smrg 31955dfecf96Smrg if (pairs == NULL) 31965dfecf96Smrg LispDestroy("out of memory"); 31975dfecf96Smrg 31985dfecf96Smrg lisp__data.pack->use.pairs = pairs; 31995dfecf96Smrg ++lisp__data.pack->use.space; 32005dfecf96Smrg } 32015dfecf96Smrg lisp__data.pack->use.pairs[lisp__data.pack->use.length++] = package; 32025dfecf96Smrg 32035dfecf96Smrg /* Import all extern symbols from package */ 32045dfecf96Smrg pack = package->data.package.package; 32055dfecf96Smrg 32065dfecf96Smrg /* Traverse atom list, searching for extern symbols */ 3207f14f4646Smrg for (atom = (LispAtom *)hash_iter_first(pack->atoms); 3208f14f4646Smrg atom; 3209f14f4646Smrg atom = (LispAtom *)hash_iter_next(pack->atoms)) { 3210f14f4646Smrg if (atom->ext) 3211f14f4646Smrg LispImportSymbol(atom->object); 32125dfecf96Smrg } 32135dfecf96Smrg} 32145dfecf96Smrg 32155dfecf96Smrg/* symbol must be of type LispAtom_t */ 32165dfecf96Smrgvoid 32175dfecf96SmrgLispImportSymbol(LispObj *symbol) 32185dfecf96Smrg{ 32195dfecf96Smrg int increment; 32205dfecf96Smrg LispAtom *atom; 32215dfecf96Smrg LispObj *current; 32225dfecf96Smrg 32235dfecf96Smrg current = LispGetVarPack(symbol); 32245dfecf96Smrg if (current == NULL || current->data.atom->property == NOPROPERTY) { 32255dfecf96Smrg /* No conflicts */ 32265dfecf96Smrg 32275dfecf96Smrg if (symbol->data.atom->a_object) { 32285dfecf96Smrg /* If it is a bounded variable */ 32295dfecf96Smrg if (lisp__data.pack->glb.length + 1 >= lisp__data.pack->glb.space) 32305dfecf96Smrg LispMoreGlobals(lisp__data.pack); 32315dfecf96Smrg lisp__data.pack->glb.pairs[lisp__data.pack->glb.length++] = symbol; 32325dfecf96Smrg } 32335dfecf96Smrg 32345dfecf96Smrg /* Create copy of atom in current package */ 3235f14f4646Smrg atom = LispDoGetAtom(ATOMID(symbol)->value, 0); 32365dfecf96Smrg /* Need to create a copy because if anything new is atached to the 32375dfecf96Smrg * property, the current package is the owner, not the previous one. */ 32385dfecf96Smrg 32395dfecf96Smrg /* And reference the same properties */ 32405dfecf96Smrg atom->property = symbol->data.atom->property; 32415dfecf96Smrg 32425dfecf96Smrg increment = 1; 32435dfecf96Smrg } 32445dfecf96Smrg else if (current->data.atom->property != symbol->data.atom->property) { 32455dfecf96Smrg /* Symbol already exists in the current package, 32465dfecf96Smrg * but does not reference the same variable */ 32475dfecf96Smrg LispContinuable("Symbol %s already defined in package %s. Redefine?", 3248f14f4646Smrg ATOMID(symbol)->value, THESTR(PACKAGE->data.package.name)); 32495dfecf96Smrg 32505dfecf96Smrg atom = current->data.atom; 32515dfecf96Smrg 32525dfecf96Smrg /* Continued from error, redefine variable */ 32535dfecf96Smrg LispDecrementAtomReference(atom); 32545dfecf96Smrg atom->property = symbol->data.atom->property; 32555dfecf96Smrg 32565dfecf96Smrg atom->a_object = atom->a_function = atom->a_builtin = 32575dfecf96Smrg atom->a_property = atom->a_defsetf = atom->a_defstruct = 0; 32585dfecf96Smrg 32595dfecf96Smrg increment = 1; 32605dfecf96Smrg } 32615dfecf96Smrg else { 32625dfecf96Smrg /* Symbol is already available in the current package, just update */ 32635dfecf96Smrg atom = current->data.atom; 32645dfecf96Smrg 32655dfecf96Smrg increment = 0; 32665dfecf96Smrg } 32675dfecf96Smrg 32685dfecf96Smrg /* If importing an important system variable */ 32695dfecf96Smrg atom->watch = symbol->data.atom->watch; 32705dfecf96Smrg 32715dfecf96Smrg /* Update constant flag */ 32725dfecf96Smrg atom->constant = symbol->data.atom->constant; 32735dfecf96Smrg 32745dfecf96Smrg /* Set home-package and unique-atom associated with symbol */ 32755dfecf96Smrg atom->package = symbol->data.atom->package; 32765dfecf96Smrg atom->object = symbol->data.atom->object; 32775dfecf96Smrg 32785dfecf96Smrg if (symbol->data.atom->a_object) 32795dfecf96Smrg atom->a_object = 1; 32805dfecf96Smrg if (symbol->data.atom->a_function) 32815dfecf96Smrg atom->a_function = 1; 32825dfecf96Smrg else if (symbol->data.atom->a_builtin) 32835dfecf96Smrg atom->a_builtin = 1; 32845dfecf96Smrg else if (symbol->data.atom->a_compiled) 32855dfecf96Smrg atom->a_compiled = 1; 32865dfecf96Smrg if (symbol->data.atom->a_property) 32875dfecf96Smrg atom->a_property = 1; 32885dfecf96Smrg if (symbol->data.atom->a_defsetf) 32895dfecf96Smrg atom->a_defsetf = 1; 32905dfecf96Smrg if (symbol->data.atom->a_defstruct) 32915dfecf96Smrg atom->a_defstruct = 1; 32925dfecf96Smrg 32935dfecf96Smrg if (increment) 32945dfecf96Smrg /* Increase reference count, more than one package using the symbol */ 32955dfecf96Smrg LispIncrementAtomReference(symbol->data.atom); 32965dfecf96Smrg} 32975dfecf96Smrg 32985dfecf96Smrg/* symbol must be of type LispAtom_t */ 32995dfecf96Smrgvoid 33005dfecf96SmrgLispExportSymbol(LispObj *symbol) 33015dfecf96Smrg{ 33025dfecf96Smrg /* This does not automatically export symbols to another package using 33035dfecf96Smrg * the symbols of the current package */ 33045dfecf96Smrg symbol->data.atom->ext = 1; 33055dfecf96Smrg} 33065dfecf96Smrg 33075dfecf96Smrg#ifdef __GNUC__ 33085dfecf96SmrgLispObj * 33095dfecf96SmrgLispGetVar(LispObj *atom) 33105dfecf96Smrg{ 33115dfecf96Smrg return (LispDoGetVar(atom)); 33125dfecf96Smrg} 33135dfecf96Smrg 33145dfecf96Smrgstatic INLINE LispObj * 33155dfecf96SmrgLispDoGetVar(LispObj *atom) 33165dfecf96Smrg#else 33175dfecf96Smrg#define LispDoGetVar LispGetVar 33185dfecf96SmrgLispObj * 33195dfecf96SmrgLispGetVar(LispObj *atom) 33205dfecf96Smrg#endif 33215dfecf96Smrg{ 33225dfecf96Smrg LispAtom *name; 33235dfecf96Smrg int i, base, offset; 33245dfecf96Smrg Atom_id id; 33255dfecf96Smrg 33265dfecf96Smrg name = atom->data.atom; 33275dfecf96Smrg if (name->constant && name->package == lisp__data.keyword) 33285dfecf96Smrg return (atom); 33295dfecf96Smrg 33305dfecf96Smrg /* XXX offset should be stored elsewhere, it is unique, like the string 33315dfecf96Smrg * pointer. Unless a multi-thread interface is implemented (where 33325dfecf96Smrg * multiple stacks would be required, the offset value should be 33335dfecf96Smrg * stored with the string, so that a few cpu cicles could be saved 33345dfecf96Smrg * by initializing the value to -1, and only searching for the symbol 33355dfecf96Smrg * binding if it is not -1, and if no binding is found, because the 33365dfecf96Smrg * lexical scope was left, reset offset to -1. */ 33375dfecf96Smrg offset = name->offset; 3338f14f4646Smrg id = name->key; 33395dfecf96Smrg base = lisp__data.env.lex; 33405dfecf96Smrg i = lisp__data.env.head - 1; 33415dfecf96Smrg 33425dfecf96Smrg if (offset <= i && (offset >= base || name->dyn) && 33435dfecf96Smrg lisp__data.env.names[offset] == id) 33445dfecf96Smrg return (lisp__data.env.values[offset]); 33455dfecf96Smrg 33465dfecf96Smrg for (; i >= base; i--) 33475dfecf96Smrg if (lisp__data.env.names[i] == id) { 33485dfecf96Smrg name->offset = i; 33495dfecf96Smrg 33505dfecf96Smrg return (lisp__data.env.values[i]); 33515dfecf96Smrg } 33525dfecf96Smrg 33535dfecf96Smrg if (name->dyn) { 33545dfecf96Smrg /* Keep searching as maybe a rebound dynamic variable */ 33555dfecf96Smrg for (; i >= 0; i--) 33565dfecf96Smrg if (lisp__data.env.names[i] == id) { 33575dfecf96Smrg name->offset = i; 33585dfecf96Smrg 33595dfecf96Smrg return (lisp__data.env.values[i]); 33605dfecf96Smrg } 33615dfecf96Smrg 33625dfecf96Smrg if (name->a_object) { 33635dfecf96Smrg /* Check for a symbol defined as special, but not yet bound. */ 33645dfecf96Smrg if (name->property->value == UNBOUND) 33655dfecf96Smrg return (NULL); 33665dfecf96Smrg 33675dfecf96Smrg return (name->property->value); 33685dfecf96Smrg } 33695dfecf96Smrg } 33705dfecf96Smrg 33715dfecf96Smrg return (name->a_object ? name->property->value : NULL); 33725dfecf96Smrg} 33735dfecf96Smrg 33745dfecf96Smrg#ifdef DEBUGGER 33755dfecf96Smrg/* Same code as LispDoGetVar, but returns the address of the pointer to 33765dfecf96Smrg * the object value. Used only by the debugger */ 33775dfecf96Smrgvoid * 33785dfecf96SmrgLispGetVarAddr(LispObj *atom) 33795dfecf96Smrg{ 33805dfecf96Smrg LispAtom *name; 33815dfecf96Smrg int i, base; 33825dfecf96Smrg Atom_id id; 33835dfecf96Smrg 33845dfecf96Smrg name = atom->data.atom; 33855dfecf96Smrg if (name->constant && name->package == lisp__data.keyword) 33865dfecf96Smrg return (&atom); 33875dfecf96Smrg 33885dfecf96Smrg id = name->string; 33895dfecf96Smrg 33905dfecf96Smrg i = lisp__data.env.head - 1; 33915dfecf96Smrg for (base = lisp__data.env.lex; i >= base; i--) 33925dfecf96Smrg if (lisp__data.env.names[i] == id) 33935dfecf96Smrg return (&(lisp__data.env.values[i])); 33945dfecf96Smrg 33955dfecf96Smrg if (name->dyn) { 33965dfecf96Smrg for (; i >= 0; i--) 33975dfecf96Smrg if (lisp__data.env.names[i] == id) 33985dfecf96Smrg return (&(lisp__data.env.values[i])); 33995dfecf96Smrg 34005dfecf96Smrg if (name->a_object) { 34015dfecf96Smrg /* Check for a symbol defined as special, but not yet bound */ 34025dfecf96Smrg if (name->property->value == UNBOUND) 34035dfecf96Smrg return (NULL); 34045dfecf96Smrg 34055dfecf96Smrg return (&(name->property->value)); 34065dfecf96Smrg } 34075dfecf96Smrg } 34085dfecf96Smrg 34095dfecf96Smrg return (name->a_object ? &(name->property->value) : NULL); 34105dfecf96Smrg} 34115dfecf96Smrg#endif 34125dfecf96Smrg 34135dfecf96Smrg/* Only removes global variables. To be called by makunbound 34145dfecf96Smrg * Local variables are unbounded once their block is closed anyway. 34155dfecf96Smrg */ 34165dfecf96Smrgvoid 34175dfecf96SmrgLispUnsetVar(LispObj *atom) 34185dfecf96Smrg{ 34195dfecf96Smrg LispAtom *name = atom->data.atom; 34205dfecf96Smrg 34215dfecf96Smrg if (name->package) { 34225dfecf96Smrg int i; 34235dfecf96Smrg LispPackage *pack = name->package->data.package.package; 34245dfecf96Smrg 34255dfecf96Smrg for (i = pack->glb.length - 1; i > 0; i--) 34265dfecf96Smrg if (pack->glb.pairs[i] == atom) { 34275dfecf96Smrg LispRemAtomObjectProperty(name); 34285dfecf96Smrg --pack->glb.length; 34295dfecf96Smrg if (i < pack->glb.length) 34305dfecf96Smrg memmove(pack->glb.pairs + i, pack->glb.pairs + i + 1, 34315dfecf96Smrg sizeof(LispObj*) * (pack->glb.length - i)); 34325dfecf96Smrg 34335dfecf96Smrg /* unset hint about dynamically binded variable */ 34345dfecf96Smrg if (name->dyn) 34355dfecf96Smrg name->dyn = 0; 34365dfecf96Smrg break; 34375dfecf96Smrg } 34385dfecf96Smrg } 34395dfecf96Smrg} 34405dfecf96Smrg 34415dfecf96SmrgLispObj * 34425dfecf96SmrgLispAddVar(LispObj *atom, LispObj *obj) 34435dfecf96Smrg{ 34445dfecf96Smrg if (lisp__data.env.length >= lisp__data.env.space) 34455dfecf96Smrg LispMoreEnvironment(); 34465dfecf96Smrg 34475dfecf96Smrg LispDoAddVar(atom, obj); 34485dfecf96Smrg 34495dfecf96Smrg return (obj); 34505dfecf96Smrg} 34515dfecf96Smrg 34525dfecf96Smrgstatic INLINE void 34535dfecf96SmrgLispDoAddVar(LispObj *symbol, LispObj *value) 34545dfecf96Smrg{ 34555dfecf96Smrg LispAtom *atom = symbol->data.atom; 34565dfecf96Smrg 34575dfecf96Smrg atom->offset = lisp__data.env.length; 34585dfecf96Smrg lisp__data.env.values[lisp__data.env.length] = value; 3459f14f4646Smrg lisp__data.env.names[lisp__data.env.length++] = atom->key; 34605dfecf96Smrg} 34615dfecf96Smrg 34625dfecf96SmrgLispObj * 34635dfecf96SmrgLispSetVar(LispObj *atom, LispObj *obj) 34645dfecf96Smrg{ 34655dfecf96Smrg LispPackage *pack; 34665dfecf96Smrg LispAtom *name; 34675dfecf96Smrg int i, base, offset; 34685dfecf96Smrg Atom_id id; 34695dfecf96Smrg 34705dfecf96Smrg name = atom->data.atom; 34715dfecf96Smrg offset = name->offset; 3472f14f4646Smrg id = name->key; 34735dfecf96Smrg base = lisp__data.env.lex; 34745dfecf96Smrg i = lisp__data.env.head - 1; 34755dfecf96Smrg 34765dfecf96Smrg if (offset <= i && (offset >= base || name->dyn) && 34775dfecf96Smrg lisp__data.env.names[offset] == id) 34785dfecf96Smrg return (lisp__data.env.values[offset] = obj); 34795dfecf96Smrg 34805dfecf96Smrg for (; i >= base; i--) 34815dfecf96Smrg if (lisp__data.env.names[i] == id) { 34825dfecf96Smrg name->offset = i; 34835dfecf96Smrg 34845dfecf96Smrg return (lisp__data.env.values[i] = obj); 34855dfecf96Smrg } 34865dfecf96Smrg 34875dfecf96Smrg if (name->dyn) { 34885dfecf96Smrg for (; i >= 0; i--) 34895dfecf96Smrg if (lisp__data.env.names[i] == id) 34905dfecf96Smrg return (lisp__data.env.values[i] = obj); 34915dfecf96Smrg 34925dfecf96Smrg if (name->watch) { 34935dfecf96Smrg LispSetAtomObjectProperty(name, obj); 34945dfecf96Smrg 34955dfecf96Smrg return (obj); 34965dfecf96Smrg } 34975dfecf96Smrg 34985dfecf96Smrg return (SETVALUE(name, obj)); 34995dfecf96Smrg } 35005dfecf96Smrg 35015dfecf96Smrg if (name->a_object) { 35025dfecf96Smrg if (name->watch) { 35035dfecf96Smrg LispSetAtomObjectProperty(name, obj); 35045dfecf96Smrg 35055dfecf96Smrg return (obj); 35065dfecf96Smrg } 35075dfecf96Smrg 35085dfecf96Smrg return (SETVALUE(name, obj)); 35095dfecf96Smrg } 35105dfecf96Smrg 35115dfecf96Smrg LispSetAtomObjectProperty(name, obj); 35125dfecf96Smrg 35135dfecf96Smrg pack = name->package->data.package.package; 35145dfecf96Smrg if (pack->glb.length >= pack->glb.space) 35155dfecf96Smrg LispMoreGlobals(pack); 35165dfecf96Smrg 35175dfecf96Smrg pack->glb.pairs[pack->glb.length++] = atom; 35185dfecf96Smrg 35195dfecf96Smrg return (obj); 35205dfecf96Smrg} 35215dfecf96Smrg 35225dfecf96Smrgvoid 35235dfecf96SmrgLispProclaimSpecial(LispObj *atom, LispObj *value, LispObj *doc) 35245dfecf96Smrg{ 35255dfecf96Smrg int i = 0, dyn, glb; 35265dfecf96Smrg LispAtom *name; 35275dfecf96Smrg LispPackage *pack; 35285dfecf96Smrg 35295dfecf96Smrg glb = 0; 35305dfecf96Smrg name = atom->data.atom; 35315dfecf96Smrg pack = name->package->data.package.package; 35325dfecf96Smrg dyn = name->dyn; 35335dfecf96Smrg 35345dfecf96Smrg if (!dyn) { 35355dfecf96Smrg /* Note: don't check if a local variable already is using the symbol */ 35365dfecf96Smrg for (i = pack->glb.length - 1; i >= 0; i--) 35375dfecf96Smrg if (pack->glb.pairs[i] == atom) { 35385dfecf96Smrg glb = 1; 35395dfecf96Smrg break; 35405dfecf96Smrg } 35415dfecf96Smrg } 35425dfecf96Smrg 35435dfecf96Smrg if (dyn) { 35445dfecf96Smrg if (name->property->value == UNBOUND && value) 35455dfecf96Smrg /* if variable was just made special, but not bounded */ 35465dfecf96Smrg LispSetAtomObjectProperty(name, value); 35475dfecf96Smrg } 35485dfecf96Smrg else if (glb) 35495dfecf96Smrg /* Already a global variable, but not marked as special. 35505dfecf96Smrg * Set hint about dynamically binded variable. */ 35515dfecf96Smrg name->dyn = 1; 35525dfecf96Smrg else { 35535dfecf96Smrg /* create new special variable */ 35545dfecf96Smrg LispSetAtomObjectProperty(name, value ? value : UNBOUND); 35555dfecf96Smrg 35565dfecf96Smrg if (pack->glb.length >= pack->glb.space) 35575dfecf96Smrg LispMoreGlobals(pack); 35585dfecf96Smrg 35595dfecf96Smrg pack->glb.pairs[pack->glb.length] = atom; 35605dfecf96Smrg ++pack->glb.length; 35615dfecf96Smrg /* set hint about possibly dynamically binded variable */ 35625dfecf96Smrg name->dyn = 1; 35635dfecf96Smrg } 35645dfecf96Smrg 35655dfecf96Smrg if (doc != NIL) 35665dfecf96Smrg LispAddDocumentation(atom, doc, LispDocVariable); 35675dfecf96Smrg} 35685dfecf96Smrg 35695dfecf96Smrgvoid 35705dfecf96SmrgLispDefconstant(LispObj *atom, LispObj *value, LispObj *doc) 35715dfecf96Smrg{ 35725dfecf96Smrg int i; 35735dfecf96Smrg LispAtom *name = atom->data.atom; 35745dfecf96Smrg LispPackage *pack = name->package->data.package.package; 35755dfecf96Smrg 35765dfecf96Smrg /* Unset hint about dynamically binded variable, if set. */ 35775dfecf96Smrg name->dyn = 0; 35785dfecf96Smrg 35795dfecf96Smrg /* Check if variable is bounded as a global variable */ 35805dfecf96Smrg for (i = pack->glb.length - 1; i >= 0; i--) 35815dfecf96Smrg if (pack->glb.pairs[i] == atom) 35825dfecf96Smrg break; 35835dfecf96Smrg 35845dfecf96Smrg if (i < 0) { 35855dfecf96Smrg /* Not a global variable */ 35865dfecf96Smrg if (pack->glb.length >= pack->glb.space) 35875dfecf96Smrg LispMoreGlobals(pack); 35885dfecf96Smrg 35895dfecf96Smrg pack->glb.pairs[pack->glb.length] = atom; 35905dfecf96Smrg ++pack->glb.length; 35915dfecf96Smrg } 35925dfecf96Smrg 35935dfecf96Smrg /* If already a constant variable */ 35945dfecf96Smrg if (name->constant && name->a_object && name->property->value != value) 35955dfecf96Smrg LispWarning("constant %s is being redefined", STROBJ(atom)); 35965dfecf96Smrg else 35975dfecf96Smrg name->constant = 1; 35985dfecf96Smrg 35995dfecf96Smrg /* Set constant value */ 36005dfecf96Smrg LispSetAtomObjectProperty(name, value); 36015dfecf96Smrg 36025dfecf96Smrg if (doc != NIL) 36035dfecf96Smrg LispAddDocumentation(atom, doc, LispDocVariable); 36045dfecf96Smrg} 36055dfecf96Smrg 36065dfecf96Smrgvoid 36075dfecf96SmrgLispAddDocumentation(LispObj *symbol, LispObj *documentation, LispDocType_t type) 36085dfecf96Smrg{ 36095dfecf96Smrg int length; 36105dfecf96Smrg char *string; 36115dfecf96Smrg LispAtom *atom; 36125dfecf96Smrg LispObj *object; 36135dfecf96Smrg 36145dfecf96Smrg if (!SYMBOLP(symbol) || !STRINGP(documentation)) 36155dfecf96Smrg LispDestroy("DOCUMENTATION: invalid argument"); 36165dfecf96Smrg 36175dfecf96Smrg atom = symbol->data.atom; 36185dfecf96Smrg if (atom->documentation[type]) 36195dfecf96Smrg LispRemDocumentation(symbol, type); 36205dfecf96Smrg 36215dfecf96Smrg /* allocate documentation in atomseg */ 36225dfecf96Smrg if (atomseg.freeobj == NIL) 36235dfecf96Smrg LispAllocSeg(&atomseg, pagesize); 36245dfecf96Smrg length = STRLEN(documentation); 36255dfecf96Smrg string = LispMalloc(length); 36265dfecf96Smrg memcpy(string, THESTR(documentation), length); 36275dfecf96Smrg string[length] = '\0'; 36285dfecf96Smrg object = atomseg.freeobj; 36295dfecf96Smrg atomseg.freeobj = CDR(object); 36305dfecf96Smrg --atomseg.nfree; 36315dfecf96Smrg 36325dfecf96Smrg object->type = LispString_t; 36335dfecf96Smrg THESTR(object) = string; 36345dfecf96Smrg STRLEN(object) = length; 36355dfecf96Smrg object->data.string.writable = 0; 36365dfecf96Smrg atom->documentation[type] = object; 36375dfecf96Smrg LispMused(string); 36385dfecf96Smrg} 36395dfecf96Smrg 36405dfecf96Smrgvoid 36415dfecf96SmrgLispRemDocumentation(LispObj *symbol, LispDocType_t type) 36425dfecf96Smrg{ 36435dfecf96Smrg LispAtom *atom; 36445dfecf96Smrg 36455dfecf96Smrg if (!SYMBOLP(symbol)) 36465dfecf96Smrg LispDestroy("DOCUMENTATION: invalid argument"); 36475dfecf96Smrg 36485dfecf96Smrg atom = symbol->data.atom; 36495dfecf96Smrg if (atom->documentation[type]) { 36505dfecf96Smrg /* reclaim object to atomseg */ 36515dfecf96Smrg free(THESTR(atom->documentation[type])); 36525dfecf96Smrg CDR(atom->documentation[type]) = atomseg.freeobj; 36535dfecf96Smrg atomseg.freeobj = atom->documentation[type]; 36545dfecf96Smrg atom->documentation[type] = NULL; 36555dfecf96Smrg ++atomseg.nfree; 36565dfecf96Smrg } 36575dfecf96Smrg} 36585dfecf96Smrg 36595dfecf96SmrgLispObj * 36605dfecf96SmrgLispGetDocumentation(LispObj *symbol, LispDocType_t type) 36615dfecf96Smrg{ 36625dfecf96Smrg LispAtom *atom; 36635dfecf96Smrg 36645dfecf96Smrg if (!SYMBOLP(symbol)) 36655dfecf96Smrg LispDestroy("DOCUMENTATION: invalid argument"); 36665dfecf96Smrg 36675dfecf96Smrg atom = symbol->data.atom; 36685dfecf96Smrg 36695dfecf96Smrg return (atom->documentation[type] ? atom->documentation[type] : NIL); 36705dfecf96Smrg} 36715dfecf96Smrg 36725dfecf96SmrgLispObj * 36735dfecf96SmrgLispReverse(LispObj *list) 36745dfecf96Smrg{ 36755dfecf96Smrg LispObj *tmp, *res = NIL; 36765dfecf96Smrg 36775dfecf96Smrg while (list != NIL) { 36785dfecf96Smrg tmp = CDR(list); 36795dfecf96Smrg CDR(list) = res; 36805dfecf96Smrg res = list; 36815dfecf96Smrg list = tmp; 36825dfecf96Smrg } 36835dfecf96Smrg 36845dfecf96Smrg return (res); 36855dfecf96Smrg} 36865dfecf96Smrg 36875dfecf96SmrgLispBlock * 36885dfecf96SmrgLispBeginBlock(LispObj *tag, LispBlockType type) 36895dfecf96Smrg{ 36905dfecf96Smrg LispBlock *block; 36915dfecf96Smrg unsigned blevel = lisp__data.block.block_level + 1; 36925dfecf96Smrg 36935dfecf96Smrg if (blevel > lisp__data.block.block_size) { 36945dfecf96Smrg LispBlock **blk; 36955dfecf96Smrg 36965dfecf96Smrg if (blevel > MAX_STACK_DEPTH) 36975dfecf96Smrg LispDestroy("stack overflow"); 36985dfecf96Smrg 36995dfecf96Smrg DISABLE_INTERRUPTS(); 37005dfecf96Smrg blk = realloc(lisp__data.block.block, sizeof(LispBlock*) * (blevel + 1)); 37015dfecf96Smrg 37025dfecf96Smrg block = NULL; 37035dfecf96Smrg if (blk == NULL || (block = malloc(sizeof(LispBlock))) == NULL) { 37045dfecf96Smrg ENABLE_INTERRUPTS(); 37055dfecf96Smrg LispDestroy("out of memory"); 37065dfecf96Smrg } 37075dfecf96Smrg lisp__data.block.block = blk; 37085dfecf96Smrg lisp__data.block.block[lisp__data.block.block_size] = block; 37095dfecf96Smrg lisp__data.block.block_size = blevel; 37105dfecf96Smrg ENABLE_INTERRUPTS(); 37115dfecf96Smrg } 37125dfecf96Smrg block = lisp__data.block.block[lisp__data.block.block_level]; 37135dfecf96Smrg if (type == LispBlockCatch && !CONSTANTP(tag)) { 37145dfecf96Smrg tag = EVAL(tag); 37155dfecf96Smrg lisp__data.protect.objects[lisp__data.protect.length++] = tag; 37165dfecf96Smrg } 37175dfecf96Smrg block->type = type; 37185dfecf96Smrg block->tag = tag; 37195dfecf96Smrg block->stack = lisp__data.stack.length; 37205dfecf96Smrg block->protect = lisp__data.protect.length; 37215dfecf96Smrg block->block_level = lisp__data.block.block_level; 37225dfecf96Smrg 37235dfecf96Smrg lisp__data.block.block_level = blevel; 37245dfecf96Smrg 37255dfecf96Smrg#ifdef DEBUGGER 37265dfecf96Smrg if (lisp__data.debugging) { 37275dfecf96Smrg block->debug_level = lisp__data.debug_level; 37285dfecf96Smrg block->debug_step = lisp__data.debug_step; 37295dfecf96Smrg } 37305dfecf96Smrg#endif 37315dfecf96Smrg 37325dfecf96Smrg return (block); 37335dfecf96Smrg} 37345dfecf96Smrg 37355dfecf96Smrgvoid 37365dfecf96SmrgLispEndBlock(LispBlock *block) 37375dfecf96Smrg{ 37385dfecf96Smrg lisp__data.protect.length = block->protect; 37395dfecf96Smrg lisp__data.block.block_level = block->block_level; 37405dfecf96Smrg 37415dfecf96Smrg#ifdef DEBUGGER 37425dfecf96Smrg if (lisp__data.debugging) { 37435dfecf96Smrg if (lisp__data.debug_level >= block->debug_level) { 37445dfecf96Smrg while (lisp__data.debug_level > block->debug_level) { 37455dfecf96Smrg DBG = CDR(DBG); 37465dfecf96Smrg --lisp__data.debug_level; 37475dfecf96Smrg } 37485dfecf96Smrg } 37495dfecf96Smrg lisp__data.debug_step = block->debug_step; 37505dfecf96Smrg } 37515dfecf96Smrg#endif 37525dfecf96Smrg} 37535dfecf96Smrg 37545dfecf96Smrgvoid 37555dfecf96SmrgLispBlockUnwind(LispBlock *block) 37565dfecf96Smrg{ 37575dfecf96Smrg LispBlock *unwind; 37585dfecf96Smrg int blevel = lisp__data.block.block_level; 37595dfecf96Smrg 37605dfecf96Smrg while (blevel > 0) { 37615dfecf96Smrg unwind = lisp__data.block.block[--blevel]; 37625dfecf96Smrg if (unwind->type == LispBlockProtect) { 37635dfecf96Smrg BLOCKJUMP(unwind); 37645dfecf96Smrg } 37655dfecf96Smrg if (unwind == block) 37665dfecf96Smrg /* jump above unwind block */ 37675dfecf96Smrg break; 37685dfecf96Smrg } 37695dfecf96Smrg} 37705dfecf96Smrg 37715dfecf96Smrgstatic LispObj * 37725dfecf96SmrgLispEvalBackquoteObject(LispObj *argument, int list, int quote) 37735dfecf96Smrg{ 37745dfecf96Smrg LispObj *result = argument, *object; 37755dfecf96Smrg 37765dfecf96Smrg if (!POINTERP(argument)) 37775dfecf96Smrg return (argument); 37785dfecf96Smrg 37795dfecf96Smrg else if (XCOMMAP(argument)) { 37805dfecf96Smrg /* argument may need to be evaluated */ 37815dfecf96Smrg 37825dfecf96Smrg int atlist; 37835dfecf96Smrg 37845dfecf96Smrg if (!list && argument->data.comma.atlist) 37855dfecf96Smrg /* cannot append, not in a list */ 37865dfecf96Smrg LispDestroy("EVAL: ,@ only allowed on lists"); 37875dfecf96Smrg 37885dfecf96Smrg --quote; 37895dfecf96Smrg if (quote < 0) 37905dfecf96Smrg LispDestroy("EVAL: comma outside of backquote"); 37915dfecf96Smrg 37925dfecf96Smrg result = object = argument->data.comma.eval; 37935dfecf96Smrg atlist = COMMAP(object) && object->data.comma.atlist; 37945dfecf96Smrg 37955dfecf96Smrg if (POINTERP(result) && (XCOMMAP(result) || XBACKQUOTEP(result))) 37965dfecf96Smrg /* nested commas, reduce 1 level, or backquote, 37975dfecf96Smrg * don't call LispEval or quote argument will be reset */ 37985dfecf96Smrg result = LispEvalBackquoteObject(object, 0, quote); 37995dfecf96Smrg 38005dfecf96Smrg else if (quote == 0) 38015dfecf96Smrg /* just evaluate it */ 38025dfecf96Smrg result = EVAL(result); 38035dfecf96Smrg 38045dfecf96Smrg if (quote != 0) 38055dfecf96Smrg result = result == object ? argument : COMMA(result, atlist); 38065dfecf96Smrg } 38075dfecf96Smrg 38085dfecf96Smrg else if (XBACKQUOTEP(argument)) { 38095dfecf96Smrg object = argument->data.quote; 38105dfecf96Smrg 38115dfecf96Smrg result = LispEvalBackquote(object, quote + 1); 38125dfecf96Smrg if (quote) 38135dfecf96Smrg result = result == object ? argument : BACKQUOTE(result); 38145dfecf96Smrg } 38155dfecf96Smrg 38165dfecf96Smrg else if (XQUOTEP(argument) && POINTERP(argument->data.quote) && 38175dfecf96Smrg (XCOMMAP(argument->data.quote) || 38185dfecf96Smrg XBACKQUOTEP(argument->data.quote) || 38195dfecf96Smrg XCONSP(argument->data.quote))) { 38205dfecf96Smrg /* ensures `',sym to be the same as `(quote ,sym) */ 38215dfecf96Smrg object = argument->data.quote; 38225dfecf96Smrg 38235dfecf96Smrg result = LispEvalBackquote(argument->data.quote, quote); 38245dfecf96Smrg result = result == object ? argument : QUOTE(result); 38255dfecf96Smrg } 38265dfecf96Smrg 38275dfecf96Smrg return (result); 38285dfecf96Smrg} 38295dfecf96Smrg 38305dfecf96SmrgLispObj * 38315dfecf96SmrgLispEvalBackquote(LispObj *argument, int quote) 38325dfecf96Smrg{ 38335dfecf96Smrg int protect; 38345dfecf96Smrg LispObj *result, *object, *cons, *cdr; 38355dfecf96Smrg 38365dfecf96Smrg if (!CONSP(argument)) 38375dfecf96Smrg return (LispEvalBackquoteObject(argument, 0, quote)); 38385dfecf96Smrg 38395dfecf96Smrg result = cdr = NIL; 38405dfecf96Smrg protect = lisp__data.protect.length; 38415dfecf96Smrg 38425dfecf96Smrg /* always generate a new list for the result, even if nothing 38435dfecf96Smrg * is evaluated. It is not expected to use backqoutes when 38445dfecf96Smrg * not required. */ 38455dfecf96Smrg 38465dfecf96Smrg /* reserve a GC protected slot for the result */ 38475dfecf96Smrg if (protect + 1 >= lisp__data.protect.space) 38485dfecf96Smrg LispMoreProtects(); 38495dfecf96Smrg lisp__data.protect.objects[lisp__data.protect.length++] = NIL; 38505dfecf96Smrg 38515dfecf96Smrg for (cons = argument; ; cons = CDR(cons)) { 38525dfecf96Smrg /* if false, last argument, and if cons is not NIL, a dotted list */ 38535dfecf96Smrg int list = CONSP(cons), insert; 38545dfecf96Smrg 38555dfecf96Smrg if (list) 38565dfecf96Smrg object = CAR(cons); 38575dfecf96Smrg else 38585dfecf96Smrg object = cons; 38595dfecf96Smrg 38605dfecf96Smrg if (COMMAP(object)) 38615dfecf96Smrg /* need to insert list elements in result, not just cons it? */ 38625dfecf96Smrg insert = object->data.comma.atlist; 38635dfecf96Smrg else 38645dfecf96Smrg insert = 0; 38655dfecf96Smrg 38665dfecf96Smrg /* evaluate object, if required */ 38675dfecf96Smrg if (CONSP(object)) 38685dfecf96Smrg object = LispEvalBackquote(object, quote); 38695dfecf96Smrg else 38705dfecf96Smrg object = LispEvalBackquoteObject(object, insert, quote); 38715dfecf96Smrg 38725dfecf96Smrg if (result == NIL) { 38735dfecf96Smrg /* if starting result list */ 38745dfecf96Smrg if (!insert) { 38755dfecf96Smrg if (list) 38765dfecf96Smrg result = cdr = CONS(object, NIL); 38775dfecf96Smrg else 38785dfecf96Smrg result = cdr = object; 38795dfecf96Smrg /* gc protect result */ 38805dfecf96Smrg lisp__data.protect.objects[protect] = result; 38815dfecf96Smrg } 38825dfecf96Smrg else { 38835dfecf96Smrg if (!CONSP(object)) { 38845dfecf96Smrg result = cdr = object; 38855dfecf96Smrg /* gc protect result */ 38865dfecf96Smrg lisp__data.protect.objects[protect] = result; 38875dfecf96Smrg } 38885dfecf96Smrg else { 38895dfecf96Smrg result = cdr = CONS(CAR(object), NIL); 38905dfecf96Smrg /* gc protect result */ 38915dfecf96Smrg lisp__data.protect.objects[protect] = result; 38925dfecf96Smrg 38935dfecf96Smrg /* add remaining elements to result */ 38945dfecf96Smrg for (object = CDR(object); 38955dfecf96Smrg CONSP(object); 38965dfecf96Smrg object = CDR(object)) { 38975dfecf96Smrg RPLACD(cdr, CONS(CAR(object), NIL)); 38985dfecf96Smrg cdr = CDR(cdr); 38995dfecf96Smrg } 39005dfecf96Smrg if (object != NIL) { 39015dfecf96Smrg /* object was a dotted list */ 39025dfecf96Smrg RPLACD(cdr, object); 39035dfecf96Smrg cdr = CDR(cdr); 39045dfecf96Smrg } 39055dfecf96Smrg } 39065dfecf96Smrg } 39075dfecf96Smrg } 39085dfecf96Smrg else { 39095dfecf96Smrg if (!CONSP(cdr)) 39105dfecf96Smrg LispDestroy("EVAL: cannot append to %s", STROBJ(cdr)); 39115dfecf96Smrg 39125dfecf96Smrg if (!insert) { 39135dfecf96Smrg if (list) { 39145dfecf96Smrg RPLACD(cdr, CONS(object, NIL)); 39155dfecf96Smrg cdr = CDR(cdr); 39165dfecf96Smrg } 39175dfecf96Smrg else { 39185dfecf96Smrg RPLACD(cdr, object); 39195dfecf96Smrg cdr = object; 39205dfecf96Smrg } 39215dfecf96Smrg } 39225dfecf96Smrg else { 39235dfecf96Smrg if (!CONSP(object)) { 39245dfecf96Smrg RPLACD(cdr, object); 39255dfecf96Smrg /* if object is NIL, it is a empty list appended, not 39265dfecf96Smrg * creating a dotted list. */ 39275dfecf96Smrg if (object != NIL) 39285dfecf96Smrg cdr = object; 39295dfecf96Smrg } 39305dfecf96Smrg else { 39315dfecf96Smrg for (; CONSP(object); object = CDR(object)) { 39325dfecf96Smrg RPLACD(cdr, CONS(CAR(object), NIL)); 39335dfecf96Smrg cdr = CDR(cdr); 39345dfecf96Smrg } 39355dfecf96Smrg if (object != NIL) { 39365dfecf96Smrg /* object was a dotted list */ 39375dfecf96Smrg RPLACD(cdr, object); 39385dfecf96Smrg cdr = CDR(cdr); 39395dfecf96Smrg } 39405dfecf96Smrg } 39415dfecf96Smrg } 39425dfecf96Smrg } 39435dfecf96Smrg 39445dfecf96Smrg /* if last argument list element processed */ 39455dfecf96Smrg if (!list) 39465dfecf96Smrg break; 39475dfecf96Smrg } 39485dfecf96Smrg 39495dfecf96Smrg lisp__data.protect.length = protect; 39505dfecf96Smrg 39515dfecf96Smrg return (result); 39525dfecf96Smrg} 39535dfecf96Smrg 39545dfecf96Smrgvoid 39555dfecf96SmrgLispMoreEnvironment(void) 39565dfecf96Smrg{ 39575dfecf96Smrg Atom_id *names; 39585dfecf96Smrg LispObj **values; 39595dfecf96Smrg 39605dfecf96Smrg DISABLE_INTERRUPTS(); 39615dfecf96Smrg names = realloc(lisp__data.env.names, 39625dfecf96Smrg (lisp__data.env.space + 256) * sizeof(Atom_id)); 39635dfecf96Smrg if (names != NULL) { 39645dfecf96Smrg values = realloc(lisp__data.env.values, 39655dfecf96Smrg (lisp__data.env.space + 256) * sizeof(LispObj*)); 39665dfecf96Smrg if (values != NULL) { 39675dfecf96Smrg lisp__data.env.names = names; 39685dfecf96Smrg lisp__data.env.values = values; 39695dfecf96Smrg lisp__data.env.space += 256; 39705dfecf96Smrg ENABLE_INTERRUPTS(); 39715dfecf96Smrg return; 39725dfecf96Smrg } 39735dfecf96Smrg else 39745dfecf96Smrg free(names); 39755dfecf96Smrg } 39765dfecf96Smrg ENABLE_INTERRUPTS(); 39775dfecf96Smrg LispDestroy("out of memory"); 39785dfecf96Smrg} 39795dfecf96Smrg 39805dfecf96Smrgvoid 39815dfecf96SmrgLispMoreStack(void) 39825dfecf96Smrg{ 39835dfecf96Smrg LispObj **values; 39845dfecf96Smrg 39855dfecf96Smrg DISABLE_INTERRUPTS(); 39865dfecf96Smrg values = realloc(lisp__data.stack.values, 39875dfecf96Smrg (lisp__data.stack.space + 256) * sizeof(LispObj*)); 39885dfecf96Smrg if (values == NULL) { 39895dfecf96Smrg ENABLE_INTERRUPTS(); 39905dfecf96Smrg LispDestroy("out of memory"); 39915dfecf96Smrg } 39925dfecf96Smrg lisp__data.stack.values = values; 39935dfecf96Smrg lisp__data.stack.space += 256; 39945dfecf96Smrg ENABLE_INTERRUPTS(); 39955dfecf96Smrg} 39965dfecf96Smrg 39975dfecf96Smrgvoid 39985dfecf96SmrgLispMoreGlobals(LispPackage *pack) 39995dfecf96Smrg{ 40005dfecf96Smrg LispObj **pairs; 40015dfecf96Smrg 40025dfecf96Smrg DISABLE_INTERRUPTS(); 40035dfecf96Smrg pairs = realloc(pack->glb.pairs, 40045dfecf96Smrg (pack->glb.space + 256) * sizeof(LispObj*)); 40055dfecf96Smrg if (pairs == NULL) { 40065dfecf96Smrg ENABLE_INTERRUPTS(); 40075dfecf96Smrg LispDestroy("out of memory"); 40085dfecf96Smrg } 40095dfecf96Smrg pack->glb.pairs = pairs; 40105dfecf96Smrg pack->glb.space += 256; 40115dfecf96Smrg ENABLE_INTERRUPTS(); 40125dfecf96Smrg} 40135dfecf96Smrg 40145dfecf96Smrgvoid 40155dfecf96SmrgLispMoreProtects(void) 40165dfecf96Smrg{ 40175dfecf96Smrg LispObj **objects; 40185dfecf96Smrg 40195dfecf96Smrg DISABLE_INTERRUPTS(); 40205dfecf96Smrg objects = realloc(lisp__data.protect.objects, 40215dfecf96Smrg (lisp__data.protect.space + 256) * sizeof(LispObj*)); 40225dfecf96Smrg if (objects == NULL) { 40235dfecf96Smrg ENABLE_INTERRUPTS(); 40245dfecf96Smrg LispDestroy("out of memory"); 40255dfecf96Smrg } 40265dfecf96Smrg lisp__data.protect.objects = objects; 40275dfecf96Smrg lisp__data.protect.space += 256; 40285dfecf96Smrg ENABLE_INTERRUPTS(); 40295dfecf96Smrg} 40305dfecf96Smrg 40315dfecf96Smrgstatic int 40325dfecf96SmrgLispMakeEnvironment(LispArgList *alist, LispObj *values, 40335dfecf96Smrg LispObj *name, int eval, int builtin) 40345dfecf96Smrg{ 40355dfecf96Smrg char *desc; 40365dfecf96Smrg int i, count, base; 40375dfecf96Smrg LispObj **symbols, **defaults, **sforms; 40385dfecf96Smrg 40395dfecf96Smrg#define BUILTIN_ARGUMENT(value) \ 40405dfecf96Smrg lisp__data.stack.values[lisp__data.stack.length++] = value 40415dfecf96Smrg 40425dfecf96Smrg/* If the index value is from register variables, this 40435dfecf96Smrg * can save some cpu time. Useful for normal arguments 40445dfecf96Smrg * that are the most common, and thus the ones that 40455dfecf96Smrg * consume more time in LispMakeEnvironment. */ 40465dfecf96Smrg#define BUILTIN_NO_EVAL_ARGUMENT(index, value) \ 40475dfecf96Smrg lisp__data.stack.values[index] = value 40485dfecf96Smrg 40495dfecf96Smrg#define NORMAL_ARGUMENT(symbol, value) \ 40505dfecf96Smrg LispDoAddVar(symbol, value) 40515dfecf96Smrg 40525dfecf96Smrg if (builtin) { 40535dfecf96Smrg base = lisp__data.stack.length; 40545dfecf96Smrg if (base + alist->num_arguments > lisp__data.stack.space) { 40555dfecf96Smrg do 40565dfecf96Smrg LispMoreStack(); 40575dfecf96Smrg while (base + alist->num_arguments > lisp__data.stack.space); 40585dfecf96Smrg } 40595dfecf96Smrg } 40605dfecf96Smrg else { 40615dfecf96Smrg base = lisp__data.env.length; 40625dfecf96Smrg if (base + alist->num_arguments > lisp__data.env.space) { 40635dfecf96Smrg do 40645dfecf96Smrg LispMoreEnvironment(); 40655dfecf96Smrg while (base + alist->num_arguments > lisp__data.env.space); 40665dfecf96Smrg } 40675dfecf96Smrg } 40685dfecf96Smrg 40695dfecf96Smrg desc = alist->description; 40705dfecf96Smrg switch (*desc++) { 40715dfecf96Smrg case '.': 40725dfecf96Smrg goto normal_label; 40735dfecf96Smrg case 'o': 40745dfecf96Smrg goto optional_label; 40755dfecf96Smrg case 'k': 40765dfecf96Smrg goto key_label; 40775dfecf96Smrg case 'r': 40785dfecf96Smrg goto rest_label; 40795dfecf96Smrg case 'a': 40805dfecf96Smrg goto aux_label; 40815dfecf96Smrg default: 40825dfecf96Smrg goto done_label; 40835dfecf96Smrg } 40845dfecf96Smrg 40855dfecf96Smrg 40865dfecf96Smrg /* Code below is done in several almost identical loops, to avoid 40875dfecf96Smrg * checking the value of the arguments eval and builtin too much times */ 40885dfecf96Smrg 40895dfecf96Smrg 40905dfecf96Smrg /* Normal arguments */ 40915dfecf96Smrgnormal_label: 40925dfecf96Smrg i = 0; 40935dfecf96Smrg count = alist->normals.num_symbols; 40945dfecf96Smrg if (builtin) { 40955dfecf96Smrg if (eval) { 40965dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) { 40975dfecf96Smrg BUILTIN_ARGUMENT(EVAL(CAR(values))); 40985dfecf96Smrg } 40995dfecf96Smrg } 41005dfecf96Smrg else { 41015dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) { 41025dfecf96Smrg BUILTIN_NO_EVAL_ARGUMENT(base + i, CAR(values)); 41035dfecf96Smrg } 41045dfecf96Smrg /* macro BUILTIN_NO_EVAL_ARGUMENT does not update 41055dfecf96Smrg * lisp__data.stack.length, as there is no risk of GC while 41065dfecf96Smrg * adding the arguments. */ 41075dfecf96Smrg lisp__data.stack.length += i; 41085dfecf96Smrg } 41095dfecf96Smrg } 41105dfecf96Smrg else { 41115dfecf96Smrg symbols = alist->normals.symbols; 41125dfecf96Smrg if (eval) { 41135dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) { 41145dfecf96Smrg NORMAL_ARGUMENT(symbols[i], EVAL(CAR(values))); 41155dfecf96Smrg } 41165dfecf96Smrg } 41175dfecf96Smrg else { 41185dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) { 41195dfecf96Smrg NORMAL_ARGUMENT(symbols[i], CAR(values)); 41205dfecf96Smrg } 41215dfecf96Smrg } 41225dfecf96Smrg } 41235dfecf96Smrg if (i < count) 41245dfecf96Smrg LispDestroy("%s: too few arguments", STROBJ(name)); 41255dfecf96Smrg 41265dfecf96Smrg switch (*desc++) { 41275dfecf96Smrg case 'o': 41285dfecf96Smrg goto optional_label; 41295dfecf96Smrg case 'k': 41305dfecf96Smrg goto key_label; 41315dfecf96Smrg case 'r': 41325dfecf96Smrg goto rest_label; 41335dfecf96Smrg case 'a': 41345dfecf96Smrg goto aux_label; 41355dfecf96Smrg default: 41365dfecf96Smrg goto done_label; 41375dfecf96Smrg } 41385dfecf96Smrg 41395dfecf96Smrg /* &OPTIONAL */ 41405dfecf96Smrgoptional_label: 41415dfecf96Smrg i = 0; 41425dfecf96Smrg count = alist->optionals.num_symbols; 41435dfecf96Smrg defaults = alist->optionals.defaults; 41445dfecf96Smrg sforms = alist->optionals.sforms; 41455dfecf96Smrg if (builtin) { 41465dfecf96Smrg if (eval) { 41475dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) 41485dfecf96Smrg BUILTIN_ARGUMENT(EVAL(CAR(values))); 41495dfecf96Smrg for (; i < count; i++) 41505dfecf96Smrg BUILTIN_ARGUMENT(UNSPEC); 41515dfecf96Smrg } 41525dfecf96Smrg else { 41535dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) 41545dfecf96Smrg BUILTIN_ARGUMENT(CAR(values)); 41555dfecf96Smrg for (; i < count; i++) 41565dfecf96Smrg BUILTIN_ARGUMENT(UNSPEC); 41575dfecf96Smrg } 41585dfecf96Smrg } 41595dfecf96Smrg else { 41605dfecf96Smrg symbols = alist->optionals.symbols; 41615dfecf96Smrg if (eval) { 41625dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) { 41635dfecf96Smrg NORMAL_ARGUMENT(symbols[i], EVAL(CAR(values))); 41645dfecf96Smrg if (sforms[i]) { 41655dfecf96Smrg NORMAL_ARGUMENT(sforms[i], T); 41665dfecf96Smrg } 41675dfecf96Smrg } 41685dfecf96Smrg } 41695dfecf96Smrg else { 41705dfecf96Smrg for (; i < count && CONSP(values); i++, values = CDR(values)) { 41715dfecf96Smrg NORMAL_ARGUMENT(symbols[i], CAR(values)); 41725dfecf96Smrg if (sforms[i]) { 41735dfecf96Smrg NORMAL_ARGUMENT(sforms[i], T); 41745dfecf96Smrg } 41755dfecf96Smrg } 41765dfecf96Smrg } 41775dfecf96Smrg 41785dfecf96Smrg /* default arguments are evaluated for macros */ 41795dfecf96Smrg for (; i < count; i++) { 41805dfecf96Smrg if (!CONSTANTP(defaults[i])) { 41815dfecf96Smrg int head = lisp__data.env.head; 41825dfecf96Smrg int lex = lisp__data.env.lex; 41835dfecf96Smrg 41845dfecf96Smrg lisp__data.env.lex = base; 41855dfecf96Smrg lisp__data.env.head = lisp__data.env.length; 41865dfecf96Smrg NORMAL_ARGUMENT(symbols[i], EVAL(defaults[i])); 41875dfecf96Smrg lisp__data.env.head = head; 41885dfecf96Smrg lisp__data.env.lex = lex; 41895dfecf96Smrg } 41905dfecf96Smrg else { 41915dfecf96Smrg NORMAL_ARGUMENT(symbols[i], defaults[i]); 41925dfecf96Smrg } 41935dfecf96Smrg if (sforms[i]) { 41945dfecf96Smrg NORMAL_ARGUMENT(sforms[i], NIL); 41955dfecf96Smrg } 41965dfecf96Smrg } 41975dfecf96Smrg } 41985dfecf96Smrg switch (*desc++) { 41995dfecf96Smrg case 'k': 42005dfecf96Smrg goto key_label; 42015dfecf96Smrg case 'r': 42025dfecf96Smrg goto rest_label; 42035dfecf96Smrg case 'a': 42045dfecf96Smrg goto aux_label; 42055dfecf96Smrg default: 42065dfecf96Smrg goto done_label; 42075dfecf96Smrg } 42085dfecf96Smrg 42095dfecf96Smrg /* &KEY */ 42105dfecf96Smrgkey_label: 42115dfecf96Smrg { 42125dfecf96Smrg int argc, nused; 42135dfecf96Smrg LispObj *val, *karg, **keys; 42145dfecf96Smrg 42155dfecf96Smrg /* Count number of remaining arguments */ 42165dfecf96Smrg for (karg = values, argc = 0; CONSP(karg); karg = CDR(karg), argc++) { 42175dfecf96Smrg karg = CDR(karg); 42185dfecf96Smrg if (!CONSP(karg)) 42195dfecf96Smrg LispDestroy("%s: &KEY needs arguments as pairs", 42205dfecf96Smrg STROBJ(name)); 42215dfecf96Smrg } 42225dfecf96Smrg 42235dfecf96Smrg 42245dfecf96Smrg /* OPTIMIZATION: 42255dfecf96Smrg * Builtin functions require that the keyword be in the keyword package. 42265dfecf96Smrg * User functions don't need the arguments being pushed in the stack 42275dfecf96Smrg * in the declared order (bytecode expects it...). 42285dfecf96Smrg * XXX Error checking should be done elsewhere, code may be looping 42295dfecf96Smrg * and doing error check here may consume too much cpu time. 42305dfecf96Smrg * XXX Would also be good to already have the arguments specified in 42315dfecf96Smrg * the correct order. 42325dfecf96Smrg */ 42335dfecf96Smrg 42345dfecf96Smrg 42355dfecf96Smrg nused = 0; 42365dfecf96Smrg val = NIL; 42375dfecf96Smrg count = alist->keys.num_symbols; 42385dfecf96Smrg symbols = alist->keys.symbols; 42395dfecf96Smrg defaults = alist->keys.defaults; 42405dfecf96Smrg sforms = alist->keys.sforms; 42415dfecf96Smrg if (builtin) { 42425dfecf96Smrg 42435dfecf96Smrg /* Arguments must be created in the declared order */ 42445dfecf96Smrg i = 0; 42455dfecf96Smrg if (eval) { 42465dfecf96Smrg for (; i < count; i++) { 42475dfecf96Smrg for (karg = values; CONSP(karg); karg = CDDR(karg)) { 42485dfecf96Smrg /* This is only true if both point to the 42495dfecf96Smrg * same symbol in the keyword package. */ 42505dfecf96Smrg if (symbols[i] == CAR(karg)) { 42515dfecf96Smrg if (karg == values) 42525dfecf96Smrg values = CDDR(values); 42535dfecf96Smrg ++nused; 42545dfecf96Smrg BUILTIN_ARGUMENT(EVAL(CADR(karg))); 42555dfecf96Smrg goto keyword_builtin_eval_used_label; 42565dfecf96Smrg } 42575dfecf96Smrg } 42585dfecf96Smrg BUILTIN_ARGUMENT(UNSPEC); 42595dfecf96Smrgkeyword_builtin_eval_used_label:; 42605dfecf96Smrg } 42615dfecf96Smrg } 42625dfecf96Smrg else { 42635dfecf96Smrg for (; i < count; i++) { 42645dfecf96Smrg for (karg = values; CONSP(karg); karg = CDDR(karg)) { 42655dfecf96Smrg if (symbols[i] == CAR(karg)) { 42665dfecf96Smrg if (karg == values) 42675dfecf96Smrg values = CDDR(values); 42685dfecf96Smrg ++nused; 42695dfecf96Smrg BUILTIN_ARGUMENT(CADR(karg)); 42705dfecf96Smrg goto keyword_builtin_used_label; 42715dfecf96Smrg } 42725dfecf96Smrg } 42735dfecf96Smrg BUILTIN_ARGUMENT(UNSPEC); 42745dfecf96Smrgkeyword_builtin_used_label:; 42755dfecf96Smrg } 42765dfecf96Smrg } 42775dfecf96Smrg 42785dfecf96Smrg if (argc != nused) { 42795dfecf96Smrg /* Argument(s) may be incorrectly specified, or specified 42805dfecf96Smrg * twice (what is not an error). */ 42815dfecf96Smrg for (karg = values; CONSP(karg); karg = CDDR(karg)) { 42825dfecf96Smrg val = CAR(karg); 42835dfecf96Smrg if (KEYWORDP(val)) { 42845dfecf96Smrg for (i = 0; i < count; i++) 42855dfecf96Smrg if (symbols[i] == val) 42865dfecf96Smrg break; 42875dfecf96Smrg } 42885dfecf96Smrg else 42895dfecf96Smrg /* Just make the error test true */ 42905dfecf96Smrg i = count; 42915dfecf96Smrg 42925dfecf96Smrg if (i == count) 42935dfecf96Smrg goto invalid_keyword_label; 42945dfecf96Smrg } 42955dfecf96Smrg } 42965dfecf96Smrg } 42975dfecf96Smrg 42985dfecf96Smrg#if 0 42995dfecf96Smrg else { 43005dfecf96Smrg /* The base offset of the atom in the stack, to check for 43015dfecf96Smrg * keywords specified twice. */ 43025dfecf96Smrg LispObj *symbol; 43035dfecf96Smrg int offset = lisp__data.env.length; 43045dfecf96Smrg 43055dfecf96Smrg keys = alist->keys.keys; 43065dfecf96Smrg for (karg = values; CONSP(karg); karg = CDDR(karg)) { 43075dfecf96Smrg symbol = CAR(karg); 43085dfecf96Smrg if (SYMBOLP(symbol)) { 43095dfecf96Smrg /* Must be a keyword, but even if it is a keyword, may 43105dfecf96Smrg * be a typo, so assume it is correct. If it is not 43115dfecf96Smrg * in the argument list, it is an error. */ 43125dfecf96Smrg for (i = 0; i < count; i++) { 43135dfecf96Smrg if (!keys[i] && symbols[i] == symbol) { 43145dfecf96Smrg LispAtom *atom = symbol->data.atom; 43155dfecf96Smrg 43165dfecf96Smrg /* Symbol found in the argument list. */ 43175dfecf96Smrg if (atom->offset >= offset && 43185dfecf96Smrg atom->offset < offset + nused && 43195dfecf96Smrg lisp__data.env.names[atom->offset] == 43205dfecf96Smrg atom->string) 43215dfecf96Smrg /* Specified more than once... */ 43225dfecf96Smrg goto keyword_duplicated_label; 43235dfecf96Smrg break; 43245dfecf96Smrg } 43255dfecf96Smrg } 43265dfecf96Smrg } 43275dfecf96Smrg else { 43285dfecf96Smrg Atom_id id; 43295dfecf96Smrg 43305dfecf96Smrg if (!QUOTEP(symbol) || !SYMBOLP(val = symbol->data.quote)) { 43315dfecf96Smrg /* Bad argument. */ 43325dfecf96Smrg val = symbol; 43335dfecf96Smrg goto invalid_keyword_label; 43345dfecf96Smrg } 43355dfecf96Smrg 43365dfecf96Smrg id = ATOMID(val); 43375dfecf96Smrg for (i = 0; i < count; i++) { 43385dfecf96Smrg if (keys[i] && ATOMID(keys[i]) == id) { 43395dfecf96Smrg LispAtom *atom = val->data.atom; 43405dfecf96Smrg 43415dfecf96Smrg /* Symbol found in the argument list. */ 43425dfecf96Smrg if (atom->offset >= offset && 43435dfecf96Smrg atom->offset < offset + nused && 43445dfecf96Smrg lisp__data.env.names[atom->offset] == 43455dfecf96Smrg atom->string) 43465dfecf96Smrg /* Specified more than once... */ 43475dfecf96Smrg goto keyword_duplicated_label; 43485dfecf96Smrg break; 43495dfecf96Smrg } 43505dfecf96Smrg } 43515dfecf96Smrg } 43525dfecf96Smrg if (i == count) { 43535dfecf96Smrg /* Argument specification not found. */ 43545dfecf96Smrg val = symbol; 43555dfecf96Smrg goto invalid_keyword_label; 43565dfecf96Smrg } 43575dfecf96Smrg ++nused; 43585dfecf96Smrg if (eval) { 43595dfecf96Smrg NORMAL_ARGUMENT(symbols[i], EVAL(CADR(karg))); 43605dfecf96Smrg } 43615dfecf96Smrg else { 43625dfecf96Smrg NORMAL_ARGUMENT(symbols[i], CADR(karg)); 43635dfecf96Smrg } 43645dfecf96Smrg if (sforms[i]) { 43655dfecf96Smrg NORMAL_ARGUMENT(sforms[i], T); 43665dfecf96Smrg } 43675dfecf96Smrgkeyword_duplicated_label:; 43685dfecf96Smrg } 43695dfecf96Smrg 43705dfecf96Smrg /* Add variables that were not specified in the function call. */ 43715dfecf96Smrg if (nused < count) { 43725dfecf96Smrg int j; 43735dfecf96Smrg 43745dfecf96Smrg for (i = 0; i < count; i++) { 43755dfecf96Smrg Atom_id id = ATOMID(symbols[i]); 43765dfecf96Smrg 43775dfecf96Smrg for (j = offset + nused - 1; j >= offset; j--) { 43785dfecf96Smrg if (lisp__data.env.names[j] == id) 43795dfecf96Smrg break; 43805dfecf96Smrg } 43815dfecf96Smrg 43825dfecf96Smrg if (j < offset) { 43835dfecf96Smrg /* Argument not specified. Use default value */ 43845dfecf96Smrg 43855dfecf96Smrg /* default arguments are evaluated for macros */ 43865dfecf96Smrg if (!CONSTANTP(defaults[i])) { 43875dfecf96Smrg int head = lisp__data.env.head; 43885dfecf96Smrg int lex = lisp__data.env.lex; 43895dfecf96Smrg 43905dfecf96Smrg lisp__data.env.lex = base; 43915dfecf96Smrg lisp__data.env.head = lisp__data.env.length; 43925dfecf96Smrg NORMAL_ARGUMENT(symbols[i], EVAL(defaults[i])); 43935dfecf96Smrg lisp__data.env.head = head; 43945dfecf96Smrg lisp__data.env.lex = lex; 43955dfecf96Smrg } 43965dfecf96Smrg else { 43975dfecf96Smrg NORMAL_ARGUMENT(symbols[i], defaults[i]); 43985dfecf96Smrg } 43995dfecf96Smrg if (sforms[i]) { 44005dfecf96Smrg NORMAL_ARGUMENT(sforms[i], NIL); 44015dfecf96Smrg } 44025dfecf96Smrg } 44035dfecf96Smrg } 44045dfecf96Smrg } 44055dfecf96Smrg } 44065dfecf96Smrg#else 44075dfecf96Smrg else { 44085dfecf96Smrg int varset; 44095dfecf96Smrg 44105dfecf96Smrg sforms = alist->keys.sforms; 44115dfecf96Smrg keys = alist->keys.keys; 44125dfecf96Smrg 44135dfecf96Smrg /* Add variables */ 44145dfecf96Smrg for (i = 0; i < alist->keys.num_symbols; i++) { 44155dfecf96Smrg val = defaults[i]; 44165dfecf96Smrg varset = 0; 44175dfecf96Smrg if (keys[i]) { 44185dfecf96Smrg Atom_id atom = ATOMID(keys[i]); 44195dfecf96Smrg 44205dfecf96Smrg /* Special keyword specification, need to compare ATOMID 44215dfecf96Smrg * and keyword specification must be a quoted object */ 44225dfecf96Smrg for (karg = values; CONSP(karg); karg = CDR(karg)) { 44235dfecf96Smrg val = CAR(karg); 44245dfecf96Smrg if (QUOTEP(val) && atom == ATOMID(val->data.quote)) { 44255dfecf96Smrg val = CADR(karg); 44265dfecf96Smrg varset = 1; 44275dfecf96Smrg ++nused; 44285dfecf96Smrg break; 44295dfecf96Smrg } 44305dfecf96Smrg karg = CDR(karg); 44315dfecf96Smrg } 44325dfecf96Smrg } 44335dfecf96Smrg 44345dfecf96Smrg else { 44355dfecf96Smrg /* Normal keyword specification, can compare object pointers, 44365dfecf96Smrg * as they point to the same object in the keyword package */ 44375dfecf96Smrg for (karg = values; CONSP(karg); karg = CDR(karg)) { 44385dfecf96Smrg /* Don't check if argument is a valid keyword or 44395dfecf96Smrg * special quoted keyword */ 44405dfecf96Smrg if (symbols[i] == CAR(karg)) { 44415dfecf96Smrg val = CADR(karg); 44425dfecf96Smrg varset = 1; 44435dfecf96Smrg ++nused; 44445dfecf96Smrg break; 44455dfecf96Smrg } 44465dfecf96Smrg karg = CDR(karg); 44475dfecf96Smrg } 44485dfecf96Smrg } 44495dfecf96Smrg 44505dfecf96Smrg /* Add the variable to environment */ 44515dfecf96Smrg if (varset) { 44525dfecf96Smrg NORMAL_ARGUMENT(symbols[i], eval ? EVAL(val) : val); 44535dfecf96Smrg if (sforms[i]) { 44545dfecf96Smrg NORMAL_ARGUMENT(sforms[i], T); 44555dfecf96Smrg } 44565dfecf96Smrg } 44575dfecf96Smrg else { 44585dfecf96Smrg /* default arguments are evaluated for macros */ 44595dfecf96Smrg if (!CONSTANTP(val)) { 44605dfecf96Smrg int head = lisp__data.env.head; 44615dfecf96Smrg int lex = lisp__data.env.lex; 44625dfecf96Smrg 44635dfecf96Smrg lisp__data.env.lex = base; 44645dfecf96Smrg lisp__data.env.head = lisp__data.env.length; 44655dfecf96Smrg NORMAL_ARGUMENT(symbols[i], EVAL(val)); 44665dfecf96Smrg lisp__data.env.head = head; 44675dfecf96Smrg lisp__data.env.lex = lex; 44685dfecf96Smrg } 44695dfecf96Smrg else { 44705dfecf96Smrg NORMAL_ARGUMENT(symbols[i], val); 44715dfecf96Smrg } 44725dfecf96Smrg if (sforms[i]) { 44735dfecf96Smrg NORMAL_ARGUMENT(sforms[i], NIL); 44745dfecf96Smrg } 44755dfecf96Smrg } 44765dfecf96Smrg } 44775dfecf96Smrg 44785dfecf96Smrg if (argc != nused) { 44795dfecf96Smrg /* Argument(s) may be incorrectly specified, or specified 44805dfecf96Smrg * twice (what is not an error). */ 44815dfecf96Smrg for (karg = values; CONSP(karg); karg = CDDR(karg)) { 44825dfecf96Smrg val = CAR(karg); 44835dfecf96Smrg if (KEYWORDP(val)) { 44845dfecf96Smrg for (i = 0; i < count; i++) 44855dfecf96Smrg if (symbols[i] == val) 44865dfecf96Smrg break; 44875dfecf96Smrg } 44885dfecf96Smrg else if (QUOTEP(val) && SYMBOLP(val->data.quote)) { 44895dfecf96Smrg Atom_id atom = ATOMID(val->data.quote); 44905dfecf96Smrg 44915dfecf96Smrg for (i = 0; i < count; i++) 44925dfecf96Smrg if (ATOMID(keys[i]) == atom) 44935dfecf96Smrg break; 44945dfecf96Smrg } 44955dfecf96Smrg else 44965dfecf96Smrg /* Just make the error test true */ 44975dfecf96Smrg i = count; 44985dfecf96Smrg 44995dfecf96Smrg if (i == count) 45005dfecf96Smrg goto invalid_keyword_label; 45015dfecf96Smrg } 45025dfecf96Smrg } 45035dfecf96Smrg } 45045dfecf96Smrg#endif 45055dfecf96Smrg goto check_aux_label; 45065dfecf96Smrg 45075dfecf96Smrginvalid_keyword_label: 45085dfecf96Smrg { 45095dfecf96Smrg /* If not in argument specification list... */ 45105dfecf96Smrg char function_name[36]; 45115dfecf96Smrg 45125dfecf96Smrg strcpy(function_name, STROBJ(name)); 45135dfecf96Smrg LispDestroy("%s: %s is an invalid keyword", 45145dfecf96Smrg function_name, STROBJ(val)); 45155dfecf96Smrg } 45165dfecf96Smrg } 45175dfecf96Smrg 45185dfecf96Smrgcheck_aux_label: 45195dfecf96Smrg if (*desc == 'a') { 45205dfecf96Smrg /* &KEY uses all remaining arguments */ 45215dfecf96Smrg values = NIL; 45225dfecf96Smrg goto aux_label; 45235dfecf96Smrg } 45245dfecf96Smrg goto finished_label; 45255dfecf96Smrg 45265dfecf96Smrg /* &REST */ 45275dfecf96Smrgrest_label: 45285dfecf96Smrg if (!CONSP(values)) { 45295dfecf96Smrg if (builtin) { 45305dfecf96Smrg BUILTIN_ARGUMENT(values); 45315dfecf96Smrg } 45325dfecf96Smrg else { 45335dfecf96Smrg NORMAL_ARGUMENT(alist->rest, values); 45345dfecf96Smrg } 45355dfecf96Smrg values = NIL; 45365dfecf96Smrg } 45375dfecf96Smrg /* always allocate a new list, don't know if it will be retained */ 45385dfecf96Smrg else if (eval) { 45395dfecf96Smrg LispObj *cons; 45405dfecf96Smrg 45415dfecf96Smrg cons = CONS(EVAL(CAR(values)), NIL); 45425dfecf96Smrg if (builtin) { 45435dfecf96Smrg BUILTIN_ARGUMENT(cons); 45445dfecf96Smrg } 45455dfecf96Smrg else { 45465dfecf96Smrg NORMAL_ARGUMENT(alist->rest, cons); 45475dfecf96Smrg } 45485dfecf96Smrg values = CDR(values); 45495dfecf96Smrg for (; CONSP(values); values = CDR(values)) { 45505dfecf96Smrg RPLACD(cons, CONS(EVAL(CAR(values)), NIL)); 45515dfecf96Smrg cons = CDR(cons); 45525dfecf96Smrg } 45535dfecf96Smrg } 45545dfecf96Smrg else { 45555dfecf96Smrg LispObj *cons; 45565dfecf96Smrg 45575dfecf96Smrg cons = CONS(CAR(values), NIL); 45585dfecf96Smrg if (builtin) { 45595dfecf96Smrg BUILTIN_ARGUMENT(cons); 45605dfecf96Smrg } 45615dfecf96Smrg else { 45625dfecf96Smrg NORMAL_ARGUMENT(alist->rest, cons); 45635dfecf96Smrg } 45645dfecf96Smrg values = CDR(values); 45655dfecf96Smrg for (; CONSP(values); values = CDR(values)) { 45665dfecf96Smrg RPLACD(cons, CONS(CAR(values), NIL)); 45675dfecf96Smrg cons = CDR(cons); 45685dfecf96Smrg } 45695dfecf96Smrg } 45705dfecf96Smrg if (*desc != 'a') 45715dfecf96Smrg goto finished_label; 45725dfecf96Smrg 45735dfecf96Smrg /* &AUX */ 45745dfecf96Smrgaux_label: 45755dfecf96Smrg i = 0; 45765dfecf96Smrg count = alist->auxs.num_symbols; 45775dfecf96Smrg defaults = alist->auxs.initials; 45785dfecf96Smrg symbols = alist->auxs.symbols; 45795dfecf96Smrg { 45805dfecf96Smrg int lex = lisp__data.env.lex; 45815dfecf96Smrg 45825dfecf96Smrg lisp__data.env.lex = base; 45835dfecf96Smrg lisp__data.env.head = lisp__data.env.length; 45845dfecf96Smrg for (; i < count; i++) { 45855dfecf96Smrg NORMAL_ARGUMENT(symbols[i], EVAL(defaults[i])); 45865dfecf96Smrg ++lisp__data.env.head; 45875dfecf96Smrg } 45885dfecf96Smrg lisp__data.env.lex = lex; 45895dfecf96Smrg } 45905dfecf96Smrg 45915dfecf96Smrgdone_label: 45925dfecf96Smrg if (CONSP(values)) 45935dfecf96Smrg LispDestroy("%s: too many arguments", STROBJ(name)); 45945dfecf96Smrg 45955dfecf96Smrgfinished_label: 45965dfecf96Smrg if (builtin) 45975dfecf96Smrg lisp__data.stack.base = base; 45985dfecf96Smrg else { 45995dfecf96Smrg lisp__data.env.head = lisp__data.env.length; 46005dfecf96Smrg } 46015dfecf96Smrg#undef BULTIN_ARGUMENT 46025dfecf96Smrg#undef NORMAL_ARGUMENT 46035dfecf96Smrg#undef BUILTIN_NO_EVAL_ARGUMENT 46045dfecf96Smrg 46055dfecf96Smrg return (base); 46065dfecf96Smrg} 46075dfecf96Smrg 46085dfecf96SmrgLispObj * 46095dfecf96SmrgLispFuncall(LispObj *function, LispObj *arguments, int eval) 46105dfecf96Smrg{ 46115dfecf96Smrg LispAtom *atom; 46125dfecf96Smrg LispArgList *alist; 46135dfecf96Smrg LispBuiltin *builtin; 46145dfecf96Smrg LispObj *lambda, *result; 46155dfecf96Smrg int macro, base; 46165dfecf96Smrg 46175dfecf96Smrg#ifdef DEBUGGER 46185dfecf96Smrg if (lisp__data.debugging) 46195dfecf96Smrg LispDebugger(LispDebugCallBegin, function, arguments); 46205dfecf96Smrg#endif 46215dfecf96Smrg 46225dfecf96Smrg switch (OBJECT_TYPE(function)) { 46235dfecf96Smrg case LispFunction_t: 46245dfecf96Smrg function = function->data.atom->object; 46255dfecf96Smrg case LispAtom_t: 46265dfecf96Smrg atom = function->data.atom; 46275dfecf96Smrg if (atom->a_builtin) { 46285dfecf96Smrg builtin = atom->property->fun.builtin; 46295dfecf96Smrg 46305dfecf96Smrg if (eval) 46315dfecf96Smrg eval = builtin->type != LispMacro; 46325dfecf96Smrg base = LispMakeEnvironment(atom->property->alist, 46335dfecf96Smrg arguments, function, eval, 1); 46345dfecf96Smrg if (builtin->multiple_values) { 46355dfecf96Smrg RETURN_COUNT = 0; 46365dfecf96Smrg result = builtin->function(builtin); 46375dfecf96Smrg } 46385dfecf96Smrg else { 46395dfecf96Smrg result = builtin->function(builtin); 46405dfecf96Smrg RETURN_COUNT = 0; 46415dfecf96Smrg } 46425dfecf96Smrg lisp__data.stack.base = lisp__data.stack.length = base; 46435dfecf96Smrg } 46445dfecf96Smrg else if (atom->a_compiled) { 46455dfecf96Smrg int lex = lisp__data.env.lex; 46465dfecf96Smrg lambda = atom->property->fun.function; 46475dfecf96Smrg alist = atom->property->alist; 46485dfecf96Smrg 46495dfecf96Smrg base = LispMakeEnvironment(alist, arguments, function, eval, 0); 46505dfecf96Smrg lisp__data.env.lex = base; 46515dfecf96Smrg result = LispExecuteBytecode(lambda); 46525dfecf96Smrg lisp__data.env.lex = lex; 46535dfecf96Smrg lisp__data.env.head = lisp__data.env.length = base; 46545dfecf96Smrg } 46555dfecf96Smrg else if (atom->a_function) { 46565dfecf96Smrg lambda = atom->property->fun.function; 46575dfecf96Smrg macro = lambda->funtype == LispMacro; 46585dfecf96Smrg alist = atom->property->alist; 46595dfecf96Smrg 46605dfecf96Smrg lambda = lambda->data.lambda.code; 46615dfecf96Smrg if (eval) 46625dfecf96Smrg eval = !macro; 46635dfecf96Smrg base = LispMakeEnvironment(alist, arguments, function, eval, 0); 46645dfecf96Smrg result = LispRunFunMac(function, lambda, macro, base); 46655dfecf96Smrg } 46665dfecf96Smrg else if (atom->a_defstruct && 46675dfecf96Smrg atom->property->structure.function != STRUCT_NAME) { 46685dfecf96Smrg LispObj cons; 46695dfecf96Smrg 46705dfecf96Smrg if (atom->property->structure.function == STRUCT_CONSTRUCTOR) 46715dfecf96Smrg atom = Omake_struct->data.atom; 46725dfecf96Smrg else if (atom->property->structure.function == STRUCT_CHECK) 46735dfecf96Smrg atom = Ostruct_type->data.atom; 46745dfecf96Smrg else 46755dfecf96Smrg atom = Ostruct_access->data.atom; 46765dfecf96Smrg builtin = atom->property->fun.builtin; 46775dfecf96Smrg 46785dfecf96Smrg cons.type = LispCons_t; 46795dfecf96Smrg cons.data.cons.cdr = arguments; 46805dfecf96Smrg if (eval) { 46815dfecf96Smrg LispObj quote; 46825dfecf96Smrg 46835dfecf96Smrg quote.type = LispQuote_t; 46845dfecf96Smrg quote.data.quote = function; 46855dfecf96Smrg cons.data.cons.car = "e; 46865dfecf96Smrg base = LispMakeEnvironment(atom->property->alist, 46875dfecf96Smrg &cons, function, 1, 1); 46885dfecf96Smrg } 46895dfecf96Smrg else { 46905dfecf96Smrg cons.data.cons.car = function; 46915dfecf96Smrg base = LispMakeEnvironment(atom->property->alist, 46925dfecf96Smrg &cons, function, 0, 1); 46935dfecf96Smrg } 46945dfecf96Smrg result = builtin->function(builtin); 46955dfecf96Smrg RETURN_COUNT = 0; 46965dfecf96Smrg lisp__data.stack.length = base; 46975dfecf96Smrg } 46985dfecf96Smrg else { 46995dfecf96Smrg LispDestroy("EVAL: the function %s is not defined", 47005dfecf96Smrg STROBJ(function)); 47015dfecf96Smrg /*NOTREACHED*/ 47025dfecf96Smrg result = NIL; 47035dfecf96Smrg } 47045dfecf96Smrg break; 47055dfecf96Smrg case LispLambda_t: 47065dfecf96Smrg lambda = function->data.lambda.code; 47075dfecf96Smrg alist = (LispArgList*)function->data.lambda.name->data.opaque.data; 47085dfecf96Smrg base = LispMakeEnvironment(alist, arguments, function, eval, 0); 47095dfecf96Smrg result = LispRunFunMac(function, lambda, 0, base); 47105dfecf96Smrg break; 47115dfecf96Smrg case LispCons_t: 47125dfecf96Smrg if (CAR(function) == Olambda) { 47135dfecf96Smrg function = EVAL(function); 47145dfecf96Smrg if (LAMBDAP(function)) { 47155dfecf96Smrg GC_ENTER(); 47165dfecf96Smrg 47175dfecf96Smrg GC_PROTECT(function); 47185dfecf96Smrg lambda = function->data.lambda.code; 47195dfecf96Smrg alist = (LispArgList*)function->data.lambda.name->data.opaque.data; 47205dfecf96Smrg base = LispMakeEnvironment(alist, arguments, NIL, eval, 0); 47215dfecf96Smrg result = LispRunFunMac(NIL, lambda, 0, base); 47225dfecf96Smrg GC_LEAVE(); 47235dfecf96Smrg break; 47245dfecf96Smrg } 47255dfecf96Smrg } 47265dfecf96Smrg default: 47275dfecf96Smrg LispDestroy("EVAL: %s is invalid as a function", 47285dfecf96Smrg STROBJ(function)); 47295dfecf96Smrg /*NOTREACHED*/ 47305dfecf96Smrg result = NIL; 47315dfecf96Smrg break; 47325dfecf96Smrg } 47335dfecf96Smrg 47345dfecf96Smrg#ifdef DEBUGGER 47355dfecf96Smrg if (lisp__data.debugging) 47365dfecf96Smrg LispDebugger(LispDebugCallEnd, function, result); 47375dfecf96Smrg#endif 47385dfecf96Smrg 47395dfecf96Smrg return (result); 47405dfecf96Smrg} 47415dfecf96Smrg 47425dfecf96SmrgLispObj * 47435dfecf96SmrgLispEval(LispObj *object) 47445dfecf96Smrg{ 47455dfecf96Smrg LispObj *result; 47465dfecf96Smrg 47475dfecf96Smrg switch (OBJECT_TYPE(object)) { 47485dfecf96Smrg case LispAtom_t: 47495dfecf96Smrg if ((result = LispDoGetVar(object)) == NULL) 47505dfecf96Smrg LispDestroy("EVAL: the variable %s is unbound", STROBJ(object)); 47515dfecf96Smrg break; 47525dfecf96Smrg case LispCons_t: 47535dfecf96Smrg result = LispFuncall(CAR(object), CDR(object), 1); 47545dfecf96Smrg break; 47555dfecf96Smrg case LispQuote_t: 47565dfecf96Smrg result = object->data.quote; 47575dfecf96Smrg break; 47585dfecf96Smrg case LispFunctionQuote_t: 47595dfecf96Smrg result = object->data.quote; 47605dfecf96Smrg if (SYMBOLP(result)) 47615dfecf96Smrg result = LispSymbolFunction(result); 47625dfecf96Smrg else if (CONSP(result) && CAR(result) == Olambda) 47635dfecf96Smrg result = EVAL(result); 47645dfecf96Smrg else 47655dfecf96Smrg LispDestroy("FUNCTION: %s is not a function", STROBJ(result)); 47665dfecf96Smrg break; 47675dfecf96Smrg case LispBackquote_t: 47685dfecf96Smrg result = LispEvalBackquote(object->data.quote, 1); 47695dfecf96Smrg break; 47705dfecf96Smrg case LispComma_t: 47715dfecf96Smrg LispDestroy("EVAL: comma outside of backquote"); 47725dfecf96Smrg default: 47735dfecf96Smrg result = object; 47745dfecf96Smrg break; 47755dfecf96Smrg } 47765dfecf96Smrg 47775dfecf96Smrg return (result); 47785dfecf96Smrg} 47795dfecf96Smrg 47805dfecf96SmrgLispObj * 47815dfecf96SmrgLispApply1(LispObj *function, LispObj *argument) 47825dfecf96Smrg{ 47835dfecf96Smrg LispObj arguments; 47845dfecf96Smrg 47855dfecf96Smrg arguments.type = LispCons_t; 47865dfecf96Smrg arguments.data.cons.car = argument; 47875dfecf96Smrg arguments.data.cons.cdr = NIL; 47885dfecf96Smrg 47895dfecf96Smrg return (LispFuncall(function, &arguments, 0)); 47905dfecf96Smrg} 47915dfecf96Smrg 47925dfecf96SmrgLispObj * 47935dfecf96SmrgLispApply2(LispObj *function, LispObj *argument1, LispObj *argument2) 47945dfecf96Smrg{ 47955dfecf96Smrg LispObj arguments, cdr; 47965dfecf96Smrg 47975dfecf96Smrg arguments.type = cdr.type = LispCons_t; 47985dfecf96Smrg arguments.data.cons.car = argument1; 47995dfecf96Smrg arguments.data.cons.cdr = &cdr; 48005dfecf96Smrg cdr.data.cons.car = argument2; 48015dfecf96Smrg cdr.data.cons.cdr = NIL; 48025dfecf96Smrg 48035dfecf96Smrg return (LispFuncall(function, &arguments, 0)); 48045dfecf96Smrg} 48055dfecf96Smrg 48065dfecf96SmrgLispObj * 48075dfecf96SmrgLispApply3(LispObj *function, LispObj *arg1, LispObj *arg2, LispObj *arg3) 48085dfecf96Smrg{ 48095dfecf96Smrg LispObj arguments, car, cdr; 48105dfecf96Smrg 48115dfecf96Smrg arguments.type = car.type = cdr.type = LispCons_t; 48125dfecf96Smrg arguments.data.cons.car = arg1; 48135dfecf96Smrg arguments.data.cons.cdr = &car; 48145dfecf96Smrg car.data.cons.car = arg2; 48155dfecf96Smrg car.data.cons.cdr = &cdr; 48165dfecf96Smrg cdr.data.cons.car = arg3; 48175dfecf96Smrg cdr.data.cons.cdr = NIL; 48185dfecf96Smrg 48195dfecf96Smrg return (LispFuncall(function, &arguments, 0)); 48205dfecf96Smrg} 48215dfecf96Smrg 48225dfecf96Smrgstatic LispObj * 48235dfecf96SmrgLispRunFunMac(LispObj *name, LispObj *code, int macro, int base) 48245dfecf96Smrg{ 48255dfecf96Smrg LispObj *result = NIL; 48265dfecf96Smrg 48275dfecf96Smrg if (!macro) { 48285dfecf96Smrg int lex = lisp__data.env.lex; 48295dfecf96Smrg int did_jump = 1; 48305dfecf96Smrg LispBlock *block; 48315dfecf96Smrg 48325dfecf96Smrg block = LispBeginBlock(name, LispBlockClosure); 48335dfecf96Smrg lisp__data.env.lex = base; 48345dfecf96Smrg if (setjmp(block->jmp) == 0) { 48355dfecf96Smrg for (; CONSP(code); code = CDR(code)) 48365dfecf96Smrg result = EVAL(CAR(code)); 48375dfecf96Smrg did_jump = 0; 48385dfecf96Smrg } 48395dfecf96Smrg LispEndBlock(block); 48405dfecf96Smrg if (did_jump) 48415dfecf96Smrg result = lisp__data.block.block_ret; 48425dfecf96Smrg lisp__data.env.lex = lex; 48435dfecf96Smrg lisp__data.env.head = lisp__data.env.length = base; 48445dfecf96Smrg } 48455dfecf96Smrg else { 48465dfecf96Smrg GC_ENTER(); 48475dfecf96Smrg 48485dfecf96Smrg for (; CONSP(code); code = CDR(code)) 48495dfecf96Smrg result = EVAL(CAR(code)); 48505dfecf96Smrg /* FIXME this does not work if macro has &aux variables, 48515dfecf96Smrg * but there are several other missing features, like 48525dfecf96Smrg * destructuring and more lambda list keywords still missing. 48535dfecf96Smrg * TODO later. 48545dfecf96Smrg */ 48555dfecf96Smrg lisp__data.env.head = lisp__data.env.length = base; 48565dfecf96Smrg 48575dfecf96Smrg GC_PROTECT(result); 48585dfecf96Smrg result = EVAL(result); 48595dfecf96Smrg GC_LEAVE(); 48605dfecf96Smrg } 48615dfecf96Smrg 48625dfecf96Smrg return (result); 48635dfecf96Smrg} 48645dfecf96Smrg 48655dfecf96SmrgLispObj * 48665dfecf96SmrgLispRunSetf(LispArgList *alist, LispObj *setf, LispObj *place, LispObj *value) 48675dfecf96Smrg{ 48685dfecf96Smrg GC_ENTER(); 48695dfecf96Smrg LispObj *store, *code, *expression, *result, quote; 48705dfecf96Smrg int base; 48715dfecf96Smrg 48725dfecf96Smrg code = setf->data.lambda.code; 48735dfecf96Smrg store = setf->data.lambda.data; 48745dfecf96Smrg 48755dfecf96Smrg quote.type = LispQuote_t; 48765dfecf96Smrg quote.data.quote = value; 48775dfecf96Smrg LispDoAddVar(CAR(store), "e); 48785dfecf96Smrg ++lisp__data.env.head; 48795dfecf96Smrg base = LispMakeEnvironment(alist, place, Oexpand_setf_method, 0, 0); 48805dfecf96Smrg 48815dfecf96Smrg /* build expansion macro */ 48825dfecf96Smrg expression = NIL; 48835dfecf96Smrg for (; CONSP(code); code = CDR(code)) 48845dfecf96Smrg expression = EVAL(CAR(code)); 48855dfecf96Smrg 48865dfecf96Smrg /* Minus 1 to pop the added variable */ 48875dfecf96Smrg lisp__data.env.head = lisp__data.env.length = base - 1; 48885dfecf96Smrg 48895dfecf96Smrg /* protect expansion, and executes it */ 48905dfecf96Smrg GC_PROTECT(expression); 48915dfecf96Smrg result = EVAL(expression); 48925dfecf96Smrg GC_LEAVE(); 48935dfecf96Smrg 48945dfecf96Smrg return (result); 48955dfecf96Smrg} 48965dfecf96Smrg 48975dfecf96SmrgLispObj * 48985dfecf96SmrgLispRunSetfMacro(LispAtom *atom, LispObj *arguments, LispObj *value) 48995dfecf96Smrg{ 49005dfecf96Smrg int base; 49015dfecf96Smrg GC_ENTER(); 49025dfecf96Smrg LispObj *place, *body, *result, quote; 49035dfecf96Smrg 49045dfecf96Smrg place = NIL; 49055dfecf96Smrg base = LispMakeEnvironment(atom->property->alist, 49065dfecf96Smrg arguments, atom->object, 0, 0); 49075dfecf96Smrg body = atom->property->fun.function->data.lambda.code; 49085dfecf96Smrg 49095dfecf96Smrg /* expand macro body */ 49105dfecf96Smrg for (; CONSP(body); body = CDR(body)) 49115dfecf96Smrg place = EVAL(CAR(body)); 49125dfecf96Smrg 49135dfecf96Smrg /* protect expansion */ 49145dfecf96Smrg GC_PROTECT(place); 49155dfecf96Smrg 49165dfecf96Smrg /* restore environment */ 49175dfecf96Smrg lisp__data.env.head = lisp__data.env.length = base; 49185dfecf96Smrg 49195dfecf96Smrg /* value is already evaluated */ 49205dfecf96Smrg quote.type = LispQuote_t; 49215dfecf96Smrg quote.data.quote = value; 49225dfecf96Smrg 49235dfecf96Smrg /* call setf again */ 49245dfecf96Smrg result = APPLY2(Osetf, place, "e); 49255dfecf96Smrg 49265dfecf96Smrg GC_LEAVE(); 49275dfecf96Smrg 49285dfecf96Smrg return (result); 49295dfecf96Smrg} 49305dfecf96Smrg 49315dfecf96Smrgchar * 49325dfecf96SmrgLispStrObj(LispObj *object) 49335dfecf96Smrg{ 49345dfecf96Smrg static int first = 1; 49355dfecf96Smrg static char buffer[34]; 49365dfecf96Smrg static LispObj stream; 49375dfecf96Smrg static LispString string; 49385dfecf96Smrg 49395dfecf96Smrg if (first) { 49405dfecf96Smrg stream.type = LispStream_t; 49415dfecf96Smrg stream.data.stream.source.string = &string; 49425dfecf96Smrg stream.data.stream.pathname = NIL; 49435dfecf96Smrg stream.data.stream.type = LispStreamString; 49445dfecf96Smrg stream.data.stream.readable = 0; 49455dfecf96Smrg stream.data.stream.writable = 1; 49465dfecf96Smrg 49475dfecf96Smrg string.string = buffer; 49485dfecf96Smrg string.fixed = 1; 49495dfecf96Smrg string.space = sizeof(buffer) - 1; 49505dfecf96Smrg first = 0; 49515dfecf96Smrg } 49525dfecf96Smrg 49535dfecf96Smrg string.length = string.output = 0; 49545dfecf96Smrg 49555dfecf96Smrg LispWriteObject(&stream, object); 49565dfecf96Smrg 49575dfecf96Smrg /* make sure string is nul terminated */ 49585dfecf96Smrg string.string[string.length] = '\0'; 49595dfecf96Smrg if (string.length >= 32) { 49605dfecf96Smrg if (buffer[0] == '(') 49615dfecf96Smrg strcpy(buffer + 27, "...)"); 49625dfecf96Smrg else 49635dfecf96Smrg strcpy(buffer + 28, "..."); 49645dfecf96Smrg } 49655dfecf96Smrg 49665dfecf96Smrg return (buffer); 49675dfecf96Smrg} 49685dfecf96Smrg 49695dfecf96Smrgvoid 49705dfecf96SmrgLispPrint(LispObj *object, LispObj *stream, int newline) 49715dfecf96Smrg{ 49725dfecf96Smrg if (stream != NIL && !STREAMP(stream)) { 49735dfecf96Smrg LispDestroy("PRINT: %s is not a stream", STROBJ(stream)); 49745dfecf96Smrg } 49755dfecf96Smrg if (newline && LispGetColumn(stream)) 49765dfecf96Smrg LispWriteChar(stream, '\n'); 49775dfecf96Smrg LispWriteObject(stream, object); 49785dfecf96Smrg if (stream == NIL || (stream->data.stream.type == LispStreamStandard && 49795dfecf96Smrg stream->data.stream.source.file == Stdout)) 49805dfecf96Smrg LispFflush(Stdout); 49815dfecf96Smrg} 49825dfecf96Smrg 49835dfecf96Smrgvoid 49845dfecf96SmrgLispUpdateResults(LispObj *cod, LispObj *res) 49855dfecf96Smrg{ 49865dfecf96Smrg LispSetVar(RUN[2], LispGetVar(RUN[1])); 49875dfecf96Smrg LispSetVar(RUN[1], LispGetVar(RUN[0])); 49885dfecf96Smrg LispSetVar(RUN[0], cod); 49895dfecf96Smrg 49905dfecf96Smrg LispSetVar(RES[2], LispGetVar(RES[1])); 49915dfecf96Smrg LispSetVar(RES[1], LispGetVar(RES[0])); 49925dfecf96Smrg LispSetVar(RES[0], res); 49935dfecf96Smrg} 49945dfecf96Smrg 49955dfecf96Smrgvoid 49965dfecf96SmrgLispSignalHandler(int signum) 49975dfecf96Smrg{ 49985dfecf96Smrg LispSignal(signum); 49995dfecf96Smrg} 50005dfecf96Smrg 50015dfecf96Smrgvoid 50025dfecf96SmrgLispSignal(int signum) 50035dfecf96Smrg{ 5004f765521fSmrg const char *errstr; 50055dfecf96Smrg char buffer[32]; 50065dfecf96Smrg 50075dfecf96Smrg if (lisp__disable_int) { 50085dfecf96Smrg lisp__interrupted = signum; 50095dfecf96Smrg return; 50105dfecf96Smrg } 50115dfecf96Smrg switch (signum) { 50125dfecf96Smrg case SIGINT: 50135dfecf96Smrg errstr = "interrupted"; 50145dfecf96Smrg break; 50155dfecf96Smrg case SIGFPE: 50165dfecf96Smrg errstr = "floating point exception"; 50175dfecf96Smrg break; 50185dfecf96Smrg default: 50195dfecf96Smrg sprintf(buffer, "signal %d received", signum); 50205dfecf96Smrg errstr = buffer; 50215dfecf96Smrg break; 50225dfecf96Smrg } 502331de2854Smrg LispDestroy("%s", errstr); 50245dfecf96Smrg} 50255dfecf96Smrg 50265dfecf96Smrgvoid 50275dfecf96SmrgLispDisableInterrupts(void) 50285dfecf96Smrg{ 50295dfecf96Smrg ++lisp__disable_int; 50305dfecf96Smrg} 50315dfecf96Smrg 50325dfecf96Smrgvoid 50335dfecf96SmrgLispEnableInterrupts(void) 50345dfecf96Smrg{ 50355dfecf96Smrg --lisp__disable_int; 50365dfecf96Smrg if (lisp__disable_int <= 0 && lisp__interrupted) 50375dfecf96Smrg LispSignal(lisp__interrupted); 50385dfecf96Smrg} 50395dfecf96Smrg 50405dfecf96Smrgvoid 50415dfecf96SmrgLispMachine(void) 50425dfecf96Smrg{ 50435dfecf96Smrg LispObj *cod, *obj; 50445dfecf96Smrg 50455dfecf96Smrg lisp__data.sigint = signal(SIGINT, LispSignalHandler); 50465dfecf96Smrg lisp__data.sigfpe = signal(SIGFPE, LispSignalHandler); 50475dfecf96Smrg 50485dfecf96Smrg /*CONSTCOND*/ 50495dfecf96Smrg while (1) { 50505dfecf96Smrg if (sigsetjmp(lisp__data.jmp, 1) == 0) { 50515dfecf96Smrg lisp__data.running = 1; 50525dfecf96Smrg if (lisp__data.interactive && lisp__data.prompt) { 50535dfecf96Smrg LispFputs(Stdout, lisp__data.prompt); 50545dfecf96Smrg LispFflush(Stdout); 50555dfecf96Smrg } 50565dfecf96Smrg if ((cod = LispRead()) != NULL) { 50575dfecf96Smrg obj = EVAL(cod); 50585dfecf96Smrg if (lisp__data.interactive) { 50595dfecf96Smrg if (RETURN_COUNT >= 0) 50605dfecf96Smrg LispPrint(obj, NIL, 1); 50615dfecf96Smrg if (RETURN_COUNT > 0) { 50625dfecf96Smrg int i; 50635dfecf96Smrg 50645dfecf96Smrg for (i = 0; i < RETURN_COUNT; i++) 50655dfecf96Smrg LispPrint(RETURN(i), NIL, 1); 50665dfecf96Smrg } 50675dfecf96Smrg LispUpdateResults(cod, obj); 50685dfecf96Smrg if (LispGetColumn(NIL)) 50695dfecf96Smrg LispWriteChar(NIL, '\n'); 50705dfecf96Smrg } 50715dfecf96Smrg } 50725dfecf96Smrg LispTopLevel(); 50735dfecf96Smrg } 50745dfecf96Smrg if (lisp__data.eof) 50755dfecf96Smrg break; 50765dfecf96Smrg } 50775dfecf96Smrg 50785dfecf96Smrg signal(SIGINT, lisp__data.sigint); 50795dfecf96Smrg signal(SIGFPE, lisp__data.sigfpe); 50805dfecf96Smrg 50815dfecf96Smrg lisp__data.running = 0; 50825dfecf96Smrg} 50835dfecf96Smrg 50845dfecf96Smrgvoid * 50855dfecf96SmrgLispExecute(char *str) 50865dfecf96Smrg{ 50875dfecf96Smrg static LispObj stream; 50885dfecf96Smrg static LispString string; 50895dfecf96Smrg static int first = 1; 50905dfecf96Smrg 50915dfecf96Smrg int running = lisp__data.running; 50925dfecf96Smrg LispObj *result, *cod, *obj, **presult = &result; 50935dfecf96Smrg 50945dfecf96Smrg if (str == NULL || *str == '\0') 50955dfecf96Smrg return (NIL); 50965dfecf96Smrg 50975dfecf96Smrg *presult = NIL; 50985dfecf96Smrg 50995dfecf96Smrg if (first) { 51005dfecf96Smrg stream.type = LispStream_t; 51015dfecf96Smrg stream.data.stream.source.string = &string; 51025dfecf96Smrg stream.data.stream.pathname = NIL; 51035dfecf96Smrg stream.data.stream.type = LispStreamString; 51045dfecf96Smrg stream.data.stream.readable = 1; 51055dfecf96Smrg stream.data.stream.writable = 0; 51065dfecf96Smrg string.output = 0; 51075dfecf96Smrg first = 0; 51085dfecf96Smrg } 51095dfecf96Smrg string.string = str; 51105dfecf96Smrg string.length = strlen(str); 51115dfecf96Smrg string.input = 0; 51125dfecf96Smrg 51135dfecf96Smrg LispPushInput(&stream); 51145dfecf96Smrg if (!running) { 51155dfecf96Smrg lisp__data.running = 1; 51165dfecf96Smrg if (sigsetjmp(lisp__data.jmp, 1) != 0) 51175dfecf96Smrg return (NULL); 51185dfecf96Smrg } 51195dfecf96Smrg 51205dfecf96Smrg cod = COD; 51215dfecf96Smrg /*CONSTCOND*/ 51225dfecf96Smrg while (1) { 51235dfecf96Smrg if ((obj = LispRead()) != NULL) { 51245dfecf96Smrg result = EVAL(obj); 51255dfecf96Smrg COD = cod; 51265dfecf96Smrg } 51275dfecf96Smrg if (lisp__data.eof) 51285dfecf96Smrg break; 51295dfecf96Smrg } 51305dfecf96Smrg LispPopInput(&stream); 51315dfecf96Smrg 51325dfecf96Smrg lisp__data.running = running; 51335dfecf96Smrg 51345dfecf96Smrg return (result); 51355dfecf96Smrg} 51365dfecf96Smrg 51375dfecf96Smrgvoid 51385dfecf96SmrgLispBegin(void) 51395dfecf96Smrg{ 51405dfecf96Smrg int i; 51415dfecf96Smrg LispAtom *atom; 51425dfecf96Smrg char results[4]; 51435dfecf96Smrg LispObj *object, *path, *ext; 51445dfecf96Smrg 51455dfecf96Smrg pagesize = LispGetPageSize(); 51465dfecf96Smrg segsize = pagesize / sizeof(LispObj); 51475dfecf96Smrg 5148f14f4646Smrg lisp__data.strings = hash_new(STRTBLSZ, NULL); 5149f14f4646Smrg lisp__data.opqs = hash_new(STRTBLSZ, NULL); 5150f14f4646Smrg 51515dfecf96Smrg /* Initialize memory management */ 51525dfecf96Smrg lisp__data.mem.mem = (void**)calloc(lisp__data.mem.space = 16, 51535dfecf96Smrg sizeof(void*)); 51545dfecf96Smrg lisp__data.mem.index = lisp__data.mem.level = 0; 51555dfecf96Smrg 51565dfecf96Smrg /* Allow LispGetVar to check ATOMID() of unbound symbols */ 51575dfecf96Smrg UNBOUND->data.atom = (LispAtom*)LispCalloc(1, sizeof(LispAtom)); 51585dfecf96Smrg LispMused(UNBOUND->data.atom); 51595dfecf96Smrg noproperty.value = UNBOUND; 51605dfecf96Smrg 51615dfecf96Smrg if (Stdin == NULL) 51625dfecf96Smrg Stdin = LispFdopen(0, FILE_READ); 51635dfecf96Smrg if (Stdout == NULL) 51645dfecf96Smrg Stdout = LispFdopen(1, FILE_WRITE | FILE_BUFFERED); 51655dfecf96Smrg if (Stderr == NULL) 51665dfecf96Smrg Stderr = LispFdopen(2, FILE_WRITE); 51675dfecf96Smrg 51685dfecf96Smrg /* minimum number of free cells after GC 51695dfecf96Smrg * if sizeof(LispObj) == 16, than a minfree of 1024 would try to keep 51705dfecf96Smrg * at least 16Kb of free cells. 51715dfecf96Smrg */ 51725dfecf96Smrg minfree = 1024; 51735dfecf96Smrg 51745dfecf96Smrg MOD = COD = PRO = NIL; 51755dfecf96Smrg#ifdef DEBUGGER 51765dfecf96Smrg DBG = BRK = NIL; 51775dfecf96Smrg#endif 51785dfecf96Smrg 51795dfecf96Smrg /* allocate initial object cells */ 51805dfecf96Smrg LispAllocSeg(&objseg, minfree); 51815dfecf96Smrg LispAllocSeg(&atomseg, pagesize); 51825dfecf96Smrg lisp__data.gc.average = segsize; 51835dfecf96Smrg 51845dfecf96Smrg /* Don't allow gc in initialization */ 51855dfecf96Smrg GCDisable(); 51865dfecf96Smrg 51875dfecf96Smrg /* Initialize package system, the current package is LISP. Order of 51885dfecf96Smrg * initialization is very important here */ 51895dfecf96Smrg lisp__data.lisp = LispNewPackage(STRING("LISP"), 51905dfecf96Smrg CONS(STRING("COMMON-LISP"), NIL)); 51915dfecf96Smrg 51925dfecf96Smrg /* Make LISP package the current one */ 51935dfecf96Smrg lisp__data.pack = lisp__data.savepack = 51945dfecf96Smrg lisp__data.lisp->data.package.package; 51955dfecf96Smrg 51965dfecf96Smrg /* Allocate space in LISP package */ 51975dfecf96Smrg LispMoreGlobals(lisp__data.pack); 51985dfecf96Smrg 51995dfecf96Smrg /* Allocate space for multiple value return values */ 52005dfecf96Smrg lisp__data.returns.values = malloc(MULTIPLE_VALUES_LIMIT * 52015dfecf96Smrg (sizeof(LispObj*))); 52025dfecf96Smrg 52035dfecf96Smrg /* Create the first atom, do it "by hand" because macro "PACKAGE" 52045dfecf96Smrg * cannot yet be used. */ 52055dfecf96Smrg atom = LispGetPermAtom("*PACKAGE*"); 52065dfecf96Smrg lisp__data.package = atomseg.freeobj; 52075dfecf96Smrg atomseg.freeobj = CDR(atomseg.freeobj); 52085dfecf96Smrg --atomseg.nfree; 52095dfecf96Smrg lisp__data.package->type = LispAtom_t; 52105dfecf96Smrg lisp__data.package->data.atom = atom; 52115dfecf96Smrg atom->object = lisp__data.package; 52125dfecf96Smrg atom->package = lisp__data.lisp; 52135dfecf96Smrg 52145dfecf96Smrg /* Set package list, to be used by (gc) and (list-all-packages) */ 52155dfecf96Smrg PACK = CONS(lisp__data.lisp, NIL); 52165dfecf96Smrg 52175dfecf96Smrg /* Make *PACKAGE* a special variable */ 52185dfecf96Smrg LispProclaimSpecial(lisp__data.package, lisp__data.lisp, NIL); 52195dfecf96Smrg 52205dfecf96Smrg /* Value of macro "PACKAGE" is now properly available */ 52215dfecf96Smrg 52225dfecf96Smrg /* Changing *PACKAGE* is like calling (in-package) */ 52235dfecf96Smrg lisp__data.package->data.atom->watch = 1; 52245dfecf96Smrg 52255dfecf96Smrg /* And available to other packages */ 52265dfecf96Smrg LispExportSymbol(lisp__data.package); 52275dfecf96Smrg 52285dfecf96Smrg /* Initialize stacks */ 52295dfecf96Smrg LispMoreEnvironment(); 52305dfecf96Smrg LispMoreStack(); 52315dfecf96Smrg 52325dfecf96Smrg /* Create the KEYWORD package */ 52335dfecf96Smrg Skeyword = GETATOMID("KEYWORD"); 5234f14f4646Smrg object = LispNewPackage(STRING(Skeyword->value), 52355dfecf96Smrg CONS(STRING(""), NIL)); 52365dfecf96Smrg 52375dfecf96Smrg /* Update list of packages */ 52385dfecf96Smrg PACK = CONS(object, PACK); 52395dfecf96Smrg 52405dfecf96Smrg /* Allow easy access to the keyword package */ 52415dfecf96Smrg lisp__data.keyword = object; 52425dfecf96Smrg lisp__data.key = object->data.package.package; 52435dfecf96Smrg 52445dfecf96Smrg /* Initialize some static important symbols */ 52455dfecf96Smrg Olambda = STATIC_ATOM("LAMBDA"); 52465dfecf96Smrg LispExportSymbol(Olambda); 52475dfecf96Smrg Okey = STATIC_ATOM("&KEY"); 52485dfecf96Smrg LispExportSymbol(Okey); 52495dfecf96Smrg Orest = STATIC_ATOM("&REST"); 52505dfecf96Smrg LispExportSymbol(Orest); 52515dfecf96Smrg Ooptional = STATIC_ATOM("&OPTIONAL"); 52525dfecf96Smrg LispExportSymbol(Ooptional); 52535dfecf96Smrg Oaux = STATIC_ATOM("&AUX"); 52545dfecf96Smrg LispExportSymbol(Oaux); 52555dfecf96Smrg Kunspecific = KEYWORD("UNSPECIFIC"); 52565dfecf96Smrg Oformat = STATIC_ATOM("FORMAT"); 52575dfecf96Smrg Oexpand_setf_method = STATIC_ATOM("EXPAND-SETF-METHOD"); 52585dfecf96Smrg 52595dfecf96Smrg Omake_struct = STATIC_ATOM("MAKE-STRUCT"); 52605dfecf96Smrg Ostruct_access = STATIC_ATOM("STRUCT-ACCESS"); 52615dfecf96Smrg Ostruct_store = STATIC_ATOM("STRUCT-STORE"); 52625dfecf96Smrg Ostruct_type = STATIC_ATOM("STRUCT-TYPE"); 52635dfecf96Smrg Smake_struct = ATOMID(Omake_struct); 52645dfecf96Smrg Sstruct_access = ATOMID(Ostruct_access); 52655dfecf96Smrg Sstruct_store = ATOMID(Ostruct_store); 52665dfecf96Smrg Sstruct_type = ATOMID(Ostruct_type); 52675dfecf96Smrg 52685dfecf96Smrg /* Initialize some static atom ids */ 52695dfecf96Smrg Snil = GETATOMID("NIL"); 52705dfecf96Smrg St = GETATOMID("T"); 52715dfecf96Smrg Saux = ATOMID(Oaux); 52725dfecf96Smrg Skey = ATOMID(Okey); 52735dfecf96Smrg Soptional = ATOMID(Ooptional); 52745dfecf96Smrg Srest = ATOMID(Orest); 52755dfecf96Smrg Sand = GETATOMID("AND"); 52765dfecf96Smrg Sor = GETATOMID("OR"); 52775dfecf96Smrg Snot = GETATOMID("NOT"); 52785dfecf96Smrg Satom = GETATOMID("ATOM"); 52795dfecf96Smrg Ssymbol = GETATOMID("SYMBOL"); 52805dfecf96Smrg Sinteger = GETATOMID("INTEGER"); 52815dfecf96Smrg Scharacter = GETATOMID("CHARACTER"); 52825dfecf96Smrg Sstring = GETATOMID("STRING"); 52835dfecf96Smrg Slist = GETATOMID("LIST"); 52845dfecf96Smrg Scons = GETATOMID("CONS"); 52855dfecf96Smrg Svector = GETATOMID("VECTOR"); 52865dfecf96Smrg Sarray = GETATOMID("ARRAY"); 52875dfecf96Smrg Sstruct = GETATOMID("STRUCT"); 52885dfecf96Smrg Sfunction = GETATOMID("FUNCTION"); 52895dfecf96Smrg Spathname = GETATOMID("PATHNAME"); 52905dfecf96Smrg Srational = GETATOMID("RATIONAL"); 52915dfecf96Smrg Sfloat = GETATOMID("FLOAT"); 52925dfecf96Smrg Scomplex = GETATOMID("COMPLEX"); 52935dfecf96Smrg Sopaque = GETATOMID("OPAQUE"); 52945dfecf96Smrg Sdefault = GETATOMID("DEFAULT"); 52955dfecf96Smrg 52965dfecf96Smrg LispArgList_t = LispRegisterOpaqueType("LispArgList*"); 52975dfecf96Smrg 52985dfecf96Smrg lisp__data.unget = malloc(sizeof(LispUngetInfo*)); 52995dfecf96Smrg lisp__data.unget[0] = calloc(1, sizeof(LispUngetInfo)); 53005dfecf96Smrg lisp__data.nunget = 1; 53015dfecf96Smrg 53025dfecf96Smrg lisp__data.standard_input = ATOM2("*STANDARD-INPUT*"); 53035dfecf96Smrg SINPUT = STANDARDSTREAM(Stdin, lisp__data.standard_input, STREAM_READ); 53045dfecf96Smrg lisp__data.interactive = 1; 53055dfecf96Smrg LispProclaimSpecial(lisp__data.standard_input, 53065dfecf96Smrg lisp__data.input_list = SINPUT, NIL); 53075dfecf96Smrg LispExportSymbol(lisp__data.standard_input); 53085dfecf96Smrg 53095dfecf96Smrg lisp__data.standard_output = ATOM2("*STANDARD-OUTPUT*"); 53105dfecf96Smrg SOUTPUT = STANDARDSTREAM(Stdout, lisp__data.standard_output, STREAM_WRITE); 53115dfecf96Smrg LispProclaimSpecial(lisp__data.standard_output, 53125dfecf96Smrg lisp__data.output_list = SOUTPUT, NIL); 53135dfecf96Smrg LispExportSymbol(lisp__data.standard_output); 53145dfecf96Smrg 53155dfecf96Smrg object = ATOM2("*STANDARD-ERROR*"); 53165dfecf96Smrg lisp__data.error_stream = STANDARDSTREAM(Stderr, object, STREAM_WRITE); 53175dfecf96Smrg LispProclaimSpecial(object, lisp__data.error_stream, NIL); 53185dfecf96Smrg LispExportSymbol(object); 53195dfecf96Smrg 53205dfecf96Smrg lisp__data.modules = ATOM2("*MODULES*"); 53215dfecf96Smrg LispProclaimSpecial(lisp__data.modules, MOD, NIL); 53225dfecf96Smrg LispExportSymbol(lisp__data.modules); 53235dfecf96Smrg 53245dfecf96Smrg object = CONS(KEYWORD("UNIX"), CONS(KEYWORD("XEDIT"), NIL)); 53255dfecf96Smrg lisp__data.features = ATOM2("*FEATURES*"); 53265dfecf96Smrg LispProclaimSpecial(lisp__data.features, object, NIL); 53275dfecf96Smrg LispExportSymbol(lisp__data.features); 53285dfecf96Smrg 53295dfecf96Smrg object = ATOM2("MULTIPLE-VALUES-LIMIT"); 53305dfecf96Smrg LispDefconstant(object, FIXNUM(MULTIPLE_VALUES_LIMIT + 1), NIL); 53315dfecf96Smrg LispExportSymbol(object); 53325dfecf96Smrg 53335dfecf96Smrg /* Reenable gc */ 53345dfecf96Smrg GCEnable(); 53355dfecf96Smrg 53365dfecf96Smrg LispBytecodeInit(); 53375dfecf96Smrg LispPackageInit(); 53385dfecf96Smrg LispCoreInit(); 53395dfecf96Smrg LispMathInit(); 53405dfecf96Smrg LispPathnameInit(); 53415dfecf96Smrg LispStreamInit(); 53425dfecf96Smrg LispRegexInit(); 53435dfecf96Smrg LispWriteInit(); 53445dfecf96Smrg 53455dfecf96Smrg lisp__data.prompt = isatty(0) ? "> " : NULL; 53465dfecf96Smrg 53475dfecf96Smrg lisp__data.errexit = !lisp__data.interactive; 53485dfecf96Smrg 53495dfecf96Smrg if (lisp__data.interactive) { 53505dfecf96Smrg /* add +, ++, +++, *, **, and *** */ 53515dfecf96Smrg for (i = 0; i < 3; i++) { 53525dfecf96Smrg results[i] = '+'; 53535dfecf96Smrg results[i + 1] = '\0'; 53545dfecf96Smrg RUN[i] = ATOM(results); 53555dfecf96Smrg LispSetVar(RUN[i], NIL); 53565dfecf96Smrg LispExportSymbol(RUN[i]); 53575dfecf96Smrg } 53585dfecf96Smrg for (i = 0; i < 3; i++) { 53595dfecf96Smrg results[i] = '*'; 53605dfecf96Smrg results[i + 1] = '\0'; 53615dfecf96Smrg RES[i] = ATOM(results); 53625dfecf96Smrg LispSetVar(RES[i], NIL); 53635dfecf96Smrg LispExportSymbol(RES[i]); 53645dfecf96Smrg } 53655dfecf96Smrg } 53665dfecf96Smrg else 53675dfecf96Smrg RUN[0] = RUN[1] = RUN[2] = RES[0] = RES[1] = RES[2] = NIL; 53685dfecf96Smrg 53695dfecf96Smrg /* Add LISP builtin functions */ 53705dfecf96Smrg for (i = 0; i < sizeof(lispbuiltins) / sizeof(lispbuiltins[0]); i++) 53715dfecf96Smrg LispAddBuiltinFunction(&lispbuiltins[i]); 53725dfecf96Smrg 53735dfecf96Smrg EXECUTE("(require \"lisp\")"); 53745dfecf96Smrg 53755dfecf96Smrg object = ATOM2("*DEFAULT-PATHNAME-DEFAULTS*"); 53765dfecf96Smrg#ifdef LISPDIR 53775dfecf96Smrg { 53785dfecf96Smrg int length; 5379f765521fSmrg const char *pathname = LISPDIR; 53805dfecf96Smrg 53815dfecf96Smrg length = strlen(pathname); 53825dfecf96Smrg if (length && pathname[length - 1] != '/') { 5383f765521fSmrg char *fixed_pathname = LispMalloc(length + 2); 53845dfecf96Smrg 5385f765521fSmrg strcpy(fixed_pathname, LISPDIR); 5386f765521fSmrg strcpy(fixed_pathname + length, "/"); 5387f765521fSmrg path = LSTRING2(fixed_pathname, length + 1); 53885dfecf96Smrg } 53895dfecf96Smrg else 53905dfecf96Smrg path = LSTRING(pathname, length); 53915dfecf96Smrg } 53925dfecf96Smrg#else 53935dfecf96Smrg path = STRING(""); 53945dfecf96Smrg#endif 53955dfecf96Smrg GCDisable(); 53965dfecf96Smrg LispProclaimSpecial(object, APPLY1(Oparse_namestring, path), NIL); 53975dfecf96Smrg LispExportSymbol(object); 53985dfecf96Smrg GCEnable(); 53995dfecf96Smrg 54005dfecf96Smrg /* Create and make EXT the current package */ 54015dfecf96Smrg PACKAGE = ext = LispNewPackage(STRING("EXT"), NIL); 54025dfecf96Smrg lisp__data.pack = lisp__data.savepack = PACKAGE->data.package.package; 54035dfecf96Smrg 54045dfecf96Smrg /* Update list of packages */ 54055dfecf96Smrg PACK = CONS(ext, PACK); 54065dfecf96Smrg 54075dfecf96Smrg /* Import LISP external symbols in EXT package */ 54085dfecf96Smrg LispUsePackage(lisp__data.lisp); 54095dfecf96Smrg 54105dfecf96Smrg /* Add EXT non standard builtin functions */ 54115dfecf96Smrg for (i = 0; i < sizeof(extbuiltins) / sizeof(extbuiltins[0]); i++) 54125dfecf96Smrg LispAddBuiltinFunction(&extbuiltins[i]); 54135dfecf96Smrg 54145dfecf96Smrg /* Create and make USER the current package */ 54155dfecf96Smrg GCDisable(); 54165dfecf96Smrg PACKAGE = LispNewPackage(STRING("USER"), 54175dfecf96Smrg CONS(STRING("COMMON-LISP-USER"), NIL)); 54185dfecf96Smrg GCEnable(); 54195dfecf96Smrg lisp__data.pack = lisp__data.savepack = PACKAGE->data.package.package; 54205dfecf96Smrg 54215dfecf96Smrg /* Update list of packages */ 54225dfecf96Smrg PACK = CONS(PACKAGE, PACK); 54235dfecf96Smrg 54245dfecf96Smrg /* USER package inherits all LISP external symbols */ 54255dfecf96Smrg LispUsePackage(lisp__data.lisp); 54265dfecf96Smrg /* And all EXT external symbols */ 54275dfecf96Smrg LispUsePackage(ext); 54285dfecf96Smrg 54295dfecf96Smrg LispTopLevel(); 54305dfecf96Smrg} 54315dfecf96Smrg 54325dfecf96Smrgvoid 5433f14f4646SmrgLispEnd(void) 54345dfecf96Smrg{ 54355dfecf96Smrg /* XXX needs to free all used memory, not just close file descriptors */ 54365dfecf96Smrg} 54375dfecf96Smrg 54385dfecf96Smrgvoid 5439f765521fSmrgLispSetPrompt(const char *prompt) 54405dfecf96Smrg{ 54415dfecf96Smrg lisp__data.prompt = prompt; 54425dfecf96Smrg} 54435dfecf96Smrg 54445dfecf96Smrgvoid 54455dfecf96SmrgLispSetInteractive(int interactive) 54465dfecf96Smrg{ 54475dfecf96Smrg lisp__data.interactive = !!interactive; 54485dfecf96Smrg} 54495dfecf96Smrg 54505dfecf96Smrgvoid 54515dfecf96SmrgLispSetExitOnError(int errexit) 54525dfecf96Smrg{ 54535dfecf96Smrg lisp__data.errexit = !!errexit; 54545dfecf96Smrg} 54555dfecf96Smrg 54565dfecf96Smrgvoid 54575dfecf96SmrgLispDebug(int enable) 54585dfecf96Smrg{ 54595dfecf96Smrg lisp__data.debugging = !!enable; 54605dfecf96Smrg 54615dfecf96Smrg#ifdef DEBUGGER 54625dfecf96Smrg /* assumes we are at the toplevel */ 54635dfecf96Smrg DBG = BRK = NIL; 54645dfecf96Smrg lisp__data.debug_level = -1; 54655dfecf96Smrg lisp__data.debug_step = 0; 54665dfecf96Smrg#endif 54675dfecf96Smrg} 5468