123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- %
- % EVAL-APPLY.RED - Function calling mechanism
- %
- % Author: Eric Benson
- % Symbolic Computation Group
- % Computer Science Dept.
- % University of Utah
- % Date: 20 August 1981
- % Copyright (c) 1981 University of Utah
- %
- % <PSL.KERNEL>EVAL-APPLY.RED.2, 20-Sep-82 10:36:28, Edit by BENSON
- % CAR of a form is never evaluated
- % <PSL.INTERP>EVAL-APPLY.RED.5, 6-Jan-82 19:22:46, Edit by GRISS
- % Add NEXPR
- % FUnBoundP and other function cell primitives found in FUNCTION-PRIMITIVES
- % Eval and Apply could have been defined using only GetD rather than these
- % primitves. They are used instead to avoid the CONS in GETD.
- % ValueCell is found in SYMBOL-VALUES.RED
- % IDApply, CodeApply, IDEvalApply and CodeEvalApply are written in LAP
- % due to register usage and to make them faster. They are found in
- % APPLY-LAP.RED. IDApply1 is handled by the compiler
- % uses EvProgN, found in EASY-SL.RED, expr for PROGN
- % Error numbers:
- % 1000 - undefined function
- % 1100 - ill-formed function expression
- % 1200 - argument number mismatch
- % 1300 - unknown function type
- % +3 in LambdaEvalApply
- % +4 in LambdaApply
- % +2 in Apply
- % +1 in Eval
- CompileTime flag('(LambdaEvalApply LambdaApply), 'InternalFunction);
- on SysLisp;
- % the only reason these 2 are in Syslisp is to speed up arithmetic (N := N + 1)
- syslsp procedure LambdaEvalApply(Fn, Args); %. Fn is Lambda, Args to be Evaled
- if not (PairP Fn and car Fn = 'LAMBDA) then
- ContinuableError('1103,
- '"Ill-formed function expression",
- Fn . Args)
- else begin scalar N, Result;
- N := BindEval(cadr Fn, Args); % hand-coded, bind formals to evlis args
- if N = -1 then return
- ContinuableError('1203,
- '"Argument number mismatch",
- Fn . Args);
- Result := EvProgN cddr Fn;
- if N neq 0 then UnBindN N;
- return Result;
- end;
- syslsp procedure LambdaApply(Fn, Args); %. Fn is Lambda, unevaled Args
- if not (PairP Fn and car Fn = 'LAMBDA) then
- ContinuableError('1104,
- '"Ill-formed function expression",
- Fn . for each X in Args collect MkQuote X)
- else begin scalar Formals, N, Result;
- Formals := cadr Fn;
- N := 0;
- while PairP Formals and PairP Args do
- << LBind1(car Formals, car Args);
- Formals := cdr Formals;
- Args := cdr Args;
- N := N + 1 >>;
- if PairP Formals or PairP Args then return
- ContinuableError('1204,
- '"Argument number mismatch",
- Fn . for each X in Args collect MkQuote X);
- Result := EvProgN cddr Fn;
- if N neq 0 then UnBindN N;
- return Result;
- end;
- off SysLisp;
- % Apply differs from the Standard Lisp Report in that functions other
- % than EXPRs are allowed to be applied, the effect being the same as
- % Apply(cdr GetD Fn, Args)
- lisp procedure Apply(Fn, Args); %. Indirect function call
- if IDP Fn then begin scalar StackMarkForBacktrace, Result;
- if FUnBoundP Fn then return
- ContinuableError(1002,
- BldMsg("%r is an undefined function", Fn),
- Fn . for each X in Args collect MkQuote X);
- StackMarkForBacktrace := MkBTR Inf Fn;
- Result := if FCodeP Fn then CodeApply(GetFCodePointer Fn, Args)
- else LambdaApply(get(Fn, '!*LambdaLink), Args);
- return Result;
- end
- else if CodeP Fn then CodeApply(Fn, Args)
- else if PairP Fn and car Fn = 'LAMBDA then
- LambdaApply(Fn, Args)
- else
- ContinuableError(1102,
- "Ill-formed function expression",
- Fn . for each X in Args collect MkQuote X);
- lisp procedure Eval U; %. Interpret S-Expression as program
- if not PairP U then
- if not IDP U then U else ValueCell U
- else begin scalar Fn;
- Fn := car U;
- return if IDP Fn then
- if FUnBoundP Fn then
- ContinuableError(1300,
- BldMsg("%r is an undefined function", Fn),
- U)
- else begin scalar FnType, StackMarkForBacktrace, Result;
- FnType := GetFnType Fn;
- StackMarkForBacktrace := MkBTR Inf Fn;
- Result := if null FnType then % must be an EXPR
- if FCodeP Fn then
- CodeEvalApply(GetFCodePointer Fn, cdr U)
- else LambdaEvalApply(get(Fn, '!*LambdaLink),
- cdr U)
- else if FnType = 'FEXPR then
- IDApply1(cdr U, Fn)
- else if FnType = 'NEXPR then
- IDApply1(EvLis cdr U, Fn)
- else if FnType = 'MACRO then
- Eval IDApply1(U, Fn)
- else
- ContinuableError(1301,
- BldMsg("Unknown function type %r",
- FnType),
- U);
- return Result;
- end
- else if CodeP Fn then CodeEvalApply(Fn, cdr U)
- else if PairP Fn and car Fn = 'LAMBDA then
- LambdaEvalApply(Fn, cdr U)
- else ContinuableError(1302,
- BldMsg("Ill-formed expression in Eval %r", U),
- U);
- end;
- END;
|