1 /*
2 * ALSA lisp implementation
3 * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
4 *
5 * Based on work of Sandro Sigala (slisp-1.2)
6 *
7 *
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 */
23
24 #include "list.h"
25
26 enum alisp_tokens {
27 ALISP_IDENTIFIER,
28 ALISP_INTEGER,
29 ALISP_FLOAT,
30 ALISP_FLOATE,
31 ALISP_STRING
32 };
33
34 enum alisp_objects {
35 ALISP_OBJ_INTEGER,
36 ALISP_OBJ_FLOAT,
37 ALISP_OBJ_IDENTIFIER,
38 ALISP_OBJ_STRING,
39 ALISP_OBJ_POINTER,
40 ALISP_OBJ_CONS,
41 ALISP_OBJ_LAST_SEARCH = ALISP_OBJ_CONS,
42 ALISP_OBJ_NIL,
43 ALISP_OBJ_T,
44 };
45
46 struct alisp_object;
47
48 #define ALISP_TYPE_MASK 0xf0000000
49 #define ALISP_TYPE_SHIFT 28
50 #define ALISP_REFS_MASK 0x0fffffff
51 #define ALISP_REFS_SHIFT 0
52 #define ALISP_MAX_REFS (ALISP_REFS_MASK>>ALISP_REFS_SHIFT)
53 #define ALISP_MAX_REFS_LIMIT ((ALISP_MAX_REFS + 1) / 2)
54
55 struct alisp_object {
56 struct list_head list;
57 unsigned int type_refs; /* type and count of references */
58 union {
59 char *s;
60 long i;
61 double f;
62 const void *ptr;
63 struct {
64 struct alisp_object *car;
65 struct alisp_object *cdr;
66 } c;
67 } value;
68 };
69
alisp_get_type(struct alisp_object * p)70 static inline enum alisp_objects alisp_get_type(struct alisp_object *p)
71 {
72 return (p->type_refs >> ALISP_TYPE_SHIFT);
73 }
74
alisp_set_type(struct alisp_object * p,enum alisp_objects type)75 static inline void alisp_set_type(struct alisp_object *p, enum alisp_objects type)
76 {
77 p->type_refs &= ~ALISP_TYPE_MASK;
78 p->type_refs |= (unsigned int)type << ALISP_TYPE_SHIFT;
79 }
80
alisp_compare_type(struct alisp_object * p,enum alisp_objects type)81 static inline int alisp_compare_type(struct alisp_object *p, enum alisp_objects type)
82 {
83 return ((unsigned int)type << ALISP_TYPE_SHIFT) ==
84 (p->type_refs & ALISP_TYPE_MASK);
85 }
86
alisp_set_refs(struct alisp_object * p,unsigned int refs)87 static inline void alisp_set_refs(struct alisp_object *p, unsigned int refs)
88 {
89 p->type_refs &= ~ALISP_REFS_MASK;
90 p->type_refs |= refs & ALISP_REFS_MASK;
91 }
92
alisp_get_refs(struct alisp_object * p)93 static inline unsigned int alisp_get_refs(struct alisp_object *p)
94 {
95 return p->type_refs & ALISP_REFS_MASK;
96 }
97
alisp_inc_refs(struct alisp_object * p)98 static inline unsigned int alisp_inc_refs(struct alisp_object *p)
99 {
100 unsigned r = alisp_get_refs(p) + 1;
101 alisp_set_refs(p, r);
102 return r;
103 }
104
alisp_dec_refs(struct alisp_object * p)105 static inline unsigned int alisp_dec_refs(struct alisp_object *p)
106 {
107 unsigned r = alisp_get_refs(p) - 1;
108 alisp_set_refs(p, r);
109 return r;
110 }
111
112 struct alisp_object_pair {
113 struct list_head list;
114 const char *name;
115 struct alisp_object *value;
116 };
117
118 #define ALISP_LEX_BUF_MAX 16
119 #define ALISP_OBJ_PAIR_HASH_SHIFT 4
120 #define ALISP_OBJ_PAIR_HASH_SIZE (1<<ALISP_OBJ_PAIR_HASH_SHIFT)
121 #define ALISP_OBJ_PAIR_HASH_MASK (ALISP_OBJ_PAIR_HASH_SIZE-1)
122 #define ALISP_FREE_OBJ_POOL 512 /* free objects above this pool */
123
124 struct alisp_instance {
125 int verbose: 1,
126 warning: 1,
127 debug: 1;
128 /* i/o */
129 snd_input_t *in;
130 snd_output_t *out;
131 snd_output_t *eout; /* error output */
132 snd_output_t *vout; /* verbose output */
133 snd_output_t *wout; /* warning output */
134 snd_output_t *dout; /* debug output */
135 /* lexer */
136 int charno;
137 int lineno;
138 int lex_buf[ALISP_LEX_BUF_MAX];
139 int *lex_bufp;
140 char *token_buffer;
141 int token_buffer_max;
142 int thistoken;
143 /* object allocator / storage */
144 long free_objs;
145 long used_objs;
146 long max_objs;
147 struct list_head free_objs_list;
148 struct list_head used_objs_list[ALISP_OBJ_PAIR_HASH_SIZE][ALISP_OBJ_LAST_SEARCH + 1];
149 /* set object */
150 struct list_head setobjs_list[ALISP_OBJ_PAIR_HASH_SIZE];
151 };
152