Home | History | Annotate | Download | only in alisp
      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