/* $Id: saol.h,v 1.7 1997/11/20 18:32:39 eds Exp $ */
/* $Log: saol.h,v $
 * Revision 1.7  1997/11/20  18:32:39  eds
 * SASBF integration.
 *
 * Revision 1.8  1997/11/15 00:43:06  luked
 * This is the result of the manual merge from the vendor branch for the
 * release tagged Fribourg_after_integration. I (brian) have probably lost
 * some history, but oh well.
 *
 * This contains the integration work by Eric Scheirer (MIT).
 *
 * Revision 1.5  1997/11/10  22:58:40  eds
 * Cleaned up forward refs for C/C++ integration.
 * Moved DIRSEP in here.
 *
 * Revision 1.4  1997/11/05  20:11:44  eds
 * Added tablemaps.
 * */
/*********************************************************************

This software module was originally developed by

Eric D. Scheirer (MIT Media Laboratory)

in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
as specified by the MPEG-2 NBC/MPEG-4 Audio standard.  ISO/IEC gives
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
software module or modifications thereof for use in hardware or
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
standards. Those intending to use this software module in hardware or
software products are advised that this use may infringe existing
patents. The original developer of this software module and his/her
company, the subsequent editors and their companies, and ISO/IEC have
no liability for use of this software module or modifications thereof
in an implementation.

This software module is hereby released into the public domain.

***********************************************************************/

/* saol.h */

#include <stdio.h> 
#include "aifif.h"

#ifdef _SASBF
#include "sfe_enab.h"
#include "sf_wave_equ.h"
#endif

#ifndef _SAOL_H

#define _SAOL_H

#define PROT_MAL(var,type,name) \
if (!(var = (type *)malloc(sizeof(type)))) \
     interror("malloc() failure in name()\n");
     
#define MAKE_IMPEXP_TAG(imp,exp) (imp ? (exp ? IMPEXP : IMPORTS) : (exp ? EXPORTS : NOTAG))

#define NUM_STD_NAMES 13
#define NUM_MIDI_CHANS 16
#define NUM_MIDI_CC 129

#ifdef _WIN32
#define DIRSEP '\\'
#else
#define DIRSEP '/'
#endif
    
     /* forward references */
struct sa_decoder_struct;
struct inputfile_struct;
struct orc_struct;
struct orc_global_struct;
struct instr_list_struct;
struct opcode_list_struct;
struct instr_decl_struct;
struct opcode_decl_struct;
struct template_decl_struct;
struct formalparam_list_struct;
struct formalparam_struct;
struct global_block_struct;
struct global_decl_struct;
struct mapblock_struct;
struct terminal_list_struct;
struct vardecl_list_struct;
struct send_list_struct;
struct route_list_struct;
struct inputmod_struct;
struct sequence_list_struct;
struct vardecl_struct;
struct namelist_struct;
struct name_struct;
struct tabledef_struct;
struct route_struct;
struct send_struct;
struct seq_struct;
struct block_struct;
struct statement_struct;
struct terminal_struct;
struct exprlist_struct;
struct expr_struct;
struct ptr_index_list_struct;
struct symbol_struct;
struct symtable_struct;
struct bustable_struct;
struct context_struct;
struct scheduler_struct;
struct instr_handle_struct;
struct core_opcode_struct;
struct opval_struct;
struct hostvar_list_struct;
struct event_list_struct;

extern struct std_name_struct {
  char *name;
  int width;
  long type;
} std_names[NUM_STD_NAMES];

/* bindings for local names */
#define LOCAL 1
#define FORMALPARAM 2
#define STANDARD_NAME 3

#define _CRTDBG_MAP_ALLOC

extern void interror(char *s);
extern void parse_error(char *s);
extern void warn(char *s);
void warn_line(char *s, int line);
void parse_error_line(char *s, int line);

typedef struct sa_decoder_struct {
  int synerror;
  int textout;
  int verbose;
  int audioout;
  struct context_struct *global_cx;
  int ksmps;
  char *outfile;
  struct orc_struct *all;
  struct ptr_index_list_struct *all_ptrs;
  int bufsize;
  int replace_count;
  struct scheduler_struct *sched;
  AIF_STRUCT *aifout;
  short *outbuf;
  int outbuf_ct;
  int ended;
  int inct, inchan, maxinsr;
  struct inputfile_struct *in;
  double **inbuf;
  struct bustable_struct *inbus;
  int MIDICCINIT;
  double midicc[NUM_MIDI_CHANS][NUM_MIDI_CC];
#ifdef _SASBF
  struct sfStuffTag sfbanks[MAXLOADEDBANKS];
#endif
} sa_decoder;

typedef struct inputfile_struct {
  char *fn;
  double delay;
  AIF_STRUCT *aif_in;
  int nchan,nbits,srate,done,running,busch;
} inputfile;

struct cmdinfo {
  char *sco;
  char *orc;
  char *out;
  char *midi;
  char *sfbank0;
  char *sfbank1;
  char *bit;
  char *temp;
  char *in[20];
  double delay[20];
  int inct;
  int text;
  int verbose;
  int has_sbf;
} ;

#ifdef _cplusplus
extern "C" {
#endif
  extern struct cmdinfo cmd; 
#ifdef _cplusplus
	   }
#endif

typedef struct orc_struct {
  struct orc_global_struct *g;
  struct instr_list_struct *il;
  struct opcode_list_struct *op;
} orc;

typedef struct orc_global_struct {
  int srate,krate,inchan,outchan;
  int max_actp_ct;
  int framesize;
  struct vardecl_list_struct *gvars;
  struct route_list_struct *routes;
  struct send_list_struct *sends;
  struct inputmod_struct *inmod;
  struct sequence_list_struct *seqs;
  struct symtable_struct *sym;
  struct bustable_struct *bus;
} orc_global;

typedef struct instr_list_struct {
  struct instr_decl_struct *i;
  struct instr_list_struct *next;
} instr_list;

typedef struct opcode_list_struct {
  struct opcode_decl_struct *o;
  struct opcode_list_struct *next;
} opcode_list;

typedef struct instr_decl_struct {
  char *name;
  int max_output_width;
  struct namelist_struct *params;
  struct vardecl_list_struct *localvars;
  struct block_struct *code;
  struct symtable_struct *sym;
  struct bustable_struct *route;
  int width;
  int n_opcodes;
  int framesize;
  int opsize;
  int inchan;
} instr_decl;

typedef struct opcode_decl_struct {
  long type,rate;
  char *name;
  struct formalparam_list_struct *params;
  struct vardecl_list_struct *localvars;
  struct block_struct *code;
  struct symtable_struct *sym;
  int minxsigrate;  /* "this opcode has xsig parameters" */
  int width; /* width of return value */
} opcode_decl;

typedef struct template_decl_struct {
  struct namelist_struct *names;
  struct namelist_struct *params;
  struct namelist_struct *tvars;
  struct mapblock_struct *mapping;
  struct vardecl_list_struct *localvars;
  struct block_struct *code;
} template_decl;

typedef struct formalparam_list_struct {
  struct formalparam_struct *fp;
  struct formalparam_list_struct *next;
} formalparam_list;

typedef struct formalparam_struct {
  long type;
  struct name_struct *n;
  int lineno;
} formalparam;

typedef struct global_block_struct {
  struct global_decl_struct *d;
  struct global_block_struct *next;
} global_block;

typedef struct global_decl_struct {
  /* one line of global declaration in the global block */
  long type;
  int rtparam;
  int lineno;
  struct vardecl_struct *vardecl;
  struct route_struct *routedef;
  struct send_struct *senddef;
  struct inputmod_struct *inmoddef;
  struct seq_struct *seqdef;
} global_decl;

typedef struct mapblock_struct {
  struct terminal_list_struct *tl;
  struct mapblock_struct *next;
} mapblock;

typedef struct terminal_list_struct {
  struct terminal_struct *t;
  struct terminal_list_struct *next;
} terminal_list;

typedef struct vardecl_list_struct {
  struct vardecl_struct *v;
  struct vardecl_list_struct *next;
} vardecl_list;

typedef struct send_list_struct {
  struct send_struct *s;
  struct send_list_struct *next;
} send_list;

typedef struct route_list_struct {
  struct route_struct *r;
  struct route_list_struct *next;
} route_list;

typedef struct inputmod_struct {
  char *instr;
  struct exprlist_struct *params;
} inputmod;

typedef struct sequence_list_struct {
  struct seq_struct *s;
  struct sequence_list_struct *next;
} sequence_list;

typedef struct vardecl_struct {
  long type;
  struct namelist_struct *nl;
  struct tabledef_struct *t;
  char *tablemap_name;
  int lineno;
  int imported;
  int exported;
} vardecl;

typedef struct namelist_struct {
  struct name_struct *n;
  struct namelist_struct *next;
  int lineno;
} namelist;

typedef struct name_struct {
  char *name;
  int width;
} name;

typedef struct tabledef_struct {
  char *name;
  char *gen;
  struct exprlist_struct *params;
} tabledef;

typedef struct route_struct {
  char *bus;
  namelist *instrs;
} routedef;
  
typedef struct send_struct {
  char *instr;
  struct exprlist_struct *pfields;
  namelist *busses;
  struct instr_handle_struct *h;
} senddef;

typedef struct seq_struct {
  namelist *seqlist;
} seqdef;

typedef struct block_struct {
  struct statement_struct *st;
  struct block_struct *next;
} block;

typedef struct statement_struct {
  long type;
  long rate;
  struct block_struct *b;
  struct block_struct *elseb;
  struct expr_struct *lvalue;      /* for assign */
  struct expr_struct *expr;
  struct exprlist_struct *params;  /* for output */
  struct namelist_struct *sfbusses; /* for sfsynth */
  struct exprlist_struct *sfextra;
  char *iname;                    /* for instr */
  char *bus;                      /* for outbus */
  int lineno;
} statement;
  
typedef struct terminal_struct {
  long type;
  char *iname;
  double cval;
  char *csval;
  struct symbol_struct *sym;
} terminal;

typedef struct exprlist_struct {
  struct expr_struct *p;
  struct exprlist_struct *next;
} exprlist;

typedef struct expr_struct {
  struct expr_struct *left, *right, *extra;
  long rate;
  exprlist *params;
  terminal *d;
  int op;
  int lineno;
  int actparam_ct;
  struct core_opcode_struct *co_ptr;
  struct symbol_struct *defn; /* opcode definition */
  struct symbol_struct *oparray_defn;
  int op_offset;
  char *opdummy; /* dummy name for opcode call */
  int width;    /* width of the expression */
} expr;

typedef struct ptr_index_list_struct {
  long index;
  void *ptr;
  struct ptr_index_list_struct *next;
} ptr_index_list;

/* these in parse_nsol.c */

orc *new_orc(void);
global_block *new_gblock(void);
void add_gblock(global_block *gb,global_decl *d);
global_decl *new_global(long type);
void set_global_rtparam(global_decl *g,long param);
void set_global_senddef(global_decl *g,senddef *s);
void set_global_routedef(global_decl *g, routedef *s);
void set_global_inputmod(global_decl *g,inputmod *in);
void set_global_seqdef(global_decl *g,seqdef *s);
void set_global_vardecl(global_decl *g,vardecl *v);

instr_list *new_instr_list(void);
opcode_list *new_opcode_list(void);
void add_instr_list(instr_list *il, instr_decl *i);
void add_opcode_list(opcode_list *op, opcode_decl *o);

instr_decl *new_instr_decl(char *name, namelist *pf, vardecl_list *local,
			   block *code);
opcode_decl *new_opcode_decl(char *name, formalparam_list *fp,
			     vardecl_list *local, block *code, long type);
template_decl *new_template_decl(namelist *names, namelist *pf,
				 namelist *tvars, mapblock *map,
				 vardecl_list *local, block *code);

mapblock *new_mapblock(terminal_list *tl);
void add_mapblock(mapblock *map, terminal_list *tl);
terminal_list *new_terminal_list(terminal *t);
void add_terminal_list(terminal_list *idl, terminal *t);

vardecl *new_vardecl(long type, long taglist, namelist *n);
void set_vardecl_tabledef(vardecl *v, tabledef *t);
tabledef *new_tabledef(char *ident,char *gen, exprlist *params);
void add_namelist(namelist *nl, name *v);
namelist *new_namelist(name *v);
name *new_name(char *ident,int width);

formalparam_list *new_formalparam_list(void);
formalparam *new_formalparam(long type, name *v);
void add_formalparam_list(formalparam_list *fpl, formalparam *fp);

routedef *new_routedef(char *bus, namelist *instrs);
senddef *new_senddef(char *instr,exprlist *pfields,namelist *busses);
inputmod *new_inmod(char *instr,exprlist *params);
seqdef *new_seqdef(namelist *seqlist);

block *new_block(void);
void add_block(block *b,statement *st);

statement *new_statement(long type,expr *e,block *b);
void set_statement_iname(statement *st, char *iname);
void set_statement_params(statement *st, exprlist *el);
void set_statement_lvalue(statement *st, expr *l);
void set_statement_else(statement *st, block *b);
void set_statement_bus(statement *st, char *bus);

expr *new_expr(expr *left,expr *right, expr *extra, int type);
void set_expr_data(expr *p,terminal *d);
void set_expr_params(expr *p,exprlist *l);

terminal *new_terminal(int type,char *cont);

exprlist *new_exprlist(expr *p);
void add_exprlist(exprlist *e,expr *p);

void *ptr_index(long i);
long add_ptr_index(void *p);

void print_block(block *b);
void print_statement(statement *st);
void print_terminal(terminal *t);
void print_expr(expr *p);
void print_exprlist(exprlist *e);

/* these in nsol_syntax.c */
  
typedef struct symbol_struct {
  char *name;
  long type;
  int mark;
  int width;
  int binding;
  int imported, exported;
  int offset;
  struct symtable_struct *symtable_ref;
  void *defn;
  struct symbol_struct *glink;
  struct tabledef_struct *table;
  namelist *tablemap;
} symbol;

typedef struct symtable_struct {
  struct symbol_struct *s;
  struct symtable_struct *next;
} symtable;

typedef struct bustable_struct {
  char *name;
  struct bustable_struct *next;
  int width;
  double **val;
  struct send_struct *send;
} bustable;
  
orc_global *new_orc_global(void);
void sort_global_decls(sa_decoder *sa,orc_global *g, global_block *gl);
void deal_with_template(sa_decoder *sa,template_decl *t);

vardecl_list *copy_vardecl_list(vardecl_list *vdl);
namelist *copy_namelist(namelist *nl);
vardecl *copy_vardecl(vardecl *vd);
name *copy_name(name *v);
block *copy_block(block *b);
tabledef *copy_tabledef(tabledef *t);
statement *copy_statement(statement *st);
expr *copy_expr(expr *e);
exprlist *copy_exprlist(exprlist *el);
terminal *copy_terminal(terminal *t);

vardecl_list *new_vardecl_list(void);
void add_vardecl_list(vardecl_list *vdl,vardecl *v);

route_list *new_route_list(routedef *r);
void add_route_list(route_list *rl,routedef *r);
send_list *new_send_list(senddef *s);
void add_send_list(send_list *sl,senddef *s);
sequence_list *new_sequence_list(seqdef *s);
void add_sequence_list(sequence_list *sl,seqdef *s);

void print_global(sa_decoder *sa);

void build_symtable(void);
void rate_checking(sa_decoder *);
symtable *new_symtable(sa_decoder *,int use_std_names);
bustable *make_bus_table(sa_decoder *,send_list *sl);
void build_sym_table(sa_decoder *sa);
symbol *add_sym_table_name(symtable *t, char *name, long type, void *ref);
void add_sym_table_namelist(sa_decoder *sa,symtable *t, namelist *nl, long type,
			    long gtag, int binding);
void add_sym_table_decls(sa_decoder *sa,symtable *t, vardecl_list *vdl);
void add_sym_table_fplist(symtable *t, formalparam_list *fpl);
void dump_sym_table(symtable *t);

void check_sym_ref_vardecls(sa_decoder *sa,symtable *t, vardecl_list *vdl);
void check_sym_ref_exprlist(sa_decoder *sa, symtable *t, exprlist *el);
void check_sym_ref_expr(sa_decoder *sa,symtable *t, expr *p);
void check_sym_ref_block(sa_decoder *sa,symtable *t, block *b);
void check_opcode_width(sa_decoder *sa,opcode_decl *op);
symtable *remove_unused_symbols(sa_decoder *sa,instr_decl *,symtable *t);
symtable *remove_sym_table(symtable *, symtable *, symtable **);
void check_sym_ref_statement(sa_decoder *sa,symtable *t, statement *b);
void check_instr_ref_namelist(symtable *t, namelist *nl);
void check_instr_ref_name(symtable *t, char *name);
int check_opcode_paramlist(sa_decoder *sa,symtable *t, exprlist *el, formalparam_list *fpl,
			   char *opname, int lineno);

symbol *get_sym_decl(symtable *t, char *name);
symbol *get_sym_decl_last(symtable *t, char *name);
symbol *get_var_decl(symtable *t, char *name);
symbol *get_opcode_decl(symtable *t, char *name);
symbol *get_instr_decl(symtable *t, char *name);
symbol *get_table_decl(symtable *t, char *name);

/* void add_bus_table(send_list *sl); */
bustable *get_bus(bustable *bt, char *name);
void check_bus(bustable *bt, char *name);
void attach_route(sa_decoder *sa,symtable *t, char *busname, namelist *nl);
void set_bus_width(bustable *bt, int width);
void set_instr_inchan(sa_decoder *sa, instr_decl *id);

/* in saol_macro.c */
void macro_expand(sa_decoder *sa);
#endif
