Commit | Line | Data |
---|---|---|
4b9ccde7 | 1 | static char *sccsid = "@(#)eval2.c 35.2 5/18/81"; |
31cef89c | 2 | |
8cd657f4 | 3 | #include "global.h" |
31cef89c BJ |
4 | |
5 | /* Iarray - handle array call. | |
6 | * fun - array object | |
7 | * args - arguments to the array call , most likely subscripts. | |
8 | * evalp - flag, if TRUE then the arguments should be evaluated when they | |
9 | * are stacked. | |
10 | */ | |
8cd657f4 | 11 | lispval |
31cef89c | 12 | Iarray(fun,args,evalp) |
8cd657f4 JF |
13 | register lispval fun,args; |
14 | { | |
15 | register lispval reg, temp; | |
16 | register struct argent *lbot, *np; | |
8cd657f4 JF |
17 | |
18 | lbot = np; | |
31cef89c BJ |
19 | protect(fun->ar.accfun); |
20 | for ( ; args != nil ; args = args->d.cdr) /* stack subscripts */ | |
21 | if(evalp) protect(eval(args->d.car)); | |
22 | else protect(args->d.car); | |
23 | protect(fun); | |
8cd657f4 | 24 | return(vtemp = Lfuncal()); |
8cd657f4 | 25 | } |
8cd657f4 | 26 | |
4b9ccde7 C |
27 | /* Ifcall :: call foreign function/subroutine |
28 | * Ifcall is handed a binary object which is the function to call. | |
29 | * This function has already been determined to be a foreign function | |
30 | * by noticing that its discipline field is a string. | |
31 | * The arguments to pass have already been evaluated and stacked. We | |
32 | * create on the stack a 'callg' type argument list to give to the | |
33 | * function. What is passed to the foreign function depends on the | |
34 | * type of argument. Certain args are passes directly, others must be | |
35 | * copied since the foreign function my want to change them. | |
36 | * When the foreign function returns, we may have to box the result, | |
37 | * depending on the type of foreign function. | |
38 | */ | |
8cd657f4 JF |
39 | lispval |
40 | Ifcall(a) | |
31cef89c | 41 | lispval a; |
8cd657f4 JF |
42 | { |
43 | int *alloca(); | |
44 | register int *arglist; | |
45 | register int index; | |
46 | register struct argent *mynp; | |
47 | register lispval ltemp; | |
48 | register struct argent *lbot; | |
49 | register struct argent *np; | |
31cef89c | 50 | int itemp; |
8cd657f4 JF |
51 | int nargs = np - lbot; |
52 | ||
53 | arglist = alloca((nargs + 1) * sizeof(int)); | |
54 | mynp = lbot; | |
55 | *arglist = nargs; | |
56 | for(index = 1; index <= nargs; index++) { | |
31cef89c | 57 | switch(TYPE(ltemp=mynp->val)) { |
4b9ccde7 | 58 | /* fixnums and flonums must be reboxed */ |
8cd657f4 JF |
59 | case INT: |
60 | arglist[index] = sp(); | |
61 | stack(0); | |
31cef89c | 62 | *(int *) arglist[index] = ltemp->i; |
8cd657f4 JF |
63 | break; |
64 | case DOUB: | |
65 | stack(0); | |
66 | arglist[index] = sp(); | |
67 | stack(0); | |
31cef89c BJ |
68 | *(double *) arglist[index] = ltemp->r; |
69 | break; | |
4b9ccde7 C |
70 | |
71 | /* these can all be sent directly */ | |
31cef89c BJ |
72 | case HUNK2: |
73 | case HUNK4: | |
74 | case HUNK8: | |
75 | case HUNK16: | |
76 | case HUNK32: | |
77 | case HUNK64: | |
78 | case HUNK128: | |
79 | case DTPR: | |
80 | case ATOM: | |
81 | case SDOT: | |
4b9ccde7 | 82 | case STRNG: |
31cef89c | 83 | arglist[index] = (int) ltemp; |
8cd657f4 | 84 | break; |
4b9ccde7 | 85 | /* these cause only part of the structure to be sent */ |
31cef89c | 86 | |
8cd657f4 | 87 | case ARRAY: |
31cef89c BJ |
88 | arglist[index] = (int) ltemp->ar.data; |
89 | break; | |
90 | ||
91 | ||
92 | case BCD: | |
93 | arglist[index] = (int) ltemp->bcd.entry; | |
94 | break; | |
95 | ||
96 | default: | |
97 | error("foreign call: illegal argument ",FALSE); | |
98 | break; | |
8cd657f4 JF |
99 | } |
100 | mynp++; | |
101 | } | |
31cef89c BJ |
102 | switch(((char *)a->bcd.discipline)[0]) { |
103 | case 'i': /* integer-function */ | |
104 | ltemp = inewint(callg(a->bcd.entry,arglist)); | |
8cd657f4 JF |
105 | break; |
106 | ||
31cef89c | 107 | case 'r': /* real-function*/ |
8cd657f4 | 108 | ltemp = newdoub(); |
31cef89c BJ |
109 | ltemp->r = (* ((double (*)()) callg))(a->bcd.entry,arglist); |
110 | break; | |
111 | ||
112 | case 'f': /* function */ | |
113 | ltemp = (lispval) callg(a->bcd.entry,arglist); | |
8cd657f4 JF |
114 | break; |
115 | ||
116 | default: | |
31cef89c BJ |
117 | case 's': /* subroutine */ |
118 | callg(a->bcd.entry,arglist); | |
8cd657f4 JF |
119 | ltemp = tatom; |
120 | } | |
31cef89c | 121 | return(ltemp); |
8cd657f4 | 122 | } |
4b9ccde7 C |
123 | |
124 | ||
8cd657f4 JF |
125 | callg(funct,arglist) |
126 | lispval (*funct)(); | |
127 | int *arglist; | |
128 | { | |
129 | asm(" callg *8(ap),*4(ap)"); | |
130 | } |