/* acid.h */
enum
{
	Eof		= -1,
	Strsize		= 4096,
	Hashsize	= 128,
	Maxarg		= 512,
	NFD		= 100,
	Maxproc		= 50,
	Maxval		= 10,
	Mempergc	= 1024*1024,
};

#pragma varargck type "L"	void

typedef struct Node	Node;
typedef struct String	String;
typedef struct Lsym	Lsym;
typedef struct List	List;
typedef struct Store	Store;
typedef struct Gc	Gc;
typedef struct Strc	Strc;
typedef struct Rplace	Rplace;
typedef struct Ptab	Ptab;
typedef struct Value	Value;
typedef struct Type	Type;
typedef struct Frtype	Frtype;

Extern int	kernel;
Extern int	remote;
Extern int rdebug;
Extern int remfd;
Extern int	protodebug;
Extern int	text;
Extern int	silent;
Extern Fhdr	fhdr;
Extern int	line;
Extern Biobuf*	bout;
Extern Biobuf*	io[32];
Extern int	iop;
Extern char	symbol[Strsize];
Extern int	interactive;
Extern Node*	code;
Extern int	na;
Extern int	wtflag;
Extern Map*	cormap;
Extern Map*	symmap;
Extern Lsym*	hash[Hashsize];
Extern long	dogc;
Extern Rplace*	ret;
Extern char*	filename;
Extern char*	aout;
Extern int	gotint;
Extern long	flen;
Extern Gc*	gcl;
Extern int	stacked;
Extern jmp_buf	err;
Extern Node*	prnt;
Extern Node*	fomt;
Extern List*	tracelist;
Extern int	initialising;
Extern int	quiet;
extern void	(*expop[])(Node*, Node*);
#define expr(n, r) (r)->nstore.comt=0; (*expop[(n)->op])(n, r);

enum
{
	TINT,
	TFLOAT,
	TSTRING,
	TLIST,
	TCODE,
};

struct Type
{
	Type*	next;
	int	offset;
	char	fmt;
	char	depth;
	Lsym*	type;
	Lsym*	tag;
	Lsym*	base;
};

struct Frtype
{
	Lsym*	var;
	Type*	type;
	Frtype*	next;
};

struct Ptab
{
	int	pid;
	int	ctl;
};
Extern Ptab	ptab[Maxproc];

struct Rplace
{
	jmp_buf	rlab;
	Node*	stak;
	Node*	val;
	Lsym*	local;
	Lsym**	tail;
};

struct Gc
{
	char	gcmark;
	Gc*	gclink;
};

struct Store
{
	char	fmt;
	Type*	comt;
	union {
		vlong	sival;
		double	sfval;
		String*	sstring;
		List*	sl;
		Node*	scc;
	} u0;
};

struct List
{
	Gc	lgc;
	List*	next;
	char	type;
	Store	lstore;
};

struct Value
{
	char	set;
	char	type;
	Store	vstore;
	Value*	pop;
	Lsym*	scope;
	Rplace*	ret;
};

struct Lsym
{
	char*	name;
	int	lexval;
	Lsym*	hash;
	Value*	v;
	Type*	lt;
	Node*	proc;
	Frtype*	local;
	void	(*builtin)(Node*, Node*);
};

struct Node
{
	Gc	ngc;
	char	op;
	char	type;
	Node*	left;
	Node*	right;
	Lsym*	sym;
	Store	nstore;
};
#define ZN	(Node*)0

struct String
{
	Gc	sgc;
	char	*string;
	int	len;
};

List*	addlist(List*, List*);
List*	al(int);
Node*	an(int, Node*, Node*);
void	append(Node*, Node*, Node*);
int	bool(Node*);
void	build(Node*);
void	call(char*, Node*, Node*, Node*, Node*);
void	checkqid(int, int);
void	cmd(void);
Node*	con(int);
List*	construct(Node*);
void	ctrace(int);
void	decl(Node*);
void	defcomplex(Node*, Node*);
void	deinstall(int);
void	delete(List*, int n, Node*);
void	detach(void);
void	dostop(int);
Lsym*	enter(char*, int);
void	error(char*, ...);
void	execute(Node*);
void	fatal(char*, ...);
ulong	findframe(ulong);
void	flatten(Node**, Node*);
void	gc(void);
char*	getstatus(int);
void*	gmalloc(long);
void	indir(Map*, ulong, char, Node*);
void install(int);
void	installbuiltin(void);
void	kinit(void);
int	Lfmt(Fmt*);
int	listcmp(List*, List*);
int	listlen(List*);
List*	listvar(char*, long);
void	loadmodule(char*);
void	loadvars(void);
Lsym*	look(char*);
void	ltag(char*);
void	setup_os_notify(void);
void	marklist(List*);
Lsym*	mkvar(char*);
void	msg(int, char*);
void	notes(int);
int	nproc(char**);
void	nthelem(List*, int, Node*);
int	numsym(char);
void	odot(Node*, Node*);
int	opentty(char*, int);
void	closetty(int);
void	pcode(Node*, int);
void	pexpr(Node*);
int	popio(void);
void	pstr(String*);
void	pushfile(char*);
void	pushstr(Node*);
ulong	raddr(char*);
void	readtext(char*);
int	remcondset(char, ulong);
int	remcondstartstop(int);
int	remget(struct segment*, ulong, long, char*, int);
int	remoteio(int, char*, char*, int);
int	remote_read(int, char*, int);
int	remote_write(int, char*, int);
int	remput(struct segment*, ulong, long, char*, int);
void	restartio(void);
vlong	rget(Map*, char*);
String	*runenode(Rune*);
char*	runcmd(char*);
int	scmp(String*, String*);
void	setdbg_opt(char, int);
int	sendremote(int, char*);
void	sproc(int);
String*	stradd(String*, String*);
String*	strnode(char*);
String*	strnodlen(char*, int);
char*	mysystem(void);
void	trlist(Map*, ulong, ulong, Symbol*);
void	unwind(void);
void	userinit(void);
void	varreg(void);
void	varsym(void);
char*	waitfor(int);
void	whatis(Lsym*);
void	windir(Map*, Node*, Node*, Node*);
void	yyerror(char*, ...);
int	yylex(void);
int	yyparse(void);

enum
{
	ONAME,
	OCONST,
	OMUL,
	ODIV,
	OMOD,
	OADD,
	OSUB,
	ORSH,
	OLSH,
	OLT,
	OGT,
	OLEQ,
	OGEQ,
	OEQ,
	ONEQ,
	OLAND,
	OXOR,
	OLOR,
	OCAND,
	OCOR,
	OASGN,
	OINDM,
	OEDEC,
	OEINC,
	OPINC,
	OPDEC,
	ONOT,
	OIF,
	ODO,
	OLIST,
	OCALL,
	OCTRUCT,
	OWHILE,
	OELSE,
	OHEAD,
	OTAIL,
	OAPPEND,
	ORET,
	OINDEX,
	OINDC,
	ODOT,
	OLOCAL,
	OFRAME,
	OCOMPLEX,
	ODELETE,
	OCAST,
	OFMT,
	OEVAL,
	OWHAT,
};
