/* Copyright (c) 1993 Stephen F. White */ #ifndef COOL_H #define COOL_H #include "os.h" #undef IN #undef IGNORE #undef ECHO #undef CTIME #include "string.h" #define raise(x) cool_raise(x) /* so as not to conflict with signal.h */ /* * useful macros */ #define Arraysize(x) (int) (sizeof(x) / sizeof(x[0])) #ifndef MIN #define MIN(A, B) ((A) < (B) ? (A) : (B)) #endif #ifndef MAX #define MAX(A, B) ((A) > (B) ? (A) : (B)) #endif #define INT_SIZE 10 /* size of buffer big enough to hold an int */ #define LONG_SIZE 20 /* size of buffer big enough to hold a long */ #define STRING_INIT_SIZE 16 /* initialize length of String values */ #define STRING_DOUBLING /* double Strings when needed */ #define STRING_GROW_BY 32 /* or use this to increment linearly */ #define CODE_INIT_SIZE 32 #define SYM_INIT_SIZE 16 #define STACK_SIZE 128 #define HASH_INIT_SIZE 37 #define HASH_INIT_LOAD 2 #define MAX_TOKEN_LEN 40 /* maximum length of internal token names */ #define MAX_PATH_LEN 1024 /* maximum length of path names */ #define SYS_OBJ 0 #define ROOT_OBJ 1 /* if defined, the server will force 1 root */ #define MAX_AGE 20 /* default max. recursion, essentially */ #define MAX_TICKS 10000 /* default maximum instructions per task */ #define PLAYER_PORT 7777 /* default player port */ typedef short Serverid; typedef int Playerid; #define NOTHING (-1) /* represents an invalid player */ #define BLOCK_SIZE 512 /* size of input block */ #define UDP_BLOCK_SIZE 2048 /* size of input block for YO packets */ #define PROGDIR "/tmp" /* temp directory for COOL programs */ #define RUNDIR "online" /* directory for on-line files */ #define MALLOC(what, number) (what *) cool_malloc((number) * sizeof(what)) #define FREE(what) cool_free( (void *) what) /* * timing stuff */ #define MSG_TIMEOUT 30 /* message timeout, in seconds */ #define MSG_RETRY 1500 /* message retry interval, in msec */ #define EXP_BACKOFF /* define this for exponential backoff */ #define LOCK_TIMEOUT 30 /* lock timeout, in seconds */ /* * input quotas */ #define MAX_CMDS 100 /* maximum commands in a burst */ #define MSEC_PER_CMD 1000 /* time between commands after a burst */ #define OUTBOUND_TIMEOUT 5 /* timeout for gethostbyname() */ #define MAX_OUTPUT 16384 /* maximum amount of queued output */ #define CONNECT_MSG "*** Connected ***\r\n" #define DISCONNECT_MSG "*** Disconnected ***\r\n" #define TRANSFER_MSG1 "*** Transferring to new connection ***\r\n" #define TRANSFER_MSG2 "*** Reconnecting to old connection ***\r\n" typedef enum Type_spec { STR, NUM, OBJ, LIST, MAP, ERR, PC } Type_spec; typedef struct Var Var; typedef struct Objid { short server; /* server id (0 == this server) */ int id; /* object id */ } Objid; typedef struct List { int len; /* length of list */ int mem; /* memory actually allocated */ int ref; /* reference count */ Var *el; /* elements of list */ } List; typedef struct MapPair MapPair; typedef enum Error { E_NONE, E_TYPE, E_RANGE, E_INVIND, E_DIV, E_MAXREC, E_METHODNF, E_VARNF, E_VERBNF, E_FOR, E_PERM, E_SERVERNF, E_SERVERDN, E_OBJNF, E_MESSAGE, E_TIMEOUT, E_STACKUND, E_STACKOVR, E_INTERNAL, E_FILE, E_ARGTYPE, E_NARGS, E_TICKS, E_TERM, E_MAPNF } Error; #define NERRS 25 /* * cannot ignore or catch these errors */ #define NOIGNORE(err) (err == E_STACKUND || err == E_STACKOVR \ || err == E_INTERNAL || err == E_TICKS) typedef struct HashT { int size; /* width of hash table */ int num; /* number of elements in table */ int ref; /* reference count */ void **table; /* have to use void *, for multiple datatypes */ } HashT; typedef HashT Map; struct Var { Type_spec type; union { int num; /* number */ Objid obj; /* object id */ String *str; /* string header */ List *list; /* list header */ Map *map; /* map header */ Error err; /* error */ } v; }; struct MapPair { Var from; /* key of map element */ Var to; /* data of map element */ MapPair *next; }; typedef struct Symbol { int ref; /* local object references to symbol */ String *s; /* symbol */ } Symbol; #define ISTRUE(x) ((x.type == NUM && x.v.num) \ || (x.type == STR && x.v.str->str[0]) \ || (x.type == OBJ && x.v.obj.id >= 0) \ || (x.type == LIST && x.v.list->len)) typedef int Inst; typedef struct Method Method; typedef struct Verbdef Verbdef; typedef struct Vardef Vardef; typedef struct Lock Lock; struct Lock { String *name; int added_by; /* msgid which added this lock */ Lock *next; }; typedef struct Object { Objid id; /* object's id */ int ref; /* reference count */ List *parents; /* parent list */ Lock *locks; HashT *methods; /* method list, hashed */ Verbdef *verbs; HashT *vars; /* variables, hashed */ int var_hashsize; int nsymb; /* number of symbols */ int st_size; /* memory actually allocated for symbols */ Symbol *symbols; /* symbol table */ int last_search; /* generational flag, last search on object */ /* kudos to greg hudson for the idea */ } Object; enum eh { EH_DEFAULT, EH_IGNORE, EH_CATCH }; struct Method { int name; /* index into symbol table */ int ninst; /* number of instructions in machine */ Inst *code; /* the compiled code */ enum eh ehandler[NERRS]; /* error handler */ Vardef *vars; /* local variables */ int ref; /* reference count */ Method *next; /* next method in linked list */ int blocked:1; /* non-overrideable ("nomask") flag */ }; struct Verbdef { int verb; /* name of verb */ int prep; /* preposition, or -1 for none */ int method; /* method to call */ Verbdef *next; /* next verbdef in linked list */ }; struct Vardef { int name; /* index into symbol table */ Var value; /* value */ Vardef *next; /* next vardef in linked list */ }; enum state { RUNNING, /* program is running */ STOPPED, /* program stopped by return or end of code */ HALTED, /* program halted by method called */ RAISED, /* program stopped by raise() */ BLOCKED }; /* program blocked on event */ typedef void (*PFV) (void); typedef enum Sys_sym { BLANK, INIT, PARSE, BOOT_SERVER, CONNECT_SERVER, DISCONNECT_SERVER, SYM_CONNECT, SYM_DISCONNECT, RAISE, RETURN } Sys_sym; enum arg_type { none, NUM_ARG, ID_ARG, STR_ARG, VARNO_ARG }; struct bf_entry { int num; const char *name; int minargs; int maxargs; }; typedef struct Op_entry { int opcode; const char name[MAX_TOKEN_LEN]; PFV func; int nargs; enum arg_type arg_type[3]; struct bf_entry *builtin; } Op_entry; #endif /* !COOL_H */