1d5ac70f0Sopenharmony_ci/* 2d5ac70f0Sopenharmony_ci * ALSA lisp implementation 3d5ac70f0Sopenharmony_ci * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz> 4d5ac70f0Sopenharmony_ci * 5d5ac70f0Sopenharmony_ci * Based on work of Sandro Sigala (slisp-1.2) 6d5ac70f0Sopenharmony_ci * 7d5ac70f0Sopenharmony_ci * 8d5ac70f0Sopenharmony_ci * This library is free software; you can redistribute it and/or modify 9d5ac70f0Sopenharmony_ci * it under the terms of the GNU Lesser General Public License as 10d5ac70f0Sopenharmony_ci * published by the Free Software Foundation; either version 2.1 of 11d5ac70f0Sopenharmony_ci * the License, or (at your option) any later version. 12d5ac70f0Sopenharmony_ci * 13d5ac70f0Sopenharmony_ci * This program is distributed in the hope that it will be useful, 14d5ac70f0Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15d5ac70f0Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16d5ac70f0Sopenharmony_ci * GNU Lesser General Public License for more details. 17d5ac70f0Sopenharmony_ci * 18d5ac70f0Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19d5ac70f0Sopenharmony_ci * License along with this library; if not, write to the Free Software 20d5ac70f0Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21d5ac70f0Sopenharmony_ci * 22d5ac70f0Sopenharmony_ci */ 23d5ac70f0Sopenharmony_ci 24d5ac70f0Sopenharmony_ci#define alisp_seq_iterator alisp_object 25d5ac70f0Sopenharmony_ci 26d5ac70f0Sopenharmony_ci#include "local.h" 27d5ac70f0Sopenharmony_ci#include "alisp.h" 28d5ac70f0Sopenharmony_ci#include "alisp_local.h" 29d5ac70f0Sopenharmony_ci 30d5ac70f0Sopenharmony_ci#include <assert.h> 31d5ac70f0Sopenharmony_ci 32d5ac70f0Sopenharmony_ci#include <limits.h> 33d5ac70f0Sopenharmony_ci#include <stdio.h> 34d5ac70f0Sopenharmony_ci#include <stdlib.h> 35d5ac70f0Sopenharmony_ci#include <string.h> 36d5ac70f0Sopenharmony_ci#include <ctype.h> 37d5ac70f0Sopenharmony_ci#include <math.h> 38d5ac70f0Sopenharmony_ci#include <err.h> 39d5ac70f0Sopenharmony_ci 40d5ac70f0Sopenharmony_ci 41d5ac70f0Sopenharmony_cistruct alisp_object alsa_lisp_nil; 42d5ac70f0Sopenharmony_cistruct alisp_object alsa_lisp_t; 43d5ac70f0Sopenharmony_ci 44d5ac70f0Sopenharmony_ci/* parser prototypes */ 45d5ac70f0Sopenharmony_cistatic struct alisp_object * parse_object(struct alisp_instance *instance, int havetoken); 46d5ac70f0Sopenharmony_cistatic void princ_cons(snd_output_t *out, struct alisp_object * p); 47d5ac70f0Sopenharmony_cistatic void princ_object(snd_output_t *out, struct alisp_object * p); 48d5ac70f0Sopenharmony_cistatic struct alisp_object * eval(struct alisp_instance *instance, struct alisp_object * p); 49d5ac70f0Sopenharmony_ci 50d5ac70f0Sopenharmony_ci/* functions */ 51d5ac70f0Sopenharmony_cistatic struct alisp_object *F_eval(struct alisp_instance *instance, struct alisp_object *); 52d5ac70f0Sopenharmony_cistatic struct alisp_object *F_progn(struct alisp_instance *instance, struct alisp_object *); 53d5ac70f0Sopenharmony_cistatic struct alisp_object *F_funcall(struct alisp_instance *instance, struct alisp_object *); 54d5ac70f0Sopenharmony_ci 55d5ac70f0Sopenharmony_ci/* others */ 56d5ac70f0Sopenharmony_cistatic int alisp_include_file(struct alisp_instance *instance, const char *filename); 57d5ac70f0Sopenharmony_ci 58d5ac70f0Sopenharmony_ci/* 59d5ac70f0Sopenharmony_ci * object handling 60d5ac70f0Sopenharmony_ci */ 61d5ac70f0Sopenharmony_ci 62d5ac70f0Sopenharmony_cistatic int get_string_hash(const char *s) 63d5ac70f0Sopenharmony_ci{ 64d5ac70f0Sopenharmony_ci int val = 0; 65d5ac70f0Sopenharmony_ci if (s == NULL) 66d5ac70f0Sopenharmony_ci return val; 67d5ac70f0Sopenharmony_ci while (*s) 68d5ac70f0Sopenharmony_ci val += *s++; 69d5ac70f0Sopenharmony_ci return val & ALISP_OBJ_PAIR_HASH_MASK; 70d5ac70f0Sopenharmony_ci} 71d5ac70f0Sopenharmony_ci 72d5ac70f0Sopenharmony_cistatic void nomem(void) 73d5ac70f0Sopenharmony_ci{ 74d5ac70f0Sopenharmony_ci SNDERR("alisp: no enough memory"); 75d5ac70f0Sopenharmony_ci} 76d5ac70f0Sopenharmony_ci 77d5ac70f0Sopenharmony_cistatic void lisp_verbose(struct alisp_instance *instance, const char *fmt, ...) 78d5ac70f0Sopenharmony_ci{ 79d5ac70f0Sopenharmony_ci va_list ap; 80d5ac70f0Sopenharmony_ci 81d5ac70f0Sopenharmony_ci if (!instance->verbose) 82d5ac70f0Sopenharmony_ci return; 83d5ac70f0Sopenharmony_ci va_start(ap, fmt); 84d5ac70f0Sopenharmony_ci snd_output_printf(instance->vout, "alisp: "); 85d5ac70f0Sopenharmony_ci snd_output_vprintf(instance->vout, fmt, ap); 86d5ac70f0Sopenharmony_ci snd_output_putc(instance->vout, '\n'); 87d5ac70f0Sopenharmony_ci va_end(ap); 88d5ac70f0Sopenharmony_ci} 89d5ac70f0Sopenharmony_ci 90d5ac70f0Sopenharmony_cistatic void lisp_error(struct alisp_instance *instance, const char *fmt, ...) 91d5ac70f0Sopenharmony_ci{ 92d5ac70f0Sopenharmony_ci va_list ap; 93d5ac70f0Sopenharmony_ci 94d5ac70f0Sopenharmony_ci if (!instance->warning) 95d5ac70f0Sopenharmony_ci return; 96d5ac70f0Sopenharmony_ci va_start(ap, fmt); 97d5ac70f0Sopenharmony_ci snd_output_printf(instance->eout, "alisp error: "); 98d5ac70f0Sopenharmony_ci snd_output_vprintf(instance->eout, fmt, ap); 99d5ac70f0Sopenharmony_ci snd_output_putc(instance->eout, '\n'); 100d5ac70f0Sopenharmony_ci va_end(ap); 101d5ac70f0Sopenharmony_ci} 102d5ac70f0Sopenharmony_ci 103d5ac70f0Sopenharmony_cistatic void lisp_warn(struct alisp_instance *instance, const char *fmt, ...) 104d5ac70f0Sopenharmony_ci{ 105d5ac70f0Sopenharmony_ci va_list ap; 106d5ac70f0Sopenharmony_ci 107d5ac70f0Sopenharmony_ci if (!instance->warning) 108d5ac70f0Sopenharmony_ci return; 109d5ac70f0Sopenharmony_ci va_start(ap, fmt); 110d5ac70f0Sopenharmony_ci snd_output_printf(instance->wout, "alisp warning: "); 111d5ac70f0Sopenharmony_ci snd_output_vprintf(instance->wout, fmt, ap); 112d5ac70f0Sopenharmony_ci snd_output_putc(instance->wout, '\n'); 113d5ac70f0Sopenharmony_ci va_end(ap); 114d5ac70f0Sopenharmony_ci} 115d5ac70f0Sopenharmony_ci 116d5ac70f0Sopenharmony_cistatic void lisp_debug(struct alisp_instance *instance, const char *fmt, ...) 117d5ac70f0Sopenharmony_ci{ 118d5ac70f0Sopenharmony_ci va_list ap; 119d5ac70f0Sopenharmony_ci 120d5ac70f0Sopenharmony_ci if (!instance->debug) 121d5ac70f0Sopenharmony_ci return; 122d5ac70f0Sopenharmony_ci va_start(ap, fmt); 123d5ac70f0Sopenharmony_ci snd_output_printf(instance->dout, "alisp debug: "); 124d5ac70f0Sopenharmony_ci snd_output_vprintf(instance->dout, fmt, ap); 125d5ac70f0Sopenharmony_ci snd_output_putc(instance->dout, '\n'); 126d5ac70f0Sopenharmony_ci va_end(ap); 127d5ac70f0Sopenharmony_ci} 128d5ac70f0Sopenharmony_ci 129d5ac70f0Sopenharmony_cistatic struct alisp_object * new_object(struct alisp_instance *instance, int type) 130d5ac70f0Sopenharmony_ci{ 131d5ac70f0Sopenharmony_ci struct alisp_object * p; 132d5ac70f0Sopenharmony_ci 133d5ac70f0Sopenharmony_ci if (list_empty(&instance->free_objs_list)) { 134d5ac70f0Sopenharmony_ci p = (struct alisp_object *)malloc(sizeof(struct alisp_object)); 135d5ac70f0Sopenharmony_ci if (p == NULL) { 136d5ac70f0Sopenharmony_ci nomem(); 137d5ac70f0Sopenharmony_ci return NULL; 138d5ac70f0Sopenharmony_ci } 139d5ac70f0Sopenharmony_ci lisp_debug(instance, "allocating cons %p", p); 140d5ac70f0Sopenharmony_ci } else { 141d5ac70f0Sopenharmony_ci p = (struct alisp_object *)instance->free_objs_list.next; 142d5ac70f0Sopenharmony_ci list_del(&p->list); 143d5ac70f0Sopenharmony_ci instance->free_objs--; 144d5ac70f0Sopenharmony_ci lisp_debug(instance, "recycling cons %p", p); 145d5ac70f0Sopenharmony_ci } 146d5ac70f0Sopenharmony_ci 147d5ac70f0Sopenharmony_ci instance->used_objs++; 148d5ac70f0Sopenharmony_ci 149d5ac70f0Sopenharmony_ci alisp_set_type(p, type); 150d5ac70f0Sopenharmony_ci alisp_set_refs(p, 1); 151d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_CONS) { 152d5ac70f0Sopenharmony_ci p->value.c.car = &alsa_lisp_nil; 153d5ac70f0Sopenharmony_ci p->value.c.cdr = &alsa_lisp_nil; 154d5ac70f0Sopenharmony_ci list_add(&p->list, &instance->used_objs_list[0][ALISP_OBJ_CONS]); 155d5ac70f0Sopenharmony_ci } 156d5ac70f0Sopenharmony_ci 157d5ac70f0Sopenharmony_ci if (instance->used_objs + instance->free_objs > instance->max_objs) 158d5ac70f0Sopenharmony_ci instance->max_objs = instance->used_objs + instance->free_objs; 159d5ac70f0Sopenharmony_ci 160d5ac70f0Sopenharmony_ci return p; 161d5ac70f0Sopenharmony_ci} 162d5ac70f0Sopenharmony_ci 163d5ac70f0Sopenharmony_cistatic void free_object(struct alisp_object * p) 164d5ac70f0Sopenharmony_ci{ 165d5ac70f0Sopenharmony_ci switch (alisp_get_type(p)) { 166d5ac70f0Sopenharmony_ci case ALISP_OBJ_STRING: 167d5ac70f0Sopenharmony_ci case ALISP_OBJ_IDENTIFIER: 168d5ac70f0Sopenharmony_ci free(p->value.s); 169d5ac70f0Sopenharmony_ci alisp_set_type(p, ALISP_OBJ_INTEGER); 170d5ac70f0Sopenharmony_ci break; 171d5ac70f0Sopenharmony_ci default: 172d5ac70f0Sopenharmony_ci break; 173d5ac70f0Sopenharmony_ci } 174d5ac70f0Sopenharmony_ci} 175d5ac70f0Sopenharmony_ci 176d5ac70f0Sopenharmony_cistatic void delete_object(struct alisp_instance *instance, struct alisp_object * p) 177d5ac70f0Sopenharmony_ci{ 178d5ac70f0Sopenharmony_ci if (p == NULL || p == &alsa_lisp_nil || p == &alsa_lisp_t) 179d5ac70f0Sopenharmony_ci return; 180d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_NIL) || 181d5ac70f0Sopenharmony_ci alisp_compare_type(p, ALISP_OBJ_T)) 182d5ac70f0Sopenharmony_ci return; 183d5ac70f0Sopenharmony_ci assert(alisp_get_refs(p) > 0); 184d5ac70f0Sopenharmony_ci lisp_debug(instance, "delete cons %p (type = %i, refs = %i) (s = '%s')", p, alisp_get_type(p), alisp_get_refs(p), 185d5ac70f0Sopenharmony_ci alisp_compare_type(p, ALISP_OBJ_STRING) || 186d5ac70f0Sopenharmony_ci alisp_compare_type(p, ALISP_OBJ_IDENTIFIER) ? p->value.s : "???"); 187d5ac70f0Sopenharmony_ci if (alisp_dec_refs(p)) 188d5ac70f0Sopenharmony_ci return; 189d5ac70f0Sopenharmony_ci list_del(&p->list); 190d5ac70f0Sopenharmony_ci instance->used_objs--; 191d5ac70f0Sopenharmony_ci free_object(p); 192d5ac70f0Sopenharmony_ci if (instance->free_objs >= ALISP_FREE_OBJ_POOL) { 193d5ac70f0Sopenharmony_ci lisp_debug(instance, "freed cons %p", p); 194d5ac70f0Sopenharmony_ci free(p); 195d5ac70f0Sopenharmony_ci return; 196d5ac70f0Sopenharmony_ci } 197d5ac70f0Sopenharmony_ci lisp_debug(instance, "moved cons %p to free list", p); 198d5ac70f0Sopenharmony_ci list_add(&p->list, &instance->free_objs_list); 199d5ac70f0Sopenharmony_ci instance->free_objs++; 200d5ac70f0Sopenharmony_ci} 201d5ac70f0Sopenharmony_ci 202d5ac70f0Sopenharmony_cistatic void delete_tree(struct alisp_instance *instance, struct alisp_object * p) 203d5ac70f0Sopenharmony_ci{ 204d5ac70f0Sopenharmony_ci if (p == NULL) 205d5ac70f0Sopenharmony_ci return; 206d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_CONS)) { 207d5ac70f0Sopenharmony_ci delete_tree(instance, p->value.c.car); 208d5ac70f0Sopenharmony_ci delete_tree(instance, p->value.c.cdr); 209d5ac70f0Sopenharmony_ci } 210d5ac70f0Sopenharmony_ci delete_object(instance, p); 211d5ac70f0Sopenharmony_ci} 212d5ac70f0Sopenharmony_ci 213d5ac70f0Sopenharmony_cistatic struct alisp_object * incref_object(struct alisp_instance *instance ATTRIBUTE_UNUSED, struct alisp_object * p) 214d5ac70f0Sopenharmony_ci{ 215d5ac70f0Sopenharmony_ci if (p == NULL || p == &alsa_lisp_nil || p == &alsa_lisp_t) 216d5ac70f0Sopenharmony_ci return p; 217d5ac70f0Sopenharmony_ci if (alisp_get_refs(p) == ALISP_MAX_REFS) { 218d5ac70f0Sopenharmony_ci assert(0); 219d5ac70f0Sopenharmony_ci fprintf(stderr, "OOPS: alsa lisp: incref fatal error\n"); 220d5ac70f0Sopenharmony_ci exit(EXIT_FAILURE); 221d5ac70f0Sopenharmony_ci } 222d5ac70f0Sopenharmony_ci alisp_inc_refs(p); 223d5ac70f0Sopenharmony_ci return p; 224d5ac70f0Sopenharmony_ci} 225d5ac70f0Sopenharmony_ci 226d5ac70f0Sopenharmony_cistatic struct alisp_object * incref_tree(struct alisp_instance *instance, struct alisp_object * p) 227d5ac70f0Sopenharmony_ci{ 228d5ac70f0Sopenharmony_ci if (p == NULL) 229d5ac70f0Sopenharmony_ci return NULL; 230d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_CONS)) { 231d5ac70f0Sopenharmony_ci incref_tree(instance, p->value.c.car); 232d5ac70f0Sopenharmony_ci incref_tree(instance, p->value.c.cdr); 233d5ac70f0Sopenharmony_ci } 234d5ac70f0Sopenharmony_ci return incref_object(instance, p); 235d5ac70f0Sopenharmony_ci} 236d5ac70f0Sopenharmony_ci 237d5ac70f0Sopenharmony_ci/* Function not used yet. Leave it commented out until we actually use it to 238d5ac70f0Sopenharmony_ci * avoid compiler complaints */ 239d5ac70f0Sopenharmony_ci#if 0 240d5ac70f0Sopenharmony_cistatic struct alisp_object * incref_tree_explicit(struct alisp_instance *instance, struct alisp_object * p, struct alisp_object * e) 241d5ac70f0Sopenharmony_ci{ 242d5ac70f0Sopenharmony_ci if (p == NULL) 243d5ac70f0Sopenharmony_ci return NULL; 244d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_CONS)) { 245d5ac70f0Sopenharmony_ci if (e == p) { 246d5ac70f0Sopenharmony_ci incref_tree(instance, p->value.c.car); 247d5ac70f0Sopenharmony_ci incref_tree(instance, p->value.c.cdr); 248d5ac70f0Sopenharmony_ci } else { 249d5ac70f0Sopenharmony_ci incref_tree_explicit(instance, p->value.c.car, e); 250d5ac70f0Sopenharmony_ci incref_tree_explicit(instance, p->value.c.cdr, e); 251d5ac70f0Sopenharmony_ci } 252d5ac70f0Sopenharmony_ci } 253d5ac70f0Sopenharmony_ci if (e == p) 254d5ac70f0Sopenharmony_ci return incref_object(instance, p); 255d5ac70f0Sopenharmony_ci return p; 256d5ac70f0Sopenharmony_ci} 257d5ac70f0Sopenharmony_ci#endif 258d5ac70f0Sopenharmony_ci 259d5ac70f0Sopenharmony_cistatic void free_objects(struct alisp_instance *instance) 260d5ac70f0Sopenharmony_ci{ 261d5ac70f0Sopenharmony_ci struct list_head *pos, *pos1; 262d5ac70f0Sopenharmony_ci struct alisp_object * p; 263d5ac70f0Sopenharmony_ci struct alisp_object_pair * pair; 264d5ac70f0Sopenharmony_ci int i, j; 265d5ac70f0Sopenharmony_ci 266d5ac70f0Sopenharmony_ci for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++) { 267d5ac70f0Sopenharmony_ci list_for_each_safe(pos, pos1, &instance->setobjs_list[i]) { 268d5ac70f0Sopenharmony_ci pair = list_entry(pos, struct alisp_object_pair, list); 269d5ac70f0Sopenharmony_ci lisp_debug(instance, "freeing pair: '%s' -> %p", pair->name, pair->value); 270d5ac70f0Sopenharmony_ci delete_tree(instance, pair->value); 271d5ac70f0Sopenharmony_ci free((void *)pair->name); 272d5ac70f0Sopenharmony_ci free(pair); 273d5ac70f0Sopenharmony_ci } 274d5ac70f0Sopenharmony_ci } 275d5ac70f0Sopenharmony_ci for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++) 276d5ac70f0Sopenharmony_ci for (j = 0; j <= ALISP_OBJ_LAST_SEARCH; j++) { 277d5ac70f0Sopenharmony_ci list_for_each_safe(pos, pos1, &instance->used_objs_list[i][j]) { 278d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 279d5ac70f0Sopenharmony_ci lisp_warn(instance, "object %p is still referenced %i times!", p, alisp_get_refs(p)); 280d5ac70f0Sopenharmony_ci#if 0 281d5ac70f0Sopenharmony_ci snd_output_printf(instance->wout, ">>>> "); 282d5ac70f0Sopenharmony_ci princ_object(instance->wout, p); 283d5ac70f0Sopenharmony_ci snd_output_printf(instance->wout, " <<<<\n"); 284d5ac70f0Sopenharmony_ci#endif 285d5ac70f0Sopenharmony_ci if (alisp_get_refs(p) > 0) 286d5ac70f0Sopenharmony_ci alisp_set_refs(p, 1); 287d5ac70f0Sopenharmony_ci delete_object(instance, p); 288d5ac70f0Sopenharmony_ci } 289d5ac70f0Sopenharmony_ci } 290d5ac70f0Sopenharmony_ci list_for_each_safe(pos, pos1, &instance->free_objs_list) { 291d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 292d5ac70f0Sopenharmony_ci list_del(&p->list); 293d5ac70f0Sopenharmony_ci free(p); 294d5ac70f0Sopenharmony_ci lisp_debug(instance, "freed (all) cons %p", p); 295d5ac70f0Sopenharmony_ci } 296d5ac70f0Sopenharmony_ci} 297d5ac70f0Sopenharmony_ci 298d5ac70f0Sopenharmony_cistatic struct alisp_object * search_object_identifier(struct alisp_instance *instance, const char *s) 299d5ac70f0Sopenharmony_ci{ 300d5ac70f0Sopenharmony_ci struct list_head * pos; 301d5ac70f0Sopenharmony_ci struct alisp_object * p; 302d5ac70f0Sopenharmony_ci 303d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->used_objs_list[get_string_hash(s)][ALISP_OBJ_IDENTIFIER]) { 304d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 305d5ac70f0Sopenharmony_ci if (alisp_get_refs(p) > ALISP_MAX_REFS_LIMIT) 306d5ac70f0Sopenharmony_ci continue; 307d5ac70f0Sopenharmony_ci if (!strcmp(p->value.s, s)) 308d5ac70f0Sopenharmony_ci return incref_object(instance, p); 309d5ac70f0Sopenharmony_ci } 310d5ac70f0Sopenharmony_ci 311d5ac70f0Sopenharmony_ci return NULL; 312d5ac70f0Sopenharmony_ci} 313d5ac70f0Sopenharmony_ci 314d5ac70f0Sopenharmony_cistatic struct alisp_object * search_object_string(struct alisp_instance *instance, const char *s) 315d5ac70f0Sopenharmony_ci{ 316d5ac70f0Sopenharmony_ci struct list_head * pos; 317d5ac70f0Sopenharmony_ci struct alisp_object * p; 318d5ac70f0Sopenharmony_ci 319d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->used_objs_list[get_string_hash(s)][ALISP_OBJ_STRING]) { 320d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 321d5ac70f0Sopenharmony_ci if (!strcmp(p->value.s, s)) { 322d5ac70f0Sopenharmony_ci if (alisp_get_refs(p) > ALISP_MAX_REFS_LIMIT) 323d5ac70f0Sopenharmony_ci continue; 324d5ac70f0Sopenharmony_ci return incref_object(instance, p); 325d5ac70f0Sopenharmony_ci } 326d5ac70f0Sopenharmony_ci } 327d5ac70f0Sopenharmony_ci 328d5ac70f0Sopenharmony_ci return NULL; 329d5ac70f0Sopenharmony_ci} 330d5ac70f0Sopenharmony_ci 331d5ac70f0Sopenharmony_cistatic struct alisp_object * search_object_integer(struct alisp_instance *instance, long in) 332d5ac70f0Sopenharmony_ci{ 333d5ac70f0Sopenharmony_ci struct list_head * pos; 334d5ac70f0Sopenharmony_ci struct alisp_object * p; 335d5ac70f0Sopenharmony_ci 336d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->used_objs_list[in & ALISP_OBJ_PAIR_HASH_MASK][ALISP_OBJ_INTEGER]) { 337d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 338d5ac70f0Sopenharmony_ci if (p->value.i == in) { 339d5ac70f0Sopenharmony_ci if (alisp_get_refs(p) > ALISP_MAX_REFS_LIMIT) 340d5ac70f0Sopenharmony_ci continue; 341d5ac70f0Sopenharmony_ci return incref_object(instance, p); 342d5ac70f0Sopenharmony_ci } 343d5ac70f0Sopenharmony_ci } 344d5ac70f0Sopenharmony_ci 345d5ac70f0Sopenharmony_ci return NULL; 346d5ac70f0Sopenharmony_ci} 347d5ac70f0Sopenharmony_ci 348d5ac70f0Sopenharmony_cistatic struct alisp_object * search_object_float(struct alisp_instance *instance, double in) 349d5ac70f0Sopenharmony_ci{ 350d5ac70f0Sopenharmony_ci struct list_head * pos; 351d5ac70f0Sopenharmony_ci struct alisp_object * p; 352d5ac70f0Sopenharmony_ci 353d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->used_objs_list[(long)in & ALISP_OBJ_PAIR_HASH_MASK][ALISP_OBJ_FLOAT]) { 354d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 355d5ac70f0Sopenharmony_ci if (p->value.i == in) { 356d5ac70f0Sopenharmony_ci if (alisp_get_refs(p) > ALISP_MAX_REFS_LIMIT) 357d5ac70f0Sopenharmony_ci continue; 358d5ac70f0Sopenharmony_ci return incref_object(instance, p); 359d5ac70f0Sopenharmony_ci } 360d5ac70f0Sopenharmony_ci } 361d5ac70f0Sopenharmony_ci 362d5ac70f0Sopenharmony_ci return NULL; 363d5ac70f0Sopenharmony_ci} 364d5ac70f0Sopenharmony_ci 365d5ac70f0Sopenharmony_cistatic struct alisp_object * search_object_pointer(struct alisp_instance *instance, const void *ptr) 366d5ac70f0Sopenharmony_ci{ 367d5ac70f0Sopenharmony_ci struct list_head * pos; 368d5ac70f0Sopenharmony_ci struct alisp_object * p; 369d5ac70f0Sopenharmony_ci 370d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->used_objs_list[(long)ptr & ALISP_OBJ_PAIR_HASH_MASK][ALISP_OBJ_POINTER]) { 371d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 372d5ac70f0Sopenharmony_ci if (p->value.ptr == ptr) { 373d5ac70f0Sopenharmony_ci if (alisp_get_refs(p) > ALISP_MAX_REFS_LIMIT) 374d5ac70f0Sopenharmony_ci continue; 375d5ac70f0Sopenharmony_ci return incref_object(instance, p); 376d5ac70f0Sopenharmony_ci } 377d5ac70f0Sopenharmony_ci } 378d5ac70f0Sopenharmony_ci 379d5ac70f0Sopenharmony_ci return NULL; 380d5ac70f0Sopenharmony_ci} 381d5ac70f0Sopenharmony_ci 382d5ac70f0Sopenharmony_cistatic struct alisp_object * new_integer(struct alisp_instance *instance, long value) 383d5ac70f0Sopenharmony_ci{ 384d5ac70f0Sopenharmony_ci struct alisp_object * obj; 385d5ac70f0Sopenharmony_ci 386d5ac70f0Sopenharmony_ci obj = search_object_integer(instance, value); 387d5ac70f0Sopenharmony_ci if (obj != NULL) 388d5ac70f0Sopenharmony_ci return obj; 389d5ac70f0Sopenharmony_ci obj = new_object(instance, ALISP_OBJ_INTEGER); 390d5ac70f0Sopenharmony_ci if (obj) { 391d5ac70f0Sopenharmony_ci list_add(&obj->list, &instance->used_objs_list[value & ALISP_OBJ_PAIR_HASH_MASK][ALISP_OBJ_INTEGER]); 392d5ac70f0Sopenharmony_ci obj->value.i = value; 393d5ac70f0Sopenharmony_ci } 394d5ac70f0Sopenharmony_ci return obj; 395d5ac70f0Sopenharmony_ci} 396d5ac70f0Sopenharmony_ci 397d5ac70f0Sopenharmony_cistatic struct alisp_object * new_float(struct alisp_instance *instance, double value) 398d5ac70f0Sopenharmony_ci{ 399d5ac70f0Sopenharmony_ci struct alisp_object * obj; 400d5ac70f0Sopenharmony_ci 401d5ac70f0Sopenharmony_ci obj = search_object_float(instance, value); 402d5ac70f0Sopenharmony_ci if (obj != NULL) 403d5ac70f0Sopenharmony_ci return obj; 404d5ac70f0Sopenharmony_ci obj = new_object(instance, ALISP_OBJ_FLOAT); 405d5ac70f0Sopenharmony_ci if (obj) { 406d5ac70f0Sopenharmony_ci list_add(&obj->list, &instance->used_objs_list[(long)value & ALISP_OBJ_PAIR_HASH_MASK][ALISP_OBJ_FLOAT]); 407d5ac70f0Sopenharmony_ci obj->value.f = value; 408d5ac70f0Sopenharmony_ci } 409d5ac70f0Sopenharmony_ci return obj; 410d5ac70f0Sopenharmony_ci} 411d5ac70f0Sopenharmony_ci 412d5ac70f0Sopenharmony_cistatic struct alisp_object * new_string(struct alisp_instance *instance, const char *str) 413d5ac70f0Sopenharmony_ci{ 414d5ac70f0Sopenharmony_ci struct alisp_object * obj; 415d5ac70f0Sopenharmony_ci 416d5ac70f0Sopenharmony_ci obj = search_object_string(instance, str); 417d5ac70f0Sopenharmony_ci if (obj != NULL) 418d5ac70f0Sopenharmony_ci return obj; 419d5ac70f0Sopenharmony_ci obj = new_object(instance, ALISP_OBJ_STRING); 420d5ac70f0Sopenharmony_ci if (obj) 421d5ac70f0Sopenharmony_ci list_add(&obj->list, &instance->used_objs_list[get_string_hash(str)][ALISP_OBJ_STRING]); 422d5ac70f0Sopenharmony_ci if (obj && (obj->value.s = strdup(str)) == NULL) { 423d5ac70f0Sopenharmony_ci delete_object(instance, obj); 424d5ac70f0Sopenharmony_ci nomem(); 425d5ac70f0Sopenharmony_ci return NULL; 426d5ac70f0Sopenharmony_ci } 427d5ac70f0Sopenharmony_ci return obj; 428d5ac70f0Sopenharmony_ci} 429d5ac70f0Sopenharmony_ci 430d5ac70f0Sopenharmony_cistatic struct alisp_object * new_identifier(struct alisp_instance *instance, const char *id) 431d5ac70f0Sopenharmony_ci{ 432d5ac70f0Sopenharmony_ci struct alisp_object * obj; 433d5ac70f0Sopenharmony_ci 434d5ac70f0Sopenharmony_ci obj = search_object_identifier(instance, id); 435d5ac70f0Sopenharmony_ci if (obj != NULL) 436d5ac70f0Sopenharmony_ci return obj; 437d5ac70f0Sopenharmony_ci obj = new_object(instance, ALISP_OBJ_IDENTIFIER); 438d5ac70f0Sopenharmony_ci if (obj) 439d5ac70f0Sopenharmony_ci list_add(&obj->list, &instance->used_objs_list[get_string_hash(id)][ALISP_OBJ_IDENTIFIER]); 440d5ac70f0Sopenharmony_ci if (obj && (obj->value.s = strdup(id)) == NULL) { 441d5ac70f0Sopenharmony_ci delete_object(instance, obj); 442d5ac70f0Sopenharmony_ci nomem(); 443d5ac70f0Sopenharmony_ci return NULL; 444d5ac70f0Sopenharmony_ci } 445d5ac70f0Sopenharmony_ci return obj; 446d5ac70f0Sopenharmony_ci} 447d5ac70f0Sopenharmony_ci 448d5ac70f0Sopenharmony_cistatic struct alisp_object * new_pointer(struct alisp_instance *instance, const void *ptr) 449d5ac70f0Sopenharmony_ci{ 450d5ac70f0Sopenharmony_ci struct alisp_object * obj; 451d5ac70f0Sopenharmony_ci 452d5ac70f0Sopenharmony_ci obj = search_object_pointer(instance, ptr); 453d5ac70f0Sopenharmony_ci if (obj != NULL) 454d5ac70f0Sopenharmony_ci return obj; 455d5ac70f0Sopenharmony_ci obj = new_object(instance, ALISP_OBJ_POINTER); 456d5ac70f0Sopenharmony_ci if (obj) { 457d5ac70f0Sopenharmony_ci list_add(&obj->list, &instance->used_objs_list[(long)ptr & ALISP_OBJ_PAIR_HASH_MASK][ALISP_OBJ_POINTER]); 458d5ac70f0Sopenharmony_ci obj->value.ptr = ptr; 459d5ac70f0Sopenharmony_ci } 460d5ac70f0Sopenharmony_ci return obj; 461d5ac70f0Sopenharmony_ci} 462d5ac70f0Sopenharmony_ci 463d5ac70f0Sopenharmony_cistatic struct alisp_object * new_cons_pointer(struct alisp_instance * instance, const char *ptr_id, void *ptr) 464d5ac70f0Sopenharmony_ci{ 465d5ac70f0Sopenharmony_ci struct alisp_object * lexpr; 466d5ac70f0Sopenharmony_ci 467d5ac70f0Sopenharmony_ci if (ptr == NULL) 468d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 469d5ac70f0Sopenharmony_ci lexpr = new_object(instance, ALISP_OBJ_CONS); 470d5ac70f0Sopenharmony_ci if (lexpr == NULL) 471d5ac70f0Sopenharmony_ci return NULL; 472d5ac70f0Sopenharmony_ci lexpr->value.c.car = new_string(instance, ptr_id); 473d5ac70f0Sopenharmony_ci if (lexpr->value.c.car == NULL) 474d5ac70f0Sopenharmony_ci goto __end; 475d5ac70f0Sopenharmony_ci lexpr->value.c.cdr = new_pointer(instance, ptr); 476d5ac70f0Sopenharmony_ci if (lexpr->value.c.cdr == NULL) { 477d5ac70f0Sopenharmony_ci delete_object(instance, lexpr->value.c.car); 478d5ac70f0Sopenharmony_ci __end: 479d5ac70f0Sopenharmony_ci delete_object(instance, lexpr); 480d5ac70f0Sopenharmony_ci return NULL; 481d5ac70f0Sopenharmony_ci } 482d5ac70f0Sopenharmony_ci return lexpr; 483d5ac70f0Sopenharmony_ci} 484d5ac70f0Sopenharmony_ci 485d5ac70f0Sopenharmony_civoid alsa_lisp_init_objects(void) __attribute__ ((constructor)); 486d5ac70f0Sopenharmony_ci 487d5ac70f0Sopenharmony_civoid alsa_lisp_init_objects(void) 488d5ac70f0Sopenharmony_ci{ 489d5ac70f0Sopenharmony_ci memset(&alsa_lisp_nil, 0, sizeof(alsa_lisp_nil)); 490d5ac70f0Sopenharmony_ci alisp_set_type(&alsa_lisp_nil, ALISP_OBJ_NIL); 491d5ac70f0Sopenharmony_ci INIT_LIST_HEAD(&alsa_lisp_nil.list); 492d5ac70f0Sopenharmony_ci memset(&alsa_lisp_t, 0, sizeof(alsa_lisp_t)); 493d5ac70f0Sopenharmony_ci alisp_set_type(&alsa_lisp_t, ALISP_OBJ_T); 494d5ac70f0Sopenharmony_ci INIT_LIST_HEAD(&alsa_lisp_t.list); 495d5ac70f0Sopenharmony_ci} 496d5ac70f0Sopenharmony_ci 497d5ac70f0Sopenharmony_ci/* 498d5ac70f0Sopenharmony_ci * lexer 499d5ac70f0Sopenharmony_ci */ 500d5ac70f0Sopenharmony_ci 501d5ac70f0Sopenharmony_cistatic int xgetc(struct alisp_instance *instance) 502d5ac70f0Sopenharmony_ci{ 503d5ac70f0Sopenharmony_ci instance->charno++; 504d5ac70f0Sopenharmony_ci if (instance->lex_bufp > instance->lex_buf) 505d5ac70f0Sopenharmony_ci return *--(instance->lex_bufp); 506d5ac70f0Sopenharmony_ci return snd_input_getc(instance->in); 507d5ac70f0Sopenharmony_ci} 508d5ac70f0Sopenharmony_ci 509d5ac70f0Sopenharmony_cistatic inline void xungetc(struct alisp_instance *instance, int c) 510d5ac70f0Sopenharmony_ci{ 511d5ac70f0Sopenharmony_ci *(instance->lex_bufp)++ = c; 512d5ac70f0Sopenharmony_ci instance->charno--; 513d5ac70f0Sopenharmony_ci} 514d5ac70f0Sopenharmony_ci 515d5ac70f0Sopenharmony_cistatic int init_lex(struct alisp_instance *instance) 516d5ac70f0Sopenharmony_ci{ 517d5ac70f0Sopenharmony_ci instance->charno = instance->lineno = 1; 518d5ac70f0Sopenharmony_ci instance->token_buffer_max = 10; 519d5ac70f0Sopenharmony_ci if ((instance->token_buffer = (char *)malloc(instance->token_buffer_max)) == NULL) { 520d5ac70f0Sopenharmony_ci nomem(); 521d5ac70f0Sopenharmony_ci return -ENOMEM; 522d5ac70f0Sopenharmony_ci } 523d5ac70f0Sopenharmony_ci instance->lex_bufp = instance->lex_buf; 524d5ac70f0Sopenharmony_ci return 0; 525d5ac70f0Sopenharmony_ci} 526d5ac70f0Sopenharmony_ci 527d5ac70f0Sopenharmony_cistatic void done_lex(struct alisp_instance *instance) 528d5ac70f0Sopenharmony_ci{ 529d5ac70f0Sopenharmony_ci free(instance->token_buffer); 530d5ac70f0Sopenharmony_ci} 531d5ac70f0Sopenharmony_ci 532d5ac70f0Sopenharmony_cistatic char * extend_buf(struct alisp_instance *instance, char *p) 533d5ac70f0Sopenharmony_ci{ 534d5ac70f0Sopenharmony_ci int off = p - instance->token_buffer; 535d5ac70f0Sopenharmony_ci 536d5ac70f0Sopenharmony_ci instance->token_buffer_max += 10; 537d5ac70f0Sopenharmony_ci instance->token_buffer = (char *)realloc(instance->token_buffer, instance->token_buffer_max); 538d5ac70f0Sopenharmony_ci if (instance->token_buffer == NULL) { 539d5ac70f0Sopenharmony_ci nomem(); 540d5ac70f0Sopenharmony_ci return NULL; 541d5ac70f0Sopenharmony_ci } 542d5ac70f0Sopenharmony_ci 543d5ac70f0Sopenharmony_ci return instance->token_buffer + off; 544d5ac70f0Sopenharmony_ci} 545d5ac70f0Sopenharmony_ci 546d5ac70f0Sopenharmony_cistatic int gettoken(struct alisp_instance *instance) 547d5ac70f0Sopenharmony_ci{ 548d5ac70f0Sopenharmony_ci char *p; 549d5ac70f0Sopenharmony_ci int c; 550d5ac70f0Sopenharmony_ci 551d5ac70f0Sopenharmony_ci for (;;) { 552d5ac70f0Sopenharmony_ci c = xgetc(instance); 553d5ac70f0Sopenharmony_ci switch (c) { 554d5ac70f0Sopenharmony_ci case '\n': 555d5ac70f0Sopenharmony_ci ++instance->lineno; 556d5ac70f0Sopenharmony_ci break; 557d5ac70f0Sopenharmony_ci 558d5ac70f0Sopenharmony_ci case ' ': case '\f': case '\t': case '\v': case '\r': 559d5ac70f0Sopenharmony_ci break; 560d5ac70f0Sopenharmony_ci 561d5ac70f0Sopenharmony_ci case ';': 562d5ac70f0Sopenharmony_ci /* Comment: ";".*"\n" */ 563d5ac70f0Sopenharmony_ci while ((c = xgetc(instance)) != '\n' && c != EOF) 564d5ac70f0Sopenharmony_ci ; 565d5ac70f0Sopenharmony_ci if (c != EOF) 566d5ac70f0Sopenharmony_ci ++instance->lineno; 567d5ac70f0Sopenharmony_ci break; 568d5ac70f0Sopenharmony_ci 569d5ac70f0Sopenharmony_ci case '?': 570d5ac70f0Sopenharmony_ci /* Character: "?". */ 571d5ac70f0Sopenharmony_ci c = xgetc(instance); 572d5ac70f0Sopenharmony_ci sprintf(instance->token_buffer, "%d", c); 573d5ac70f0Sopenharmony_ci return instance->thistoken = ALISP_INTEGER; 574d5ac70f0Sopenharmony_ci 575d5ac70f0Sopenharmony_ci case '-': 576d5ac70f0Sopenharmony_ci /* Minus sign: "-". */ 577d5ac70f0Sopenharmony_ci c = xgetc(instance); 578d5ac70f0Sopenharmony_ci if (!isdigit(c)) { 579d5ac70f0Sopenharmony_ci xungetc(instance, c); 580d5ac70f0Sopenharmony_ci c = '-'; 581d5ac70f0Sopenharmony_ci goto got_id; 582d5ac70f0Sopenharmony_ci } 583d5ac70f0Sopenharmony_ci xungetc(instance, c); 584d5ac70f0Sopenharmony_ci c = '-'; 585d5ac70f0Sopenharmony_ci /* FALLTRHU */ 586d5ac70f0Sopenharmony_ci 587d5ac70f0Sopenharmony_ci case '0': 588d5ac70f0Sopenharmony_ci case '1': case '2': case '3': 589d5ac70f0Sopenharmony_ci case '4': case '5': case '6': 590d5ac70f0Sopenharmony_ci case '7': case '8': case '9': 591d5ac70f0Sopenharmony_ci /* Integer: [0-9]+ */ 592d5ac70f0Sopenharmony_ci p = instance->token_buffer; 593d5ac70f0Sopenharmony_ci instance->thistoken = ALISP_INTEGER; 594d5ac70f0Sopenharmony_ci do { 595d5ac70f0Sopenharmony_ci __ok: 596d5ac70f0Sopenharmony_ci if (p - instance->token_buffer >= instance->token_buffer_max - 1) { 597d5ac70f0Sopenharmony_ci p = extend_buf(instance, p); 598d5ac70f0Sopenharmony_ci if (p == NULL) 599d5ac70f0Sopenharmony_ci return instance->thistoken = EOF; 600d5ac70f0Sopenharmony_ci } 601d5ac70f0Sopenharmony_ci *p++ = c; 602d5ac70f0Sopenharmony_ci c = xgetc(instance); 603d5ac70f0Sopenharmony_ci if (c == '.' && instance->thistoken == ALISP_INTEGER) { 604d5ac70f0Sopenharmony_ci c = xgetc(instance); 605d5ac70f0Sopenharmony_ci xungetc(instance, c); 606d5ac70f0Sopenharmony_ci if (isdigit(c)) { 607d5ac70f0Sopenharmony_ci instance->thistoken = ALISP_FLOAT; 608d5ac70f0Sopenharmony_ci c = '.'; 609d5ac70f0Sopenharmony_ci goto __ok; 610d5ac70f0Sopenharmony_ci } else { 611d5ac70f0Sopenharmony_ci c = '.'; 612d5ac70f0Sopenharmony_ci } 613d5ac70f0Sopenharmony_ci } else if (c == 'e' && instance->thistoken == ALISP_FLOAT) { 614d5ac70f0Sopenharmony_ci c = xgetc(instance); 615d5ac70f0Sopenharmony_ci if (isdigit(c)) { 616d5ac70f0Sopenharmony_ci instance->thistoken = ALISP_FLOATE; 617d5ac70f0Sopenharmony_ci goto __ok; 618d5ac70f0Sopenharmony_ci } 619d5ac70f0Sopenharmony_ci } 620d5ac70f0Sopenharmony_ci } while (isdigit(c)); 621d5ac70f0Sopenharmony_ci xungetc(instance, c); 622d5ac70f0Sopenharmony_ci *p = '\0'; 623d5ac70f0Sopenharmony_ci return instance->thistoken; 624d5ac70f0Sopenharmony_ci 625d5ac70f0Sopenharmony_ci got_id: 626d5ac70f0Sopenharmony_ci case '!': case '_': case '+': case '*': case '/': case '%': 627d5ac70f0Sopenharmony_ci case '<': case '>': case '=': case '&': 628d5ac70f0Sopenharmony_ci case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 629d5ac70f0Sopenharmony_ci case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': 630d5ac70f0Sopenharmony_ci case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': 631d5ac70f0Sopenharmony_ci case 's': case 't': case 'u': case 'v': case 'w': case 'x': 632d5ac70f0Sopenharmony_ci case 'y': case 'z': 633d5ac70f0Sopenharmony_ci case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 634d5ac70f0Sopenharmony_ci case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 635d5ac70f0Sopenharmony_ci case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 636d5ac70f0Sopenharmony_ci case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 637d5ac70f0Sopenharmony_ci case 'Y': case 'Z': 638d5ac70f0Sopenharmony_ci /* Identifier: [!-/+*%<>=&a-zA-Z_][-/+*%<>=&a-zA-Z_0-9]* */ 639d5ac70f0Sopenharmony_ci p = instance->token_buffer; 640d5ac70f0Sopenharmony_ci do { 641d5ac70f0Sopenharmony_ci if (p - instance->token_buffer >= instance->token_buffer_max - 1) { 642d5ac70f0Sopenharmony_ci p = extend_buf(instance, p); 643d5ac70f0Sopenharmony_ci if (p == NULL) 644d5ac70f0Sopenharmony_ci return instance->thistoken = EOF; 645d5ac70f0Sopenharmony_ci } 646d5ac70f0Sopenharmony_ci *p++ = c; 647d5ac70f0Sopenharmony_ci c = xgetc(instance); 648d5ac70f0Sopenharmony_ci } while (isalnum(c) || strchr("!_-+*/%<>=&", c) != NULL); 649d5ac70f0Sopenharmony_ci xungetc(instance, c); 650d5ac70f0Sopenharmony_ci *p = '\0'; 651d5ac70f0Sopenharmony_ci return instance->thistoken = ALISP_IDENTIFIER; 652d5ac70f0Sopenharmony_ci 653d5ac70f0Sopenharmony_ci case '"': 654d5ac70f0Sopenharmony_ci /* String: "\""([^"]|"\\".)*"\"" */ 655d5ac70f0Sopenharmony_ci p = instance->token_buffer; 656d5ac70f0Sopenharmony_ci while ((c = xgetc(instance)) != '"' && c != EOF) { 657d5ac70f0Sopenharmony_ci if (p - instance->token_buffer >= instance->token_buffer_max - 1) { 658d5ac70f0Sopenharmony_ci p = extend_buf(instance, p); 659d5ac70f0Sopenharmony_ci if (p == NULL) 660d5ac70f0Sopenharmony_ci return instance->thistoken = EOF; 661d5ac70f0Sopenharmony_ci } 662d5ac70f0Sopenharmony_ci if (c == '\\') { 663d5ac70f0Sopenharmony_ci c = xgetc(instance); 664d5ac70f0Sopenharmony_ci switch (c) { 665d5ac70f0Sopenharmony_ci case '\n': ++instance->lineno; break; 666d5ac70f0Sopenharmony_ci case 'a': *p++ = '\a'; break; 667d5ac70f0Sopenharmony_ci case 'b': *p++ = '\b'; break; 668d5ac70f0Sopenharmony_ci case 'f': *p++ = '\f'; break; 669d5ac70f0Sopenharmony_ci case 'n': *p++ = '\n'; break; 670d5ac70f0Sopenharmony_ci case 'r': *p++ = '\r'; break; 671d5ac70f0Sopenharmony_ci case 't': *p++ = '\t'; break; 672d5ac70f0Sopenharmony_ci case 'v': *p++ = '\v'; break; 673d5ac70f0Sopenharmony_ci default: *p++ = c; 674d5ac70f0Sopenharmony_ci } 675d5ac70f0Sopenharmony_ci } else { 676d5ac70f0Sopenharmony_ci if (c == '\n') 677d5ac70f0Sopenharmony_ci ++instance->lineno; 678d5ac70f0Sopenharmony_ci *p++ = c; 679d5ac70f0Sopenharmony_ci } 680d5ac70f0Sopenharmony_ci } 681d5ac70f0Sopenharmony_ci *p = '\0'; 682d5ac70f0Sopenharmony_ci return instance->thistoken = ALISP_STRING; 683d5ac70f0Sopenharmony_ci 684d5ac70f0Sopenharmony_ci default: 685d5ac70f0Sopenharmony_ci return instance->thistoken = c; 686d5ac70f0Sopenharmony_ci } 687d5ac70f0Sopenharmony_ci } 688d5ac70f0Sopenharmony_ci} 689d5ac70f0Sopenharmony_ci 690d5ac70f0Sopenharmony_ci/* 691d5ac70f0Sopenharmony_ci * parser 692d5ac70f0Sopenharmony_ci */ 693d5ac70f0Sopenharmony_ci 694d5ac70f0Sopenharmony_cistatic struct alisp_object * parse_form(struct alisp_instance *instance) 695d5ac70f0Sopenharmony_ci{ 696d5ac70f0Sopenharmony_ci int thistoken; 697d5ac70f0Sopenharmony_ci struct alisp_object * p, * first = NULL, * prev = NULL; 698d5ac70f0Sopenharmony_ci 699d5ac70f0Sopenharmony_ci while ((thistoken = gettoken(instance)) != ')' && thistoken != EOF) { 700d5ac70f0Sopenharmony_ci /* 701d5ac70f0Sopenharmony_ci * Parse a dotted pair notation. 702d5ac70f0Sopenharmony_ci */ 703d5ac70f0Sopenharmony_ci if (thistoken == '.') { 704d5ac70f0Sopenharmony_ci gettoken(instance); 705d5ac70f0Sopenharmony_ci if (prev == NULL) { 706d5ac70f0Sopenharmony_ci lisp_error(instance, "unexpected '.'"); 707d5ac70f0Sopenharmony_ci __err: 708d5ac70f0Sopenharmony_ci delete_tree(instance, first); 709d5ac70f0Sopenharmony_ci return NULL; 710d5ac70f0Sopenharmony_ci } 711d5ac70f0Sopenharmony_ci prev->value.c.cdr = parse_object(instance, 1); 712d5ac70f0Sopenharmony_ci if (prev->value.c.cdr == NULL) 713d5ac70f0Sopenharmony_ci goto __err; 714d5ac70f0Sopenharmony_ci if ((thistoken = gettoken(instance)) != ')') { 715d5ac70f0Sopenharmony_ci lisp_error(instance, "expected ')'"); 716d5ac70f0Sopenharmony_ci goto __err; 717d5ac70f0Sopenharmony_ci } 718d5ac70f0Sopenharmony_ci break; 719d5ac70f0Sopenharmony_ci } 720d5ac70f0Sopenharmony_ci 721d5ac70f0Sopenharmony_ci p = new_object(instance, ALISP_OBJ_CONS); 722d5ac70f0Sopenharmony_ci if (p == NULL) 723d5ac70f0Sopenharmony_ci goto __err; 724d5ac70f0Sopenharmony_ci 725d5ac70f0Sopenharmony_ci if (first == NULL) 726d5ac70f0Sopenharmony_ci first = p; 727d5ac70f0Sopenharmony_ci if (prev != NULL) 728d5ac70f0Sopenharmony_ci prev->value.c.cdr = p; 729d5ac70f0Sopenharmony_ci 730d5ac70f0Sopenharmony_ci p->value.c.car = parse_object(instance, 1); 731d5ac70f0Sopenharmony_ci if (p->value.c.car == NULL) 732d5ac70f0Sopenharmony_ci goto __err; 733d5ac70f0Sopenharmony_ci 734d5ac70f0Sopenharmony_ci prev = p; 735d5ac70f0Sopenharmony_ci } 736d5ac70f0Sopenharmony_ci 737d5ac70f0Sopenharmony_ci if (first == NULL) 738d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 739d5ac70f0Sopenharmony_ci else 740d5ac70f0Sopenharmony_ci return first; 741d5ac70f0Sopenharmony_ci} 742d5ac70f0Sopenharmony_ci 743d5ac70f0Sopenharmony_cistatic struct alisp_object * quote_object(struct alisp_instance *instance, struct alisp_object * obj) 744d5ac70f0Sopenharmony_ci{ 745d5ac70f0Sopenharmony_ci struct alisp_object * p; 746d5ac70f0Sopenharmony_ci 747d5ac70f0Sopenharmony_ci if (obj == NULL) 748d5ac70f0Sopenharmony_ci goto __end1; 749d5ac70f0Sopenharmony_ci 750d5ac70f0Sopenharmony_ci p = new_object(instance, ALISP_OBJ_CONS); 751d5ac70f0Sopenharmony_ci if (p == NULL) 752d5ac70f0Sopenharmony_ci goto __end1; 753d5ac70f0Sopenharmony_ci 754d5ac70f0Sopenharmony_ci p->value.c.car = new_identifier(instance, "quote"); 755d5ac70f0Sopenharmony_ci if (p->value.c.car == NULL) 756d5ac70f0Sopenharmony_ci goto __end; 757d5ac70f0Sopenharmony_ci p->value.c.cdr = new_object(instance, ALISP_OBJ_CONS); 758d5ac70f0Sopenharmony_ci if (p->value.c.cdr == NULL) { 759d5ac70f0Sopenharmony_ci delete_object(instance, p->value.c.car); 760d5ac70f0Sopenharmony_ci __end: 761d5ac70f0Sopenharmony_ci delete_object(instance, p); 762d5ac70f0Sopenharmony_ci __end1: 763d5ac70f0Sopenharmony_ci delete_tree(instance, obj); 764d5ac70f0Sopenharmony_ci return NULL; 765d5ac70f0Sopenharmony_ci } 766d5ac70f0Sopenharmony_ci 767d5ac70f0Sopenharmony_ci p->value.c.cdr->value.c.car = obj; 768d5ac70f0Sopenharmony_ci return p; 769d5ac70f0Sopenharmony_ci} 770d5ac70f0Sopenharmony_ci 771d5ac70f0Sopenharmony_cistatic inline struct alisp_object * parse_quote(struct alisp_instance *instance) 772d5ac70f0Sopenharmony_ci{ 773d5ac70f0Sopenharmony_ci return quote_object(instance, parse_object(instance, 0)); 774d5ac70f0Sopenharmony_ci} 775d5ac70f0Sopenharmony_ci 776d5ac70f0Sopenharmony_cistatic struct alisp_object * parse_object(struct alisp_instance *instance, int havetoken) 777d5ac70f0Sopenharmony_ci{ 778d5ac70f0Sopenharmony_ci int thistoken; 779d5ac70f0Sopenharmony_ci struct alisp_object * p = NULL; 780d5ac70f0Sopenharmony_ci 781d5ac70f0Sopenharmony_ci if (!havetoken) 782d5ac70f0Sopenharmony_ci thistoken = gettoken(instance); 783d5ac70f0Sopenharmony_ci else 784d5ac70f0Sopenharmony_ci thistoken = instance->thistoken; 785d5ac70f0Sopenharmony_ci 786d5ac70f0Sopenharmony_ci switch (thistoken) { 787d5ac70f0Sopenharmony_ci case EOF: 788d5ac70f0Sopenharmony_ci break; 789d5ac70f0Sopenharmony_ci case '(': 790d5ac70f0Sopenharmony_ci p = parse_form(instance); 791d5ac70f0Sopenharmony_ci break; 792d5ac70f0Sopenharmony_ci case '\'': 793d5ac70f0Sopenharmony_ci p = parse_quote(instance); 794d5ac70f0Sopenharmony_ci break; 795d5ac70f0Sopenharmony_ci case ALISP_IDENTIFIER: 796d5ac70f0Sopenharmony_ci if (!strcmp(instance->token_buffer, "t")) 797d5ac70f0Sopenharmony_ci p = &alsa_lisp_t; 798d5ac70f0Sopenharmony_ci else if (!strcmp(instance->token_buffer, "nil")) 799d5ac70f0Sopenharmony_ci p = &alsa_lisp_nil; 800d5ac70f0Sopenharmony_ci else { 801d5ac70f0Sopenharmony_ci p = new_identifier(instance, instance->token_buffer); 802d5ac70f0Sopenharmony_ci } 803d5ac70f0Sopenharmony_ci break; 804d5ac70f0Sopenharmony_ci case ALISP_INTEGER: { 805d5ac70f0Sopenharmony_ci p = new_integer(instance, atol(instance->token_buffer)); 806d5ac70f0Sopenharmony_ci break; 807d5ac70f0Sopenharmony_ci } 808d5ac70f0Sopenharmony_ci case ALISP_FLOAT: 809d5ac70f0Sopenharmony_ci case ALISP_FLOATE: { 810d5ac70f0Sopenharmony_ci p = new_float(instance, atof(instance->token_buffer)); 811d5ac70f0Sopenharmony_ci break; 812d5ac70f0Sopenharmony_ci } 813d5ac70f0Sopenharmony_ci case ALISP_STRING: 814d5ac70f0Sopenharmony_ci p = new_string(instance, instance->token_buffer); 815d5ac70f0Sopenharmony_ci break; 816d5ac70f0Sopenharmony_ci default: 817d5ac70f0Sopenharmony_ci lisp_warn(instance, "%d:%d: unexpected character `%c'", instance->lineno, instance->charno, thistoken); 818d5ac70f0Sopenharmony_ci break; 819d5ac70f0Sopenharmony_ci } 820d5ac70f0Sopenharmony_ci 821d5ac70f0Sopenharmony_ci return p; 822d5ac70f0Sopenharmony_ci} 823d5ac70f0Sopenharmony_ci 824d5ac70f0Sopenharmony_ci/* 825d5ac70f0Sopenharmony_ci * object manipulation 826d5ac70f0Sopenharmony_ci */ 827d5ac70f0Sopenharmony_ci 828d5ac70f0Sopenharmony_cistatic struct alisp_object_pair * set_object_direct(struct alisp_instance *instance, struct alisp_object * name, struct alisp_object * value) 829d5ac70f0Sopenharmony_ci{ 830d5ac70f0Sopenharmony_ci struct alisp_object_pair *p; 831d5ac70f0Sopenharmony_ci const char *id; 832d5ac70f0Sopenharmony_ci 833d5ac70f0Sopenharmony_ci id = name->value.s; 834d5ac70f0Sopenharmony_ci p = (struct alisp_object_pair *)malloc(sizeof(struct alisp_object_pair)); 835d5ac70f0Sopenharmony_ci if (p == NULL) { 836d5ac70f0Sopenharmony_ci nomem(); 837d5ac70f0Sopenharmony_ci return NULL; 838d5ac70f0Sopenharmony_ci } 839d5ac70f0Sopenharmony_ci p->name = strdup(id); 840d5ac70f0Sopenharmony_ci if (p->name == NULL) { 841d5ac70f0Sopenharmony_ci delete_tree(instance, value); 842d5ac70f0Sopenharmony_ci free(p); 843d5ac70f0Sopenharmony_ci return NULL; 844d5ac70f0Sopenharmony_ci } 845d5ac70f0Sopenharmony_ci list_add(&p->list, &instance->setobjs_list[get_string_hash(id)]); 846d5ac70f0Sopenharmony_ci p->value = value; 847d5ac70f0Sopenharmony_ci return p; 848d5ac70f0Sopenharmony_ci} 849d5ac70f0Sopenharmony_ci 850d5ac70f0Sopenharmony_cistatic int check_set_object(struct alisp_instance * instance, struct alisp_object * name) 851d5ac70f0Sopenharmony_ci{ 852d5ac70f0Sopenharmony_ci if (name == &alsa_lisp_nil) { 853d5ac70f0Sopenharmony_ci lisp_warn(instance, "setting the value of a nil object"); 854d5ac70f0Sopenharmony_ci return 0; 855d5ac70f0Sopenharmony_ci } 856d5ac70f0Sopenharmony_ci if (name == &alsa_lisp_t) { 857d5ac70f0Sopenharmony_ci lisp_warn(instance, "setting the value of a t object"); 858d5ac70f0Sopenharmony_ci return 0; 859d5ac70f0Sopenharmony_ci } 860d5ac70f0Sopenharmony_ci if (!alisp_compare_type(name, ALISP_OBJ_IDENTIFIER) && 861d5ac70f0Sopenharmony_ci !alisp_compare_type(name, ALISP_OBJ_STRING)) { 862d5ac70f0Sopenharmony_ci lisp_warn(instance, "setting the value of an object with non-indentifier"); 863d5ac70f0Sopenharmony_ci return 0; 864d5ac70f0Sopenharmony_ci } 865d5ac70f0Sopenharmony_ci return 1; 866d5ac70f0Sopenharmony_ci} 867d5ac70f0Sopenharmony_ci 868d5ac70f0Sopenharmony_cistatic struct alisp_object_pair * set_object(struct alisp_instance *instance, struct alisp_object * name, struct alisp_object * value) 869d5ac70f0Sopenharmony_ci{ 870d5ac70f0Sopenharmony_ci struct list_head *pos; 871d5ac70f0Sopenharmony_ci struct alisp_object_pair *p; 872d5ac70f0Sopenharmony_ci const char *id; 873d5ac70f0Sopenharmony_ci 874d5ac70f0Sopenharmony_ci if (name == NULL || value == NULL) 875d5ac70f0Sopenharmony_ci return NULL; 876d5ac70f0Sopenharmony_ci 877d5ac70f0Sopenharmony_ci id = name->value.s; 878d5ac70f0Sopenharmony_ci 879d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->setobjs_list[get_string_hash(id)]) { 880d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object_pair, list); 881d5ac70f0Sopenharmony_ci if (!strcmp(p->name, id)) { 882d5ac70f0Sopenharmony_ci delete_tree(instance, p->value); 883d5ac70f0Sopenharmony_ci p->value = value; 884d5ac70f0Sopenharmony_ci return p; 885d5ac70f0Sopenharmony_ci } 886d5ac70f0Sopenharmony_ci } 887d5ac70f0Sopenharmony_ci 888d5ac70f0Sopenharmony_ci p = (struct alisp_object_pair *)malloc(sizeof(struct alisp_object_pair)); 889d5ac70f0Sopenharmony_ci if (p == NULL) { 890d5ac70f0Sopenharmony_ci nomem(); 891d5ac70f0Sopenharmony_ci return NULL; 892d5ac70f0Sopenharmony_ci } 893d5ac70f0Sopenharmony_ci p->name = strdup(id); 894d5ac70f0Sopenharmony_ci if (p->name == NULL) { 895d5ac70f0Sopenharmony_ci delete_tree(instance, value); 896d5ac70f0Sopenharmony_ci free(p); 897d5ac70f0Sopenharmony_ci return NULL; 898d5ac70f0Sopenharmony_ci } 899d5ac70f0Sopenharmony_ci list_add(&p->list, &instance->setobjs_list[get_string_hash(id)]); 900d5ac70f0Sopenharmony_ci p->value = value; 901d5ac70f0Sopenharmony_ci return p; 902d5ac70f0Sopenharmony_ci} 903d5ac70f0Sopenharmony_ci 904d5ac70f0Sopenharmony_cistatic struct alisp_object * unset_object(struct alisp_instance *instance, struct alisp_object * name) 905d5ac70f0Sopenharmony_ci{ 906d5ac70f0Sopenharmony_ci struct list_head *pos; 907d5ac70f0Sopenharmony_ci struct alisp_object *res; 908d5ac70f0Sopenharmony_ci struct alisp_object_pair *p; 909d5ac70f0Sopenharmony_ci const char *id; 910d5ac70f0Sopenharmony_ci 911d5ac70f0Sopenharmony_ci if (!alisp_compare_type(name, ALISP_OBJ_IDENTIFIER) && 912d5ac70f0Sopenharmony_ci !alisp_compare_type(name, ALISP_OBJ_STRING)) { 913d5ac70f0Sopenharmony_ci lisp_warn(instance, "unset object with a non-indentifier"); 914d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 915d5ac70f0Sopenharmony_ci } 916d5ac70f0Sopenharmony_ci id = name->value.s; 917d5ac70f0Sopenharmony_ci 918d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->setobjs_list[get_string_hash(id)]) { 919d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object_pair, list); 920d5ac70f0Sopenharmony_ci if (!strcmp(p->name, id)) { 921d5ac70f0Sopenharmony_ci list_del(&p->list); 922d5ac70f0Sopenharmony_ci res = p->value; 923d5ac70f0Sopenharmony_ci free((void *)p->name); 924d5ac70f0Sopenharmony_ci free(p); 925d5ac70f0Sopenharmony_ci return res; 926d5ac70f0Sopenharmony_ci } 927d5ac70f0Sopenharmony_ci } 928d5ac70f0Sopenharmony_ci 929d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 930d5ac70f0Sopenharmony_ci} 931d5ac70f0Sopenharmony_ci 932d5ac70f0Sopenharmony_cistatic struct alisp_object * get_object1(struct alisp_instance *instance, const char *id) 933d5ac70f0Sopenharmony_ci{ 934d5ac70f0Sopenharmony_ci struct alisp_object_pair *p; 935d5ac70f0Sopenharmony_ci struct list_head *pos; 936d5ac70f0Sopenharmony_ci 937d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->setobjs_list[get_string_hash(id)]) { 938d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object_pair, list); 939d5ac70f0Sopenharmony_ci if (!strcmp(p->name, id)) 940d5ac70f0Sopenharmony_ci return p->value; 941d5ac70f0Sopenharmony_ci } 942d5ac70f0Sopenharmony_ci 943d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 944d5ac70f0Sopenharmony_ci} 945d5ac70f0Sopenharmony_ci 946d5ac70f0Sopenharmony_cistatic struct alisp_object * get_object(struct alisp_instance *instance, struct alisp_object * name) 947d5ac70f0Sopenharmony_ci{ 948d5ac70f0Sopenharmony_ci if (!alisp_compare_type(name, ALISP_OBJ_IDENTIFIER) && 949d5ac70f0Sopenharmony_ci !alisp_compare_type(name, ALISP_OBJ_STRING)) { 950d5ac70f0Sopenharmony_ci delete_tree(instance, name); 951d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 952d5ac70f0Sopenharmony_ci } 953d5ac70f0Sopenharmony_ci return get_object1(instance, name->value.s); 954d5ac70f0Sopenharmony_ci} 955d5ac70f0Sopenharmony_ci 956d5ac70f0Sopenharmony_cistatic struct alisp_object * replace_object(struct alisp_instance *instance, struct alisp_object * name, struct alisp_object * onew) 957d5ac70f0Sopenharmony_ci{ 958d5ac70f0Sopenharmony_ci struct alisp_object_pair *p; 959d5ac70f0Sopenharmony_ci struct alisp_object *r; 960d5ac70f0Sopenharmony_ci struct list_head *pos; 961d5ac70f0Sopenharmony_ci const char *id; 962d5ac70f0Sopenharmony_ci 963d5ac70f0Sopenharmony_ci if (!alisp_compare_type(name, ALISP_OBJ_IDENTIFIER) && 964d5ac70f0Sopenharmony_ci !alisp_compare_type(name, ALISP_OBJ_STRING)) { 965d5ac70f0Sopenharmony_ci delete_tree(instance, name); 966d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 967d5ac70f0Sopenharmony_ci } 968d5ac70f0Sopenharmony_ci id = name->value.s; 969d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->setobjs_list[get_string_hash(id)]) { 970d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object_pair, list); 971d5ac70f0Sopenharmony_ci if (!strcmp(p->name, id)) { 972d5ac70f0Sopenharmony_ci r = p->value; 973d5ac70f0Sopenharmony_ci p->value = onew; 974d5ac70f0Sopenharmony_ci return r; 975d5ac70f0Sopenharmony_ci } 976d5ac70f0Sopenharmony_ci } 977d5ac70f0Sopenharmony_ci 978d5ac70f0Sopenharmony_ci return NULL; 979d5ac70f0Sopenharmony_ci} 980d5ac70f0Sopenharmony_ci 981d5ac70f0Sopenharmony_cistatic void dump_objects(struct alisp_instance *instance, const char *fname) 982d5ac70f0Sopenharmony_ci{ 983d5ac70f0Sopenharmony_ci struct alisp_object_pair *p; 984d5ac70f0Sopenharmony_ci snd_output_t *out; 985d5ac70f0Sopenharmony_ci struct list_head *pos; 986d5ac70f0Sopenharmony_ci int i, err; 987d5ac70f0Sopenharmony_ci 988d5ac70f0Sopenharmony_ci if (!strcmp(fname, "-")) 989d5ac70f0Sopenharmony_ci err = snd_output_stdio_attach(&out, stdout, 0); 990d5ac70f0Sopenharmony_ci else 991d5ac70f0Sopenharmony_ci err = snd_output_stdio_open(&out, fname, "w+"); 992d5ac70f0Sopenharmony_ci if (err < 0) { 993d5ac70f0Sopenharmony_ci SNDERR("alisp: cannot open file '%s' for writing (%s)", fname, snd_strerror(errno)); 994d5ac70f0Sopenharmony_ci return; 995d5ac70f0Sopenharmony_ci } 996d5ac70f0Sopenharmony_ci 997d5ac70f0Sopenharmony_ci for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++) { 998d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->setobjs_list[i]) { 999d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object_pair, list); 1000d5ac70f0Sopenharmony_ci if (alisp_compare_type(p->value, ALISP_OBJ_CONS) && 1001d5ac70f0Sopenharmony_ci alisp_compare_type(p->value->value.c.car, ALISP_OBJ_IDENTIFIER) && 1002d5ac70f0Sopenharmony_ci !strcmp(p->value->value.c.car->value.s, "lambda")) { 1003d5ac70f0Sopenharmony_ci snd_output_printf(out, "(defun %s ", p->name); 1004d5ac70f0Sopenharmony_ci princ_cons(out, p->value->value.c.cdr); 1005d5ac70f0Sopenharmony_ci snd_output_printf(out, ")\n"); 1006d5ac70f0Sopenharmony_ci continue; 1007d5ac70f0Sopenharmony_ci } 1008d5ac70f0Sopenharmony_ci snd_output_printf(out, "(setq %s '", p->name); 1009d5ac70f0Sopenharmony_ci princ_object(out, p->value); 1010d5ac70f0Sopenharmony_ci snd_output_printf(out, ")\n"); 1011d5ac70f0Sopenharmony_ci } 1012d5ac70f0Sopenharmony_ci } 1013d5ac70f0Sopenharmony_ci snd_output_close(out); 1014d5ac70f0Sopenharmony_ci} 1015d5ac70f0Sopenharmony_ci 1016d5ac70f0Sopenharmony_cistatic const char *obj_type_str(struct alisp_object * p) 1017d5ac70f0Sopenharmony_ci{ 1018d5ac70f0Sopenharmony_ci switch (alisp_get_type(p)) { 1019d5ac70f0Sopenharmony_ci case ALISP_OBJ_NIL: return "nil"; 1020d5ac70f0Sopenharmony_ci case ALISP_OBJ_T: return "t"; 1021d5ac70f0Sopenharmony_ci case ALISP_OBJ_INTEGER: return "integer"; 1022d5ac70f0Sopenharmony_ci case ALISP_OBJ_FLOAT: return "float"; 1023d5ac70f0Sopenharmony_ci case ALISP_OBJ_IDENTIFIER: return "identifier"; 1024d5ac70f0Sopenharmony_ci case ALISP_OBJ_STRING: return "string"; 1025d5ac70f0Sopenharmony_ci case ALISP_OBJ_POINTER: return "pointer"; 1026d5ac70f0Sopenharmony_ci case ALISP_OBJ_CONS: return "cons"; 1027d5ac70f0Sopenharmony_ci default: assert(0); 1028d5ac70f0Sopenharmony_ci } 1029d5ac70f0Sopenharmony_ci} 1030d5ac70f0Sopenharmony_ci 1031d5ac70f0Sopenharmony_cistatic void print_obj_lists(struct alisp_instance *instance, snd_output_t *out) 1032d5ac70f0Sopenharmony_ci{ 1033d5ac70f0Sopenharmony_ci struct list_head *pos; 1034d5ac70f0Sopenharmony_ci struct alisp_object * p; 1035d5ac70f0Sopenharmony_ci int i, j; 1036d5ac70f0Sopenharmony_ci 1037d5ac70f0Sopenharmony_ci snd_output_printf(out, "** used objects\n"); 1038d5ac70f0Sopenharmony_ci for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++) 1039d5ac70f0Sopenharmony_ci for (j = 0; j <= ALISP_OBJ_LAST_SEARCH; j++) 1040d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->used_objs_list[i][j]) { 1041d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 1042d5ac70f0Sopenharmony_ci snd_output_printf(out, "** %p (%s) (", p, obj_type_str(p)); 1043d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_CONS)) 1044d5ac70f0Sopenharmony_ci princ_object(out, p); 1045d5ac70f0Sopenharmony_ci else 1046d5ac70f0Sopenharmony_ci snd_output_printf(out, "cons"); 1047d5ac70f0Sopenharmony_ci snd_output_printf(out, ") refs=%i\n", alisp_get_refs(p)); 1048d5ac70f0Sopenharmony_ci } 1049d5ac70f0Sopenharmony_ci snd_output_printf(out, "** free objects\n"); 1050d5ac70f0Sopenharmony_ci list_for_each(pos, &instance->free_objs_list) { 1051d5ac70f0Sopenharmony_ci p = list_entry(pos, struct alisp_object, list); 1052d5ac70f0Sopenharmony_ci snd_output_printf(out, "** %p\n", p); 1053d5ac70f0Sopenharmony_ci } 1054d5ac70f0Sopenharmony_ci} 1055d5ac70f0Sopenharmony_ci 1056d5ac70f0Sopenharmony_cistatic void dump_obj_lists(struct alisp_instance *instance, const char *fname) 1057d5ac70f0Sopenharmony_ci{ 1058d5ac70f0Sopenharmony_ci snd_output_t *out; 1059d5ac70f0Sopenharmony_ci int err; 1060d5ac70f0Sopenharmony_ci 1061d5ac70f0Sopenharmony_ci if (!strcmp(fname, "-")) 1062d5ac70f0Sopenharmony_ci err = snd_output_stdio_attach(&out, stdout, 0); 1063d5ac70f0Sopenharmony_ci else 1064d5ac70f0Sopenharmony_ci err = snd_output_stdio_open(&out, fname, "w+"); 1065d5ac70f0Sopenharmony_ci if (err < 0) { 1066d5ac70f0Sopenharmony_ci SNDERR("alisp: cannot open file '%s' for writing (%s)", fname, snd_strerror(errno)); 1067d5ac70f0Sopenharmony_ci return; 1068d5ac70f0Sopenharmony_ci } 1069d5ac70f0Sopenharmony_ci 1070d5ac70f0Sopenharmony_ci print_obj_lists(instance, out); 1071d5ac70f0Sopenharmony_ci 1072d5ac70f0Sopenharmony_ci snd_output_close(out); 1073d5ac70f0Sopenharmony_ci} 1074d5ac70f0Sopenharmony_ci 1075d5ac70f0Sopenharmony_ci/* 1076d5ac70f0Sopenharmony_ci * functions 1077d5ac70f0Sopenharmony_ci */ 1078d5ac70f0Sopenharmony_ci 1079d5ac70f0Sopenharmony_cistatic int count_list(struct alisp_object * p) 1080d5ac70f0Sopenharmony_ci{ 1081d5ac70f0Sopenharmony_ci int i = 0; 1082d5ac70f0Sopenharmony_ci 1083d5ac70f0Sopenharmony_ci while (p != &alsa_lisp_nil && alisp_compare_type(p, ALISP_OBJ_CONS)) { 1084d5ac70f0Sopenharmony_ci p = p->value.c.cdr; 1085d5ac70f0Sopenharmony_ci ++i; 1086d5ac70f0Sopenharmony_ci } 1087d5ac70f0Sopenharmony_ci 1088d5ac70f0Sopenharmony_ci return i; 1089d5ac70f0Sopenharmony_ci} 1090d5ac70f0Sopenharmony_ci 1091d5ac70f0Sopenharmony_cistatic inline struct alisp_object * car(struct alisp_object * p) 1092d5ac70f0Sopenharmony_ci{ 1093d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_CONS)) 1094d5ac70f0Sopenharmony_ci return p->value.c.car; 1095d5ac70f0Sopenharmony_ci 1096d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1097d5ac70f0Sopenharmony_ci} 1098d5ac70f0Sopenharmony_ci 1099d5ac70f0Sopenharmony_cistatic inline struct alisp_object * cdr(struct alisp_object * p) 1100d5ac70f0Sopenharmony_ci{ 1101d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_CONS)) 1102d5ac70f0Sopenharmony_ci return p->value.c.cdr; 1103d5ac70f0Sopenharmony_ci 1104d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1105d5ac70f0Sopenharmony_ci} 1106d5ac70f0Sopenharmony_ci 1107d5ac70f0Sopenharmony_ci/* 1108d5ac70f0Sopenharmony_ci * Syntax: (car expr) 1109d5ac70f0Sopenharmony_ci */ 1110d5ac70f0Sopenharmony_cistatic struct alisp_object * F_car(struct alisp_instance *instance, struct alisp_object * args) 1111d5ac70f0Sopenharmony_ci{ 1112d5ac70f0Sopenharmony_ci struct alisp_object *p1 = car(args), *p2; 1113d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 1114d5ac70f0Sopenharmony_ci delete_object(instance, args); 1115d5ac70f0Sopenharmony_ci p1 = eval(instance, p1); 1116d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p1)); 1117d5ac70f0Sopenharmony_ci p2 = car(p1); 1118d5ac70f0Sopenharmony_ci delete_object(instance, p1); 1119d5ac70f0Sopenharmony_ci return p2; 1120d5ac70f0Sopenharmony_ci} 1121d5ac70f0Sopenharmony_ci 1122d5ac70f0Sopenharmony_ci/* 1123d5ac70f0Sopenharmony_ci * Syntax: (cdr expr) 1124d5ac70f0Sopenharmony_ci */ 1125d5ac70f0Sopenharmony_cistatic struct alisp_object * F_cdr(struct alisp_instance *instance, struct alisp_object * args) 1126d5ac70f0Sopenharmony_ci{ 1127d5ac70f0Sopenharmony_ci struct alisp_object *p1 = car(args), *p2; 1128d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 1129d5ac70f0Sopenharmony_ci delete_object(instance, args); 1130d5ac70f0Sopenharmony_ci p1 = eval(instance, p1); 1131d5ac70f0Sopenharmony_ci delete_tree(instance, car(p1)); 1132d5ac70f0Sopenharmony_ci p2 = cdr(p1); 1133d5ac70f0Sopenharmony_ci delete_object(instance, p1); 1134d5ac70f0Sopenharmony_ci return p2; 1135d5ac70f0Sopenharmony_ci} 1136d5ac70f0Sopenharmony_ci 1137d5ac70f0Sopenharmony_ci/* 1138d5ac70f0Sopenharmony_ci * Syntax: (+ expr...) 1139d5ac70f0Sopenharmony_ci */ 1140d5ac70f0Sopenharmony_cistatic struct alisp_object * F_add(struct alisp_instance *instance, struct alisp_object * args) 1141d5ac70f0Sopenharmony_ci{ 1142d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1, * n; 1143d5ac70f0Sopenharmony_ci long v = 0; 1144d5ac70f0Sopenharmony_ci double f = 0; 1145d5ac70f0Sopenharmony_ci int type = ALISP_OBJ_INTEGER; 1146d5ac70f0Sopenharmony_ci 1147d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1148d5ac70f0Sopenharmony_ci for (;;) { 1149d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER)) { 1150d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_FLOAT) 1151d5ac70f0Sopenharmony_ci f += p1->value.i; 1152d5ac70f0Sopenharmony_ci else 1153d5ac70f0Sopenharmony_ci v += p1->value.i; 1154d5ac70f0Sopenharmony_ci } else if (alisp_compare_type(p1, ALISP_OBJ_FLOAT)) { 1155d5ac70f0Sopenharmony_ci f += p1->value.f + v; 1156d5ac70f0Sopenharmony_ci v = 0; 1157d5ac70f0Sopenharmony_ci type = ALISP_OBJ_FLOAT; 1158d5ac70f0Sopenharmony_ci } else { 1159d5ac70f0Sopenharmony_ci lisp_warn(instance, "sum with a non integer or float operand"); 1160d5ac70f0Sopenharmony_ci } 1161d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1162d5ac70f0Sopenharmony_ci p = cdr(n = p); 1163d5ac70f0Sopenharmony_ci delete_object(instance, n); 1164d5ac70f0Sopenharmony_ci if (p == &alsa_lisp_nil) 1165d5ac70f0Sopenharmony_ci break; 1166d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1167d5ac70f0Sopenharmony_ci } 1168d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_INTEGER) { 1169d5ac70f0Sopenharmony_ci return new_integer(instance, v); 1170d5ac70f0Sopenharmony_ci } else { 1171d5ac70f0Sopenharmony_ci return new_float(instance, f); 1172d5ac70f0Sopenharmony_ci } 1173d5ac70f0Sopenharmony_ci} 1174d5ac70f0Sopenharmony_ci 1175d5ac70f0Sopenharmony_ci/* 1176d5ac70f0Sopenharmony_ci * Syntax: (concat expr...) 1177d5ac70f0Sopenharmony_ci */ 1178d5ac70f0Sopenharmony_cistatic struct alisp_object * F_concat(struct alisp_instance *instance, struct alisp_object * args) 1179d5ac70f0Sopenharmony_ci{ 1180d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1, * n; 1181d5ac70f0Sopenharmony_ci char *str = NULL, *str1; 1182d5ac70f0Sopenharmony_ci 1183d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1184d5ac70f0Sopenharmony_ci for (;;) { 1185d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_STRING)) { 1186d5ac70f0Sopenharmony_ci str1 = realloc(str, (str ? strlen(str) : 0) + strlen(p1->value.s) + 1); 1187d5ac70f0Sopenharmony_ci if (str1 == NULL) { 1188d5ac70f0Sopenharmony_ci nomem(); 1189d5ac70f0Sopenharmony_ci free(str); 1190d5ac70f0Sopenharmony_ci return NULL; 1191d5ac70f0Sopenharmony_ci } 1192d5ac70f0Sopenharmony_ci if (str == NULL) 1193d5ac70f0Sopenharmony_ci strcpy(str1, p1->value.s); 1194d5ac70f0Sopenharmony_ci else 1195d5ac70f0Sopenharmony_ci strcat(str1, p1->value.s); 1196d5ac70f0Sopenharmony_ci str = str1; 1197d5ac70f0Sopenharmony_ci } else { 1198d5ac70f0Sopenharmony_ci lisp_warn(instance, "concat with a non string or identifier operand"); 1199d5ac70f0Sopenharmony_ci } 1200d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1201d5ac70f0Sopenharmony_ci p = cdr(n = p); 1202d5ac70f0Sopenharmony_ci delete_object(instance, n); 1203d5ac70f0Sopenharmony_ci if (p == &alsa_lisp_nil) 1204d5ac70f0Sopenharmony_ci break; 1205d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1206d5ac70f0Sopenharmony_ci } 1207d5ac70f0Sopenharmony_ci if (str) { 1208d5ac70f0Sopenharmony_ci p = new_string(instance, str); 1209d5ac70f0Sopenharmony_ci free(str); 1210d5ac70f0Sopenharmony_ci } else { 1211d5ac70f0Sopenharmony_ci p = &alsa_lisp_nil; 1212d5ac70f0Sopenharmony_ci } 1213d5ac70f0Sopenharmony_ci return p; 1214d5ac70f0Sopenharmony_ci} 1215d5ac70f0Sopenharmony_ci 1216d5ac70f0Sopenharmony_ci/* 1217d5ac70f0Sopenharmony_ci * Syntax: (- expr...) 1218d5ac70f0Sopenharmony_ci */ 1219d5ac70f0Sopenharmony_cistatic struct alisp_object * F_sub(struct alisp_instance *instance, struct alisp_object * args) 1220d5ac70f0Sopenharmony_ci{ 1221d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1, * n; 1222d5ac70f0Sopenharmony_ci long v = 0; 1223d5ac70f0Sopenharmony_ci double f = 0; 1224d5ac70f0Sopenharmony_ci int type = ALISP_OBJ_INTEGER; 1225d5ac70f0Sopenharmony_ci 1226d5ac70f0Sopenharmony_ci do { 1227d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1228d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER)) { 1229d5ac70f0Sopenharmony_ci if (p == args && cdr(p) != &alsa_lisp_nil) { 1230d5ac70f0Sopenharmony_ci v = p1->value.i; 1231d5ac70f0Sopenharmony_ci } else { 1232d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_FLOAT) 1233d5ac70f0Sopenharmony_ci f -= p1->value.i; 1234d5ac70f0Sopenharmony_ci else 1235d5ac70f0Sopenharmony_ci v -= p1->value.i; 1236d5ac70f0Sopenharmony_ci } 1237d5ac70f0Sopenharmony_ci } else if (alisp_compare_type(p1, ALISP_OBJ_FLOAT)) { 1238d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_INTEGER) { 1239d5ac70f0Sopenharmony_ci f = v; 1240d5ac70f0Sopenharmony_ci type = ALISP_OBJ_FLOAT; 1241d5ac70f0Sopenharmony_ci } 1242d5ac70f0Sopenharmony_ci if (p == args && cdr(p) != &alsa_lisp_nil) 1243d5ac70f0Sopenharmony_ci f = p1->value.f; 1244d5ac70f0Sopenharmony_ci else { 1245d5ac70f0Sopenharmony_ci f -= p1->value.f; 1246d5ac70f0Sopenharmony_ci } 1247d5ac70f0Sopenharmony_ci } else 1248d5ac70f0Sopenharmony_ci lisp_warn(instance, "difference with a non integer or float operand"); 1249d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1250d5ac70f0Sopenharmony_ci n = cdr(p); 1251d5ac70f0Sopenharmony_ci delete_object(instance, p); 1252d5ac70f0Sopenharmony_ci p = n; 1253d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 1254d5ac70f0Sopenharmony_ci 1255d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_INTEGER) { 1256d5ac70f0Sopenharmony_ci return new_integer(instance, v); 1257d5ac70f0Sopenharmony_ci } else { 1258d5ac70f0Sopenharmony_ci return new_float(instance, f); 1259d5ac70f0Sopenharmony_ci } 1260d5ac70f0Sopenharmony_ci} 1261d5ac70f0Sopenharmony_ci 1262d5ac70f0Sopenharmony_ci/* 1263d5ac70f0Sopenharmony_ci * Syntax: (* expr...) 1264d5ac70f0Sopenharmony_ci */ 1265d5ac70f0Sopenharmony_cistatic struct alisp_object * F_mul(struct alisp_instance *instance, struct alisp_object * args) 1266d5ac70f0Sopenharmony_ci{ 1267d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1, * n; 1268d5ac70f0Sopenharmony_ci long v = 1; 1269d5ac70f0Sopenharmony_ci double f = 1; 1270d5ac70f0Sopenharmony_ci int type = ALISP_OBJ_INTEGER; 1271d5ac70f0Sopenharmony_ci 1272d5ac70f0Sopenharmony_ci do { 1273d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1274d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER)) { 1275d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_FLOAT) 1276d5ac70f0Sopenharmony_ci f *= p1->value.i; 1277d5ac70f0Sopenharmony_ci else 1278d5ac70f0Sopenharmony_ci v *= p1->value.i; 1279d5ac70f0Sopenharmony_ci } else if (alisp_compare_type(p1, ALISP_OBJ_FLOAT)) { 1280d5ac70f0Sopenharmony_ci f *= p1->value.f * v; v = 1; 1281d5ac70f0Sopenharmony_ci type = ALISP_OBJ_FLOAT; 1282d5ac70f0Sopenharmony_ci } else { 1283d5ac70f0Sopenharmony_ci lisp_warn(instance, "product with a non integer or float operand"); 1284d5ac70f0Sopenharmony_ci } 1285d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1286d5ac70f0Sopenharmony_ci n = cdr(p); 1287d5ac70f0Sopenharmony_ci delete_object(instance, p); 1288d5ac70f0Sopenharmony_ci p = n; 1289d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 1290d5ac70f0Sopenharmony_ci 1291d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_INTEGER) { 1292d5ac70f0Sopenharmony_ci return new_integer(instance, v); 1293d5ac70f0Sopenharmony_ci } else { 1294d5ac70f0Sopenharmony_ci return new_float(instance, f); 1295d5ac70f0Sopenharmony_ci } 1296d5ac70f0Sopenharmony_ci} 1297d5ac70f0Sopenharmony_ci 1298d5ac70f0Sopenharmony_ci/* 1299d5ac70f0Sopenharmony_ci * Syntax: (/ expr...) 1300d5ac70f0Sopenharmony_ci */ 1301d5ac70f0Sopenharmony_cistatic struct alisp_object * F_div(struct alisp_instance *instance, struct alisp_object * args) 1302d5ac70f0Sopenharmony_ci{ 1303d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1, * n; 1304d5ac70f0Sopenharmony_ci long v = 0; 1305d5ac70f0Sopenharmony_ci double f = 0; 1306d5ac70f0Sopenharmony_ci int type = ALISP_OBJ_INTEGER; 1307d5ac70f0Sopenharmony_ci 1308d5ac70f0Sopenharmony_ci do { 1309d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1310d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER)) { 1311d5ac70f0Sopenharmony_ci if (p == args && cdr(p) != &alsa_lisp_nil) { 1312d5ac70f0Sopenharmony_ci v = p1->value.i; 1313d5ac70f0Sopenharmony_ci } else { 1314d5ac70f0Sopenharmony_ci if (p1->value.i == 0) { 1315d5ac70f0Sopenharmony_ci lisp_warn(instance, "division by zero"); 1316d5ac70f0Sopenharmony_ci v = 0; 1317d5ac70f0Sopenharmony_ci f = 0; 1318d5ac70f0Sopenharmony_ci break; 1319d5ac70f0Sopenharmony_ci } else { 1320d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_FLOAT) 1321d5ac70f0Sopenharmony_ci f /= p1->value.i; 1322d5ac70f0Sopenharmony_ci else 1323d5ac70f0Sopenharmony_ci v /= p1->value.i; 1324d5ac70f0Sopenharmony_ci } 1325d5ac70f0Sopenharmony_ci } 1326d5ac70f0Sopenharmony_ci } else if (alisp_compare_type(p1, ALISP_OBJ_FLOAT)) { 1327d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_INTEGER) { 1328d5ac70f0Sopenharmony_ci f = v; 1329d5ac70f0Sopenharmony_ci type = ALISP_OBJ_FLOAT; 1330d5ac70f0Sopenharmony_ci } 1331d5ac70f0Sopenharmony_ci if (p == args && cdr(p) != &alsa_lisp_nil) { 1332d5ac70f0Sopenharmony_ci f = p1->value.f; 1333d5ac70f0Sopenharmony_ci } else { 1334d5ac70f0Sopenharmony_ci if (p1->value.f == 0) { 1335d5ac70f0Sopenharmony_ci lisp_warn(instance, "division by zero"); 1336d5ac70f0Sopenharmony_ci f = 0; 1337d5ac70f0Sopenharmony_ci break; 1338d5ac70f0Sopenharmony_ci } else { 1339d5ac70f0Sopenharmony_ci f /= p1->value.i; 1340d5ac70f0Sopenharmony_ci } 1341d5ac70f0Sopenharmony_ci } 1342d5ac70f0Sopenharmony_ci } else 1343d5ac70f0Sopenharmony_ci lisp_warn(instance, "quotient with a non integer or float operand"); 1344d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1345d5ac70f0Sopenharmony_ci n = cdr(p); 1346d5ac70f0Sopenharmony_ci delete_object(instance, p); 1347d5ac70f0Sopenharmony_ci p = n; 1348d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 1349d5ac70f0Sopenharmony_ci 1350d5ac70f0Sopenharmony_ci if (type == ALISP_OBJ_INTEGER) { 1351d5ac70f0Sopenharmony_ci return new_integer(instance, v); 1352d5ac70f0Sopenharmony_ci } else { 1353d5ac70f0Sopenharmony_ci return new_float(instance, f); 1354d5ac70f0Sopenharmony_ci } 1355d5ac70f0Sopenharmony_ci} 1356d5ac70f0Sopenharmony_ci 1357d5ac70f0Sopenharmony_ci/* 1358d5ac70f0Sopenharmony_ci * Syntax: (% expr1 expr2) 1359d5ac70f0Sopenharmony_ci */ 1360d5ac70f0Sopenharmony_cistatic struct alisp_object * F_mod(struct alisp_instance *instance, struct alisp_object * args) 1361d5ac70f0Sopenharmony_ci{ 1362d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * p3; 1363d5ac70f0Sopenharmony_ci 1364d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1365d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1366d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1367d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1368d5ac70f0Sopenharmony_ci delete_object(instance, args); 1369d5ac70f0Sopenharmony_ci 1370d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER) && 1371d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_INTEGER)) { 1372d5ac70f0Sopenharmony_ci if (p2->value.i == 0) { 1373d5ac70f0Sopenharmony_ci lisp_warn(instance, "module by zero"); 1374d5ac70f0Sopenharmony_ci p3 = new_integer(instance, 0); 1375d5ac70f0Sopenharmony_ci } else { 1376d5ac70f0Sopenharmony_ci p3 = new_integer(instance, p1->value.i % p2->value.i); 1377d5ac70f0Sopenharmony_ci } 1378d5ac70f0Sopenharmony_ci } else if ((alisp_compare_type(p1, ALISP_OBJ_INTEGER) || 1379d5ac70f0Sopenharmony_ci alisp_compare_type(p1, ALISP_OBJ_FLOAT)) && 1380d5ac70f0Sopenharmony_ci (alisp_compare_type(p2, ALISP_OBJ_INTEGER) || 1381d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_FLOAT))) { 1382d5ac70f0Sopenharmony_ci double f1, f2; 1383d5ac70f0Sopenharmony_ci f1 = alisp_compare_type(p1, ALISP_OBJ_INTEGER) ? p1->value.i : p1->value.f; 1384d5ac70f0Sopenharmony_ci f2 = alisp_compare_type(p2, ALISP_OBJ_INTEGER) ? p2->value.i : p2->value.f; 1385d5ac70f0Sopenharmony_ci f1 = fmod(f1, f2); 1386d5ac70f0Sopenharmony_ci if (f1 == EDOM) { 1387d5ac70f0Sopenharmony_ci lisp_warn(instance, "module by zero"); 1388d5ac70f0Sopenharmony_ci p3 = new_float(instance, 0); 1389d5ac70f0Sopenharmony_ci } else { 1390d5ac70f0Sopenharmony_ci p3 = new_float(instance, f1); 1391d5ac70f0Sopenharmony_ci } 1392d5ac70f0Sopenharmony_ci } else { 1393d5ac70f0Sopenharmony_ci lisp_warn(instance, "module with a non integer or float operand"); 1394d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1395d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1396d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1397d5ac70f0Sopenharmony_ci } 1398d5ac70f0Sopenharmony_ci 1399d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1400d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1401d5ac70f0Sopenharmony_ci return p3; 1402d5ac70f0Sopenharmony_ci} 1403d5ac70f0Sopenharmony_ci 1404d5ac70f0Sopenharmony_ci/* 1405d5ac70f0Sopenharmony_ci * Syntax: (< expr1 expr2) 1406d5ac70f0Sopenharmony_ci */ 1407d5ac70f0Sopenharmony_cistatic struct alisp_object * F_lt(struct alisp_instance *instance, struct alisp_object * args) 1408d5ac70f0Sopenharmony_ci{ 1409d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1410d5ac70f0Sopenharmony_ci 1411d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1412d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1413d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1414d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1415d5ac70f0Sopenharmony_ci delete_object(instance, args); 1416d5ac70f0Sopenharmony_ci 1417d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER) && 1418d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_INTEGER)) { 1419d5ac70f0Sopenharmony_ci if (p1->value.i < p2->value.i) { 1420d5ac70f0Sopenharmony_ci __true: 1421d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1422d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1423d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1424d5ac70f0Sopenharmony_ci } 1425d5ac70f0Sopenharmony_ci } else if ((alisp_compare_type(p1, ALISP_OBJ_INTEGER) || 1426d5ac70f0Sopenharmony_ci alisp_compare_type(p1, ALISP_OBJ_FLOAT)) && 1427d5ac70f0Sopenharmony_ci (alisp_compare_type(p2, ALISP_OBJ_INTEGER) || 1428d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_FLOAT))) { 1429d5ac70f0Sopenharmony_ci double f1, f2; 1430d5ac70f0Sopenharmony_ci f1 = alisp_compare_type(p1, ALISP_OBJ_INTEGER) ? p1->value.i : p1->value.f; 1431d5ac70f0Sopenharmony_ci f2 = alisp_compare_type(p2, ALISP_OBJ_INTEGER) ? p2->value.i : p2->value.f; 1432d5ac70f0Sopenharmony_ci if (f1 < f2) 1433d5ac70f0Sopenharmony_ci goto __true; 1434d5ac70f0Sopenharmony_ci } else { 1435d5ac70f0Sopenharmony_ci lisp_warn(instance, "comparison with a non integer or float operand"); 1436d5ac70f0Sopenharmony_ci } 1437d5ac70f0Sopenharmony_ci 1438d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1439d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1440d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1441d5ac70f0Sopenharmony_ci} 1442d5ac70f0Sopenharmony_ci 1443d5ac70f0Sopenharmony_ci/* 1444d5ac70f0Sopenharmony_ci * Syntax: (> expr1 expr2) 1445d5ac70f0Sopenharmony_ci */ 1446d5ac70f0Sopenharmony_cistatic struct alisp_object * F_gt(struct alisp_instance *instance, struct alisp_object * args) 1447d5ac70f0Sopenharmony_ci{ 1448d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1449d5ac70f0Sopenharmony_ci 1450d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1451d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1452d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1453d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1454d5ac70f0Sopenharmony_ci delete_object(instance, args); 1455d5ac70f0Sopenharmony_ci 1456d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER) && 1457d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_INTEGER)) { 1458d5ac70f0Sopenharmony_ci if (p1->value.i > p2->value.i) { 1459d5ac70f0Sopenharmony_ci __true: 1460d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1461d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1462d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1463d5ac70f0Sopenharmony_ci } 1464d5ac70f0Sopenharmony_ci } else if ((alisp_compare_type(p1, ALISP_OBJ_INTEGER) || 1465d5ac70f0Sopenharmony_ci alisp_compare_type(p1, ALISP_OBJ_FLOAT)) && 1466d5ac70f0Sopenharmony_ci (alisp_compare_type(p2, ALISP_OBJ_INTEGER) || 1467d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_FLOAT))) { 1468d5ac70f0Sopenharmony_ci double f1, f2; 1469d5ac70f0Sopenharmony_ci f1 = alisp_compare_type(p1, ALISP_OBJ_INTEGER) ? p1->value.i : p1->value.f; 1470d5ac70f0Sopenharmony_ci f2 = alisp_compare_type(p2, ALISP_OBJ_INTEGER) ? p2->value.i : p2->value.f; 1471d5ac70f0Sopenharmony_ci if (f1 > f2) 1472d5ac70f0Sopenharmony_ci goto __true; 1473d5ac70f0Sopenharmony_ci } else { 1474d5ac70f0Sopenharmony_ci lisp_warn(instance, "comparison with a non integer or float operand"); 1475d5ac70f0Sopenharmony_ci } 1476d5ac70f0Sopenharmony_ci 1477d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1478d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1479d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1480d5ac70f0Sopenharmony_ci} 1481d5ac70f0Sopenharmony_ci 1482d5ac70f0Sopenharmony_ci/* 1483d5ac70f0Sopenharmony_ci * Syntax: (<= expr1 expr2) 1484d5ac70f0Sopenharmony_ci */ 1485d5ac70f0Sopenharmony_cistatic struct alisp_object * F_le(struct alisp_instance *instance, struct alisp_object * args) 1486d5ac70f0Sopenharmony_ci{ 1487d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1488d5ac70f0Sopenharmony_ci 1489d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1490d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1491d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1492d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1493d5ac70f0Sopenharmony_ci delete_object(instance, args); 1494d5ac70f0Sopenharmony_ci 1495d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER) && 1496d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_INTEGER)) { 1497d5ac70f0Sopenharmony_ci if (p1->value.i <= p2->value.i) { 1498d5ac70f0Sopenharmony_ci __true: 1499d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1500d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1501d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1502d5ac70f0Sopenharmony_ci } 1503d5ac70f0Sopenharmony_ci } else if ((alisp_compare_type(p1, ALISP_OBJ_INTEGER) || 1504d5ac70f0Sopenharmony_ci alisp_compare_type(p1, ALISP_OBJ_FLOAT)) && 1505d5ac70f0Sopenharmony_ci (alisp_compare_type(p2, ALISP_OBJ_INTEGER) || 1506d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_FLOAT))) { 1507d5ac70f0Sopenharmony_ci double f1, f2; 1508d5ac70f0Sopenharmony_ci f1 = alisp_compare_type(p1, ALISP_OBJ_INTEGER) ? p1->value.i : p1->value.f; 1509d5ac70f0Sopenharmony_ci f2 = alisp_compare_type(p2, ALISP_OBJ_INTEGER) ? p2->value.i : p2->value.f; 1510d5ac70f0Sopenharmony_ci if (f1 <= f2) 1511d5ac70f0Sopenharmony_ci goto __true; 1512d5ac70f0Sopenharmony_ci } else { 1513d5ac70f0Sopenharmony_ci lisp_warn(instance, "comparison with a non integer or float operand"); 1514d5ac70f0Sopenharmony_ci } 1515d5ac70f0Sopenharmony_ci 1516d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1517d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1518d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1519d5ac70f0Sopenharmony_ci} 1520d5ac70f0Sopenharmony_ci 1521d5ac70f0Sopenharmony_ci/* 1522d5ac70f0Sopenharmony_ci * Syntax: (>= expr1 expr2) 1523d5ac70f0Sopenharmony_ci */ 1524d5ac70f0Sopenharmony_cistatic struct alisp_object * F_ge(struct alisp_instance *instance, struct alisp_object * args) 1525d5ac70f0Sopenharmony_ci{ 1526d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1527d5ac70f0Sopenharmony_ci 1528d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1529d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1530d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1531d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1532d5ac70f0Sopenharmony_ci delete_object(instance, args); 1533d5ac70f0Sopenharmony_ci 1534d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER) && 1535d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_INTEGER)) { 1536d5ac70f0Sopenharmony_ci if (p1->value.i >= p2->value.i) { 1537d5ac70f0Sopenharmony_ci __true: 1538d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1539d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1540d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1541d5ac70f0Sopenharmony_ci } 1542d5ac70f0Sopenharmony_ci } else if ((alisp_compare_type(p1, ALISP_OBJ_INTEGER) || 1543d5ac70f0Sopenharmony_ci alisp_compare_type(p1, ALISP_OBJ_FLOAT)) && 1544d5ac70f0Sopenharmony_ci (alisp_compare_type(p2, ALISP_OBJ_INTEGER) || 1545d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_FLOAT))) { 1546d5ac70f0Sopenharmony_ci double f1, f2; 1547d5ac70f0Sopenharmony_ci f1 = alisp_compare_type(p1, ALISP_OBJ_INTEGER) ? p1->value.i : p1->value.f; 1548d5ac70f0Sopenharmony_ci f2 = alisp_compare_type(p2, ALISP_OBJ_INTEGER) ? p2->value.i : p2->value.f; 1549d5ac70f0Sopenharmony_ci if (f1 >= f2) 1550d5ac70f0Sopenharmony_ci goto __true; 1551d5ac70f0Sopenharmony_ci } else { 1552d5ac70f0Sopenharmony_ci lisp_warn(instance, "comparison with a non integer or float operand"); 1553d5ac70f0Sopenharmony_ci } 1554d5ac70f0Sopenharmony_ci 1555d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1556d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1557d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1558d5ac70f0Sopenharmony_ci} 1559d5ac70f0Sopenharmony_ci 1560d5ac70f0Sopenharmony_ci/* 1561d5ac70f0Sopenharmony_ci * Syntax: (= expr1 expr2) 1562d5ac70f0Sopenharmony_ci */ 1563d5ac70f0Sopenharmony_cistatic struct alisp_object * F_numeq(struct alisp_instance *instance, struct alisp_object * args) 1564d5ac70f0Sopenharmony_ci{ 1565d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1566d5ac70f0Sopenharmony_ci 1567d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1568d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1569d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1570d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1571d5ac70f0Sopenharmony_ci delete_object(instance, args); 1572d5ac70f0Sopenharmony_ci 1573d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_INTEGER) && 1574d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_INTEGER)) { 1575d5ac70f0Sopenharmony_ci if (p1->value.i == p2->value.i) { 1576d5ac70f0Sopenharmony_ci __true: 1577d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1578d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1579d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1580d5ac70f0Sopenharmony_ci } 1581d5ac70f0Sopenharmony_ci } else if ((alisp_compare_type(p1, ALISP_OBJ_INTEGER) || 1582d5ac70f0Sopenharmony_ci alisp_compare_type(p1, ALISP_OBJ_FLOAT)) && 1583d5ac70f0Sopenharmony_ci (alisp_compare_type(p2, ALISP_OBJ_INTEGER) || 1584d5ac70f0Sopenharmony_ci alisp_compare_type(p2, ALISP_OBJ_FLOAT))) { 1585d5ac70f0Sopenharmony_ci double f1, f2; 1586d5ac70f0Sopenharmony_ci f1 = alisp_compare_type(p1, ALISP_OBJ_INTEGER) ? p1->value.i : p1->value.f; 1587d5ac70f0Sopenharmony_ci f2 = alisp_compare_type(p2, ALISP_OBJ_INTEGER) ? p2->value.i : p2->value.f; 1588d5ac70f0Sopenharmony_ci if (f1 == f2) 1589d5ac70f0Sopenharmony_ci goto __true; 1590d5ac70f0Sopenharmony_ci } else { 1591d5ac70f0Sopenharmony_ci lisp_warn(instance, "comparison with a non integer or float operand"); 1592d5ac70f0Sopenharmony_ci } 1593d5ac70f0Sopenharmony_ci 1594d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1595d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1596d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1597d5ac70f0Sopenharmony_ci} 1598d5ac70f0Sopenharmony_ci 1599d5ac70f0Sopenharmony_ci/* 1600d5ac70f0Sopenharmony_ci * Syntax: (!= expr1 expr2) 1601d5ac70f0Sopenharmony_ci */ 1602d5ac70f0Sopenharmony_cistatic struct alisp_object * F_numneq(struct alisp_instance *instance, struct alisp_object * args) 1603d5ac70f0Sopenharmony_ci{ 1604d5ac70f0Sopenharmony_ci struct alisp_object * p; 1605d5ac70f0Sopenharmony_ci 1606d5ac70f0Sopenharmony_ci p = F_numeq(instance, args); 1607d5ac70f0Sopenharmony_ci if (p == &alsa_lisp_nil) 1608d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1609d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1610d5ac70f0Sopenharmony_ci} 1611d5ac70f0Sopenharmony_ci 1612d5ac70f0Sopenharmony_ci/* 1613d5ac70f0Sopenharmony_ci * Syntax: (exfun name) 1614d5ac70f0Sopenharmony_ci * Test, if a function exists 1615d5ac70f0Sopenharmony_ci */ 1616d5ac70f0Sopenharmony_cistatic struct alisp_object * F_exfun(struct alisp_instance *instance, struct alisp_object * args) 1617d5ac70f0Sopenharmony_ci{ 1618d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1619d5ac70f0Sopenharmony_ci 1620d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1621d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 1622d5ac70f0Sopenharmony_ci delete_object(instance, args); 1623d5ac70f0Sopenharmony_ci p2 = get_object(instance, p1); 1624d5ac70f0Sopenharmony_ci if (p2 == &alsa_lisp_nil) { 1625d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1626d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1627d5ac70f0Sopenharmony_ci } 1628d5ac70f0Sopenharmony_ci p2 = car(p2); 1629d5ac70f0Sopenharmony_ci if (alisp_compare_type(p2, ALISP_OBJ_IDENTIFIER) && 1630d5ac70f0Sopenharmony_ci !strcmp(p2->value.s, "lambda")) { 1631d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1632d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1633d5ac70f0Sopenharmony_ci } 1634d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1635d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1636d5ac70f0Sopenharmony_ci} 1637d5ac70f0Sopenharmony_ci 1638d5ac70f0Sopenharmony_cistatic void princ_string(snd_output_t *out, char *s) 1639d5ac70f0Sopenharmony_ci{ 1640d5ac70f0Sopenharmony_ci char *p; 1641d5ac70f0Sopenharmony_ci 1642d5ac70f0Sopenharmony_ci snd_output_putc(out, '"'); 1643d5ac70f0Sopenharmony_ci for (p = s; *p != '\0'; ++p) 1644d5ac70f0Sopenharmony_ci switch (*p) { 1645d5ac70f0Sopenharmony_ci case '\a': snd_output_putc(out, '\\'); snd_output_putc(out, 'a'); break; 1646d5ac70f0Sopenharmony_ci case '\b': snd_output_putc(out, '\\'); snd_output_putc(out, 'b'); break; 1647d5ac70f0Sopenharmony_ci case '\f': snd_output_putc(out, '\\'); snd_output_putc(out, 'f'); break; 1648d5ac70f0Sopenharmony_ci case '\n': snd_output_putc(out, '\\'); snd_output_putc(out, 'n'); break; 1649d5ac70f0Sopenharmony_ci case '\r': snd_output_putc(out, '\\'); snd_output_putc(out, 'r'); break; 1650d5ac70f0Sopenharmony_ci case '\t': snd_output_putc(out, '\\'); snd_output_putc(out, 't'); break; 1651d5ac70f0Sopenharmony_ci case '\v': snd_output_putc(out, '\\'); snd_output_putc(out, 'v'); break; 1652d5ac70f0Sopenharmony_ci case '"': snd_output_putc(out, '\\'); snd_output_putc(out, '"'); break; 1653d5ac70f0Sopenharmony_ci default: snd_output_putc(out, *p); 1654d5ac70f0Sopenharmony_ci } 1655d5ac70f0Sopenharmony_ci snd_output_putc(out, '"'); 1656d5ac70f0Sopenharmony_ci} 1657d5ac70f0Sopenharmony_ci 1658d5ac70f0Sopenharmony_cistatic void princ_cons(snd_output_t *out, struct alisp_object * p) 1659d5ac70f0Sopenharmony_ci{ 1660d5ac70f0Sopenharmony_ci do { 1661d5ac70f0Sopenharmony_ci princ_object(out, p->value.c.car); 1662d5ac70f0Sopenharmony_ci p = p->value.c.cdr; 1663d5ac70f0Sopenharmony_ci if (p != &alsa_lisp_nil) { 1664d5ac70f0Sopenharmony_ci snd_output_putc(out, ' '); 1665d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_CONS)) { 1666d5ac70f0Sopenharmony_ci snd_output_printf(out, ". "); 1667d5ac70f0Sopenharmony_ci princ_object(out, p); 1668d5ac70f0Sopenharmony_ci } 1669d5ac70f0Sopenharmony_ci } 1670d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil && alisp_compare_type(p, ALISP_OBJ_CONS)); 1671d5ac70f0Sopenharmony_ci} 1672d5ac70f0Sopenharmony_ci 1673d5ac70f0Sopenharmony_cistatic void princ_object(snd_output_t *out, struct alisp_object * p) 1674d5ac70f0Sopenharmony_ci{ 1675d5ac70f0Sopenharmony_ci switch (alisp_get_type(p)) { 1676d5ac70f0Sopenharmony_ci case ALISP_OBJ_NIL: 1677d5ac70f0Sopenharmony_ci snd_output_printf(out, "nil"); 1678d5ac70f0Sopenharmony_ci break; 1679d5ac70f0Sopenharmony_ci case ALISP_OBJ_T: 1680d5ac70f0Sopenharmony_ci snd_output_putc(out, 't'); 1681d5ac70f0Sopenharmony_ci break; 1682d5ac70f0Sopenharmony_ci case ALISP_OBJ_IDENTIFIER: 1683d5ac70f0Sopenharmony_ci snd_output_printf(out, "%s", p->value.s); 1684d5ac70f0Sopenharmony_ci break; 1685d5ac70f0Sopenharmony_ci case ALISP_OBJ_STRING: 1686d5ac70f0Sopenharmony_ci princ_string(out, p->value.s); 1687d5ac70f0Sopenharmony_ci break; 1688d5ac70f0Sopenharmony_ci case ALISP_OBJ_INTEGER: 1689d5ac70f0Sopenharmony_ci snd_output_printf(out, "%ld", p->value.i); 1690d5ac70f0Sopenharmony_ci break; 1691d5ac70f0Sopenharmony_ci case ALISP_OBJ_FLOAT: 1692d5ac70f0Sopenharmony_ci snd_output_printf(out, "%f", p->value.f); 1693d5ac70f0Sopenharmony_ci break; 1694d5ac70f0Sopenharmony_ci case ALISP_OBJ_POINTER: 1695d5ac70f0Sopenharmony_ci snd_output_printf(out, "<%p>", p->value.ptr); 1696d5ac70f0Sopenharmony_ci break; 1697d5ac70f0Sopenharmony_ci case ALISP_OBJ_CONS: 1698d5ac70f0Sopenharmony_ci snd_output_putc(out, '('); 1699d5ac70f0Sopenharmony_ci princ_cons(out, p); 1700d5ac70f0Sopenharmony_ci snd_output_putc(out, ')'); 1701d5ac70f0Sopenharmony_ci } 1702d5ac70f0Sopenharmony_ci} 1703d5ac70f0Sopenharmony_ci 1704d5ac70f0Sopenharmony_ci/* 1705d5ac70f0Sopenharmony_ci * Syntax: (princ expr...) 1706d5ac70f0Sopenharmony_ci */ 1707d5ac70f0Sopenharmony_cistatic struct alisp_object * F_princ(struct alisp_instance *instance, struct alisp_object * args) 1708d5ac70f0Sopenharmony_ci{ 1709d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1 = NULL, * n; 1710d5ac70f0Sopenharmony_ci 1711d5ac70f0Sopenharmony_ci do { 1712d5ac70f0Sopenharmony_ci if (p1) 1713d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1714d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1715d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_STRING)) 1716d5ac70f0Sopenharmony_ci snd_output_printf(instance->out, "%s", p1->value.s); 1717d5ac70f0Sopenharmony_ci else 1718d5ac70f0Sopenharmony_ci princ_object(instance->out, p1); 1719d5ac70f0Sopenharmony_ci n = cdr(p); 1720d5ac70f0Sopenharmony_ci delete_object(instance, p); 1721d5ac70f0Sopenharmony_ci p = n; 1722d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 1723d5ac70f0Sopenharmony_ci 1724d5ac70f0Sopenharmony_ci return p1; 1725d5ac70f0Sopenharmony_ci} 1726d5ac70f0Sopenharmony_ci 1727d5ac70f0Sopenharmony_ci/* 1728d5ac70f0Sopenharmony_ci * Syntax: (atom expr) 1729d5ac70f0Sopenharmony_ci */ 1730d5ac70f0Sopenharmony_cistatic struct alisp_object * F_atom(struct alisp_instance *instance, struct alisp_object * args) 1731d5ac70f0Sopenharmony_ci{ 1732d5ac70f0Sopenharmony_ci struct alisp_object * p; 1733d5ac70f0Sopenharmony_ci 1734d5ac70f0Sopenharmony_ci p = eval(instance, car(args)); 1735d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 1736d5ac70f0Sopenharmony_ci delete_object(instance, args); 1737d5ac70f0Sopenharmony_ci if (p == NULL) 1738d5ac70f0Sopenharmony_ci return NULL; 1739d5ac70f0Sopenharmony_ci 1740d5ac70f0Sopenharmony_ci switch (alisp_get_type(p)) { 1741d5ac70f0Sopenharmony_ci case ALISP_OBJ_T: 1742d5ac70f0Sopenharmony_ci case ALISP_OBJ_NIL: 1743d5ac70f0Sopenharmony_ci case ALISP_OBJ_INTEGER: 1744d5ac70f0Sopenharmony_ci case ALISP_OBJ_FLOAT: 1745d5ac70f0Sopenharmony_ci case ALISP_OBJ_STRING: 1746d5ac70f0Sopenharmony_ci case ALISP_OBJ_IDENTIFIER: 1747d5ac70f0Sopenharmony_ci case ALISP_OBJ_POINTER: 1748d5ac70f0Sopenharmony_ci delete_tree(instance, p); 1749d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1750d5ac70f0Sopenharmony_ci default: 1751d5ac70f0Sopenharmony_ci break; 1752d5ac70f0Sopenharmony_ci } 1753d5ac70f0Sopenharmony_ci 1754d5ac70f0Sopenharmony_ci delete_tree(instance, p); 1755d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1756d5ac70f0Sopenharmony_ci} 1757d5ac70f0Sopenharmony_ci 1758d5ac70f0Sopenharmony_ci/* 1759d5ac70f0Sopenharmony_ci * Syntax: (cons expr1 expr2) 1760d5ac70f0Sopenharmony_ci */ 1761d5ac70f0Sopenharmony_cistatic struct alisp_object * F_cons(struct alisp_instance *instance, struct alisp_object * args) 1762d5ac70f0Sopenharmony_ci{ 1763d5ac70f0Sopenharmony_ci struct alisp_object * p; 1764d5ac70f0Sopenharmony_ci 1765d5ac70f0Sopenharmony_ci p = new_object(instance, ALISP_OBJ_CONS); 1766d5ac70f0Sopenharmony_ci if (p) { 1767d5ac70f0Sopenharmony_ci p->value.c.car = eval(instance, car(args)); 1768d5ac70f0Sopenharmony_ci p->value.c.cdr = eval(instance, car(cdr(args))); 1769d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1770d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1771d5ac70f0Sopenharmony_ci delete_object(instance, args); 1772d5ac70f0Sopenharmony_ci } else { 1773d5ac70f0Sopenharmony_ci delete_tree(instance, args); 1774d5ac70f0Sopenharmony_ci } 1775d5ac70f0Sopenharmony_ci 1776d5ac70f0Sopenharmony_ci return p; 1777d5ac70f0Sopenharmony_ci} 1778d5ac70f0Sopenharmony_ci 1779d5ac70f0Sopenharmony_ci/* 1780d5ac70f0Sopenharmony_ci * Syntax: (list expr1...) 1781d5ac70f0Sopenharmony_ci */ 1782d5ac70f0Sopenharmony_cistatic struct alisp_object * F_list(struct alisp_instance *instance, struct alisp_object * args) 1783d5ac70f0Sopenharmony_ci{ 1784d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * first = NULL, * prev = NULL, * p1; 1785d5ac70f0Sopenharmony_ci 1786d5ac70f0Sopenharmony_ci if (p == &alsa_lisp_nil) 1787d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1788d5ac70f0Sopenharmony_ci 1789d5ac70f0Sopenharmony_ci do { 1790d5ac70f0Sopenharmony_ci p1 = new_object(instance, ALISP_OBJ_CONS); 1791d5ac70f0Sopenharmony_ci if (p1 == NULL) { 1792d5ac70f0Sopenharmony_ci delete_tree(instance, p); 1793d5ac70f0Sopenharmony_ci delete_tree(instance, first); 1794d5ac70f0Sopenharmony_ci return NULL; 1795d5ac70f0Sopenharmony_ci } 1796d5ac70f0Sopenharmony_ci p1->value.c.car = eval(instance, car(p)); 1797d5ac70f0Sopenharmony_ci if (p1->value.c.car == NULL) { 1798d5ac70f0Sopenharmony_ci delete_tree(instance, first); 1799d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p)); 1800d5ac70f0Sopenharmony_ci delete_object(instance, p); 1801d5ac70f0Sopenharmony_ci return NULL; 1802d5ac70f0Sopenharmony_ci } 1803d5ac70f0Sopenharmony_ci if (first == NULL) 1804d5ac70f0Sopenharmony_ci first = p1; 1805d5ac70f0Sopenharmony_ci if (prev != NULL) 1806d5ac70f0Sopenharmony_ci prev->value.c.cdr = p1; 1807d5ac70f0Sopenharmony_ci prev = p1; 1808d5ac70f0Sopenharmony_ci p = cdr(p1 = p); 1809d5ac70f0Sopenharmony_ci delete_object(instance, p1); 1810d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 1811d5ac70f0Sopenharmony_ci 1812d5ac70f0Sopenharmony_ci return first; 1813d5ac70f0Sopenharmony_ci} 1814d5ac70f0Sopenharmony_ci 1815d5ac70f0Sopenharmony_cistatic inline int eq(struct alisp_object * p1, struct alisp_object * p2) 1816d5ac70f0Sopenharmony_ci{ 1817d5ac70f0Sopenharmony_ci return p1 == p2; 1818d5ac70f0Sopenharmony_ci} 1819d5ac70f0Sopenharmony_ci 1820d5ac70f0Sopenharmony_cistatic int equal(struct alisp_object * p1, struct alisp_object * p2) 1821d5ac70f0Sopenharmony_ci{ 1822d5ac70f0Sopenharmony_ci int type1, type2; 1823d5ac70f0Sopenharmony_ci 1824d5ac70f0Sopenharmony_ci if (eq(p1, p2)) 1825d5ac70f0Sopenharmony_ci return 1; 1826d5ac70f0Sopenharmony_ci 1827d5ac70f0Sopenharmony_ci type1 = alisp_get_type(p1); 1828d5ac70f0Sopenharmony_ci type2 = alisp_get_type(p2); 1829d5ac70f0Sopenharmony_ci 1830d5ac70f0Sopenharmony_ci if (type1 == ALISP_OBJ_CONS || type2 == ALISP_OBJ_CONS) 1831d5ac70f0Sopenharmony_ci return 0; 1832d5ac70f0Sopenharmony_ci 1833d5ac70f0Sopenharmony_ci if (type1 == type2) { 1834d5ac70f0Sopenharmony_ci switch (type1) { 1835d5ac70f0Sopenharmony_ci case ALISP_OBJ_STRING: 1836d5ac70f0Sopenharmony_ci return !strcmp(p1->value.s, p2->value.s); 1837d5ac70f0Sopenharmony_ci case ALISP_OBJ_INTEGER: 1838d5ac70f0Sopenharmony_ci return p1->value.i == p2->value.i; 1839d5ac70f0Sopenharmony_ci case ALISP_OBJ_FLOAT: 1840d5ac70f0Sopenharmony_ci return p1->value.i == p2->value.i; 1841d5ac70f0Sopenharmony_ci } 1842d5ac70f0Sopenharmony_ci } 1843d5ac70f0Sopenharmony_ci 1844d5ac70f0Sopenharmony_ci return 0; 1845d5ac70f0Sopenharmony_ci} 1846d5ac70f0Sopenharmony_ci 1847d5ac70f0Sopenharmony_ci/* 1848d5ac70f0Sopenharmony_ci * Syntax: (eq expr1 expr2) 1849d5ac70f0Sopenharmony_ci */ 1850d5ac70f0Sopenharmony_cistatic struct alisp_object * F_eq(struct alisp_instance *instance, struct alisp_object * args) 1851d5ac70f0Sopenharmony_ci{ 1852d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1853d5ac70f0Sopenharmony_ci 1854d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1855d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1856d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1857d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1858d5ac70f0Sopenharmony_ci delete_object(instance, args); 1859d5ac70f0Sopenharmony_ci 1860d5ac70f0Sopenharmony_ci if (eq(p1, p2)) { 1861d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1862d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1863d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1864d5ac70f0Sopenharmony_ci } 1865d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1866d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1867d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1868d5ac70f0Sopenharmony_ci} 1869d5ac70f0Sopenharmony_ci 1870d5ac70f0Sopenharmony_ci/* 1871d5ac70f0Sopenharmony_ci * Syntax: (equal expr1 expr2) 1872d5ac70f0Sopenharmony_ci */ 1873d5ac70f0Sopenharmony_cistatic struct alisp_object * F_equal(struct alisp_instance *instance, struct alisp_object * args) 1874d5ac70f0Sopenharmony_ci{ 1875d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 1876d5ac70f0Sopenharmony_ci 1877d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 1878d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 1879d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 1880d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 1881d5ac70f0Sopenharmony_ci delete_object(instance, args); 1882d5ac70f0Sopenharmony_ci 1883d5ac70f0Sopenharmony_ci if (equal(p1, p2)) { 1884d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1885d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1886d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1887d5ac70f0Sopenharmony_ci } 1888d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1889d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1890d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1891d5ac70f0Sopenharmony_ci} 1892d5ac70f0Sopenharmony_ci 1893d5ac70f0Sopenharmony_ci/* 1894d5ac70f0Sopenharmony_ci * Syntax: (quote expr) 1895d5ac70f0Sopenharmony_ci */ 1896d5ac70f0Sopenharmony_cistatic struct alisp_object * F_quote(struct alisp_instance *instance ATTRIBUTE_UNUSED, struct alisp_object * args) 1897d5ac70f0Sopenharmony_ci{ 1898d5ac70f0Sopenharmony_ci struct alisp_object *p = car(args); 1899d5ac70f0Sopenharmony_ci 1900d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 1901d5ac70f0Sopenharmony_ci delete_object(instance, args); 1902d5ac70f0Sopenharmony_ci return p; 1903d5ac70f0Sopenharmony_ci} 1904d5ac70f0Sopenharmony_ci 1905d5ac70f0Sopenharmony_ci/* 1906d5ac70f0Sopenharmony_ci * Syntax: (and expr...) 1907d5ac70f0Sopenharmony_ci */ 1908d5ac70f0Sopenharmony_cistatic struct alisp_object * F_and(struct alisp_instance *instance, struct alisp_object * args) 1909d5ac70f0Sopenharmony_ci{ 1910d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1 = NULL, * n; 1911d5ac70f0Sopenharmony_ci 1912d5ac70f0Sopenharmony_ci do { 1913d5ac70f0Sopenharmony_ci if (p1) 1914d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1915d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1916d5ac70f0Sopenharmony_ci if (p1 == &alsa_lisp_nil) { 1917d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1918d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p)); 1919d5ac70f0Sopenharmony_ci delete_object(instance, p); 1920d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1921d5ac70f0Sopenharmony_ci } 1922d5ac70f0Sopenharmony_ci p = cdr(n = p); 1923d5ac70f0Sopenharmony_ci delete_object(instance, n); 1924d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 1925d5ac70f0Sopenharmony_ci 1926d5ac70f0Sopenharmony_ci return p1; 1927d5ac70f0Sopenharmony_ci} 1928d5ac70f0Sopenharmony_ci 1929d5ac70f0Sopenharmony_ci/* 1930d5ac70f0Sopenharmony_ci * Syntax: (or expr...) 1931d5ac70f0Sopenharmony_ci */ 1932d5ac70f0Sopenharmony_cistatic struct alisp_object * F_or(struct alisp_instance *instance, struct alisp_object * args) 1933d5ac70f0Sopenharmony_ci{ 1934d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1 = NULL, * n; 1935d5ac70f0Sopenharmony_ci 1936d5ac70f0Sopenharmony_ci do { 1937d5ac70f0Sopenharmony_ci if (p1) 1938d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 1939d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 1940d5ac70f0Sopenharmony_ci if (p1 != &alsa_lisp_nil) { 1941d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p)); 1942d5ac70f0Sopenharmony_ci delete_object(instance, p); 1943d5ac70f0Sopenharmony_ci return p1; 1944d5ac70f0Sopenharmony_ci } 1945d5ac70f0Sopenharmony_ci p = cdr(n = p); 1946d5ac70f0Sopenharmony_ci delete_object(instance, n); 1947d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 1948d5ac70f0Sopenharmony_ci 1949d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1950d5ac70f0Sopenharmony_ci} 1951d5ac70f0Sopenharmony_ci 1952d5ac70f0Sopenharmony_ci/* 1953d5ac70f0Sopenharmony_ci * Syntax: (not expr) 1954d5ac70f0Sopenharmony_ci * Syntax: (null expr) 1955d5ac70f0Sopenharmony_ci */ 1956d5ac70f0Sopenharmony_cistatic struct alisp_object * F_not(struct alisp_instance *instance, struct alisp_object * args) 1957d5ac70f0Sopenharmony_ci{ 1958d5ac70f0Sopenharmony_ci struct alisp_object * p = eval(instance, car(args)); 1959d5ac70f0Sopenharmony_ci 1960d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 1961d5ac70f0Sopenharmony_ci delete_object(instance, args); 1962d5ac70f0Sopenharmony_ci if (p != &alsa_lisp_nil) { 1963d5ac70f0Sopenharmony_ci delete_tree(instance, p); 1964d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 1965d5ac70f0Sopenharmony_ci } 1966d5ac70f0Sopenharmony_ci 1967d5ac70f0Sopenharmony_ci delete_tree(instance, p); 1968d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 1969d5ac70f0Sopenharmony_ci} 1970d5ac70f0Sopenharmony_ci 1971d5ac70f0Sopenharmony_ci/* 1972d5ac70f0Sopenharmony_ci * Syntax: (cond (expr1 [expr2])...) 1973d5ac70f0Sopenharmony_ci */ 1974d5ac70f0Sopenharmony_cistatic struct alisp_object * F_cond(struct alisp_instance *instance, struct alisp_object * args) 1975d5ac70f0Sopenharmony_ci{ 1976d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1, * p2, * p3; 1977d5ac70f0Sopenharmony_ci 1978d5ac70f0Sopenharmony_ci do { 1979d5ac70f0Sopenharmony_ci p1 = car(p); 1980d5ac70f0Sopenharmony_ci if ((p2 = eval(instance, car(p1))) != &alsa_lisp_nil) { 1981d5ac70f0Sopenharmony_ci p3 = cdr(p1); 1982d5ac70f0Sopenharmony_ci delete_object(instance, p1); 1983d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p)); 1984d5ac70f0Sopenharmony_ci delete_object(instance, p); 1985d5ac70f0Sopenharmony_ci if (p3 != &alsa_lisp_nil) { 1986d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1987d5ac70f0Sopenharmony_ci return F_progn(instance, p3); 1988d5ac70f0Sopenharmony_ci } else { 1989d5ac70f0Sopenharmony_ci delete_tree(instance, p3); 1990d5ac70f0Sopenharmony_ci return p2; 1991d5ac70f0Sopenharmony_ci } 1992d5ac70f0Sopenharmony_ci } else { 1993d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 1994d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p1)); 1995d5ac70f0Sopenharmony_ci delete_object(instance, p1); 1996d5ac70f0Sopenharmony_ci } 1997d5ac70f0Sopenharmony_ci p = cdr(p2 = p); 1998d5ac70f0Sopenharmony_ci delete_object(instance, p2); 1999d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 2000d5ac70f0Sopenharmony_ci 2001d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2002d5ac70f0Sopenharmony_ci} 2003d5ac70f0Sopenharmony_ci 2004d5ac70f0Sopenharmony_ci/* 2005d5ac70f0Sopenharmony_ci * Syntax: (if expr then-expr else-expr...) 2006d5ac70f0Sopenharmony_ci */ 2007d5ac70f0Sopenharmony_cistatic struct alisp_object * F_if(struct alisp_instance *instance, struct alisp_object * args) 2008d5ac70f0Sopenharmony_ci{ 2009d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * p3; 2010d5ac70f0Sopenharmony_ci 2011d5ac70f0Sopenharmony_ci p1 = car(args); 2012d5ac70f0Sopenharmony_ci p2 = car(cdr(args)); 2013d5ac70f0Sopenharmony_ci p3 = cdr(cdr(args)); 2014d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2015d5ac70f0Sopenharmony_ci delete_object(instance, args); 2016d5ac70f0Sopenharmony_ci 2017d5ac70f0Sopenharmony_ci p1 = eval(instance, p1); 2018d5ac70f0Sopenharmony_ci if (p1 != &alsa_lisp_nil) { 2019d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2020d5ac70f0Sopenharmony_ci delete_tree(instance, p3); 2021d5ac70f0Sopenharmony_ci return eval(instance, p2); 2022d5ac70f0Sopenharmony_ci } 2023d5ac70f0Sopenharmony_ci 2024d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2025d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2026d5ac70f0Sopenharmony_ci return F_progn(instance, p3); 2027d5ac70f0Sopenharmony_ci} 2028d5ac70f0Sopenharmony_ci 2029d5ac70f0Sopenharmony_ci/* 2030d5ac70f0Sopenharmony_ci * Syntax: (when expr then-expr...) 2031d5ac70f0Sopenharmony_ci */ 2032d5ac70f0Sopenharmony_cistatic struct alisp_object * F_when(struct alisp_instance *instance, struct alisp_object * args) 2033d5ac70f0Sopenharmony_ci{ 2034d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 2035d5ac70f0Sopenharmony_ci 2036d5ac70f0Sopenharmony_ci p1 = car(args); 2037d5ac70f0Sopenharmony_ci p2 = cdr(args); 2038d5ac70f0Sopenharmony_ci delete_object(instance, args); 2039d5ac70f0Sopenharmony_ci if ((p1 = eval(instance, p1)) != &alsa_lisp_nil) { 2040d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2041d5ac70f0Sopenharmony_ci return F_progn(instance, p2); 2042d5ac70f0Sopenharmony_ci } else { 2043d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2044d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2045d5ac70f0Sopenharmony_ci } 2046d5ac70f0Sopenharmony_ci 2047d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2048d5ac70f0Sopenharmony_ci} 2049d5ac70f0Sopenharmony_ci 2050d5ac70f0Sopenharmony_ci/* 2051d5ac70f0Sopenharmony_ci * Syntax: (unless expr else-expr...) 2052d5ac70f0Sopenharmony_ci */ 2053d5ac70f0Sopenharmony_cistatic struct alisp_object * F_unless(struct alisp_instance *instance, struct alisp_object * args) 2054d5ac70f0Sopenharmony_ci{ 2055d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2; 2056d5ac70f0Sopenharmony_ci 2057d5ac70f0Sopenharmony_ci p1 = car(args); 2058d5ac70f0Sopenharmony_ci p2 = cdr(args); 2059d5ac70f0Sopenharmony_ci delete_object(instance, args); 2060d5ac70f0Sopenharmony_ci if ((p1 = eval(instance, p1)) == &alsa_lisp_nil) { 2061d5ac70f0Sopenharmony_ci return F_progn(instance, p2); 2062d5ac70f0Sopenharmony_ci } else { 2063d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2064d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2065d5ac70f0Sopenharmony_ci } 2066d5ac70f0Sopenharmony_ci 2067d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2068d5ac70f0Sopenharmony_ci} 2069d5ac70f0Sopenharmony_ci 2070d5ac70f0Sopenharmony_ci/* 2071d5ac70f0Sopenharmony_ci * Syntax: (while expr exprs...) 2072d5ac70f0Sopenharmony_ci */ 2073d5ac70f0Sopenharmony_cistatic struct alisp_object * F_while(struct alisp_instance *instance, struct alisp_object * args) 2074d5ac70f0Sopenharmony_ci{ 2075d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * p3; 2076d5ac70f0Sopenharmony_ci 2077d5ac70f0Sopenharmony_ci p1 = car(args); 2078d5ac70f0Sopenharmony_ci p2 = cdr(args); 2079d5ac70f0Sopenharmony_ci 2080d5ac70f0Sopenharmony_ci delete_object(instance, args); 2081d5ac70f0Sopenharmony_ci while (1) { 2082d5ac70f0Sopenharmony_ci incref_tree(instance, p1); 2083d5ac70f0Sopenharmony_ci if ((p3 = eval(instance, p1)) == &alsa_lisp_nil) 2084d5ac70f0Sopenharmony_ci break; 2085d5ac70f0Sopenharmony_ci delete_tree(instance, p3); 2086d5ac70f0Sopenharmony_ci incref_tree(instance, p2); 2087d5ac70f0Sopenharmony_ci delete_tree(instance, F_progn(instance, p2)); 2088d5ac70f0Sopenharmony_ci } 2089d5ac70f0Sopenharmony_ci 2090d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2091d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2092d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2093d5ac70f0Sopenharmony_ci} 2094d5ac70f0Sopenharmony_ci 2095d5ac70f0Sopenharmony_ci/* 2096d5ac70f0Sopenharmony_ci * Syntax: (progn expr...) 2097d5ac70f0Sopenharmony_ci */ 2098d5ac70f0Sopenharmony_cistatic struct alisp_object * F_progn(struct alisp_instance *instance, struct alisp_object * args) 2099d5ac70f0Sopenharmony_ci{ 2100d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1 = NULL, * n; 2101d5ac70f0Sopenharmony_ci 2102d5ac70f0Sopenharmony_ci do { 2103d5ac70f0Sopenharmony_ci if (p1) 2104d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2105d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 2106d5ac70f0Sopenharmony_ci n = cdr(p); 2107d5ac70f0Sopenharmony_ci delete_object(instance, p); 2108d5ac70f0Sopenharmony_ci p = n; 2109d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 2110d5ac70f0Sopenharmony_ci 2111d5ac70f0Sopenharmony_ci return p1; 2112d5ac70f0Sopenharmony_ci} 2113d5ac70f0Sopenharmony_ci 2114d5ac70f0Sopenharmony_ci/* 2115d5ac70f0Sopenharmony_ci * Syntax: (prog1 expr...) 2116d5ac70f0Sopenharmony_ci */ 2117d5ac70f0Sopenharmony_cistatic struct alisp_object * F_prog1(struct alisp_instance *instance, struct alisp_object * args) 2118d5ac70f0Sopenharmony_ci{ 2119d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * first = NULL, * p1; 2120d5ac70f0Sopenharmony_ci 2121d5ac70f0Sopenharmony_ci do { 2122d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 2123d5ac70f0Sopenharmony_ci if (first == NULL) 2124d5ac70f0Sopenharmony_ci first = p1; 2125d5ac70f0Sopenharmony_ci else 2126d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2127d5ac70f0Sopenharmony_ci p1 = cdr(p); 2128d5ac70f0Sopenharmony_ci delete_object(instance, p); 2129d5ac70f0Sopenharmony_ci p = p1; 2130d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 2131d5ac70f0Sopenharmony_ci 2132d5ac70f0Sopenharmony_ci if (first == NULL) 2133d5ac70f0Sopenharmony_ci first = &alsa_lisp_nil; 2134d5ac70f0Sopenharmony_ci 2135d5ac70f0Sopenharmony_ci return first; 2136d5ac70f0Sopenharmony_ci} 2137d5ac70f0Sopenharmony_ci 2138d5ac70f0Sopenharmony_ci/* 2139d5ac70f0Sopenharmony_ci * Syntax: (prog2 expr...) 2140d5ac70f0Sopenharmony_ci */ 2141d5ac70f0Sopenharmony_cistatic struct alisp_object * F_prog2(struct alisp_instance *instance, struct alisp_object * args) 2142d5ac70f0Sopenharmony_ci{ 2143d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * second = NULL, * p1; 2144d5ac70f0Sopenharmony_ci int i = 0; 2145d5ac70f0Sopenharmony_ci 2146d5ac70f0Sopenharmony_ci do { 2147d5ac70f0Sopenharmony_ci ++i; 2148d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 2149d5ac70f0Sopenharmony_ci if (i == 2) 2150d5ac70f0Sopenharmony_ci second = p1; 2151d5ac70f0Sopenharmony_ci else 2152d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2153d5ac70f0Sopenharmony_ci p1 = cdr(p); 2154d5ac70f0Sopenharmony_ci delete_object(instance, p); 2155d5ac70f0Sopenharmony_ci p = p1; 2156d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 2157d5ac70f0Sopenharmony_ci 2158d5ac70f0Sopenharmony_ci if (second == NULL) 2159d5ac70f0Sopenharmony_ci second = &alsa_lisp_nil; 2160d5ac70f0Sopenharmony_ci 2161d5ac70f0Sopenharmony_ci return second; 2162d5ac70f0Sopenharmony_ci} 2163d5ac70f0Sopenharmony_ci 2164d5ac70f0Sopenharmony_ci/* 2165d5ac70f0Sopenharmony_ci * Syntax: (set name value) 2166d5ac70f0Sopenharmony_ci */ 2167d5ac70f0Sopenharmony_cistatic struct alisp_object * F_set(struct alisp_instance *instance, struct alisp_object * args) 2168d5ac70f0Sopenharmony_ci{ 2169d5ac70f0Sopenharmony_ci struct alisp_object * p1 = eval(instance, car(args)), 2170d5ac70f0Sopenharmony_ci * p2 = eval(instance, car(cdr(args))); 2171d5ac70f0Sopenharmony_ci 2172d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 2173d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2174d5ac70f0Sopenharmony_ci delete_object(instance, args); 2175d5ac70f0Sopenharmony_ci if (!check_set_object(instance, p1)) { 2176d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2177d5ac70f0Sopenharmony_ci p2 = &alsa_lisp_nil; 2178d5ac70f0Sopenharmony_ci } else { 2179d5ac70f0Sopenharmony_ci if (set_object(instance, p1, p2) == NULL) { 2180d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2181d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2182d5ac70f0Sopenharmony_ci return NULL; 2183d5ac70f0Sopenharmony_ci } 2184d5ac70f0Sopenharmony_ci } 2185d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2186d5ac70f0Sopenharmony_ci return incref_tree(instance, p2); 2187d5ac70f0Sopenharmony_ci} 2188d5ac70f0Sopenharmony_ci 2189d5ac70f0Sopenharmony_ci/* 2190d5ac70f0Sopenharmony_ci * Syntax: (unset name) 2191d5ac70f0Sopenharmony_ci */ 2192d5ac70f0Sopenharmony_cistatic struct alisp_object * F_unset(struct alisp_instance *instance, struct alisp_object * args) 2193d5ac70f0Sopenharmony_ci{ 2194d5ac70f0Sopenharmony_ci struct alisp_object * p1 = eval(instance, car(args)); 2195d5ac70f0Sopenharmony_ci 2196d5ac70f0Sopenharmony_ci delete_tree(instance, unset_object(instance, p1)); 2197d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 2198d5ac70f0Sopenharmony_ci delete_object(instance, args); 2199d5ac70f0Sopenharmony_ci return p1; 2200d5ac70f0Sopenharmony_ci} 2201d5ac70f0Sopenharmony_ci 2202d5ac70f0Sopenharmony_ci/* 2203d5ac70f0Sopenharmony_ci * Syntax: (setq name value...) 2204d5ac70f0Sopenharmony_ci * Syntax: (setf name value...) 2205d5ac70f0Sopenharmony_ci * `name' is not evalled 2206d5ac70f0Sopenharmony_ci */ 2207d5ac70f0Sopenharmony_cistatic struct alisp_object * F_setq(struct alisp_instance *instance, struct alisp_object * args) 2208d5ac70f0Sopenharmony_ci{ 2209d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1, * p2 = NULL, *n; 2210d5ac70f0Sopenharmony_ci 2211d5ac70f0Sopenharmony_ci do { 2212d5ac70f0Sopenharmony_ci p1 = car(p); 2213d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(p))); 2214d5ac70f0Sopenharmony_ci n = cdr(cdr(p)); 2215d5ac70f0Sopenharmony_ci delete_object(instance, cdr(p)); 2216d5ac70f0Sopenharmony_ci delete_object(instance, p); 2217d5ac70f0Sopenharmony_ci if (!check_set_object(instance, p1)) { 2218d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2219d5ac70f0Sopenharmony_ci p2 = &alsa_lisp_nil; 2220d5ac70f0Sopenharmony_ci } else { 2221d5ac70f0Sopenharmony_ci if (set_object(instance, p1, p2) == NULL) { 2222d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2223d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2224d5ac70f0Sopenharmony_ci return NULL; 2225d5ac70f0Sopenharmony_ci } 2226d5ac70f0Sopenharmony_ci } 2227d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2228d5ac70f0Sopenharmony_ci p = n; 2229d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 2230d5ac70f0Sopenharmony_ci 2231d5ac70f0Sopenharmony_ci return incref_tree(instance, p2); 2232d5ac70f0Sopenharmony_ci} 2233d5ac70f0Sopenharmony_ci 2234d5ac70f0Sopenharmony_ci/* 2235d5ac70f0Sopenharmony_ci * Syntax: (unsetq name...) 2236d5ac70f0Sopenharmony_ci * Syntax: (unsetf name...) 2237d5ac70f0Sopenharmony_ci * `name' is not evalled 2238d5ac70f0Sopenharmony_ci */ 2239d5ac70f0Sopenharmony_cistatic struct alisp_object * F_unsetq(struct alisp_instance *instance, struct alisp_object * args) 2240d5ac70f0Sopenharmony_ci{ 2241d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1 = NULL, * n; 2242d5ac70f0Sopenharmony_ci 2243d5ac70f0Sopenharmony_ci do { 2244d5ac70f0Sopenharmony_ci if (p1) 2245d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2246d5ac70f0Sopenharmony_ci p1 = unset_object(instance, car(p)); 2247d5ac70f0Sopenharmony_ci delete_tree(instance, car(p)); 2248d5ac70f0Sopenharmony_ci p = cdr(n = p); 2249d5ac70f0Sopenharmony_ci delete_object(instance, n); 2250d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 2251d5ac70f0Sopenharmony_ci 2252d5ac70f0Sopenharmony_ci return p1; 2253d5ac70f0Sopenharmony_ci} 2254d5ac70f0Sopenharmony_ci 2255d5ac70f0Sopenharmony_ci/* 2256d5ac70f0Sopenharmony_ci * Syntax: (defun name arglist expr...) 2257d5ac70f0Sopenharmony_ci * `name' is not evalled 2258d5ac70f0Sopenharmony_ci * `arglist' is not evalled 2259d5ac70f0Sopenharmony_ci */ 2260d5ac70f0Sopenharmony_cistatic struct alisp_object * F_defun(struct alisp_instance *instance, struct alisp_object * args) 2261d5ac70f0Sopenharmony_ci{ 2262d5ac70f0Sopenharmony_ci struct alisp_object * p1 = car(args), 2263d5ac70f0Sopenharmony_ci * p2 = car(cdr(args)), 2264d5ac70f0Sopenharmony_ci * p3 = cdr(cdr(args)); 2265d5ac70f0Sopenharmony_ci struct alisp_object * lexpr; 2266d5ac70f0Sopenharmony_ci 2267d5ac70f0Sopenharmony_ci lexpr = new_object(instance, ALISP_OBJ_CONS); 2268d5ac70f0Sopenharmony_ci if (lexpr) { 2269d5ac70f0Sopenharmony_ci lexpr->value.c.car = new_identifier(instance, "lambda"); 2270d5ac70f0Sopenharmony_ci if (lexpr->value.c.car == NULL) { 2271d5ac70f0Sopenharmony_ci delete_object(instance, lexpr); 2272d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2273d5ac70f0Sopenharmony_ci return NULL; 2274d5ac70f0Sopenharmony_ci } 2275d5ac70f0Sopenharmony_ci if ((lexpr->value.c.cdr = new_object(instance, ALISP_OBJ_CONS)) == NULL) { 2276d5ac70f0Sopenharmony_ci delete_object(instance, lexpr->value.c.car); 2277d5ac70f0Sopenharmony_ci delete_object(instance, lexpr); 2278d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2279d5ac70f0Sopenharmony_ci return NULL; 2280d5ac70f0Sopenharmony_ci } 2281d5ac70f0Sopenharmony_ci lexpr->value.c.cdr->value.c.car = p2; 2282d5ac70f0Sopenharmony_ci lexpr->value.c.cdr->value.c.cdr = p3; 2283d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2284d5ac70f0Sopenharmony_ci delete_object(instance, args); 2285d5ac70f0Sopenharmony_ci if (set_object(instance, p1, lexpr) == NULL) { 2286d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2287d5ac70f0Sopenharmony_ci delete_tree(instance, lexpr); 2288d5ac70f0Sopenharmony_ci return NULL; 2289d5ac70f0Sopenharmony_ci } 2290d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2291d5ac70f0Sopenharmony_ci } else { 2292d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2293d5ac70f0Sopenharmony_ci } 2294d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2295d5ac70f0Sopenharmony_ci} 2296d5ac70f0Sopenharmony_ci 2297d5ac70f0Sopenharmony_cistatic struct alisp_object * eval_func(struct alisp_instance *instance, struct alisp_object * p, struct alisp_object * args) 2298d5ac70f0Sopenharmony_ci{ 2299d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * p3, * p4; 2300d5ac70f0Sopenharmony_ci struct alisp_object ** eval_objs, ** save_objs; 2301d5ac70f0Sopenharmony_ci int i; 2302d5ac70f0Sopenharmony_ci 2303d5ac70f0Sopenharmony_ci p1 = car(p); 2304d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_IDENTIFIER) && 2305d5ac70f0Sopenharmony_ci !strcmp(p1->value.s, "lambda")) { 2306d5ac70f0Sopenharmony_ci p2 = car(cdr(p)); 2307d5ac70f0Sopenharmony_ci p3 = args; 2308d5ac70f0Sopenharmony_ci 2309d5ac70f0Sopenharmony_ci if ((i = count_list(p2)) != count_list(p3)) { 2310d5ac70f0Sopenharmony_ci lisp_warn(instance, "wrong number of parameters"); 2311d5ac70f0Sopenharmony_ci goto _delete; 2312d5ac70f0Sopenharmony_ci } 2313d5ac70f0Sopenharmony_ci 2314d5ac70f0Sopenharmony_ci eval_objs = malloc(2 * i * sizeof(struct alisp_object *)); 2315d5ac70f0Sopenharmony_ci if (eval_objs == NULL) { 2316d5ac70f0Sopenharmony_ci nomem(); 2317d5ac70f0Sopenharmony_ci goto _delete; 2318d5ac70f0Sopenharmony_ci } 2319d5ac70f0Sopenharmony_ci save_objs = eval_objs + i; 2320d5ac70f0Sopenharmony_ci 2321d5ac70f0Sopenharmony_ci /* 2322d5ac70f0Sopenharmony_ci * Save the new variable values. 2323d5ac70f0Sopenharmony_ci */ 2324d5ac70f0Sopenharmony_ci i = 0; 2325d5ac70f0Sopenharmony_ci while (p3 != &alsa_lisp_nil) { 2326d5ac70f0Sopenharmony_ci eval_objs[i++] = eval(instance, car(p3)); 2327d5ac70f0Sopenharmony_ci p3 = cdr(p4 = p3); 2328d5ac70f0Sopenharmony_ci delete_object(instance, p4); 2329d5ac70f0Sopenharmony_ci } 2330d5ac70f0Sopenharmony_ci 2331d5ac70f0Sopenharmony_ci /* 2332d5ac70f0Sopenharmony_ci * Save the old variable values and set the new ones. 2333d5ac70f0Sopenharmony_ci */ 2334d5ac70f0Sopenharmony_ci i = 0; 2335d5ac70f0Sopenharmony_ci while (p2 != &alsa_lisp_nil) { 2336d5ac70f0Sopenharmony_ci p3 = car(p2); 2337d5ac70f0Sopenharmony_ci save_objs[i] = replace_object(instance, p3, eval_objs[i]); 2338d5ac70f0Sopenharmony_ci if (save_objs[i] == NULL && 2339d5ac70f0Sopenharmony_ci set_object_direct(instance, p3, eval_objs[i]) == NULL) { 2340d5ac70f0Sopenharmony_ci p4 = NULL; 2341d5ac70f0Sopenharmony_ci goto _end; 2342d5ac70f0Sopenharmony_ci } 2343d5ac70f0Sopenharmony_ci p2 = cdr(p2); 2344d5ac70f0Sopenharmony_ci ++i; 2345d5ac70f0Sopenharmony_ci } 2346d5ac70f0Sopenharmony_ci 2347d5ac70f0Sopenharmony_ci p4 = F_progn(instance, cdr(incref_tree(instance, p3 = cdr(p)))); 2348d5ac70f0Sopenharmony_ci 2349d5ac70f0Sopenharmony_ci /* 2350d5ac70f0Sopenharmony_ci * Restore the old variable values. 2351d5ac70f0Sopenharmony_ci */ 2352d5ac70f0Sopenharmony_ci p2 = car(p3); 2353d5ac70f0Sopenharmony_ci delete_object(instance, p3); 2354d5ac70f0Sopenharmony_ci i = 0; 2355d5ac70f0Sopenharmony_ci while (p2 != &alsa_lisp_nil) { 2356d5ac70f0Sopenharmony_ci p3 = car(p2); 2357d5ac70f0Sopenharmony_ci if (save_objs[i] == NULL) { 2358d5ac70f0Sopenharmony_ci p3 = unset_object(instance, p3); 2359d5ac70f0Sopenharmony_ci } else { 2360d5ac70f0Sopenharmony_ci p3 = replace_object(instance, p3, save_objs[i]); 2361d5ac70f0Sopenharmony_ci } 2362d5ac70f0Sopenharmony_ci i++; 2363d5ac70f0Sopenharmony_ci delete_tree(instance, p3); 2364d5ac70f0Sopenharmony_ci delete_tree(instance, car(p2)); 2365d5ac70f0Sopenharmony_ci p2 = cdr(p3 = p2); 2366d5ac70f0Sopenharmony_ci delete_object(instance, p3); 2367d5ac70f0Sopenharmony_ci } 2368d5ac70f0Sopenharmony_ci 2369d5ac70f0Sopenharmony_ci _end: 2370d5ac70f0Sopenharmony_ci free(eval_objs); 2371d5ac70f0Sopenharmony_ci 2372d5ac70f0Sopenharmony_ci return p4; 2373d5ac70f0Sopenharmony_ci } else { 2374d5ac70f0Sopenharmony_ci _delete: 2375d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2376d5ac70f0Sopenharmony_ci } 2377d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2378d5ac70f0Sopenharmony_ci} 2379d5ac70f0Sopenharmony_ci 2380d5ac70f0Sopenharmony_cistruct alisp_object * F_gc(struct alisp_instance *instance ATTRIBUTE_UNUSED, struct alisp_object * args ATTRIBUTE_UNUSED) 2381d5ac70f0Sopenharmony_ci{ 2382d5ac70f0Sopenharmony_ci /* improved: no more traditional gc */ 2383d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 2384d5ac70f0Sopenharmony_ci} 2385d5ac70f0Sopenharmony_ci 2386d5ac70f0Sopenharmony_ci/* 2387d5ac70f0Sopenharmony_ci * Syntax: (path what) 2388d5ac70f0Sopenharmony_ci * what is string ('data') 2389d5ac70f0Sopenharmony_ci */ 2390d5ac70f0Sopenharmony_cistruct alisp_object * F_path(struct alisp_instance *instance, struct alisp_object * args) 2391d5ac70f0Sopenharmony_ci{ 2392d5ac70f0Sopenharmony_ci struct alisp_object * p1; 2393d5ac70f0Sopenharmony_ci 2394d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 2395d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 2396d5ac70f0Sopenharmony_ci delete_object(instance, args); 2397d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p1, ALISP_OBJ_STRING)) { 2398d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2399d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2400d5ac70f0Sopenharmony_ci } 2401d5ac70f0Sopenharmony_ci if (!strcmp(p1->value.s, "data")) { 2402d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2403d5ac70f0Sopenharmony_ci return new_string(instance, snd_config_topdir()); 2404d5ac70f0Sopenharmony_ci } 2405d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2406d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2407d5ac70f0Sopenharmony_ci} 2408d5ac70f0Sopenharmony_ci 2409d5ac70f0Sopenharmony_ci/* 2410d5ac70f0Sopenharmony_ci * Syntax: (include filename...) 2411d5ac70f0Sopenharmony_ci */ 2412d5ac70f0Sopenharmony_cistruct alisp_object * F_include(struct alisp_instance *instance, struct alisp_object * args) 2413d5ac70f0Sopenharmony_ci{ 2414d5ac70f0Sopenharmony_ci struct alisp_object * p = args, * p1; 2415d5ac70f0Sopenharmony_ci int res = -ENOENT; 2416d5ac70f0Sopenharmony_ci 2417d5ac70f0Sopenharmony_ci do { 2418d5ac70f0Sopenharmony_ci p1 = eval(instance, car(p)); 2419d5ac70f0Sopenharmony_ci if (alisp_compare_type(p1, ALISP_OBJ_STRING)) 2420d5ac70f0Sopenharmony_ci res = alisp_include_file(instance, p1->value.s); 2421d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2422d5ac70f0Sopenharmony_ci p = cdr(p1 = p); 2423d5ac70f0Sopenharmony_ci delete_object(instance, p1); 2424d5ac70f0Sopenharmony_ci } while (p != &alsa_lisp_nil); 2425d5ac70f0Sopenharmony_ci 2426d5ac70f0Sopenharmony_ci return new_integer(instance, res); 2427d5ac70f0Sopenharmony_ci} 2428d5ac70f0Sopenharmony_ci 2429d5ac70f0Sopenharmony_ci/* 2430d5ac70f0Sopenharmony_ci * Syntax: (string-to-integer value) 2431d5ac70f0Sopenharmony_ci * 'value' can be integer or float type 2432d5ac70f0Sopenharmony_ci */ 2433d5ac70f0Sopenharmony_cistruct alisp_object * F_string_to_integer(struct alisp_instance *instance, struct alisp_object * args) 2434d5ac70f0Sopenharmony_ci{ 2435d5ac70f0Sopenharmony_ci struct alisp_object * p = eval(instance, car(args)), * p1; 2436d5ac70f0Sopenharmony_ci 2437d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 2438d5ac70f0Sopenharmony_ci delete_object(instance, args); 2439d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_INTEGER)) 2440d5ac70f0Sopenharmony_ci return p; 2441d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_FLOAT)) { 2442d5ac70f0Sopenharmony_ci p1 = new_integer(instance, floor(p->value.f)); 2443d5ac70f0Sopenharmony_ci } else { 2444d5ac70f0Sopenharmony_ci lisp_warn(instance, "expected an integer or float for integer conversion"); 2445d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2446d5ac70f0Sopenharmony_ci } 2447d5ac70f0Sopenharmony_ci delete_tree(instance, p); 2448d5ac70f0Sopenharmony_ci return p1; 2449d5ac70f0Sopenharmony_ci} 2450d5ac70f0Sopenharmony_ci 2451d5ac70f0Sopenharmony_ci/* 2452d5ac70f0Sopenharmony_ci * Syntax: (string-to-float value) 2453d5ac70f0Sopenharmony_ci * 'value' can be integer or float type 2454d5ac70f0Sopenharmony_ci */ 2455d5ac70f0Sopenharmony_cistruct alisp_object * F_string_to_float(struct alisp_instance *instance, struct alisp_object * args) 2456d5ac70f0Sopenharmony_ci{ 2457d5ac70f0Sopenharmony_ci struct alisp_object * p = eval(instance, car(args)), * p1; 2458d5ac70f0Sopenharmony_ci 2459d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 2460d5ac70f0Sopenharmony_ci delete_object(instance, args); 2461d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_FLOAT)) 2462d5ac70f0Sopenharmony_ci return p; 2463d5ac70f0Sopenharmony_ci if (alisp_compare_type(p, ALISP_OBJ_INTEGER)) { 2464d5ac70f0Sopenharmony_ci p1 = new_float(instance, p->value.i); 2465d5ac70f0Sopenharmony_ci } else { 2466d5ac70f0Sopenharmony_ci lisp_warn(instance, "expected an integer or float for integer conversion"); 2467d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2468d5ac70f0Sopenharmony_ci } 2469d5ac70f0Sopenharmony_ci delete_tree(instance, p); 2470d5ac70f0Sopenharmony_ci return p1; 2471d5ac70f0Sopenharmony_ci} 2472d5ac70f0Sopenharmony_ci 2473d5ac70f0Sopenharmony_cistatic int append_to_string(char **s, int *len, char *from, int size) 2474d5ac70f0Sopenharmony_ci{ 2475d5ac70f0Sopenharmony_ci if (*len == 0) { 2476d5ac70f0Sopenharmony_ci *s = malloc(*len = size + 1); 2477d5ac70f0Sopenharmony_ci if (*s == NULL) { 2478d5ac70f0Sopenharmony_ci nomem(); 2479d5ac70f0Sopenharmony_ci return -ENOMEM; 2480d5ac70f0Sopenharmony_ci } 2481d5ac70f0Sopenharmony_ci memcpy(*s, from, size); 2482d5ac70f0Sopenharmony_ci } else { 2483d5ac70f0Sopenharmony_ci *len += size; 2484d5ac70f0Sopenharmony_ci *s = realloc(*s, *len); 2485d5ac70f0Sopenharmony_ci if (*s == NULL) { 2486d5ac70f0Sopenharmony_ci nomem(); 2487d5ac70f0Sopenharmony_ci return -ENOMEM; 2488d5ac70f0Sopenharmony_ci } 2489d5ac70f0Sopenharmony_ci memcpy(*s + strlen(*s), from, size); 2490d5ac70f0Sopenharmony_ci } 2491d5ac70f0Sopenharmony_ci (*s)[*len - 1] = '\0'; 2492d5ac70f0Sopenharmony_ci return 0; 2493d5ac70f0Sopenharmony_ci} 2494d5ac70f0Sopenharmony_ci 2495d5ac70f0Sopenharmony_cistatic int format_parse_char(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p) 2496d5ac70f0Sopenharmony_ci{ 2497d5ac70f0Sopenharmony_ci char b; 2498d5ac70f0Sopenharmony_ci 2499d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_INTEGER)) { 2500d5ac70f0Sopenharmony_ci lisp_warn(instance, "format: expected integer\n"); 2501d5ac70f0Sopenharmony_ci return 0; 2502d5ac70f0Sopenharmony_ci } 2503d5ac70f0Sopenharmony_ci b = p->value.i; 2504d5ac70f0Sopenharmony_ci return append_to_string(s, len, &b, 1); 2505d5ac70f0Sopenharmony_ci} 2506d5ac70f0Sopenharmony_ci 2507d5ac70f0Sopenharmony_cistatic int format_parse_integer(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p) 2508d5ac70f0Sopenharmony_ci{ 2509d5ac70f0Sopenharmony_ci int res; 2510d5ac70f0Sopenharmony_ci char *s1; 2511d5ac70f0Sopenharmony_ci 2512d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_INTEGER) && 2513d5ac70f0Sopenharmony_ci !alisp_compare_type(p, ALISP_OBJ_FLOAT)) { 2514d5ac70f0Sopenharmony_ci lisp_warn(instance, "format: expected integer or float\n"); 2515d5ac70f0Sopenharmony_ci return 0; 2516d5ac70f0Sopenharmony_ci } 2517d5ac70f0Sopenharmony_ci s1 = malloc(64); 2518d5ac70f0Sopenharmony_ci if (s1 == NULL) { 2519d5ac70f0Sopenharmony_ci nomem(); 2520d5ac70f0Sopenharmony_ci return -ENOMEM; 2521d5ac70f0Sopenharmony_ci } 2522d5ac70f0Sopenharmony_ci sprintf(s1, "%li", alisp_compare_type(p, ALISP_OBJ_FLOAT) ? (long)floor(p->value.f) : p->value.i); 2523d5ac70f0Sopenharmony_ci res = append_to_string(s, len, s1, strlen(s1)); 2524d5ac70f0Sopenharmony_ci free(s1); 2525d5ac70f0Sopenharmony_ci return res; 2526d5ac70f0Sopenharmony_ci} 2527d5ac70f0Sopenharmony_ci 2528d5ac70f0Sopenharmony_cistatic int format_parse_float(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p) 2529d5ac70f0Sopenharmony_ci{ 2530d5ac70f0Sopenharmony_ci int res; 2531d5ac70f0Sopenharmony_ci char *s1; 2532d5ac70f0Sopenharmony_ci 2533d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_INTEGER) && 2534d5ac70f0Sopenharmony_ci !alisp_compare_type(p, ALISP_OBJ_FLOAT)) { 2535d5ac70f0Sopenharmony_ci lisp_warn(instance, "format: expected integer or float\n"); 2536d5ac70f0Sopenharmony_ci return 0; 2537d5ac70f0Sopenharmony_ci } 2538d5ac70f0Sopenharmony_ci s1 = malloc(64); 2539d5ac70f0Sopenharmony_ci if (s1 == NULL) { 2540d5ac70f0Sopenharmony_ci nomem(); 2541d5ac70f0Sopenharmony_ci return -ENOMEM; 2542d5ac70f0Sopenharmony_ci } 2543d5ac70f0Sopenharmony_ci sprintf(s1, "%f", alisp_compare_type(p, ALISP_OBJ_FLOAT) ? p->value.f : (double)p->value.i); 2544d5ac70f0Sopenharmony_ci res = append_to_string(s, len, s1, strlen(s1)); 2545d5ac70f0Sopenharmony_ci free(s1); 2546d5ac70f0Sopenharmony_ci return res; 2547d5ac70f0Sopenharmony_ci} 2548d5ac70f0Sopenharmony_ci 2549d5ac70f0Sopenharmony_cistatic int format_parse_string(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p) 2550d5ac70f0Sopenharmony_ci{ 2551d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_STRING)) { 2552d5ac70f0Sopenharmony_ci lisp_warn(instance, "format: expected string\n"); 2553d5ac70f0Sopenharmony_ci return 0; 2554d5ac70f0Sopenharmony_ci } 2555d5ac70f0Sopenharmony_ci return append_to_string(s, len, p->value.s, strlen(p->value.s)); 2556d5ac70f0Sopenharmony_ci} 2557d5ac70f0Sopenharmony_ci 2558d5ac70f0Sopenharmony_ci/* 2559d5ac70f0Sopenharmony_ci * Syntax: (format format value...) 2560d5ac70f0Sopenharmony_ci * 'format' is C-like format string 2561d5ac70f0Sopenharmony_ci */ 2562d5ac70f0Sopenharmony_cistruct alisp_object * F_format(struct alisp_instance *instance, struct alisp_object * args) 2563d5ac70f0Sopenharmony_ci{ 2564d5ac70f0Sopenharmony_ci struct alisp_object * p = eval(instance, car(args)), * p1 = cdr(args), * n; 2565d5ac70f0Sopenharmony_ci char *s, *s1, *s2; 2566d5ac70f0Sopenharmony_ci int len; 2567d5ac70f0Sopenharmony_ci 2568d5ac70f0Sopenharmony_ci delete_object(instance, args); 2569d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_STRING)) { 2570d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2571d5ac70f0Sopenharmony_ci delete_tree(instance, p); 2572d5ac70f0Sopenharmony_ci lisp_warn(instance, "format: expected an format string"); 2573d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2574d5ac70f0Sopenharmony_ci } 2575d5ac70f0Sopenharmony_ci s = p->value.s; 2576d5ac70f0Sopenharmony_ci s1 = NULL; 2577d5ac70f0Sopenharmony_ci len = 0; 2578d5ac70f0Sopenharmony_ci n = eval(instance, car(p1)); 2579d5ac70f0Sopenharmony_ci do { 2580d5ac70f0Sopenharmony_ci while (1) { 2581d5ac70f0Sopenharmony_ci s2 = s; 2582d5ac70f0Sopenharmony_ci while (*s2 && *s2 != '%') 2583d5ac70f0Sopenharmony_ci s2++; 2584d5ac70f0Sopenharmony_ci if (s2 != s) { 2585d5ac70f0Sopenharmony_ci if (append_to_string(&s1, &len, s, s2 - s) < 0) { 2586d5ac70f0Sopenharmony_ci __error: 2587d5ac70f0Sopenharmony_ci delete_tree(instance, n); 2588d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p1)); 2589d5ac70f0Sopenharmony_ci delete_object(instance, p1); 2590d5ac70f0Sopenharmony_ci delete_tree(instance, p); 2591d5ac70f0Sopenharmony_ci return NULL; 2592d5ac70f0Sopenharmony_ci } 2593d5ac70f0Sopenharmony_ci } 2594d5ac70f0Sopenharmony_ci if (*s2 == '%') 2595d5ac70f0Sopenharmony_ci s2++; 2596d5ac70f0Sopenharmony_ci switch (*s2) { 2597d5ac70f0Sopenharmony_ci case '%': 2598d5ac70f0Sopenharmony_ci if (append_to_string(&s1, &len, s2, 1) < 0) 2599d5ac70f0Sopenharmony_ci goto __error; 2600d5ac70f0Sopenharmony_ci s = s2 + 1; 2601d5ac70f0Sopenharmony_ci break; 2602d5ac70f0Sopenharmony_ci case 'c': 2603d5ac70f0Sopenharmony_ci if (format_parse_char(instance, &s1, &len, n) < 0) 2604d5ac70f0Sopenharmony_ci goto __error; 2605d5ac70f0Sopenharmony_ci s = s2 + 1; 2606d5ac70f0Sopenharmony_ci goto __next; 2607d5ac70f0Sopenharmony_ci case 'd': 2608d5ac70f0Sopenharmony_ci case 'i': 2609d5ac70f0Sopenharmony_ci if (format_parse_integer(instance, &s1, &len, n) < 0) 2610d5ac70f0Sopenharmony_ci goto __error; 2611d5ac70f0Sopenharmony_ci s = s2 + 1; 2612d5ac70f0Sopenharmony_ci goto __next; 2613d5ac70f0Sopenharmony_ci case 'f': 2614d5ac70f0Sopenharmony_ci if (format_parse_float(instance, &s1, &len, n) < 0) 2615d5ac70f0Sopenharmony_ci goto __error; 2616d5ac70f0Sopenharmony_ci s = s2 + 1; 2617d5ac70f0Sopenharmony_ci goto __next; 2618d5ac70f0Sopenharmony_ci case 's': 2619d5ac70f0Sopenharmony_ci if (format_parse_string(instance, &s1, &len, n) < 0) 2620d5ac70f0Sopenharmony_ci goto __error; 2621d5ac70f0Sopenharmony_ci s = s2 + 1; 2622d5ac70f0Sopenharmony_ci goto __next; 2623d5ac70f0Sopenharmony_ci case '\0': 2624d5ac70f0Sopenharmony_ci goto __end; 2625d5ac70f0Sopenharmony_ci default: 2626d5ac70f0Sopenharmony_ci lisp_warn(instance, "unknown format char '%c'", *s2); 2627d5ac70f0Sopenharmony_ci s = s2 + 1; 2628d5ac70f0Sopenharmony_ci goto __next; 2629d5ac70f0Sopenharmony_ci } 2630d5ac70f0Sopenharmony_ci } 2631d5ac70f0Sopenharmony_ci __next: 2632d5ac70f0Sopenharmony_ci delete_tree(instance, n); 2633d5ac70f0Sopenharmony_ci p1 = cdr(n = p1); 2634d5ac70f0Sopenharmony_ci delete_object(instance, n); 2635d5ac70f0Sopenharmony_ci n = eval(instance, car(p1)); 2636d5ac70f0Sopenharmony_ci } while (*s); 2637d5ac70f0Sopenharmony_ci __end: 2638d5ac70f0Sopenharmony_ci delete_tree(instance, n); 2639d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p1)); 2640d5ac70f0Sopenharmony_ci delete_object(instance, p1); 2641d5ac70f0Sopenharmony_ci delete_tree(instance, p); 2642d5ac70f0Sopenharmony_ci if (len > 0) { 2643d5ac70f0Sopenharmony_ci p1 = new_string(instance, s1); 2644d5ac70f0Sopenharmony_ci free(s1); 2645d5ac70f0Sopenharmony_ci } else { 2646d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2647d5ac70f0Sopenharmony_ci } 2648d5ac70f0Sopenharmony_ci return p1; 2649d5ac70f0Sopenharmony_ci} 2650d5ac70f0Sopenharmony_ci 2651d5ac70f0Sopenharmony_ci/* 2652d5ac70f0Sopenharmony_ci * Syntax: (compare-strings str1 start1 end1 str2 start2 end2 /opt-case-insensitive) 2653d5ac70f0Sopenharmony_ci * 'str1' is first compared string 2654d5ac70f0Sopenharmony_ci * 'start1' is first char (0..) 2655d5ac70f0Sopenharmony_ci * 'end1' is last char (0..) 2656d5ac70f0Sopenharmony_ci * 'str2' is second compared string 2657d5ac70f0Sopenharmony_ci * 'start2' is first char (0..) 2658d5ac70f0Sopenharmony_ci * 'end2' is last char (0..) 2659d5ac70f0Sopenharmony_ci * /opt-case-insensitive true - case insensitive match 2660d5ac70f0Sopenharmony_ci */ 2661d5ac70f0Sopenharmony_cistruct alisp_object * F_compare_strings(struct alisp_instance *instance, struct alisp_object * args) 2662d5ac70f0Sopenharmony_ci{ 2663d5ac70f0Sopenharmony_ci struct alisp_object * p1 = args, * n, * p[7]; 2664d5ac70f0Sopenharmony_ci char *s1, *s2; 2665d5ac70f0Sopenharmony_ci int start1, end1, start2, end2; 2666d5ac70f0Sopenharmony_ci 2667d5ac70f0Sopenharmony_ci for (start1 = 0; start1 < 7; start1++) { 2668d5ac70f0Sopenharmony_ci p[start1] = eval(instance, car(p1)); 2669d5ac70f0Sopenharmony_ci p1 = cdr(n = p1); 2670d5ac70f0Sopenharmony_ci delete_object(instance, n); 2671d5ac70f0Sopenharmony_ci } 2672d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2673d5ac70f0Sopenharmony_ci if (alisp_compare_type(p[0], ALISP_OBJ_STRING)) { 2674d5ac70f0Sopenharmony_ci lisp_warn(instance, "compare-strings: first argument must be string\n"); 2675d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2676d5ac70f0Sopenharmony_ci goto __err; 2677d5ac70f0Sopenharmony_ci } 2678d5ac70f0Sopenharmony_ci if (alisp_compare_type(p[1], ALISP_OBJ_INTEGER)) { 2679d5ac70f0Sopenharmony_ci lisp_warn(instance, "compare-strings: second argument must be integer\n"); 2680d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2681d5ac70f0Sopenharmony_ci goto __err; 2682d5ac70f0Sopenharmony_ci } 2683d5ac70f0Sopenharmony_ci if (alisp_compare_type(p[2], ALISP_OBJ_INTEGER)) { 2684d5ac70f0Sopenharmony_ci lisp_warn(instance, "compare-strings: third argument must be integer\n"); 2685d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2686d5ac70f0Sopenharmony_ci goto __err; 2687d5ac70f0Sopenharmony_ci } 2688d5ac70f0Sopenharmony_ci if (alisp_compare_type(p[3], ALISP_OBJ_STRING)) { 2689d5ac70f0Sopenharmony_ci lisp_warn(instance, "compare-strings: fifth argument must be string\n"); 2690d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2691d5ac70f0Sopenharmony_ci goto __err; 2692d5ac70f0Sopenharmony_ci } 2693d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p[4], ALISP_OBJ_NIL) && 2694d5ac70f0Sopenharmony_ci !alisp_compare_type(p[4], ALISP_OBJ_INTEGER)) { 2695d5ac70f0Sopenharmony_ci lisp_warn(instance, "compare-strings: fourth argument must be integer\n"); 2696d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2697d5ac70f0Sopenharmony_ci goto __err; 2698d5ac70f0Sopenharmony_ci } 2699d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p[5], ALISP_OBJ_NIL) && 2700d5ac70f0Sopenharmony_ci !alisp_compare_type(p[5], ALISP_OBJ_INTEGER)) { 2701d5ac70f0Sopenharmony_ci lisp_warn(instance, "compare-strings: sixth argument must be integer\n"); 2702d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2703d5ac70f0Sopenharmony_ci goto __err; 2704d5ac70f0Sopenharmony_ci } 2705d5ac70f0Sopenharmony_ci s1 = p[0]->value.s; 2706d5ac70f0Sopenharmony_ci start1 = p[1]->value.i; 2707d5ac70f0Sopenharmony_ci end1 = p[2]->value.i; 2708d5ac70f0Sopenharmony_ci s2 = p[3]->value.s; 2709d5ac70f0Sopenharmony_ci start2 = alisp_compare_type(p[4], ALISP_OBJ_NIL) ? 0 : p[4]->value.i; 2710d5ac70f0Sopenharmony_ci end2 = alisp_compare_type(p[5], ALISP_OBJ_NIL) ? start2 + (end1 - start1) : p[5]->value.i; 2711d5ac70f0Sopenharmony_ci if (start1 < 0 || start2 < 0 || end1 < 0 || end2 < 0 || 2712d5ac70f0Sopenharmony_ci start1 >= (int)strlen(s1) || start2 >= (int)strlen(s2) || 2713d5ac70f0Sopenharmony_ci (end1 - start1) != (end2 - start2)) { 2714d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2715d5ac70f0Sopenharmony_ci goto __err; 2716d5ac70f0Sopenharmony_ci } 2717d5ac70f0Sopenharmony_ci if (p[6] != &alsa_lisp_nil) { 2718d5ac70f0Sopenharmony_ci while (start1 < end1) { 2719d5ac70f0Sopenharmony_ci if (s1[start1] == '\0' || 2720d5ac70f0Sopenharmony_ci s2[start2] == '\0' || 2721d5ac70f0Sopenharmony_ci tolower(s1[start1]) != tolower(s2[start2])) { 2722d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2723d5ac70f0Sopenharmony_ci goto __err; 2724d5ac70f0Sopenharmony_ci } 2725d5ac70f0Sopenharmony_ci start1++; 2726d5ac70f0Sopenharmony_ci start2++; 2727d5ac70f0Sopenharmony_ci } 2728d5ac70f0Sopenharmony_ci } else { 2729d5ac70f0Sopenharmony_ci while (start1 < end1) { 2730d5ac70f0Sopenharmony_ci if (s1[start1] == '\0' || 2731d5ac70f0Sopenharmony_ci s2[start2] == '\0' || 2732d5ac70f0Sopenharmony_ci s1[start1] != s2[start2]) { 2733d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_nil; 2734d5ac70f0Sopenharmony_ci goto __err; 2735d5ac70f0Sopenharmony_ci } 2736d5ac70f0Sopenharmony_ci start1++; 2737d5ac70f0Sopenharmony_ci start2++; 2738d5ac70f0Sopenharmony_ci } 2739d5ac70f0Sopenharmony_ci } 2740d5ac70f0Sopenharmony_ci p1 = &alsa_lisp_t; 2741d5ac70f0Sopenharmony_ci 2742d5ac70f0Sopenharmony_ci __err: 2743d5ac70f0Sopenharmony_ci for (start1 = 0; start1 < 7; start1++) 2744d5ac70f0Sopenharmony_ci delete_tree(instance, p[start1]); 2745d5ac70f0Sopenharmony_ci return p1; 2746d5ac70f0Sopenharmony_ci} 2747d5ac70f0Sopenharmony_ci 2748d5ac70f0Sopenharmony_ci/* 2749d5ac70f0Sopenharmony_ci * Syntax: (assoc key alist) 2750d5ac70f0Sopenharmony_ci */ 2751d5ac70f0Sopenharmony_cistruct alisp_object * F_assoc(struct alisp_instance *instance, struct alisp_object * args) 2752d5ac70f0Sopenharmony_ci{ 2753d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * n; 2754d5ac70f0Sopenharmony_ci 2755d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 2756d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 2757d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 2758d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2759d5ac70f0Sopenharmony_ci delete_object(instance, args); 2760d5ac70f0Sopenharmony_ci 2761d5ac70f0Sopenharmony_ci do { 2762d5ac70f0Sopenharmony_ci if (eq(p1, car(car(p2)))) { 2763d5ac70f0Sopenharmony_ci n = car(p2); 2764d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2765d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p2)); 2766d5ac70f0Sopenharmony_ci delete_object(instance, p2); 2767d5ac70f0Sopenharmony_ci return n; 2768d5ac70f0Sopenharmony_ci } 2769d5ac70f0Sopenharmony_ci delete_tree(instance, car(p2)); 2770d5ac70f0Sopenharmony_ci p2 = cdr(n = p2); 2771d5ac70f0Sopenharmony_ci delete_object(instance, n); 2772d5ac70f0Sopenharmony_ci } while (p2 != &alsa_lisp_nil); 2773d5ac70f0Sopenharmony_ci 2774d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2775d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2776d5ac70f0Sopenharmony_ci} 2777d5ac70f0Sopenharmony_ci 2778d5ac70f0Sopenharmony_ci/* 2779d5ac70f0Sopenharmony_ci * Syntax: (rassoc value alist) 2780d5ac70f0Sopenharmony_ci */ 2781d5ac70f0Sopenharmony_cistruct alisp_object * F_rassoc(struct alisp_instance *instance, struct alisp_object * args) 2782d5ac70f0Sopenharmony_ci{ 2783d5ac70f0Sopenharmony_ci struct alisp_object * p1, *p2, * n; 2784d5ac70f0Sopenharmony_ci 2785d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 2786d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 2787d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 2788d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2789d5ac70f0Sopenharmony_ci delete_object(instance, args); 2790d5ac70f0Sopenharmony_ci 2791d5ac70f0Sopenharmony_ci do { 2792d5ac70f0Sopenharmony_ci if (eq(p1, cdr(car(p2)))) { 2793d5ac70f0Sopenharmony_ci n = car(p2); 2794d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2795d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p2)); 2796d5ac70f0Sopenharmony_ci delete_object(instance, p2); 2797d5ac70f0Sopenharmony_ci return n; 2798d5ac70f0Sopenharmony_ci } 2799d5ac70f0Sopenharmony_ci delete_tree(instance, car(p2)); 2800d5ac70f0Sopenharmony_ci p2 = cdr(n = p2); 2801d5ac70f0Sopenharmony_ci delete_object(instance, n); 2802d5ac70f0Sopenharmony_ci } while (p2 != &alsa_lisp_nil); 2803d5ac70f0Sopenharmony_ci 2804d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2805d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2806d5ac70f0Sopenharmony_ci} 2807d5ac70f0Sopenharmony_ci 2808d5ac70f0Sopenharmony_ci/* 2809d5ac70f0Sopenharmony_ci * Syntax: (assq key alist) 2810d5ac70f0Sopenharmony_ci */ 2811d5ac70f0Sopenharmony_cistruct alisp_object * F_assq(struct alisp_instance *instance, struct alisp_object * args) 2812d5ac70f0Sopenharmony_ci{ 2813d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * n; 2814d5ac70f0Sopenharmony_ci 2815d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 2816d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 2817d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 2818d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2819d5ac70f0Sopenharmony_ci delete_object(instance, args); 2820d5ac70f0Sopenharmony_ci 2821d5ac70f0Sopenharmony_ci do { 2822d5ac70f0Sopenharmony_ci if (equal(p1, car(car(p2)))) { 2823d5ac70f0Sopenharmony_ci n = car(p2); 2824d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2825d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p2)); 2826d5ac70f0Sopenharmony_ci delete_object(instance, p2); 2827d5ac70f0Sopenharmony_ci return n; 2828d5ac70f0Sopenharmony_ci } 2829d5ac70f0Sopenharmony_ci delete_tree(instance, car(p2)); 2830d5ac70f0Sopenharmony_ci p2 = cdr(n = p2); 2831d5ac70f0Sopenharmony_ci delete_object(instance, n); 2832d5ac70f0Sopenharmony_ci } while (p2 != &alsa_lisp_nil); 2833d5ac70f0Sopenharmony_ci 2834d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2835d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2836d5ac70f0Sopenharmony_ci} 2837d5ac70f0Sopenharmony_ci 2838d5ac70f0Sopenharmony_ci/* 2839d5ac70f0Sopenharmony_ci * Syntax: (nth index alist) 2840d5ac70f0Sopenharmony_ci */ 2841d5ac70f0Sopenharmony_cistruct alisp_object * F_nth(struct alisp_instance *instance, struct alisp_object * args) 2842d5ac70f0Sopenharmony_ci{ 2843d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * n; 2844d5ac70f0Sopenharmony_ci long idx; 2845d5ac70f0Sopenharmony_ci 2846d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 2847d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 2848d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 2849d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2850d5ac70f0Sopenharmony_ci delete_object(instance, args); 2851d5ac70f0Sopenharmony_ci 2852d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p1, ALISP_OBJ_INTEGER)) { 2853d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2854d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2855d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2856d5ac70f0Sopenharmony_ci } 2857d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p2, ALISP_OBJ_CONS)) { 2858d5ac70f0Sopenharmony_ci delete_object(instance, p1); 2859d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 2860d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2861d5ac70f0Sopenharmony_ci } 2862d5ac70f0Sopenharmony_ci idx = p1->value.i; 2863d5ac70f0Sopenharmony_ci delete_object(instance, p1); 2864d5ac70f0Sopenharmony_ci while (idx-- > 0) { 2865d5ac70f0Sopenharmony_ci delete_tree(instance, car(p2)); 2866d5ac70f0Sopenharmony_ci p2 = cdr(n = p2); 2867d5ac70f0Sopenharmony_ci delete_object(instance, n); 2868d5ac70f0Sopenharmony_ci } 2869d5ac70f0Sopenharmony_ci n = car(p2); 2870d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p2)); 2871d5ac70f0Sopenharmony_ci delete_object(instance, p2); 2872d5ac70f0Sopenharmony_ci return n; 2873d5ac70f0Sopenharmony_ci} 2874d5ac70f0Sopenharmony_ci 2875d5ac70f0Sopenharmony_ci/* 2876d5ac70f0Sopenharmony_ci * Syntax: (rassq value alist) 2877d5ac70f0Sopenharmony_ci */ 2878d5ac70f0Sopenharmony_cistruct alisp_object * F_rassq(struct alisp_instance *instance, struct alisp_object * args) 2879d5ac70f0Sopenharmony_ci{ 2880d5ac70f0Sopenharmony_ci struct alisp_object * p1, * p2, * n; 2881d5ac70f0Sopenharmony_ci 2882d5ac70f0Sopenharmony_ci p1 = eval(instance, car(args)); 2883d5ac70f0Sopenharmony_ci p2 = eval(instance, car(cdr(args))); 2884d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(cdr(args))); 2885d5ac70f0Sopenharmony_ci delete_object(instance, cdr(args)); 2886d5ac70f0Sopenharmony_ci delete_object(instance, args); 2887d5ac70f0Sopenharmony_ci 2888d5ac70f0Sopenharmony_ci do { 2889d5ac70f0Sopenharmony_ci if (equal(p1, cdr(car(p2)))) { 2890d5ac70f0Sopenharmony_ci n = car(p2); 2891d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2892d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(p2)); 2893d5ac70f0Sopenharmony_ci delete_object(instance, p2); 2894d5ac70f0Sopenharmony_ci return n; 2895d5ac70f0Sopenharmony_ci } 2896d5ac70f0Sopenharmony_ci delete_tree(instance, car(p2)); 2897d5ac70f0Sopenharmony_ci p2 = cdr(n = p2); 2898d5ac70f0Sopenharmony_ci delete_object(instance, n); 2899d5ac70f0Sopenharmony_ci } while (p2 != &alsa_lisp_nil); 2900d5ac70f0Sopenharmony_ci 2901d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 2902d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2903d5ac70f0Sopenharmony_ci} 2904d5ac70f0Sopenharmony_ci 2905d5ac70f0Sopenharmony_cistatic struct alisp_object * F_dump_memory(struct alisp_instance *instance, struct alisp_object * args) 2906d5ac70f0Sopenharmony_ci{ 2907d5ac70f0Sopenharmony_ci struct alisp_object * p = car(args); 2908d5ac70f0Sopenharmony_ci 2909d5ac70f0Sopenharmony_ci if (p != &alsa_lisp_nil && cdr(args) == &alsa_lisp_nil && 2910d5ac70f0Sopenharmony_ci alisp_compare_type(p, ALISP_OBJ_STRING)) { 2911d5ac70f0Sopenharmony_ci if (strlen(p->value.s) > 0) { 2912d5ac70f0Sopenharmony_ci dump_objects(instance, p->value.s); 2913d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2914d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 2915d5ac70f0Sopenharmony_ci } else 2916d5ac70f0Sopenharmony_ci lisp_warn(instance, "expected filename"); 2917d5ac70f0Sopenharmony_ci } else 2918d5ac70f0Sopenharmony_ci lisp_warn(instance, "wrong number of parameters (expected string)"); 2919d5ac70f0Sopenharmony_ci 2920d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2921d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2922d5ac70f0Sopenharmony_ci} 2923d5ac70f0Sopenharmony_ci 2924d5ac70f0Sopenharmony_cistatic struct alisp_object * F_stat_memory(struct alisp_instance *instance, struct alisp_object * args) 2925d5ac70f0Sopenharmony_ci{ 2926d5ac70f0Sopenharmony_ci snd_output_printf(instance->out, "*** Memory stats\n"); 2927d5ac70f0Sopenharmony_ci snd_output_printf(instance->out, " used_objs = %li, free_objs = %li, max_objs = %li, obj_size = %i (total bytes = %li, max bytes = %li)\n", 2928d5ac70f0Sopenharmony_ci instance->used_objs, 2929d5ac70f0Sopenharmony_ci instance->free_objs, 2930d5ac70f0Sopenharmony_ci instance->max_objs, 2931d5ac70f0Sopenharmony_ci (int)sizeof(struct alisp_object), 2932d5ac70f0Sopenharmony_ci (long)((instance->used_objs + instance->free_objs) * sizeof(struct alisp_object)), 2933d5ac70f0Sopenharmony_ci (long)(instance->max_objs * sizeof(struct alisp_object))); 2934d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2935d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2936d5ac70f0Sopenharmony_ci} 2937d5ac70f0Sopenharmony_ci 2938d5ac70f0Sopenharmony_cistatic struct alisp_object * F_check_memory(struct alisp_instance *instance, struct alisp_object * args) 2939d5ac70f0Sopenharmony_ci{ 2940d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2941d5ac70f0Sopenharmony_ci if (instance->used_objs > 0) { 2942d5ac70f0Sopenharmony_ci fprintf(stderr, "!!!alsa lisp - check memory failed!!!\n"); 2943d5ac70f0Sopenharmony_ci F_stat_memory(instance, &alsa_lisp_nil); 2944d5ac70f0Sopenharmony_ci exit(EXIT_FAILURE); 2945d5ac70f0Sopenharmony_ci } 2946d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 2947d5ac70f0Sopenharmony_ci} 2948d5ac70f0Sopenharmony_ci 2949d5ac70f0Sopenharmony_cistatic struct alisp_object * F_dump_objects(struct alisp_instance *instance, struct alisp_object * args) 2950d5ac70f0Sopenharmony_ci{ 2951d5ac70f0Sopenharmony_ci struct alisp_object * p = car(args); 2952d5ac70f0Sopenharmony_ci 2953d5ac70f0Sopenharmony_ci if (p != &alsa_lisp_nil && cdr(args) == &alsa_lisp_nil && 2954d5ac70f0Sopenharmony_ci alisp_compare_type(p, ALISP_OBJ_STRING)) { 2955d5ac70f0Sopenharmony_ci if (strlen(p->value.s) > 0) { 2956d5ac70f0Sopenharmony_ci dump_obj_lists(instance, p->value.s); 2957d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2958d5ac70f0Sopenharmony_ci return &alsa_lisp_t; 2959d5ac70f0Sopenharmony_ci } else 2960d5ac70f0Sopenharmony_ci lisp_warn(instance, "expected filename"); 2961d5ac70f0Sopenharmony_ci } else 2962d5ac70f0Sopenharmony_ci lisp_warn(instance, "wrong number of parameters (expected string)"); 2963d5ac70f0Sopenharmony_ci 2964d5ac70f0Sopenharmony_ci delete_tree(instance, args); 2965d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 2966d5ac70f0Sopenharmony_ci} 2967d5ac70f0Sopenharmony_ci 2968d5ac70f0Sopenharmony_cistruct intrinsic { 2969d5ac70f0Sopenharmony_ci const char *name; 2970d5ac70f0Sopenharmony_ci struct alisp_object * (*func)(struct alisp_instance *instance, struct alisp_object * args); 2971d5ac70f0Sopenharmony_ci}; 2972d5ac70f0Sopenharmony_ci 2973d5ac70f0Sopenharmony_cistatic const struct intrinsic intrinsics[] = { 2974d5ac70f0Sopenharmony_ci { "!=", F_numneq }, 2975d5ac70f0Sopenharmony_ci { "%", F_mod }, 2976d5ac70f0Sopenharmony_ci { "&check-memory", F_check_memory }, 2977d5ac70f0Sopenharmony_ci { "&dump-memory", F_dump_memory }, 2978d5ac70f0Sopenharmony_ci { "&dump-objects", F_dump_objects }, 2979d5ac70f0Sopenharmony_ci { "&stat-memory", F_stat_memory }, 2980d5ac70f0Sopenharmony_ci { "*", F_mul }, 2981d5ac70f0Sopenharmony_ci { "+", F_add }, 2982d5ac70f0Sopenharmony_ci { "-", F_sub }, 2983d5ac70f0Sopenharmony_ci { "/", F_div }, 2984d5ac70f0Sopenharmony_ci { "<", F_lt }, 2985d5ac70f0Sopenharmony_ci { "<=", F_le }, 2986d5ac70f0Sopenharmony_ci { "=", F_numeq }, 2987d5ac70f0Sopenharmony_ci { ">", F_gt }, 2988d5ac70f0Sopenharmony_ci { ">=", F_ge }, 2989d5ac70f0Sopenharmony_ci { "and", F_and }, 2990d5ac70f0Sopenharmony_ci { "assoc", F_assoc }, 2991d5ac70f0Sopenharmony_ci { "assq", F_assq }, 2992d5ac70f0Sopenharmony_ci { "atom", F_atom }, 2993d5ac70f0Sopenharmony_ci { "car", F_car }, 2994d5ac70f0Sopenharmony_ci { "cdr", F_cdr }, 2995d5ac70f0Sopenharmony_ci { "compare-strings", F_compare_strings }, 2996d5ac70f0Sopenharmony_ci { "concat", F_concat }, 2997d5ac70f0Sopenharmony_ci { "cond", F_cond }, 2998d5ac70f0Sopenharmony_ci { "cons", F_cons }, 2999d5ac70f0Sopenharmony_ci { "defun", F_defun }, 3000d5ac70f0Sopenharmony_ci { "eq", F_eq }, 3001d5ac70f0Sopenharmony_ci { "equal", F_equal }, 3002d5ac70f0Sopenharmony_ci { "eval", F_eval }, 3003d5ac70f0Sopenharmony_ci { "exfun", F_exfun }, 3004d5ac70f0Sopenharmony_ci { "format", F_format }, 3005d5ac70f0Sopenharmony_ci { "funcall", F_funcall }, 3006d5ac70f0Sopenharmony_ci { "garbage-collect", F_gc }, 3007d5ac70f0Sopenharmony_ci { "gc", F_gc }, 3008d5ac70f0Sopenharmony_ci { "if", F_if }, 3009d5ac70f0Sopenharmony_ci { "include", F_include }, 3010d5ac70f0Sopenharmony_ci { "list", F_list }, 3011d5ac70f0Sopenharmony_ci { "not", F_not }, 3012d5ac70f0Sopenharmony_ci { "nth", F_nth }, 3013d5ac70f0Sopenharmony_ci { "null", F_not }, 3014d5ac70f0Sopenharmony_ci { "or", F_or }, 3015d5ac70f0Sopenharmony_ci { "path", F_path }, 3016d5ac70f0Sopenharmony_ci { "princ", F_princ }, 3017d5ac70f0Sopenharmony_ci { "prog1", F_prog1 }, 3018d5ac70f0Sopenharmony_ci { "prog2", F_prog2 }, 3019d5ac70f0Sopenharmony_ci { "progn", F_progn }, 3020d5ac70f0Sopenharmony_ci { "quote", F_quote }, 3021d5ac70f0Sopenharmony_ci { "rassoc", F_rassoc }, 3022d5ac70f0Sopenharmony_ci { "rassq", F_rassq }, 3023d5ac70f0Sopenharmony_ci { "set", F_set }, 3024d5ac70f0Sopenharmony_ci { "setf", F_setq }, 3025d5ac70f0Sopenharmony_ci { "setq", F_setq }, 3026d5ac70f0Sopenharmony_ci { "string-equal", F_equal }, 3027d5ac70f0Sopenharmony_ci { "string-to-float", F_string_to_float }, 3028d5ac70f0Sopenharmony_ci { "string-to-integer", F_string_to_integer }, 3029d5ac70f0Sopenharmony_ci { "string-to-number", F_string_to_float }, 3030d5ac70f0Sopenharmony_ci { "string=", F_equal }, 3031d5ac70f0Sopenharmony_ci { "unless", F_unless }, 3032d5ac70f0Sopenharmony_ci { "unset", F_unset }, 3033d5ac70f0Sopenharmony_ci { "unsetf", F_unsetq }, 3034d5ac70f0Sopenharmony_ci { "unsetq", F_unsetq }, 3035d5ac70f0Sopenharmony_ci { "when", F_when }, 3036d5ac70f0Sopenharmony_ci { "while", F_while }, 3037d5ac70f0Sopenharmony_ci}; 3038d5ac70f0Sopenharmony_ci 3039d5ac70f0Sopenharmony_ci#include "alisp_snd.c" 3040d5ac70f0Sopenharmony_ci 3041d5ac70f0Sopenharmony_cistatic int compar(const void *p1, const void *p2) 3042d5ac70f0Sopenharmony_ci{ 3043d5ac70f0Sopenharmony_ci return strcmp(((struct intrinsic *)p1)->name, 3044d5ac70f0Sopenharmony_ci ((struct intrinsic *)p2)->name); 3045d5ac70f0Sopenharmony_ci} 3046d5ac70f0Sopenharmony_ci 3047d5ac70f0Sopenharmony_cistatic inline struct alisp_object * eval_cons1(struct alisp_instance *instance, struct alisp_object * p1, struct alisp_object * p2) 3048d5ac70f0Sopenharmony_ci{ 3049d5ac70f0Sopenharmony_ci struct alisp_object * p3; 3050d5ac70f0Sopenharmony_ci struct intrinsic key, *item; 3051d5ac70f0Sopenharmony_ci 3052d5ac70f0Sopenharmony_ci key.name = p1->value.s; 3053d5ac70f0Sopenharmony_ci 3054d5ac70f0Sopenharmony_ci if ((item = bsearch(&key, intrinsics, 3055d5ac70f0Sopenharmony_ci sizeof intrinsics / sizeof intrinsics[0], 3056d5ac70f0Sopenharmony_ci sizeof intrinsics[0], compar)) != NULL) { 3057d5ac70f0Sopenharmony_ci delete_object(instance, p1); 3058d5ac70f0Sopenharmony_ci return item->func(instance, p2); 3059d5ac70f0Sopenharmony_ci } 3060d5ac70f0Sopenharmony_ci 3061d5ac70f0Sopenharmony_ci if ((item = bsearch(&key, snd_intrinsics, 3062d5ac70f0Sopenharmony_ci sizeof snd_intrinsics / sizeof snd_intrinsics[0], 3063d5ac70f0Sopenharmony_ci sizeof snd_intrinsics[0], compar)) != NULL) { 3064d5ac70f0Sopenharmony_ci delete_object(instance, p1); 3065d5ac70f0Sopenharmony_ci return item->func(instance, p2); 3066d5ac70f0Sopenharmony_ci } 3067d5ac70f0Sopenharmony_ci 3068d5ac70f0Sopenharmony_ci if ((p3 = get_object(instance, p1)) != &alsa_lisp_nil) { 3069d5ac70f0Sopenharmony_ci delete_object(instance, p1); 3070d5ac70f0Sopenharmony_ci return eval_func(instance, p3, p2); 3071d5ac70f0Sopenharmony_ci } else { 3072d5ac70f0Sopenharmony_ci lisp_warn(instance, "function `%s' is undefined", p1->value.s); 3073d5ac70f0Sopenharmony_ci delete_object(instance, p1); 3074d5ac70f0Sopenharmony_ci delete_tree(instance, p2); 3075d5ac70f0Sopenharmony_ci } 3076d5ac70f0Sopenharmony_ci 3077d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 3078d5ac70f0Sopenharmony_ci} 3079d5ac70f0Sopenharmony_ci 3080d5ac70f0Sopenharmony_ci/* 3081d5ac70f0Sopenharmony_ci * Syntax: (funcall function args...) 3082d5ac70f0Sopenharmony_ci */ 3083d5ac70f0Sopenharmony_cistatic struct alisp_object * F_funcall(struct alisp_instance *instance, struct alisp_object * args) 3084d5ac70f0Sopenharmony_ci{ 3085d5ac70f0Sopenharmony_ci struct alisp_object * p = eval(instance, car(args)), * p1; 3086d5ac70f0Sopenharmony_ci 3087d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p, ALISP_OBJ_IDENTIFIER) && 3088d5ac70f0Sopenharmony_ci !alisp_compare_type(p, ALISP_OBJ_STRING)) { 3089d5ac70f0Sopenharmony_ci lisp_warn(instance, "expected an function name"); 3090d5ac70f0Sopenharmony_ci delete_tree(instance, p); 3091d5ac70f0Sopenharmony_ci delete_tree(instance, cdr(args)); 3092d5ac70f0Sopenharmony_ci delete_object(instance, args); 3093d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 3094d5ac70f0Sopenharmony_ci } 3095d5ac70f0Sopenharmony_ci p1 = cdr(args); 3096d5ac70f0Sopenharmony_ci delete_object(instance, args); 3097d5ac70f0Sopenharmony_ci return eval_cons1(instance, p, p1); 3098d5ac70f0Sopenharmony_ci} 3099d5ac70f0Sopenharmony_ci 3100d5ac70f0Sopenharmony_cistatic inline struct alisp_object * eval_cons(struct alisp_instance *instance, struct alisp_object * p) 3101d5ac70f0Sopenharmony_ci{ 3102d5ac70f0Sopenharmony_ci struct alisp_object * p1 = car(p), * p2; 3103d5ac70f0Sopenharmony_ci 3104d5ac70f0Sopenharmony_ci if (p1 != &alsa_lisp_nil && alisp_compare_type(p1, ALISP_OBJ_IDENTIFIER)) { 3105d5ac70f0Sopenharmony_ci if (!strcmp(p1->value.s, "lambda")) 3106d5ac70f0Sopenharmony_ci return p; 3107d5ac70f0Sopenharmony_ci 3108d5ac70f0Sopenharmony_ci p2 = cdr(p); 3109d5ac70f0Sopenharmony_ci delete_object(instance, p); 3110d5ac70f0Sopenharmony_ci return eval_cons1(instance, p1, p2); 3111d5ac70f0Sopenharmony_ci } else { 3112d5ac70f0Sopenharmony_ci delete_tree(instance, p); 3113d5ac70f0Sopenharmony_ci } 3114d5ac70f0Sopenharmony_ci 3115d5ac70f0Sopenharmony_ci return &alsa_lisp_nil; 3116d5ac70f0Sopenharmony_ci} 3117d5ac70f0Sopenharmony_ci 3118d5ac70f0Sopenharmony_cistatic struct alisp_object * eval(struct alisp_instance *instance, struct alisp_object * p) 3119d5ac70f0Sopenharmony_ci{ 3120d5ac70f0Sopenharmony_ci switch (alisp_get_type(p)) { 3121d5ac70f0Sopenharmony_ci case ALISP_OBJ_IDENTIFIER: { 3122d5ac70f0Sopenharmony_ci struct alisp_object *r = incref_tree(instance, get_object(instance, p)); 3123d5ac70f0Sopenharmony_ci delete_object(instance, p); 3124d5ac70f0Sopenharmony_ci return r; 3125d5ac70f0Sopenharmony_ci } 3126d5ac70f0Sopenharmony_ci case ALISP_OBJ_INTEGER: 3127d5ac70f0Sopenharmony_ci case ALISP_OBJ_FLOAT: 3128d5ac70f0Sopenharmony_ci case ALISP_OBJ_STRING: 3129d5ac70f0Sopenharmony_ci case ALISP_OBJ_POINTER: 3130d5ac70f0Sopenharmony_ci return p; 3131d5ac70f0Sopenharmony_ci case ALISP_OBJ_CONS: 3132d5ac70f0Sopenharmony_ci return eval_cons(instance, p); 3133d5ac70f0Sopenharmony_ci default: 3134d5ac70f0Sopenharmony_ci break; 3135d5ac70f0Sopenharmony_ci } 3136d5ac70f0Sopenharmony_ci 3137d5ac70f0Sopenharmony_ci return p; 3138d5ac70f0Sopenharmony_ci} 3139d5ac70f0Sopenharmony_ci 3140d5ac70f0Sopenharmony_cistatic struct alisp_object * F_eval(struct alisp_instance *instance, struct alisp_object * args) 3141d5ac70f0Sopenharmony_ci{ 3142d5ac70f0Sopenharmony_ci return eval(instance, eval(instance, car(args))); 3143d5ac70f0Sopenharmony_ci} 3144d5ac70f0Sopenharmony_ci 3145d5ac70f0Sopenharmony_ci/* 3146d5ac70f0Sopenharmony_ci * main routine 3147d5ac70f0Sopenharmony_ci */ 3148d5ac70f0Sopenharmony_ci 3149d5ac70f0Sopenharmony_cistatic int alisp_include_file(struct alisp_instance *instance, const char *filename) 3150d5ac70f0Sopenharmony_ci{ 3151d5ac70f0Sopenharmony_ci snd_input_t *old_in; 3152d5ac70f0Sopenharmony_ci struct alisp_object *p, *p1; 3153d5ac70f0Sopenharmony_ci char *name; 3154d5ac70f0Sopenharmony_ci int retval = 0, err; 3155d5ac70f0Sopenharmony_ci 3156d5ac70f0Sopenharmony_ci err = snd_user_file(filename, &name); 3157d5ac70f0Sopenharmony_ci if (err < 0) 3158d5ac70f0Sopenharmony_ci return err; 3159d5ac70f0Sopenharmony_ci old_in = instance->in; 3160d5ac70f0Sopenharmony_ci err = snd_input_stdio_open(&instance->in, name, "r"); 3161d5ac70f0Sopenharmony_ci if (err < 0) { 3162d5ac70f0Sopenharmony_ci retval = err; 3163d5ac70f0Sopenharmony_ci goto _err; 3164d5ac70f0Sopenharmony_ci } 3165d5ac70f0Sopenharmony_ci if (instance->verbose) 3166d5ac70f0Sopenharmony_ci lisp_verbose(instance, "** include filename '%s'", name); 3167d5ac70f0Sopenharmony_ci 3168d5ac70f0Sopenharmony_ci for (;;) { 3169d5ac70f0Sopenharmony_ci if ((p = parse_object(instance, 0)) == NULL) 3170d5ac70f0Sopenharmony_ci break; 3171d5ac70f0Sopenharmony_ci if (instance->verbose) { 3172d5ac70f0Sopenharmony_ci lisp_verbose(instance, "** code"); 3173d5ac70f0Sopenharmony_ci princ_object(instance->vout, p); 3174d5ac70f0Sopenharmony_ci snd_output_putc(instance->vout, '\n'); 3175d5ac70f0Sopenharmony_ci } 3176d5ac70f0Sopenharmony_ci p1 = eval(instance, p); 3177d5ac70f0Sopenharmony_ci if (p1 == NULL) { 3178d5ac70f0Sopenharmony_ci retval = -ENOMEM; 3179d5ac70f0Sopenharmony_ci break; 3180d5ac70f0Sopenharmony_ci } 3181d5ac70f0Sopenharmony_ci if (instance->verbose) { 3182d5ac70f0Sopenharmony_ci lisp_verbose(instance, "** result"); 3183d5ac70f0Sopenharmony_ci princ_object(instance->vout, p1); 3184d5ac70f0Sopenharmony_ci snd_output_putc(instance->vout, '\n'); 3185d5ac70f0Sopenharmony_ci } 3186d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 3187d5ac70f0Sopenharmony_ci if (instance->debug) { 3188d5ac70f0Sopenharmony_ci lisp_debug(instance, "** objects after operation"); 3189d5ac70f0Sopenharmony_ci print_obj_lists(instance, instance->dout); 3190d5ac70f0Sopenharmony_ci } 3191d5ac70f0Sopenharmony_ci } 3192d5ac70f0Sopenharmony_ci 3193d5ac70f0Sopenharmony_ci snd_input_close(instance->in); 3194d5ac70f0Sopenharmony_ci _err: 3195d5ac70f0Sopenharmony_ci free(name); 3196d5ac70f0Sopenharmony_ci instance->in = old_in; 3197d5ac70f0Sopenharmony_ci return retval; 3198d5ac70f0Sopenharmony_ci} 3199d5ac70f0Sopenharmony_ci 3200d5ac70f0Sopenharmony_ciint alsa_lisp(struct alisp_cfg *cfg, struct alisp_instance **_instance) 3201d5ac70f0Sopenharmony_ci{ 3202d5ac70f0Sopenharmony_ci struct alisp_instance *instance; 3203d5ac70f0Sopenharmony_ci struct alisp_object *p, *p1; 3204d5ac70f0Sopenharmony_ci int i, j, retval = 0; 3205d5ac70f0Sopenharmony_ci 3206d5ac70f0Sopenharmony_ci instance = (struct alisp_instance *)calloc(1, sizeof(struct alisp_instance)); 3207d5ac70f0Sopenharmony_ci if (instance == NULL) { 3208d5ac70f0Sopenharmony_ci nomem(); 3209d5ac70f0Sopenharmony_ci return -ENOMEM; 3210d5ac70f0Sopenharmony_ci } 3211d5ac70f0Sopenharmony_ci instance->verbose = cfg->verbose && cfg->vout; 3212d5ac70f0Sopenharmony_ci instance->warning = cfg->warning && cfg->wout; 3213d5ac70f0Sopenharmony_ci instance->debug = cfg->debug && cfg->dout; 3214d5ac70f0Sopenharmony_ci instance->in = cfg->in; 3215d5ac70f0Sopenharmony_ci instance->out = cfg->out; 3216d5ac70f0Sopenharmony_ci instance->vout = cfg->vout; 3217d5ac70f0Sopenharmony_ci instance->eout = cfg->eout; 3218d5ac70f0Sopenharmony_ci instance->wout = cfg->wout; 3219d5ac70f0Sopenharmony_ci instance->dout = cfg->dout; 3220d5ac70f0Sopenharmony_ci INIT_LIST_HEAD(&instance->free_objs_list); 3221d5ac70f0Sopenharmony_ci for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++) { 3222d5ac70f0Sopenharmony_ci for (j = 0; j <= ALISP_OBJ_LAST_SEARCH; j++) 3223d5ac70f0Sopenharmony_ci INIT_LIST_HEAD(&instance->used_objs_list[i][j]); 3224d5ac70f0Sopenharmony_ci INIT_LIST_HEAD(&instance->setobjs_list[i]); 3225d5ac70f0Sopenharmony_ci } 3226d5ac70f0Sopenharmony_ci 3227d5ac70f0Sopenharmony_ci init_lex(instance); 3228d5ac70f0Sopenharmony_ci 3229d5ac70f0Sopenharmony_ci for (;;) { 3230d5ac70f0Sopenharmony_ci if ((p = parse_object(instance, 0)) == NULL) 3231d5ac70f0Sopenharmony_ci break; 3232d5ac70f0Sopenharmony_ci if (instance->verbose) { 3233d5ac70f0Sopenharmony_ci lisp_verbose(instance, "** code"); 3234d5ac70f0Sopenharmony_ci princ_object(instance->vout, p); 3235d5ac70f0Sopenharmony_ci snd_output_putc(instance->vout, '\n'); 3236d5ac70f0Sopenharmony_ci } 3237d5ac70f0Sopenharmony_ci p1 = eval(instance, p); 3238d5ac70f0Sopenharmony_ci if (p1 == NULL) { 3239d5ac70f0Sopenharmony_ci retval = -ENOMEM; 3240d5ac70f0Sopenharmony_ci break; 3241d5ac70f0Sopenharmony_ci } 3242d5ac70f0Sopenharmony_ci if (instance->verbose) { 3243d5ac70f0Sopenharmony_ci lisp_verbose(instance, "** result"); 3244d5ac70f0Sopenharmony_ci princ_object(instance->vout, p1); 3245d5ac70f0Sopenharmony_ci snd_output_putc(instance->vout, '\n'); 3246d5ac70f0Sopenharmony_ci } 3247d5ac70f0Sopenharmony_ci delete_tree(instance, p1); 3248d5ac70f0Sopenharmony_ci if (instance->debug) { 3249d5ac70f0Sopenharmony_ci lisp_debug(instance, "** objects after operation"); 3250d5ac70f0Sopenharmony_ci print_obj_lists(instance, instance->dout); 3251d5ac70f0Sopenharmony_ci } 3252d5ac70f0Sopenharmony_ci } 3253d5ac70f0Sopenharmony_ci 3254d5ac70f0Sopenharmony_ci if (_instance) 3255d5ac70f0Sopenharmony_ci *_instance = instance; 3256d5ac70f0Sopenharmony_ci else 3257d5ac70f0Sopenharmony_ci alsa_lisp_free(instance); 3258d5ac70f0Sopenharmony_ci 3259d5ac70f0Sopenharmony_ci return retval; 3260d5ac70f0Sopenharmony_ci} 3261d5ac70f0Sopenharmony_ci 3262d5ac70f0Sopenharmony_civoid alsa_lisp_free(struct alisp_instance *instance) 3263d5ac70f0Sopenharmony_ci{ 3264d5ac70f0Sopenharmony_ci if (instance == NULL) 3265d5ac70f0Sopenharmony_ci return; 3266d5ac70f0Sopenharmony_ci done_lex(instance); 3267d5ac70f0Sopenharmony_ci free_objects(instance); 3268d5ac70f0Sopenharmony_ci free(instance); 3269d5ac70f0Sopenharmony_ci} 3270d5ac70f0Sopenharmony_ci 3271d5ac70f0Sopenharmony_cistruct alisp_cfg *alsa_lisp_default_cfg(snd_input_t *input) 3272d5ac70f0Sopenharmony_ci{ 3273d5ac70f0Sopenharmony_ci snd_output_t *output, *eoutput; 3274d5ac70f0Sopenharmony_ci struct alisp_cfg *cfg; 3275d5ac70f0Sopenharmony_ci int err; 3276d5ac70f0Sopenharmony_ci 3277d5ac70f0Sopenharmony_ci err = snd_output_stdio_attach(&output, stdout, 0); 3278d5ac70f0Sopenharmony_ci if (err < 0) 3279d5ac70f0Sopenharmony_ci return NULL; 3280d5ac70f0Sopenharmony_ci err = snd_output_stdio_attach(&eoutput, stderr, 0); 3281d5ac70f0Sopenharmony_ci if (err < 0) { 3282d5ac70f0Sopenharmony_ci snd_output_close(output); 3283d5ac70f0Sopenharmony_ci return NULL; 3284d5ac70f0Sopenharmony_ci } 3285d5ac70f0Sopenharmony_ci cfg = calloc(1, sizeof(struct alisp_cfg)); 3286d5ac70f0Sopenharmony_ci if (cfg == NULL) { 3287d5ac70f0Sopenharmony_ci snd_output_close(eoutput); 3288d5ac70f0Sopenharmony_ci snd_output_close(output); 3289d5ac70f0Sopenharmony_ci return NULL; 3290d5ac70f0Sopenharmony_ci } 3291d5ac70f0Sopenharmony_ci cfg->out = output; 3292d5ac70f0Sopenharmony_ci cfg->wout = eoutput; 3293d5ac70f0Sopenharmony_ci cfg->eout = eoutput; 3294d5ac70f0Sopenharmony_ci cfg->dout = eoutput; 3295d5ac70f0Sopenharmony_ci cfg->in = input; 3296d5ac70f0Sopenharmony_ci return cfg; 3297d5ac70f0Sopenharmony_ci} 3298d5ac70f0Sopenharmony_ci 3299d5ac70f0Sopenharmony_civoid alsa_lisp_default_cfg_free(struct alisp_cfg *cfg) 3300d5ac70f0Sopenharmony_ci{ 3301d5ac70f0Sopenharmony_ci snd_input_close(cfg->in); 3302d5ac70f0Sopenharmony_ci snd_output_close(cfg->out); 3303d5ac70f0Sopenharmony_ci snd_output_close(cfg->dout); 3304d5ac70f0Sopenharmony_ci free(cfg); 3305d5ac70f0Sopenharmony_ci} 3306d5ac70f0Sopenharmony_ci 3307d5ac70f0Sopenharmony_ciint alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterator **result, 3308d5ac70f0Sopenharmony_ci const char *id, const char *args, ...) 3309d5ac70f0Sopenharmony_ci{ 3310d5ac70f0Sopenharmony_ci int err = 0; 3311d5ac70f0Sopenharmony_ci struct alisp_object *aargs = NULL, *obj, *res; 3312d5ac70f0Sopenharmony_ci 3313d5ac70f0Sopenharmony_ci if (args && *args != 'n') { 3314d5ac70f0Sopenharmony_ci va_list ap; 3315d5ac70f0Sopenharmony_ci struct alisp_object *p; 3316d5ac70f0Sopenharmony_ci p = NULL; 3317d5ac70f0Sopenharmony_ci va_start(ap, args); 3318d5ac70f0Sopenharmony_ci while (*args) { 3319d5ac70f0Sopenharmony_ci if (*args++ != '%') { 3320d5ac70f0Sopenharmony_ci err = -EINVAL; 3321d5ac70f0Sopenharmony_ci break; 3322d5ac70f0Sopenharmony_ci } 3323d5ac70f0Sopenharmony_ci if (*args == '\0') { 3324d5ac70f0Sopenharmony_ci err = -EINVAL; 3325d5ac70f0Sopenharmony_ci break; 3326d5ac70f0Sopenharmony_ci } 3327d5ac70f0Sopenharmony_ci obj = NULL; 3328d5ac70f0Sopenharmony_ci err = 0; 3329d5ac70f0Sopenharmony_ci switch (*args++) { 3330d5ac70f0Sopenharmony_ci case 's': 3331d5ac70f0Sopenharmony_ci obj = new_string(instance, va_arg(ap, char *)); 3332d5ac70f0Sopenharmony_ci break; 3333d5ac70f0Sopenharmony_ci case 'i': 3334d5ac70f0Sopenharmony_ci obj = new_integer(instance, va_arg(ap, int)); 3335d5ac70f0Sopenharmony_ci break; 3336d5ac70f0Sopenharmony_ci case 'l': 3337d5ac70f0Sopenharmony_ci obj = new_integer(instance, va_arg(ap, long)); 3338d5ac70f0Sopenharmony_ci break; 3339d5ac70f0Sopenharmony_ci case 'f': 3340d5ac70f0Sopenharmony_ci case 'd': 3341d5ac70f0Sopenharmony_ci obj = new_integer(instance, va_arg(ap, double)); 3342d5ac70f0Sopenharmony_ci break; 3343d5ac70f0Sopenharmony_ci case 'p': { 3344d5ac70f0Sopenharmony_ci char _ptrid[24]; 3345d5ac70f0Sopenharmony_ci char *ptrid = _ptrid; 3346d5ac70f0Sopenharmony_ci while (*args && *args != '%') 3347d5ac70f0Sopenharmony_ci *ptrid++ = *args++; 3348d5ac70f0Sopenharmony_ci *ptrid = 0; 3349d5ac70f0Sopenharmony_ci if (ptrid == _ptrid) { 3350d5ac70f0Sopenharmony_ci err = -EINVAL; 3351d5ac70f0Sopenharmony_ci break; 3352d5ac70f0Sopenharmony_ci } 3353d5ac70f0Sopenharmony_ci obj = new_cons_pointer(instance, _ptrid, va_arg(ap, void *)); 3354d5ac70f0Sopenharmony_ci obj = quote_object(instance, obj); 3355d5ac70f0Sopenharmony_ci break; 3356d5ac70f0Sopenharmony_ci } 3357d5ac70f0Sopenharmony_ci default: 3358d5ac70f0Sopenharmony_ci err = -EINVAL; 3359d5ac70f0Sopenharmony_ci break; 3360d5ac70f0Sopenharmony_ci } 3361d5ac70f0Sopenharmony_ci if (err < 0) 3362d5ac70f0Sopenharmony_ci goto __args_end; 3363d5ac70f0Sopenharmony_ci if (obj == NULL) { 3364d5ac70f0Sopenharmony_ci err = -ENOMEM; 3365d5ac70f0Sopenharmony_ci goto __args_end; 3366d5ac70f0Sopenharmony_ci } 3367d5ac70f0Sopenharmony_ci if (p == NULL) { 3368d5ac70f0Sopenharmony_ci p = aargs = new_object(instance, ALISP_OBJ_CONS); 3369d5ac70f0Sopenharmony_ci } else { 3370d5ac70f0Sopenharmony_ci p->value.c.cdr = new_object(instance, ALISP_OBJ_CONS); 3371d5ac70f0Sopenharmony_ci p = p->value.c.cdr; 3372d5ac70f0Sopenharmony_ci } 3373d5ac70f0Sopenharmony_ci if (p == NULL) { 3374d5ac70f0Sopenharmony_ci err = -ENOMEM; 3375d5ac70f0Sopenharmony_ci goto __args_end; 3376d5ac70f0Sopenharmony_ci } 3377d5ac70f0Sopenharmony_ci p->value.c.car = obj; 3378d5ac70f0Sopenharmony_ci } 3379d5ac70f0Sopenharmony_ci __args_end: 3380d5ac70f0Sopenharmony_ci va_end(ap); 3381d5ac70f0Sopenharmony_ci if (err < 0) 3382d5ac70f0Sopenharmony_ci return err; 3383d5ac70f0Sopenharmony_ci#if 0 3384d5ac70f0Sopenharmony_ci snd_output_printf(instance->wout, ">>>"); 3385d5ac70f0Sopenharmony_ci princ_object(instance->wout, aargs); 3386d5ac70f0Sopenharmony_ci snd_output_printf(instance->wout, "<<<\n"); 3387d5ac70f0Sopenharmony_ci#endif 3388d5ac70f0Sopenharmony_ci } 3389d5ac70f0Sopenharmony_ci 3390d5ac70f0Sopenharmony_ci err = -ENOENT; 3391d5ac70f0Sopenharmony_ci if (aargs == NULL) 3392d5ac70f0Sopenharmony_ci aargs = &alsa_lisp_nil; 3393d5ac70f0Sopenharmony_ci if ((obj = get_object1(instance, id)) != &alsa_lisp_nil) { 3394d5ac70f0Sopenharmony_ci res = eval_func(instance, obj, aargs); 3395d5ac70f0Sopenharmony_ci err = 0; 3396d5ac70f0Sopenharmony_ci } else { 3397d5ac70f0Sopenharmony_ci struct intrinsic key, *item; 3398d5ac70f0Sopenharmony_ci key.name = id; 3399d5ac70f0Sopenharmony_ci if ((item = bsearch(&key, intrinsics, 3400d5ac70f0Sopenharmony_ci sizeof intrinsics / sizeof intrinsics[0], 3401d5ac70f0Sopenharmony_ci sizeof intrinsics[0], compar)) != NULL) { 3402d5ac70f0Sopenharmony_ci res = item->func(instance, aargs); 3403d5ac70f0Sopenharmony_ci err = 0; 3404d5ac70f0Sopenharmony_ci } else if ((item = bsearch(&key, snd_intrinsics, 3405d5ac70f0Sopenharmony_ci sizeof snd_intrinsics / sizeof snd_intrinsics[0], 3406d5ac70f0Sopenharmony_ci sizeof snd_intrinsics[0], compar)) != NULL) { 3407d5ac70f0Sopenharmony_ci res = item->func(instance, aargs); 3408d5ac70f0Sopenharmony_ci err = 0; 3409d5ac70f0Sopenharmony_ci } else { 3410d5ac70f0Sopenharmony_ci res = &alsa_lisp_nil; 3411d5ac70f0Sopenharmony_ci } 3412d5ac70f0Sopenharmony_ci } 3413d5ac70f0Sopenharmony_ci if (res == NULL) 3414d5ac70f0Sopenharmony_ci err = -ENOMEM; 3415d5ac70f0Sopenharmony_ci if (err == 0 && result) { 3416d5ac70f0Sopenharmony_ci *result = res; 3417d5ac70f0Sopenharmony_ci } else { 3418d5ac70f0Sopenharmony_ci delete_tree(instance, res); 3419d5ac70f0Sopenharmony_ci } 3420d5ac70f0Sopenharmony_ci 3421d5ac70f0Sopenharmony_ci return 0; 3422d5ac70f0Sopenharmony_ci} 3423d5ac70f0Sopenharmony_ci 3424d5ac70f0Sopenharmony_civoid alsa_lisp_result_free(struct alisp_instance *instance, 3425d5ac70f0Sopenharmony_ci struct alisp_seq_iterator *result) 3426d5ac70f0Sopenharmony_ci{ 3427d5ac70f0Sopenharmony_ci delete_tree(instance, result); 3428d5ac70f0Sopenharmony_ci} 3429d5ac70f0Sopenharmony_ci 3430d5ac70f0Sopenharmony_ciint alsa_lisp_seq_first(struct alisp_instance *instance, const char *id, 3431d5ac70f0Sopenharmony_ci struct alisp_seq_iterator **seq) 3432d5ac70f0Sopenharmony_ci{ 3433d5ac70f0Sopenharmony_ci struct alisp_object * p1; 3434d5ac70f0Sopenharmony_ci 3435d5ac70f0Sopenharmony_ci p1 = get_object1(instance, id); 3436d5ac70f0Sopenharmony_ci if (p1 == NULL) 3437d5ac70f0Sopenharmony_ci return -ENOMEM; 3438d5ac70f0Sopenharmony_ci *seq = p1; 3439d5ac70f0Sopenharmony_ci return 0; 3440d5ac70f0Sopenharmony_ci} 3441d5ac70f0Sopenharmony_ci 3442d5ac70f0Sopenharmony_ciint alsa_lisp_seq_next(struct alisp_seq_iterator **seq) 3443d5ac70f0Sopenharmony_ci{ 3444d5ac70f0Sopenharmony_ci struct alisp_object * p1 = *seq; 3445d5ac70f0Sopenharmony_ci 3446d5ac70f0Sopenharmony_ci p1 = cdr(p1); 3447d5ac70f0Sopenharmony_ci if (p1 == &alsa_lisp_nil) 3448d5ac70f0Sopenharmony_ci return -ENOENT; 3449d5ac70f0Sopenharmony_ci *seq = p1; 3450d5ac70f0Sopenharmony_ci return 0; 3451d5ac70f0Sopenharmony_ci} 3452d5ac70f0Sopenharmony_ci 3453d5ac70f0Sopenharmony_ciint alsa_lisp_seq_count(struct alisp_seq_iterator *seq) 3454d5ac70f0Sopenharmony_ci{ 3455d5ac70f0Sopenharmony_ci int count = 0; 3456d5ac70f0Sopenharmony_ci 3457d5ac70f0Sopenharmony_ci while (seq != &alsa_lisp_nil) { 3458d5ac70f0Sopenharmony_ci count++; 3459d5ac70f0Sopenharmony_ci seq = cdr(seq); 3460d5ac70f0Sopenharmony_ci } 3461d5ac70f0Sopenharmony_ci return count; 3462d5ac70f0Sopenharmony_ci} 3463d5ac70f0Sopenharmony_ci 3464d5ac70f0Sopenharmony_ciint alsa_lisp_seq_integer(struct alisp_seq_iterator *seq, long *val) 3465d5ac70f0Sopenharmony_ci{ 3466d5ac70f0Sopenharmony_ci if (alisp_compare_type(seq, ALISP_OBJ_CONS)) 3467d5ac70f0Sopenharmony_ci seq = seq->value.c.cdr; 3468d5ac70f0Sopenharmony_ci if (alisp_compare_type(seq, ALISP_OBJ_INTEGER)) 3469d5ac70f0Sopenharmony_ci *val = seq->value.i; 3470d5ac70f0Sopenharmony_ci else 3471d5ac70f0Sopenharmony_ci return -EINVAL; 3472d5ac70f0Sopenharmony_ci return 0; 3473d5ac70f0Sopenharmony_ci} 3474d5ac70f0Sopenharmony_ci 3475d5ac70f0Sopenharmony_ciint alsa_lisp_seq_pointer(struct alisp_seq_iterator *seq, const char *ptr_id, void **ptr) 3476d5ac70f0Sopenharmony_ci{ 3477d5ac70f0Sopenharmony_ci struct alisp_object * p2; 3478d5ac70f0Sopenharmony_ci 3479d5ac70f0Sopenharmony_ci if (alisp_compare_type(seq, ALISP_OBJ_CONS) && 3480d5ac70f0Sopenharmony_ci alisp_compare_type(seq->value.c.car, ALISP_OBJ_CONS)) 3481d5ac70f0Sopenharmony_ci seq = seq->value.c.car; 3482d5ac70f0Sopenharmony_ci if (alisp_compare_type(seq, ALISP_OBJ_CONS)) { 3483d5ac70f0Sopenharmony_ci p2 = seq->value.c.car; 3484d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p2, ALISP_OBJ_STRING)) 3485d5ac70f0Sopenharmony_ci return -EINVAL; 3486d5ac70f0Sopenharmony_ci if (strcmp(p2->value.s, ptr_id)) 3487d5ac70f0Sopenharmony_ci return -EINVAL; 3488d5ac70f0Sopenharmony_ci p2 = seq->value.c.cdr; 3489d5ac70f0Sopenharmony_ci if (!alisp_compare_type(p2, ALISP_OBJ_POINTER)) 3490d5ac70f0Sopenharmony_ci return -EINVAL; 3491d5ac70f0Sopenharmony_ci *ptr = (void *)seq->value.ptr; 3492d5ac70f0Sopenharmony_ci } else 3493d5ac70f0Sopenharmony_ci return -EINVAL; 3494d5ac70f0Sopenharmony_ci return 0; 3495d5ac70f0Sopenharmony_ci} 3496