/* Global definitions of limits and constants */ #define MAX_LINE_LENGTH 1024 #define MAX_LINE_TOKENS 1024 typedef enum { ArrayTag, FunctionTag, HybridTag, MonadicOpTag, DyadicOpTag, BoundFunctionTag, /* Function with left arg bound */ LParTag, RParTag, ArrowTag, AssignmentTag, NameTag, } datumTag; typedef enum { AtypeInt, AtypeFloat, AtypeRune, AtypeMixed, AtypeArray, } arrayDataType; typedef enum { OperatortypeDop, OperatortypePrim, OperatortypeHybrid, } operatorType; typedef enum { FunctypeDfn, FunctypePrim, FunctypeOp, FunctypeQuad, FunctypeHybrid, FunctypeTrain, } functionType; typedef enum { /* The numbers are the same as in dyalog */ ESyntax = 2, EIndex = 3, ERank = 4, ELength = 5, EValue = 6, EDomain = 11, ETimeout = 12, /* not in dyalog */ EStack = 13, /* C stack overflow */ ENotImplemented = 100, /* not in dyalog */ } errorCodes; /* Data types */ typedef struct Mixed Mixed; typedef struct Array Array; typedef struct Statement Statement; typedef struct Operator Operator; typedef struct FunctionTrain FunctionTrain; typedef struct Function Function; typedef struct Datum Datum; typedef struct Symbol Symbol; typedef struct Symtab Symtab; typedef struct QuadnameDef QuadnameDef; typedef struct ErrorGuard ErrorGuard; typedef struct DfnFrame DfnFrame; typedef struct ThreadData ThreadData; typedef struct Mail Mail; struct Mixed { u8int type; union { vlong i; double f; Rune r; }; }; #define GetRank(a) ((u8int)((a->info & 0x000000000000000F) >> 0)) #define GetType(a) ((u8int)((a->info & 0x000000000000000F) >> 4)) #define GetStrand(a) ((u8int)((a->info & 0x0000000000000010) >> 8)) #define SetRank(a,v) (a->info ^= ((u64int)(GetRank(a)^v) << 0)) #define SetType(a,v) (a->info ^= ((u64int)(GetType(a)^v) << 4)) #define SetStrand(a,v) (a->info ^= ((u64int)(GetStrand(a)^v) << 8)) struct Array { u64int *shape; union { char *rawdata; vlong *intdata; double *floatdata; Rune *runedata; Mixed *mixeddata; Array **arraydata; Array *prototype; /* only in use when size == 0 and type == AtypeArray */ }; uvlong size; Ref; /* Reference count */ u64int info; /* info is a bitmap of information, divided as follows: * 0-3: 4 bits for the rank (max rank 15) * 4-7: 4 bits for the type (16 options) * 8: 1 bit for stranding * 9-63: unused * NOTE: should only be modified through the macros defined above */ }; struct Statement { int ntoks; int errorguard; /* if guard != nil, is the guard an error guard? */ Datum **toks; Statement *guard; Statement *next; }; struct Operator { operatorType type; int dyadic; union { int code; Rune *dop; }; Symtab *scope; Datum *left; Datum *right; }; struct FunctionTrain { int nfuncs; Function *funcs; }; struct Function { functionType type; union { int code; Rune *dfn; Operator operator; QuadnameDef *quad; FunctionTrain train; }; Symtab *scope; Array *left; }; struct Datum { datumTag tag; int shy; union { Array *array; Statement stmt; Function func; Operator operator; int hybrid; Rune *name; Statement names; }; Ref; /* reference count*/ }; struct Symbol { Rune *name; Datum *value; Datum *(*getfn)(void); void (*setfn)(Datum *); }; struct Symtab { int nsyms; int io; /* index origin */ int div; /* division method */ Symtab *chain; Symbol **syms; }; typedef Array* (*fnmonad)(Array*); typedef Array* (*fndyad)(Array*, Array*); typedef Array* (*opmonad)(Datum *, Array *, Array *); typedef Array* (*opdyad)(Datum *, Datum *, Array *, Array *); struct QuadnameDef { Rune *name; datumTag tag; Datum *(*get)(void); void (*set)(Datum *); fnmonad monadfn; fndyad dyadfn; opmonad monadop; opdyad dyadop; }; struct ErrorGuard { u64int code; /* a bitmask of errors */ int active; /* can the guard be used? */ jmp_buf jmp; Statement *guard; DfnFrame *frame; /* the frame to replace with upon activation of error guard */ ErrorGuard *next; }; struct DfnFrame { Rune *code; Symtab *symtab; Datum *left; Array *right; Datum *lefto; Datum *righto; ErrorGuard *errorguards; /* a linked list of error handlers */ DfnFrame *prev; /* prev in the call stack */ }; struct ThreadData { int id; int stackused; DfnFrame *currentdfn; Mail *mail; Mail *lastmail; int lasterror; int timeout; /* number of milli seconds to timeout */ int timedout; /* true if the recv timed out */ Rune *lasterrormsg; ErrorGuard *globalerrorguard; QLock lock; Rendez newmail; Array *name; }; struct Mail { Array *contents; Mail *next; }; /* Function prototypes for the different source files */ /* main.c */ Datum *evalline(Rune *, Biobuf *, int); /* print.c */ Rune *ppdatum(Datum *); Rune *ppdatums(Datum **, int); Rune *pparray(Array *); Rune *ppoperator(Operator); Rune *ppfunction(Function); /* lexer.c */ Statement *lexlinebio(Biobuf *, int); Statement *lexlinestr(Rune *, int); /* array.c */ Array *mkscalarint(vlong); Array *mkscalarfloat(double); Array *mkscalarrune(Rune); Array *mkrunearray(Rune *); Array *duparray(Array *); Array *duparrayshape(Array *, int); int simplearray(Array *); int simplescalar(Array *); Array *extend(Array *, Array *); int scalarextend(Array *, Array *, Array **, Array **); int commontype(Array *, Array *, Array **, Array **, int); Array *arrayitem(Array *, int); Array *simplifyarray(Array *); int comparearray(Array *, Array *, int); Array *fillelement(Array *); uvlong arrayspaceused(Array *); int arraydepth(Array *, int *); /* eval.c */ Datum *eval(Statement *, int); /* symbol.c */ Symbol *getsym(Rune *, int); void initsymtab(void); DfnFrame *getcurrentdfn(void); DfnFrame *pushdfnframe(Rune *, Symtab *, Datum *, Datum *, Array *, Array *); DfnFrame *dupdfnframe(DfnFrame *); void freedfnframe(DfnFrame *, int); void popdfnframe(void); vlong globalIO(void); void globalIOset(vlong); int globalDIV(void); void globalDIVset(int); Symtab *dupscope(Symtab *); Symtab *getcurrentsymtab(void); void freesymtab(Symtab *); /* memory.c */ void *emalloc(ulong); void *emallocz(ulong, int); void *erealloc(void *, ulong); void checkmem(char *); Array *allocarray(int, int, int); void freearray(Array *); Datum *allocdatum(int, int); void freedatum(Datum *); void freefunction(Function); void freeoperator(Operator); void freestatement(Statement); Function dupfunction(Function); Operator dupoperator(Operator); void freeerrorguards(ErrorGuard *); void freeerrorguard(ErrorGuard *); /* functions.c */ Array *runfunc(Function, Array *, Array *); Array *rundfn(Rune *, Datum *, Datum *, Array *, Array *); Array *runtrain(Function *, int, Array *, Array *, Array *); /* quadnames.c */ void initquadnames(void); Datum *quadnamedatum(QuadnameDef); void outputmain(Datum *); Array *runfile(Array *); /* error.c */ ErrorGuard *newerrorguard(Array *, Statement *); void throwerror(Rune *, int); Rune *errorstr(int); void displayerror(void); /* inverse.c */ Function inverse(Function); /* concurrency.c */ void initthreads(void); int spawnthread(Function, Array *, Array *, Array *); ThreadData *getthreaddata(void); void messagesend(Array *, int); Array *messagerecv(Function, int); Array *runningthreads(void); Array *threadproperty(vlong, vlong); void stackusage(void); /* Monadic functions from function.c */ Array *fnNegate(Array *); Array *fnSign(Array *); Array *fnRecip(Array *); Array *fnExponent(Array *); Array *fnNaturalLog(Array *); Array *fnMatrixInverse(Array *); Array *fnPiTimes(Array *); Array *fnFactorial(Array *); Array *fnRoll(Array *); Array *fnMagnitude(Array *); Array *fnCeiling(Array *); Array *fnFloor(Array *); Array *fnSame(Array *); Array *fnUniqueMask(Array *); Array *fnDepth(Array *); Array *fnTally(Array *); Array *fnMix(Array *); Array *fnSplit(Array *); Array *fnEnclose(Array *); Array *fnDisclose(Array *); Array *fnNest(Array *); Array *fnGradeUp(Array *); Array *fnGradeDown(Array *); Array *fnIndexGenerator(Array *); Array *fnWhere(Array *); Array *fnEnlist(Array *); Array *fnUnique(Array *); Array *fnNot(Array *); Array *fnRavel(Array *); Array *fnTable(Array *); Array *fnShape(Array *); Array *fnReverseLast(Array *); Array *fnReverseFirst(Array *); Array *fnTranspose(Array *); Array *fnExecute(Array *); Array *fnFormat(Array *); Array *fnSelfReference1(Array *); /* Dyadic functions from function.c */ Array *fnPlus(Array *, Array *); Array *fnMinus(Array *, Array *); Array *fnTimes(Array *, Array *); Array *fnDivide(Array *, Array *); Array *fnPower(Array *, Array *); Array *fnLogarithm(Array *, Array *); Array *fnMatrixDivide(Array *, Array *); Array *fnCircular(Array *, Array *); Array *fnBinomial(Array *, Array *); Array *fnDeal(Array *, Array *); Array *fnResidue(Array *, Array *); Array *fnMaximum(Array *, Array *); Array *fnMinimum(Array *, Array *); Array *fnDecode(Array *, Array *); Array *fnEncode(Array *, Array *); Array *fnLeft(Array *, Array *); Array *fnRight(Array *, Array *); Array *fnEqual(Array *, Array *); Array *fnNotEqual(Array *, Array *); Array *fnLessEqual(Array *, Array *); Array *fnLess(Array *, Array *); Array *fnGreater(Array *, Array *); Array *fnGreaterEqual(Array *, Array *); Array *fnMatch(Array *, Array *); Array *fnNotMatch(Array *, Array *); Array *fnOr(Array *, Array *); Array *fnAnd(Array *, Array *); Array *fnNand(Array *, Array *); Array *fnNor(Array *, Array *); Array *fnTake(Array *, Array *); Array *fnDrop(Array *, Array *); Array *fnPick(Array *, Array *); Array *fnPartition(Array *, Array *); Array *fnIndex(Array *, Array *); Array *fnIndexOf(Array *, Array *); Array *fnIntervalIndex(Array *, Array *); Array *fnMembership(Array *, Array *); Array *fnFind(Array *, Array *); Array *fnUnion(Array *, Array *); Array *fnIntersection(Array *, Array *); Array *fnExcluding(Array *, Array *); Array *fnCatenateLast(Array *, Array *); Array *fnCatenateFirst(Array *, Array *); Array *fnReshape(Array *, Array *); Array *fnRotateLast(Array *, Array *); Array *fnRotateFirst(Array *, Array *); Array *fnSelfReference2(Array *, Array *); Array *fnSend(Array *, Array *); /* Monadic operators from operators.c */ Array *opEach(Datum *, Array *, Array *); Array *opSwitch(Datum *, Array *, Array *); Array *opKey(Datum *, Array *, Array *); Array *opOuterProduct(Datum *, Array *, Array *); Array *opSelfReference1(Datum *, Array *, Array *); Array *opReceive(Datum *, Array *, Array *); /* Dyadic operators from operators.c */ Array *opPower(Datum *, Datum *, Array *, Array *); Array *opInnerProduct(Datum *, Datum *, Array *, Array *); Array *opBind(Datum *, Datum *, Array *, Array *); Array *opAtop(Datum *, Datum *, Array *, Array *); Array *opOver(Datum *, Datum *, Array *, Array *); Array *opUnder(Datum *, Datum *, Array *, Array *); Array *opObverse(Datum *, Datum *, Array *, Array *); Array *opSelfReference2(Datum *, Datum *, Array *, Array *); Array *opSpawn(Datum *, Datum *, Array *, Array *); /* Dyadic functions from hybrids.c */ Array *fnReplicateLast(Array *, Array *); Array *fnExpandLast(Array *, Array *); Array *fnReplicateFirst(Array *, Array *); Array *fnExpandFirst(Array *, Array *); /* Monadic operators from hybrids.c */ Array *opReduceLast(Datum *, Array *, Array *); Array *opScanLast(Datum *, Array *, Array *); Array *opReduceFirst(Datum *, Array *, Array *); Array *opScanFirst(Datum *, Array *, Array *); /* Global variables */ extern Biobuf *stdin; /* main.c */ extern int traceeval; /* eval.c */ extern int debugmem; /* memory.c */ extern int datasizes[]; /* array.c */ extern Rune primfuncnames[]; /* functions.c */ extern Rune primmonopnames[]; /* operators.c */ extern Rune primdyadopnames[]; /* operators.c */ extern Rune primhybridnames[]; /* hybrids.c */ extern fnmonad monadfunctiondefs[]; /* functions.c */ extern fndyad dyadfunctiondefs[]; /* functions.c */ extern opmonad monadoperatordefs[]; /* operators.c */ extern opdyad dyadoperatordefs[]; /* operators.c */ extern fndyad hybridfunctiondefs[]; /* hybrids.c */ extern opmonad hybridoperatordefs[]; /* hybrids.c */ extern int arrayalloccounts; /* memory.c */ extern int datumalloccounts; /* memory.c */ extern QuadnameDef quadnames[]; /* quadnames.c */ extern int printprecision; /* print.c */