1 /* 2 * ALSA lisp implementation 3 * Copyright (c) 2003 by Jaroslav Kysela <perex (at) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 70 static inline enum alisp_objects alisp_get_type(struct alisp_object *p) 71 { 72 return (p->type_refs >> ALISP_TYPE_SHIFT); 73 } 74 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 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 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 93 static inline unsigned int alisp_get_refs(struct alisp_object *p) 94 { 95 return p->type_refs & ALISP_REFS_MASK; 96 } 97 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 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