2
Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
4
This file is part of GNU Common Lisp, herein referred to as GCL
6
GCL is free software; you can redistribute it and/or modify it under
7
the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
8
the Free Software Foundation; either version 2, or (at your option)
11
GCL is distributed in the hope that it will be useful, but WITHOUT
12
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14
License for more details.
16
You should have received a copy of the GNU Library General Public License
17
along with GCL; see the file COPYING. If not, write to the Free Software
18
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
33
struct nil3 { object nil3_self[3]; } three_nils;
34
struct nil6 { object nil6_self[6]; } six_nils;
75
#define isdeclare(x) ((x) == sLdeclare)
78
lambda_bind(object *arg_top)
82
object lambda, lambda_list, body, form=Cnil, x, ds, vs, v;
84
object *base = vs_base;
85
struct required *required;
87
struct optional *optional=NULL;
89
struct rest *rest=NULL;
91
struct keyword *keyword=NULL;
93
bool allow_other_keys_flag, other_keys_appeared;
97
bool special_processed;
102
if (type_of(lambda) != t_cons)
103
FEerror("No lambda list.", 0);
104
lambda_list = lambda->c.c_car;
105
body = lambda->c.c_cdr;
107
required = (struct required *)vs_top;
110
if (endp(lambda_list))
112
x = lambda_list->c.c_car;
113
lambda_list = lambda_list->c.c_cdr;
115
if (x == ANDallow_other_keys)
117
if (x == ANDoptional) {
118
nopt = nkey = naux = 0;
119
rest_flag = key_flag = allow_other_keys_flag
124
nopt = nkey = naux = 0;
125
key_flag = allow_other_keys_flag
130
nopt = nkey = naux = 0;
131
rest_flag = allow_other_keys_flag
136
nopt = nkey = naux = 0;
137
rest_flag = key_flag = allow_other_keys_flag
141
if ((enum stype)x->s.s_stype == stp_constant)
142
FEerror("~S is not a variable.", 1, x);
149
optional = (struct optional *)vs_top;
151
if (endp(lambda_list))
153
x = lambda_list->c.c_car;
154
lambda_list = lambda_list->c.c_cdr;
155
if (type_of(x) == t_cons) {
156
check_symbol(x->c.c_car);
157
check_var(x->c.c_car);
162
*(struct nil3 *)vs_top = three_nils;
173
check_symbol(x->c.c_car);
174
check_var(x->c.c_car);
177
if (!endp(x->c.c_cdr))
181
if (x == ANDoptional ||
182
x == ANDallow_other_keys)
192
*(struct nil6 *)vs_top = six_nils;
198
rest = (struct rest *)vs_top;
199
if (endp(lambda_list))
201
check_symbol(lambda_list->c.c_car);
202
check_var(lambda_list->c.c_car);
204
vs_push(lambda_list->c.c_car);
206
lambda_list = lambda_list->c.c_cdr;
207
if (endp(lambda_list))
209
x = lambda_list->c.c_car;
210
lambda_list = lambda_list->c.c_cdr;
212
if (x == ANDoptional || x == ANDrest ||
213
x == ANDallow_other_keys)
222
keyword = (struct keyword *)vs_top;
225
if (endp(lambda_list))
227
x = lambda_list->c.c_car;
228
lambda_list = lambda_list->c.c_cdr;
229
if (type_of(x) == t_cons) {
230
if (type_of(x->c.c_car) == t_cons) {
231
if (!keywordp(x->c.c_car->c.c_car))
232
/* FIXME better message */
233
FEunexpected_keyword(x->c.c_car->c.c_car);
234
vs_push(x->c.c_car->c.c_car);
235
if (endp(x->c.c_car->c.c_cdr))
237
check_symbol(x->c.c_car
239
vs_push(x->c.c_car->c.c_cdr->c.c_car);
240
if (!endp(x->c.c_car->c.c_cdr->c.c_cdr))
243
check_symbol(x->c.c_car);
244
check_var(x->c.c_car);
245
vs_push(intern(x->c.c_car, keyword_package));
251
*(struct nil6 *)vs_top = six_nils;
258
*(struct nil6 *)vs_top = six_nils;
262
check_symbol(x->c.c_car);
263
check_var(x->c.c_car);
266
if (!endp(x->c.c_cdr))
272
if (x == ANDallow_other_keys) {
273
allow_other_keys_flag = TRUE;
274
if (endp(lambda_list))
276
x = lambda_list->c.c_car;
277
lambda_list = lambda_list->c.c_cdr;
279
if (x == ANDoptional || x == ANDrest ||
280
x == ANDkey || x == ANDallow_other_keys)
285
vs_push(intern(x, keyword_package));
287
*(struct nil6 *)vs_top = six_nils;
293
aux = (struct aux *)vs_top;
295
if (endp(lambda_list))
297
x = lambda_list->c.c_car;
298
lambda_list = lambda_list->c.c_cdr;
299
if (type_of(x) == t_cons) {
300
check_symbol(x->c.c_car);
301
check_var(x->c.c_car);
310
if (!endp(x->c.c_cdr))
314
if (x == ANDoptional || x == ANDrest ||
315
x == ANDkey || x == ANDallow_other_keys ||
327
for (; !endp(body); body = body->c.c_cdr) {
328
form = body->c.c_car;
330
/* MACRO EXPANSION */
331
form = macro_expand(form);
334
if (type_of(form) == t_string) {
335
if (endp(body->c.c_cdr))
339
if (type_of(form)!=t_cons || !isdeclare(form->c.c_car))
341
for (ds = form->c.c_cdr; !endp(ds); ds = ds->c.c_cdr) {
342
if (type_of(ds->c.c_car) != t_cons)
343
illegal_declare(form);
344
if (ds->c.c_car->c.c_car == sLspecial) {
345
vs = ds->c.c_car->c.c_cdr;
346
for (; !endp(vs); vs = vs->c.c_cdr) {
351
special_processed = FALSE;
352
for (i = 0; i < nreq; i++)
353
if (required[i].req_var == v) {
354
required[i].req_spp = Ct;
355
special_processed = TRUE;
357
for (i = 0; i < nopt; i++)
358
if (optional[i].opt_var == v) {
359
optional[i].opt_spp = Ct;
360
special_processed = TRUE;
361
} else if (optional[i].opt_svar == v) {
362
optional[i].opt_svar_spp = Ct;
363
special_processed = TRUE;
365
if (rest_flag && rest->rest_var == v) {
367
special_processed = TRUE;
369
for (i = 0; i < nkey; i++)
370
if (keyword[i].key_var == v) {
371
keyword[i].key_spp = Ct;
372
special_processed = TRUE;
373
} else if (keyword[i].key_svar == v) {
374
keyword[i].key_svar_spp = Ct;
375
special_processed = TRUE;
377
for (i = 0; i < naux; i++)
378
if (aux[i].aux_var == v) {
380
special_processed = TRUE;
382
if (special_processed)
384
/* lex_special_bind(v); */
385
lex_env[0] = MMcons(MMcons(v, Cnil), lex_env[0]);
393
narg = arg_top - base;
395
if (nopt == 0 && !rest_flag && !key_flag) {
398
check_arg_failed(nreq);
400
FEtoo_few_arguments(base, arg_top);
402
if (!rest_flag && !key_flag && narg > nreq+nopt) {
406
check_arg_failed(nreq);
408
FEtoo_many_arguments(base, arg_top);
410
for (i = 0; i < nreq; i++)
411
bind_var(required[i].req_var,
413
required[i].req_spp);
414
for (i = 0; i < nopt; i++)
416
bind_var(optional[i].opt_var,
418
optional[i].opt_spp);
419
if (optional[i].opt_svar != Cnil)
420
bind_var(optional[i].opt_svar,
422
optional[i].opt_svar_spp);
424
eval_assign(temporary, optional[i].opt_init);
425
bind_var(optional[i].opt_var,
427
optional[i].opt_spp);
428
if (optional[i].opt_svar != Cnil)
429
bind_var(optional[i].opt_svar,
431
optional[i].opt_svar_spp);
435
for (i = narg, j = nreq+nopt; --i >= j; )
436
vs_head = make_cons(base[i], vs_head);
437
bind_var(rest->rest_var, vs_head, rest->rest_spp);
440
i = narg - nreq - nopt;
441
if (i >= 0 && i%2 != 0)
442
/* FIXME better message */
443
FEunexpected_keyword(Cnil);
444
other_keys_appeared = FALSE;
445
for (i = nreq + nopt; i < narg; i += 2) {
446
if (!keywordp(base[i]))
447
FEunexpected_keyword(base[i]);
448
if (base[i] == sKallow_other_keys &&
450
allow_other_keys_flag = TRUE;
451
for (j = 0; j < nkey; j++) {
452
if (keyword[j].key_word == base[i]) {
453
if (keyword[j].key_svar_val
458
keyword[j].key_svar_val
463
other_keys_appeared = TRUE;
468
if (other_keys_appeared && !allow_other_keys_flag)
469
/* FIXME better message */
470
FEunexpected_keyword(Ct);
472
for (i = 0; i < nkey; i++)
473
if (keyword[i].key_svar_val != Cnil) {
474
bind_var(keyword[i].key_var,
477
if (keyword[i].key_svar != Cnil)
478
bind_var(keyword[i].key_svar,
479
keyword[i].key_svar_val,
480
keyword[i].key_svar_spp);
482
eval_assign(temporary, keyword[i].key_init);
483
bind_var(keyword[i].key_var,
486
if (keyword[i].key_svar != Cnil)
487
bind_var(keyword[i].key_svar,
488
keyword[i].key_svar_val,
489
keyword[i].key_svar_spp);
491
for (i = 0; i < naux; i++) {
492
eval_assign(temporary, aux[i].aux_init);
493
bind_var(aux[i].aux_var, temporary, aux[i].aux_spp);
495
if (type_of(body) != t_cons || body->c.c_car == form) {
499
body = make_cons(form, body->c.c_cdr);
507
for (; !endp(body); body = body->c.c_cdr) {
508
form = body->c.c_car;
510
/* MACRO EXPANSION */
511
vs_head = form = macro_expand(form);
513
if (type_of(form) == t_string) {
514
if (endp(body->c.c_cdr))
518
if (type_of(form)!=t_cons || !isdeclare(form->c.c_car))
520
for (ds = form->c.c_cdr; !endp(ds); ds = ds->c.c_cdr) {
521
if (type_of(ds->c.c_car) != t_cons)
522
illegal_declare(form);
523
if (ds->c.c_car->c.c_car == sLspecial) {
524
vs = ds->c.c_car->c.c_cdr;
525
for (; !endp(vs); vs = vs->c.c_cdr) {
530
special_processed = FALSE;
531
for (i = 0; i < nreq; i++)
532
if (required[i].req_var == v) {
533
required[i].req_spp = Ct;
534
special_processed = TRUE;
536
if (special_processed)
538
/* lex_special_bind(v); */
539
temporary = MMcons(v, Cnil);
540
lex_env[0] = MMcons(temporary, lex_env[0]);
548
narg = arg_top - base;
552
check_arg_failed(nreq);
554
for (i = 0; i < nreq; i++)
555
bind_var(required[i].req_var,
557
required[i].req_spp);
558
if (type_of(body) != t_cons || body->c.c_car == form) {
562
body = make_cons(form, body->c.c_cdr);
569
bind_var(object var, object val, object spp)
574
switch (var->s.s_stype) {
576
FEerror("Cannot bind the constant ~S.", 1, var);
584
/* lex_special_bind(var); */
585
temporary = MMcons(var, Cnil);
586
lex_env[0] = MMcons(temporary, lex_env[0]);
589
/* lex_local_bind(var, val); */
590
temporary = MMcons(val, Cnil);
591
temporary = MMcons(var, temporary);
592
lex_env[0] = MMcons(temporary, lex_env[0]);
602
FEerror("Illegal lambda expression.", 0);
615
find_special(object body, struct bind_temp *start, struct bind_temp *end)
620
struct bind_temp *bt;
621
bool special_processed;
625
for (; !endp(body); body = body->c.c_cdr) {
626
form = body->c.c_car;
628
/* MACRO EXPANSION */
629
form = macro_expand(form);
632
if (type_of(form) == t_string) {
633
if (endp(body->c.c_cdr))
637
if (type_of(form)!=t_cons || !isdeclare(form->c.c_car))
639
for (ds = form->c.c_cdr; !endp(ds); ds = ds->c.c_cdr) {
640
if (type_of(ds->c.c_car) != t_cons)
641
illegal_declare(form);
642
if (ds->c.c_car->c.c_car == sLspecial) {
643
vs = ds->c.c_car->c.c_cdr;
644
for (; !endp(vs); vs = vs->c.c_cdr) {
648
special_processed = FALSE;
649
for (bt = start; bt < end; bt++)
650
if (bt->bt_var == v) {
652
special_processed = TRUE;
654
if (special_processed)
656
/* lex_special_bind(v); */
657
temporary = MMcons(v, Cnil);
658
lex_env[0] = MMcons(temporary, lex_env[0]);
665
if (body != Cnil && body->c.c_car != form)
666
body = make_cons(form, body->c.c_cdr);
672
let_bind(object body, struct bind_temp *start, struct bind_temp *end)
674
struct bind_temp *bt;
677
vs_push(find_special(body, start, end));
678
for (bt = start; bt < end; bt++) {
679
eval_assign(bt->bt_init, bt->bt_init);
681
for (bt = start; bt < end; bt++) {
682
bind_var(bt->bt_var, bt->bt_init, bt->bt_spp);
688
letA_bind(object body, struct bind_temp *start, struct bind_temp *end)
690
struct bind_temp *bt;
693
vs_push(find_special(body, start, end));
694
for (bt = start; bt < end; bt++) {
695
eval_assign(bt->bt_init, bt->bt_init);
696
bind_var(bt->bt_var, bt->bt_init, bt->bt_spp);
708
#define NOT_KEYWORD 1
711
parse_key(object *base, bool rest, bool allow_other_keys,int n, ...)
715
object other_key = OBJNULL;
716
int narg, error_flag = 0, allow_other_keys_found=0;
720
narg = vs_top - base;
727
for (i = 0; i < n; i++) {
734
/* FIXME better message */
735
FEunexpected_keyword(Cnil);
739
FEunexpected_keyword(k);
740
if (k == sKallow_other_keys && ! allow_other_keys_found) {
741
allow_other_keys_found=1;
743
allow_other_keys=TRUE;
749
other_key = k == sKallow_other_keys ? OBJNULL : k;
751
for (i = 0; i < n; i++) {
753
if (va_arg(ap,object) == k) {
764
temporary = make_cons(temporary, Cnil);
765
base[-1] = make_cons(k, temporary);
767
if (other_key != OBJNULL && !allow_other_keys)
768
FEunexpected_keyword(other_key);
772
for (i = 0; i < n; i++) {
773
k = va_arg(ap,object);
774
k->s.s_stype = NOT_YET;
778
for (v = base; v < vs_top; v += 2) {
781
error_flag = NOT_KEYWORD;
785
if (k->s.s_stype == NOT_YET) {
787
k->s.s_stype = FOUND;
788
} else if (k->s.s_stype == FOUND) {
790
} else if (other_key == OBJNULL && k!=sKallow_other_keys)
792
if (k == sKallow_other_keys && !allow_other_keys_found) {
793
allow_other_keys_found=1;
795
allow_other_keys = TRUE;
802
while (base < vs_top)
808
for (i = 0; i < n; i++) {
809
k = va_arg(ap,object);
810
base[i] = k->s.s_dbind;
811
top[i] = k->s.s_stype == FOUND ? Ct : Cnil;
813
k->s.s_stype = (short)stp_constant;
816
if (error_flag == NOT_KEYWORD)
817
FEunexpected_keyword(other_key);
818
if (other_key != OBJNULL && !allow_other_keys)
819
FEunexpected_keyword(other_key);
823
check_other_key(object l, int n, ...)
826
object other_key = OBJNULL;
829
bool allow_other_keys = FALSE;
831
for (; !endp(l); l = l->c.c_cdr->c.c_cdr) {
834
FEunexpected_keyword(k);
835
if (endp(l->c.c_cdr))
836
/* FIXME better message */
837
FEunexpected_keyword(Cnil);
838
if (k == sKallow_other_keys && l->c.c_cdr->c.c_car != Cnil) {
839
allow_other_keys = TRUE;
844
for (i = 0; i < n; i++)
845
{ if (va_arg(ap,object) == k &&
846
buf[i] ==0) {buf[i]=1; break;}}
848
if (i >= n) other_key = k;
851
if (other_key != OBJNULL && !allow_other_keys)
852
FEunexpected_keyword(other_key);
856
/* struct key {short n,allow_other_keys; */
857
/* iobject *defaults; */
858
/* iobject keys[1]; */
862
object Cstd_key_defaults[15]={Cnil,Cnil,Cnil,Cnil,Cnil,Cnil,Cnil,
863
Cnil,Cnil,Cnil,Cnil,Cnil,Cnil,Cnil,Cnil};
865
/* FIXME rewrite this */
867
/* parse_key_new(int n, object *base, struct key *keys, va_list ap) */
869
/* COERCE_VA_LIST(new,ap,n); */
871
/* new = new + n ; */
872
/* {int j=keys->n; */
873
/* object *p= (object *)(keys->defaults); */
874
/* while (--j >=0) base[j]=p[j]; */
876
/* {if (n==0){ return 0;} */
877
/* {int allow = keys->allow_other_keys; */
882
/* for (i=n;i>0 && new[-i]!=sKallow_other_keys;i-=2); */
883
/* if (i>0 && new[-i+1]!=Cnil) */
889
/* {int i= keys->n; */
890
/* iobject *ke=keys->keys ; */
893
/* while(--i >= 0) */
894
/* {if ((*(ke++)).o == k) */
895
/* {base[i]= new[1]; */
899
/* the key is a new one */
900
/* if (allow || k==sKallow_other_keys) */
905
/* FIXME better message */
906
/* if (n!=0) FEunexpected_keyword(Cnil); */
909
/* FEunexpected_keyword(k); */
914
parse_key_new_new(int n, object *base, struct key *keys, object first, va_list ap)
916
COERCE_VA_LIST_NEW(new,first,ap,n);
918
/* from here down identical to parse_key_rest */
921
object *p= (object *)(keys->defaults);
922
while (--j >=0) base[j]=p[j];
924
{if (n==0){ return 0;}
925
{int allow = keys->allow_other_keys;
930
for (i=n;i>0 && new[-i]!=sKallow_other_keys;i-=2);
931
if (i>0 && new[-i+1]!=Cnil)
938
iobject *ke=keys->keys ;
942
{if ((*(ke++)).o == k)
947
/* the key is a new one */
948
if (allow || k==sKallow_other_keys)
953
/* FIXME better message */
954
if (n!=0) FEunexpected_keyword(Cnil);
957
FEunexpected_keyword(k);
962
/* parse_key_rest(object rest, int n, object *base, struct key *keys, va_list ap) */
964
/* COERCE_VA_LIST(new,ap,n); */
966
/* copy the rest arg */
967
/* {object *p = new; */
969
/* while (--m >= 0) */
970
/* {rest->c.c_car = *p++; */
971
/* rest = rest->c.c_cdr;}} */
973
/* new = new + n ; */
974
/* {int j=keys->n; */
975
/* object *p= (object *)(keys->defaults); */
976
/* while (--j >=0) base[j]=p[j]; */
978
/* {if (n==0){ return 0;} */
979
/* {int allow = keys->allow_other_keys; */
984
/* for (i=n;i>0 && new[-i]!=sKallow_other_keys;i-=2); */
985
/* if (i>0 && new[-i+1]!=Cnil) */
991
/* {int i= keys->n; */
992
/* iobject *ke=keys->keys ; */
995
/* while(--i >= 0) */
996
/* {if ((*(ke++)).o == k) */
997
/* {base[i]= new[1]; */
1001
/* the key is a new one */
1002
/* if (allow || k==sKallow_other_keys) */
1007
/* FIXME better message */
1008
/* if (n!=0) FEunexpected_keyword(Cnil); */
1011
/* FEunexpected_keyword(k); */
1016
parse_key_rest_new(object rest, int n, object *base, struct key *keys, object first,va_list ap)
1018
COERCE_VA_LIST_NEW(new,first,ap,n);
1020
/* copy the rest arg */
1024
{rest->c.c_car = *p++;
1025
rest = rest->c.c_cdr;}}
1029
object *p= (object *)(keys->defaults);
1030
while (--j >=0) base[j]=p[j];
1032
{if (n==0){ return 0;}
1033
{int allow = keys->allow_other_keys;
1038
for (i=n;i>0 && new[-i]!=sKallow_other_keys;i-=2);
1039
if (i>0 && new[-i+1]!=Cnil)
1046
iobject *ke=keys->keys ;
1050
{if ((*(ke++)).o == k)
1055
/* the key is a new one */
1056
if (allow || k==sKallow_other_keys)
1061
/* FIXME better message */
1062
if (n!=0) FEunexpected_keyword(Cnil);
1065
FEunexpected_keyword(k);
1071
set_key_struct(struct key *ks, object data)
1074
{ks->keys[i].o = data->cfd.cfd_self[ ks->keys[i].i ];
1075
if (ks->defaults != (void *)Cstd_key_defaults)
1076
{fixnum m=ks->defaults[i].i;
1080
data->cfd.cfd_self[m]);}
1085
DEF_ORDINARY("ALLOW-OTHER-KEYS",sKallow_other_keys,KEYWORD,"");
1091
ANDoptional = make_ordinary("&OPTIONAL");
1092
enter_mark_origin(&ANDoptional);
1093
ANDrest = make_ordinary("&REST");
1094
enter_mark_origin(&ANDrest);
1095
ANDkey = make_ordinary("&KEY");
1096
enter_mark_origin(&ANDkey);
1097
ANDallow_other_keys = make_ordinary("&ALLOW-OTHER-KEYS");
1098
enter_mark_origin(&ANDallow_other_keys);
1099
ANDaux = make_ordinary("&AUX");
1100
enter_mark_origin(&ANDaux);
1102
make_constant("LAMBDA-LIST-KEYWORDS",
1103
make_cons(ANDoptional,
1106
make_cons(ANDallow_other_keys,
1108
make_cons(make_ordinary("&WHOLE"),
1109
make_cons(make_ordinary("&ENVIRONMENT"),
1110
make_cons(make_ordinary("&BODY"), Cnil)))))))));
1112
make_constant("LAMBDA-PARAMETERS-LIMIT",
1117
three_nils.nil3_self[0] = Cnil;
1118
three_nils.nil3_self[1] = Cnil;
1119
three_nils.nil3_self[2] = Cnil;
1121
six_nils.nil6_self[0] = Cnil;
1122
six_nils.nil6_self[1] = Cnil;
1123
six_nils.nil6_self[2] = Cnil;
1124
six_nils.nil6_self[3] = Cnil;
1125
six_nils.nil6_self[4] = Cnil;
1126
six_nils.nil6_self[5] = Cnil;