Edinburgh Speech Tools  2.1-release
slib_list.cc
Go to the documentation of this file.
1 /*
2  * COPYRIGHT (c) 1988-1994 BY *
3  * PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. *
4  * See the source file SLIB.C for more information. *
5 
6  * Reorganization of files (Mar 1999) by Alan W Black <awb@cstr.ed.ac.uk>
7 
8  * General list functions
9 
10 */
11 #include <cstdio>
12 #include "siod.h"
13 #include "siodp.h"
14 
15 static LISP llength(LISP obj)
16 {LISP l;
17  long n;
18  switch TYPE(obj)
19  {case tc_string:
20  return(flocons(obj->storage_as.string.dim));
21  case tc_double_array:
22  return(flocons(obj->storage_as.double_array.dim));
23  case tc_long_array:
24  return(flocons(obj->storage_as.long_array.dim));
25  case tc_lisp_array:
26  return(flocons(obj->storage_as.lisp_array.dim));
27  case tc_nil:
28  return(flocons(0.0));
29  case tc_cons:
30  for(l=obj,n=0;CONSP(l);l=CDR(l),++n) INTERRUPT_CHECK();
31  if NNULLP(l) err("improper list to length",obj);
32  return(flocons(n));
33  default:
34  err("wrong type of argument to length",obj);}}
35 
36 LISP assoc(LISP x,LISP alist)
37 {LISP l,tmp;
38  for(l=alist;CONSP(l);l=CDR(l))
39  {tmp = CAR(l);
40  if (CONSP(tmp) && equal(CAR(tmp),x)) return(tmp);
41  INTERRUPT_CHECK();}
42  if EQ(l,NIL) return(NIL);
43  err("improper list to assoc",alist);}
44 
45 LISP assq(LISP x,LISP alist)
46 {LISP l,tmp;
47  for(l=alist;CONSP(l);l=CDR(l))
48  {tmp = CAR(l);
49  if (CONSP(tmp) && EQ(CAR(tmp),x)) return(tmp);
50  INTERRUPT_CHECK();}
51  if EQ(l,NIL) return(NIL);
52  err("improper list to assq",alist);}
53 
54 LISP setcar(LISP cell, LISP value)
55 {if NCONSP(cell) err("wrong type of argument to setcar",cell);
56  return(CAR(cell) = value);}
57 
58 LISP setcdr(LISP cell, LISP value)
59 {if NCONSP(cell) err("wrong type of argument to setcdr",cell);
60  return(CDR(cell) = value);}
61 
62 LISP delq(LISP elem,LISP l)
63 {if NULLP(l) return(l);
64  STACK_CHECK(&elem);
65  if EQ(elem,car(l)) return(cdr(l));
66  setcdr(l,delq(elem,cdr(l)));
67  return(l);}
68 
69 LISP copy_list(LISP x)
70 {if NULLP(x) return(NIL);
71  STACK_CHECK(&x);
72  return(cons(car(x),copy_list(cdr(x))));}
73 
74 static LISP eq(LISP x,LISP y)
75 {if EQ(x,y) return(truth); else return(NIL);}
76 
77 LISP eql(LISP x,LISP y)
78 {if EQ(x,y) return(truth); else
79  if NFLONUMP(x) return(NIL); else
80  if NFLONUMP(y) return(NIL); else
81  if (FLONM(x) == FLONM(y)) return(truth);
82  return(NIL);}
83 
84 static LISP nullp(LISP x)
85 {if EQ(x,NIL) return(truth); else return(NIL);}
86 
87 LISP siod_flatten(LISP tree)
88 {
89  if (tree == NIL)
90  return NIL;
91  else if (consp(tree))
92  return append(siod_flatten(car(tree)),siod_flatten(cdr(tree)));
93  else
94  return cons(tree,NIL);
95 }
96 
97 LISP cons(LISP x,LISP y)
98 {LISP z;
99  NEWCELL(z,tc_cons);
100  CAR(z) = x;
101  CDR(z) = y;
102  return(z);}
103 
104 LISP atomp(LISP x)
105 {
106  if ((x==NIL) || CONSP(x))
107  return NIL;
108  else
109  return truth;
110 }
111 
112 LISP consp(LISP x)
113 {if CONSP(x) return(truth); else return(NIL);}
114 
115 LISP car(LISP x)
116 {switch TYPE(x)
117  {case tc_nil:
118  return(NIL);
119  case tc_cons:
120  return(CAR(x));
121  default:
122  err("wrong type of argument to car",x);}}
123 
124 LISP cdr(LISP x)
125 {switch TYPE(x)
126  {case tc_nil:
127  return(NIL);
128  case tc_cons:
129  return(CDR(x));
130  default:
131  err("wrong type of argument to cdr",x);}}
132 
133 LISP equal(LISP a,LISP b)
134 {struct user_type_hooks *p;
135  long atype;
136  STACK_CHECK(&a);
137  loop:
138  INTERRUPT_CHECK();
139  if EQ(a,b) return(truth);
140  if (a==NULL || b == NULL) return(NIL);
141  atype = TYPE(a);
142  if (atype != TYPE(b)) return(NIL);
143  switch(atype)
144  {case tc_cons:
145  if NULLP(equal(car(a),car(b))) return(NIL);
146  a = cdr(a);
147  b = cdr(b);
148  goto loop;
149  case tc_flonum:
150  return((FLONM(a) == FLONM(b)) ? truth : NIL);
151  case tc_symbol:
152  case tc_closure:
153  case tc_subr_0:
154  case tc_subr_1:
155  case tc_subr_2:
156  case tc_subr_3:
157  case tc_subr_4:
158  case tc_lsubr:
159  case tc_fsubr:
160  case tc_msubr:
161  return(NIL);
162  default:
163  p = get_user_type_hooks(atype);
164  if (p && p->equal)
165  return((*p->equal)(a,b));
166  else if (p) /* a user type */
167  return ((USERVAL(a) == USERVAL(b)) ? truth : NIL);
168  else
169  return(NIL);}}
170 
171 LISP reverse(LISP l)
172 {LISP n,p;
173  n = NIL;
174  for(p=l;NNULLP(p);p=cdr(p)) n = cons(car(p),n);
175  return(n);}
176 
177 LISP append(LISP l1, LISP l2)
178 {LISP n=l2,p,rl1 = reverse(l1);
179  for(p=rl1;NNULLP(p);p=cdr(p))
180  n = cons(car(p),n);
181  return(n);}
182 
183 void init_subrs_list(void)
184 {
185  init_subr_2("assoc",assoc,
186  "(assoc KEY A-LIST)\n\
187  Return pair with KEY in A-LIST or nil.");
188  init_subr_1("length",llength,
189  "(length LIST)\n\
190  Return length of LIST, or 0 if LIST is not a list.");
191  init_subr_1("flatten",siod_flatten,
192  "(flatten LIST)\n\
193  Return flatend list (list of all atoms in LIST).");
194  init_subr_2("assq",assq,
195  "(assq ITEM ALIST)\n\
196  Returns pairs from ALIST whose car is ITEM or nil if ITEM is not in ALIST.");
197  init_subr_2("delq",delq,
198  "(delq ITEM LIST)\n\
199  Destructively delete ITEM from LIST, returns LIST, if ITEM is not first\n\
200  in LIST, cdr of LIST otherwise. If ITEM is not in LIST, LIST is\n\
201  returned unchanged." );
202  init_subr_1("copy-list",copy_list,
203  "(copy-list LIST)\n\
204  Return new list with same members as LIST.");
205  init_subr_2("cons",cons,
206  "(cons DATA1 DATA2)\n\
207  Construct cons pair whose car is DATA1 and cdr is DATA2.");
208  init_subr_1("pair?",consp,
209  "(pair? DATA)\n\
210  Returns t if DATA is a cons cell, nil otherwise.");
211  init_subr_1("car",car,
212  "(car DATA1)\n\
213  Returns car of DATA1. If DATA1 is nil or a symbol, return nil.");
214  init_subr_1("cdr",cdr,
215  "(cdr DATA1)\n\
216  Returns cdr of DATA1. If DATA1 is nil or a symbol, return nil.");
217  init_subr_2("set-car!",setcar,
218  "(set-car! CONS1 DATA1)\n\
219  Set car of CONS1 to be DATA1. Returns CONS1. If CONS1 not of type\n\
220  consp an error is is given. This is a destructive operation.");
221  init_subr_2("set-cdr!",setcdr,
222  "(set-cdr! CONS1 DATA1)\n\
223  Set cdr of CONS1 to be DATA1. Returns CONS1. If CONS1 not of type\n\
224  consp an error is is given. This is a destructive operation.");
225  init_subr_2("eq?",eq,
226  "(eq? DATA1 DATA2)\n\
227  Returns t if DATA1 and DATA2 are the same object.");
228  init_subr_2("eqv?",eql,
229  "(eqv? DATA1 DATA2)\n\
230  Returns t if DATA1 and DATA2 are the same object or equal numbers.");
231  init_subr_2("equal?",equal,
232  "(equal? A B)\n\
233  t if s-expressions A and B are recursively equal, nil otherwise.");
234  init_subr_1("not",nullp,
235  "(not DATA)\n\
236  Returns t if DATA is nil, nil otherwise.");
237  init_subr_1("null?",nullp,
238  "(null? DATA)\n\
239  Returns t if DATA is nil, nil otherwise.");
240  init_subr_1("reverse",reverse,
241  "(reverse LIST)\n\
242  Returns destructively reversed LIST.");
243  init_subr_2("append",append,
244  "(append LIST1 LIST2)\n\
245  Returns LIST2 appended to LIST1, LIST1 is distroyed.");
246 }
Definition: siod_defs.h:32
#define tc_fsubr
Definition: siod_defs.h:112
#define INTERRUPT_CHECK()
Definition: siodp.h:87
#define tc_symbol
Definition: siod_defs.h:106
#define NULLP(x)
Definition: siod_defs.h:95
LISP setcar(LISP cell, LISP value)
Definition: slib_list.cc:54
LISP car(LISP x)
Definition: slib_list.cc:115
LISP siod_flatten(LISP tree)
Definition: slib_list.cc:87
LISP delq(LISP elem, LISP l)
Definition: slib_list.cc:62
#define NIL
Definition: siod_defs.h:92
#define STACK_CHECK(_ptr)
Definition: siodp.h:94
void init_subr_2(const char *name, LISP(*fcn)(LISP, LISP), const char *doc)
Definition: slib.cc:900
#define EQ(x, y)
Definition: siod_defs.h:93
#define NEWCELL(_into, _type)
Definition: siodp.h:69
LISP equal(LISP a, LISP b)
Definition: slib_list.cc:133
#define tc_flonum
Definition: siod_defs.h:105
#define NFLONUMP(x)
Definition: siod_defs.h:159
#define TYPE(x)
Definition: siod_defs.h:98
LISP assq(LISP x, LISP alist)
Definition: slib_list.cc:45
#define tc_lisp_array
Definition: siod_defs.h:119
LISP cons(LISP x, LISP y)
Definition: slib_list.cc:97
void err(const char *message, LISP x) EST_NORETURN
Definition: slib.cc:608
#define tc_lsubr
Definition: siod_defs.h:111
LISP consp(LISP x)
Definition: slib_list.cc:112
LISP(* equal)(LISP, LISP)
Definition: siodp.h:56
#define tc_msubr
Definition: siod_defs.h:113
#define NCONSP(x)
Definition: siod_defs.h:158
#define tc_nil
Definition: siod_defs.h:103
#define l2
#define tc_cons
Definition: siod_defs.h:104
LISP reverse(LISP l)
Definition: slib_list.cc:171
#define tc_subr_0
Definition: siod_defs.h:107
LISP setcdr(LISP cell, LISP value)
Definition: slib_list.cc:58
NULL
Definition: EST_WFST.cc:55
void init_subr_1(const char *name, LISP(*fcn)(LISP), const char *doc)
Definition: slib.cc:898
#define tc_subr_3
Definition: siod_defs.h:110
LISP append(LISP l1, LISP l2)
Definition: slib_list.cc:177
LISP cdr(LISP x)
Definition: slib_list.cc:124
#define tc_closure
Definition: siod_defs.h:114
#define CAR(x)
Definition: siod_defs.h:76
#define tc_string
Definition: siod_defs.h:116
LISP eql(LISP x, LISP y)
Definition: slib_list.cc:77
#define tc_subr_2
Definition: siod_defs.h:109
void init_subrs_list(void)
Definition: slib_list.cc:183
LISP assoc(LISP x, LISP alist)
Definition: slib_list.cc:36
#define tc_subr_4
Definition: siod_defs.h:122
struct user_type_hooks * get_user_type_hooks(long type)
Definition: slib.cc:913
LISP flocons(double x)
Definition: slib.cc:673
#define tc_subr_1
Definition: siod_defs.h:108
#define l1
LISP copy_list(LISP x)
Definition: slib_list.cc:69
#define USERVAL(x)
Definition: siod_defs.h:89
int tree
Definition: rxp.c:21
LISP truth
Definition: slib.cc:135
#define tc_double_array
Definition: siod_defs.h:117
#define tc_long_array
Definition: siod_defs.h:118
#define CONSP(x)
Definition: siod_defs.h:153
LISP atomp(LISP x)
Definition: slib_list.cc:104
#define CDR(x)
Definition: siod_defs.h:77
#define FLONM(x)
Definition: siod_defs.h:87
#define NNULLP(x)
Definition: siod_defs.h:96