1 /* 2 * $Id: ydata.h,v 1.9 2010-07-03 19:42:31 dhmunro Exp $ 3 * Declare structures and functions for Yorick's "private" data. 4 */ 5 /* Copyright (c) 2005, The Regents of the University of California. 6 * All rights reserved. 7 * This file is part of yorick (http://yorick.sourceforge.net). 8 * Read the accompanying LICENSE file for details. 9 */ 10 11 /* use the functions declared in yapi.h to retrieve information 12 * for use by new built-in functions - the functions and data 13 * structures here are for internal use by the interpreter, and 14 * are subject to change as the interpreter evolves 15 */ 16 17 #ifndef YDATA_H 18 #define YDATA_H 19 20 #include "yapi.h" 21 22 #include "hash.h" 23 #include "binio.h" 24 25 /* "Universal" data types -- arrays of numbers, text strings, and 26 data structures compounded of these -- are declared in binio.h. 27 This file contains declarations of Yorick's "private" data types 28 -- interpreted functions, built-in functions, index ranges -- 29 the virtual function tables, Yorick's program stack, and the like. */ 30 31 /*--------------------------------------------------------------------------*/ 32 33 /* The DataBlock and Symbol structures are fundamental to the 34 Yorick interpreter. 35 36 A DataBlock is a virtual base class (in C++ parlance) for storing 37 information of an unknown data type. The 2nd edition of K&R blesses 38 the programming style I have adopted here in the last paragraph of 39 section A8.3; namely, a struct is derived (in the sense of a C++ 40 derived class) from a DataBlock if its first members match the 41 members of the generic DataBlock struct. In this case, a DataBlock 42 consists of a reference counter and an Operations table. The 43 Operations table is a virtual function table defining all of the 44 operations whose precise meaning depends on the particular data 45 type. For example, addition of two ints is quite a different thing 46 than addition of two doubles, so the Add member of the Operations 47 table for an int and the Add member of the Operations table for a 48 double will point to different functions. 49 50 A Symbol represents a variable or an intermediate result in an 51 expression evaluation; Yorick's global symtab and program stack 52 consist of Symbols. Symbols are distinct from DataBlocks in an 53 attempt to speed up simple operations on common data types (that is, 54 on ints, longs, and doubles), without drastically increasing the 55 number of virtual functions. Binary operations cause the conflict 56 between table size and speed, since for a fast binary function, each 57 possible ordered *pair* of operand types requires a separate function. 58 Since there are only 4 different Symbol types, the OpTable virtual 59 function table is not too unwieldy; with about 16 DataBlock types, 60 a comparable Operations table would have to be 10 times as large. 61 */ 62 63 typedef struct DataBlock DataBlock; 64 struct DataBlock { 65 int references; /* reference counter */ 66 Operations *ops; /* virtual function table */ 67 }; 68 69 typedef struct Symbol Symbol; 70 71 /* OpTable is required to define Symbol, and is itself defined below. */ 72 typedef struct OpTable OpTable; /* operations on a Symbol */ 73 74 /* A range function takes an Array and an integer indicating which index 75 of the array to operate on (0 for fastest varying, 1 for next, etc.). 76 The result of the operation is placed on top of the stack, and the 77 function returns 0 if the result Array (the result MUST be an Array) 78 has the same rank as the input Array, 1 if the result array has 79 reduced rank (the input index is missing in the result). */ 80 typedef int RangeFunc(Array *array, int index); /* also in yio.h */ 81 82 typedef void VMaction(void); 83 typedef union Instruction Instruction; 84 union Instruction { 85 VMaction *Action; /* do something */ 86 int count; /* parameter count */ 87 long index; /* index into global symbol table */ 88 long displace; /* branch displacement */ 89 Symbol *constant; /* pointer into function's constant table */ 90 RangeFunc *rf; 91 }; 92 93 typedef union SymbolValue SymbolValue; 94 union SymbolValue { 95 int i; /* intScalar */ 96 long l; /* longScalar */ 97 double d; /* doubleScalar */ 98 DataBlock *db; /* dataBlockSym */ 99 100 /* A fifth Symbol type, referenceSym, is used ONLY on the stack in 101 function parameter lists, i.e.- as an argument to the Eval function 102 (see array.c and fnctn.c). On the stack, a Symbol with ops==0 103 is used to mark keyword parameters and function return addresses 104 as well (again, see array.c and fnctn.c). */ 105 106 /* The offset and pc are used keywords and returnSym; 107 offset is also used in referenceSym (see referenceSym below): */ 108 Instruction *pc; 109 long offset; 110 }; 111 112 struct Symbol { 113 OpTable *ops; /* virtual function table */ 114 long index; /* into global symtab (for replacing local variables) */ 115 SymbolValue value; /* appropriate member selected by ops */ 116 }; 117 118 /*--------------------------------------------------------------------------*/ 119 120 /* The structures derived from DataBlock are the objects the Yorick 121 interpreter works with. 122 123 Array, StructDef, and IOStream are DataBlocks defined in 124 binio.h. These are the types necessary for representing "universal" 125 data in memory and on disk. 126 127 Function is a list of virtual machine instructions, which results 128 from parsing interpreter input. The source file and line numbers 129 corresponding to the function are recorded, although this information 130 is only used for error messages. 131 132 BIFunction points to a builtin (i.e.- compiled) function, which 133 must have type BuiltIn. A compiled function may be called from the 134 Yorick interpreter by defining a wrapper of type BuiltIn which pulls 135 its arguments off of the Yorick program stack, converts them to the 136 appropriate types, then calls the compiled function. The Codger 137 code generator can generate simple wrapper functions automatically. 138 */ 139 140 /* LValue represents an object into which an Array may be stored, or 141 from which an Array can be fetched. It has a data type (StructDef), 142 dimensions, and an optional list of Strider (see below) specifications 143 to indicate how the data is to be extracted as a multidimensional 144 subset of a larger object. An LValue represents data on disk or in 145 memory, according to whether its type is a disk or memory StructDef. 146 147 LValues are used for 3 purposes: 148 (1) As a temporary describing the result of an indexing operation. 149 Further indexing, or other operations not immediately 150 requiring data, may then procede without actually fetching 151 the data. This is crucial for extracting parts of complicated 152 data structures (especially data in disk files), which 153 often requires several member extractions and/or subarray 154 specifications to get to the interesting data. 155 (2) As an Array with "remote" data -- the result of a reshape 156 operation. This is Yorick's version of FORTRAN equivalence 157 statements. 158 (3) To point to data not owned by the Yorick interpreter -- 159 for example, a global data structure from a compiled routine, 160 like a FORTRAN common block. 161 */ 162 typedef struct LValue LValue; 163 struct LValue { 164 int references; /* reference counter */ 165 Operations *ops; /* virtual function table */ 166 Array *owner; /* 0 if data is in disk file or unowned */ 167 Member type; /* full data type of result, base x[]..[] */ 168 union { 169 long d; /* byte address on disk if file!=0 */ 170 char *m; /* memory address if file==0 */ 171 } address; 172 Strider *strider; /* hierachy of strides to take */ 173 /* If non-0, the strider MUST be set up to include a list element 174 for any contiguous blocks of type->base.size; 175 the Gather and Scatter routines in bcast.c, and the YRead and 176 YWrite routines recognize that no loop is required for 177 contiguous blocks. */ 178 }; 179 180 typedef struct Function Function; 181 struct Function { 182 int references; /* reference counter */ 183 Operations *ops; /* pointer to virtual functions */ 184 Symbol *constantTable; /* constants used by this function */ 185 long nConstants; /* length of constantTable */ 186 int nReq; /* worst case number of stack elements required */ 187 int nPos, nKey, nLocal; /* number of positionals, keywords, and locals */ 188 long hasPosList; /* bit 0- 0 unless declared with .. parameter 189 bits 1-30 set if that positional parameter 190 marked as an output */ 191 int errup; /* to mark func to enter caller for dbug */ 192 long isrc; /* index of source file from RecordSource */ 193 Instruction code[1]; /* virtual machine instructions begin here */ 194 /* First 1+nPos+hasPosList+nKey+nLocal instructions are code[i].index 195 for function name (in definition), positional parameters, 196 optional .. ("*va*") parameter, keyword parameters, and local variables. 197 End of code is marked by code[i].Action==&Return, code[i+1].Action==0, 198 code[i+2].index==(length of code). */ 199 }; 200 201 /* Built-in functions are called with a single argument -- the number 202 of actual parameters on the top of the stack (keyword parameters 203 count as two). The function should leave its result on the top of 204 the stack. As many other items may be left on the stack as 205 necessary, but if more than the input parameters plus one scratch 206 plus the return value are necessary, then the built-in must call 207 CheckStack. (The built-in may clean up the stack itself, as long 208 as its result is at or above sp-n when it returns.) */ 209 typedef void BuiltIn(int); 210 211 typedef struct BIFunction BIFunction; 212 struct BIFunction { 213 int references; /* reference counter */ 214 Operations *ops; /* pointer to virtual functions */ 215 BuiltIn *function; 216 long index; /* to globTab -- shorthand for function name */ 217 }; 218 219 /* Auto-loaded functions are special interpreted functions which 220 trigger parsing of their source file when first used. */ 221 typedef struct autoload_t autoload_t; 222 struct autoload_t { 223 int references; /* reference counter */ 224 Operations *ops; /* virtual function table */ 225 long ifile; /* index into table of autoload files */ 226 long isymbol; /* global symtab index */ 227 autoload_t *next; /* linked list for each ifile */ 228 }; 229 230 /* TextStream is a "foreign" data block defined in ascio.c */ 231 typedef struct TextStream TextStream; 232 233 /*--------------------------------------------------------------------------*/ 234 235 /* Range - A range triple min:max:inc or rf:min:max:inc 236 237 Memory management for these objects is via a special block allocator 238 for reasons of efficiency. 239 */ 240 241 typedef struct Range Range; 242 struct Range { 243 int references; /* reference counter */ 244 Operations *ops; /* virtual function table */ 245 long min, max, inc; /* min:max:inc, inc guaranteed non-zero */ 246 int nilFlags; /* + 1 if min is nil (:N) 247 + 2 if max is nil (N:) 248 Note: if inc is nil, inc==1 249 + 4 if marked index (+:min:max:inc) 250 + 8 if pseudo index (-:min:max:inc) 251 +16 if rubber index (..) 252 +32 if nullifying index, e.g.- where(0) */ 253 #define R_MINNIL 1 254 #define R_MAXNIL 2 255 #define R_MARKED 4 256 #define R_PSEUDO 8 257 #define R_RUBBER 16 258 #define R_NULLER 32 259 RangeFunc *rf; /* possible range function, rf:min:max:inc */ 260 }; 261 262 /*--------------------------------------------------------------------------*/ 263 264 /* Operations on DataBlocks take Operand arguments -- this is an 265 abbreviated sort of LValue, allowing reshaped Arrays (in LValues) or 266 scalar Symbols to interact efficiently with DataBlocks. The data 267 type of an operand may mutate before it is actually used, hence 268 an Operand includes the Symbol *owner, which will be updated as 269 the Operand changes. */ 270 typedef struct Operand Operand; 271 struct Operand { 272 Symbol *owner; 273 Operations *ops; /* NEVER &lvalueOps */ 274 int references; /* 0 if owner points to temporary Array */ 275 Member type; /* all 0 unless ops is an Array type */ 276 void *value; /* 0 unless ops is an Array type */ 277 }; 278 279 typedef void StackOp(void); 280 281 struct OpTable { /* virtual function table for Symbol */ 282 int id; /* index into binary operations array (0-3) */ 283 Operand *(*FormOperand)(Symbol *owner, Operand *op); 284 StackOp *ToChar, *ToShort, *ToInt, *ToLong, *ToFloat, *ToDouble, *ToComplex; 285 StackOp *Negate, *Complement, *Not, *True; 286 StackOp *Add[4], *Subtract[4], *Multiply[4], *Divide[4], *Modulo[4], 287 *Power[4]; 288 StackOp *Equal[4], *NotEqual[4], 289 *Greater[4], *Less[4], *GreaterEQ[4], *LessEQ[4]; 290 StackOp *ShiftL[4], *ShiftR[4]; 291 StackOp *Or[4], *And[4], *Xor[4]; 292 }; 293 294 /* Virtual function tables for the 5 Symbol types: */ 295 PLUG_API OpTable intScalar; 296 PLUG_API OpTable longScalar; 297 PLUG_API OpTable doubleScalar; 298 PLUG_API OpTable dataBlockSym; 299 PLUG_API OpTable referenceSym; /* referenceSym is not a "complete" Symbol 300 in the sense that the parser ensures it 301 never appears in a binary operation 302 ops - &referenceSym 303 index - to globTab entry 304 value.offset - stack offset (for Return only) */ 305 PLUG_API OpTable returnSym; /* returnSym is not a "complete" Symbol 306 in the sense that the parser ensures it 307 never appears in a binary operation 308 ops - &returnSym 309 index - (unused) 310 value.pc - VM program counter (for Return only) */ 311 /* Keywords may also appear on the program stack-- 312 these are marked by ops==0. */ 313 314 /*--------------------------------------------------------------------------*/ 315 316 /* Unary operators take an Operand*, perform the required operation, 317 and replace the Symbol at op->owner with the result. */ 318 typedef void UnaryOp(Operand *op); 319 320 /* Binary operators take two Operand* representing the left and right 321 operands, perform the required operation, and replace the Symbol 322 at l->owner with the result. The r->owner may be changed as well, 323 if the right operand had to be type converted or broadcast. */ 324 typedef void BinaryOp(Operand *l, Operand *r); 325 326 /* Type promotion operators take two Operand*s, and do 327 arithmetic promotion (using one stack element for protected 328 scratch space). Either the left or the right Symbol (but not both) 329 is updated, and the operator returns the Operations* for the result 330 type, or 0 if the required promotion operation was impossible. 331 Legal types for promotion are: char, short, int, long, float, double, 332 complex, for either Array or LValue (7 Array types plus LValue). 333 Non-numeric types return dl->ops if the dl->ops==dr->ops, else 0. */ 334 typedef Operations *PromoteOp(Operand *l, Operand *r); 335 336 typedef void MemberOp(Operand *op, char *name); 337 338 struct Operations { /* virtual function table for DataBlock */ 339 void (*Free)(void *); /* crucial member for Unref -- first in struct 340 to allow alternate Operations to be used */ 341 int typeID; /* unique type ID number */ 342 int isArray; /* 1 if this is one of the Array DataBlocks */ 343 int promoteID; /* index into Promote array (0-7, 7 means illegal) */ 344 char *typeName; /* ASCII name describing this data type */ 345 PromoteOp *Promote[8]; 346 UnaryOp *ToChar, *ToShort, *ToInt, *ToLong, *ToFloat, *ToDouble, *ToComplex; 347 UnaryOp *Negate, *Complement, *Not, *True; 348 BinaryOp *Add, *Subtract, *Multiply, *Divide, *Modulo, *Power; 349 BinaryOp *Equal, *NotEqual, *Greater, *GreaterEQ; 350 BinaryOp *ShiftL, *ShiftR, *Or, *And, *Xor; 351 BinaryOp *Assign; /* WARNING- first parameter non-standard, see ops3.c */ 352 UnaryOp *Eval; /* WARNING- parameter non-standard, see ops3.c */ 353 UnaryOp *Setup; /* see array.c -- set up for array indexing */ 354 MemberOp *GetMember; /* WARNING- parameter non-standard, see ops3.c */ 355 BinaryOp *MatMult; /* WARNING- non-standard semantics, see ops.c */ 356 UnaryOp *Print; /* uses PrintFunc to output each line, see yio.h */ 357 }; 358 359 /* Virtual function tables for the DataBlock types: */ 360 PLUG_API Operations charOps; 361 PLUG_API Operations shortOps; 362 PLUG_API Operations intOps; 363 PLUG_API Operations longOps; 364 PLUG_API Operations floatOps; 365 PLUG_API Operations doubleOps; 366 PLUG_API Operations complexOps; 367 PLUG_API Operations stringOps; 368 PLUG_API Operations pointerOps; 369 PLUG_API Operations structOps; 370 371 PLUG_API Operations rangeOps; 372 PLUG_API Operations lvalueOps; 373 PLUG_API Operations voidOps; 374 PLUG_API Operations functionOps; 375 PLUG_API Operations builtinOps; 376 PLUG_API Operations structDefOps; 377 PLUG_API Operations streamOps; 378 PLUG_API Operations textOps; 379 PLUG_API Operations listOps; 380 PLUG_API Operations auto_ops; 381 382 /* generic operators are needed to implement foreign objects */ 383 PLUG_API UnaryOp ComplementX, NegateX, NotX, TrueX, ToAnyX, EvalX, SetupX; 384 PLUG_API BinaryOp AddX, SubtractX, MultiplyX, DivideX, ModuloX, PowerX; 385 PLUG_API BinaryOp GreaterX, GreaterEQX, EqualX, NotEqualX, AssignX; 386 PLUG_API BinaryOp OrX, AndX, XorX, ShiftLX, ShiftRX, MatMultX; 387 PLUG_API MemberOp GetMemberX; 388 PLUG_API PromoteOp PromXX; 389 PLUG_API UnaryOp PrintX; 390 PLUG_API UnaryOp y_setup_func_hack; /* do not use y_setup_func_hack */ 391 392 /*--------------------------------------------------------------------------*/ 393 394 PLUG_API DataBlock nilDB; /* Nil, or [], the one instance of a void. */ 395 396 PLUG_API Instruction *pc; /* virtual machine program counter */ 397 PLUG_API Symbol *sp; /* virtual machine stack pointer */ 398 PLUG_API Symbol *spBottom; /* current bottom of stack */ 399 PLUG_API HashTable globalTable; /* hash table for globTab symbols */ 400 PLUG_API Symbol *globTab; /* global symbol table, contains any 401 variable referenced by a Function */ 402 403 PLUG_API Function *y_idler_function; /* used by yorick-gl */ 404 405 /*--------------------------------------------------------------------------*/ 406 407 /* typeIDs for the basic Array data types */ 408 #define T_CHAR 0 409 #define T_SHORT 1 410 #define T_INT 2 411 #define T_LONG 3 412 #define T_FLOAT 4 413 #define T_DOUBLE 5 414 #define T_COMPLEX 6 415 #define T_STRING 7 416 #define T_POINTER 8 417 #define T_STRUCT 9 418 419 /* typeIDs for the non-Array data types */ 420 #define T_RANGE 10 421 #define T_LVALUE 11 422 #define T_VOID 12 423 #define T_FUNCTION 13 424 #define T_BUILTIN 14 425 #define T_STRUCTDEF 15 426 #define T_STREAM 16 427 428 /* typeID for data types which are opaque to Yorick */ 429 #define T_OPAQUE 17 430 431 /*--------------------------------------------------------------------------*/ 432 433 PLUG_API LValue *NewLValueD(long address, StructDef *base, Dimension *dims); 434 PLUG_API LValue *NewLValueM(Array *owner, void *address, 435 StructDef *base, Dimension *dims); 436 PLUG_API void FreeLValue(void *lvalue); /* *** Use Unref(lvalue) *** */ 437 438 PLUG_API Function *NewFunction(Symbol *consts, long nConsts,int nPos,int nKey, 439 int nLocal, long hasPL, int maxStackDepth, 440 Instruction *code, long codeSize); 441 PLUG_API void FreeFunction(void *func); /* *** Use Unref(func) *** */ 442 443 PLUG_API Range *NewRange(long min, long max, long inc, int nilFlags); 444 PLUG_API void FreeRange(void *range); /* *** Use Unref(range) *** */ 445 446 PLUG_API BIFunction *NewBIFunction(BuiltIn *bi, long index); 447 PLUG_API void FreeBIFunction(void *bif); /* *** Use Unref(bif) *** */ 448 449 PLUG_API int yDebugLevel; 450 451 /* ------------------------------------------------------------------------ */ 452 /* mixed old-new functions for oxy object extension, wrap_args */ 453 PLUG_API void *yget_obj_s(DataBlock *db); 454 PLUG_API void yo_cupdate(int iarg); 455 456 /*--------------------------------------------------------------------------*/ 457 /* following are deprecated -- use alternatives in yapi.h */ 458 459 PLUG_API long Globalize(const char *name, long n); 460 PLUG_API long GlobalizeDB(const char *name, long n, void *db); 461 462 /* CheckStack ensures that at least n more elements are available at 463 the top of the virtual machine stack. It returns 1 if the stack had 464 to be copied to get more space (so that sp changed), else 0. */ 465 PLUG_API int CheckStack(int n); 466 PLUG_API void PushIntValue(int i); 467 PLUG_API void PushLongValue(long l); 468 PLUG_API void PushDoubleValue(double d); 469 PLUG_API int PushCopy(Symbol *s); /* returns 1 if s is DataBlock, else 0 */ 470 PLUG_API void *PushDataBlock(void *db); /* returns db */ 471 PLUG_API void Drop(int n); 472 PLUG_API void PopTo(Symbol *s); 473 474 PLUG_API void ReplaceRef(Symbol *stack); 475 PLUG_API DataBlock *ForceToDB(Symbol *s); 476 477 /* Conform sets 4 bit if not conformable, sets 1 bit if ldims==1 where 478 rdims>1, sets 2 bit if rdims==1 where ldims>1. The result dimension 479 list is returned in tmpDims. */ 480 PLUG_API int Conform(Dimension *ldims, Dimension *rdims); 481 /* BinaryConform assures that the operands are conformable; either or 482 both may be broadcast. Result dimensions are left in tmpDims. 483 RightConform is the same except an error is signaled if ldims would 484 need to be broadcast. 485 Both functions return 0 on success, 1 on failure. */ 486 PLUG_API int BinaryConform(Operand *l, Operand *r); 487 PLUG_API int RightConform(Dimension *ldims, Operand *r); 488 489 PLUG_API Array *FetchLValue(void *db, Symbol *dsts); 490 PLUG_API void StoreLValue(void *db, void *data); 491 492 /*--------------------------------------------------------------------------*/ 493 494 PLUG_API void PushTask(Function *task); 495 PLUG_API void RunTaskNow(Function *task); 496 497 PLUG_API int CalledAsSubroutine(void); 498 499 /* Extract scalar integers, reals, and strings from the stack */ 500 PLUG_API long YGetInteger(Symbol *s); 501 PLUG_API double YGetReal(Symbol *s); 502 PLUG_API char *YGetString(Symbol *s); 503 504 PLUG_API int YNotNil(Symbol *s); 505 506 /* Scan stack[0],...,stack[nArgs-1] for keywords with names in the 507 0-terminated list keyNames, putting the corresponding Symbol*s in 508 the array symbols, or 0 if the keyName was not found. Returns the 509 Symbol* of the first non-keyword in the input stack list, or 0 if 510 none. */ 511 PLUG_API Symbol *YGetKeywords(Symbol *stack, int nArgs, char **keyNames, 512 Symbol **symbols); 513 514 PLUG_API IOStream *YGetFile(Symbol *stack); 515 516 /* Retrieve array arguments for foreign code wrappers, 517 applying type conversion (modifies s) if necessary. 518 If dims is non-zero, *dims is set to the Dimension * for the argument. 519 -- Just cast YGetInteger, YGetReal for scalar arguments, and 520 use YGetString for scalar strings. */ 521 PLUG_API char *YGet_C(Symbol *s, int nilOK, Dimension **dims); 522 PLUG_API short *YGet_S(Symbol *s, int nilOK, Dimension **dims); 523 PLUG_API int *YGet_I(Symbol *s, int nilOK, Dimension **dims); 524 PLUG_API long *YGet_L(Symbol *s, int nilOK, Dimension **dims); 525 PLUG_API float *YGet_F(Symbol *s, int nilOK, Dimension **dims); 526 PLUG_API double *YGet_D(Symbol *s, int nilOK, Dimension **dims); 527 PLUG_API double *YGet_Z(Symbol *s, int nilOK, Dimension **dims); 528 PLUG_API char **YGet_Q(Symbol *s, int nilOK, Dimension **dims); 529 PLUG_API void **YGet_P(Symbol *s, int nilOK, Dimension **dims); 530 /* Convenience routine YGet_dims converts a Dimension * linked list 531 to a dimension list dlist -- 532 dlist[0] is the first dimension length, dlist[1] the second, and so on. 533 The return value is the actual number of dimensions. 534 No dimensions beyond dlist[maxDims-1] will be set, so dlist need have 535 at most maxDims elements. 536 Use the TotalNumber and CountDims functions to get just the length 537 or number of dimensions of an array. */ 538 PLUG_API int YGet_dims(const Dimension *dims, long *dlist, int maxDims); 539 /* If a compiled function is to treat a parameter as an update or an 540 output, call YPut_Result after you call the function. The required 541 index is obtained from YGet_Ref, which must be called BEFORE YGet_... 542 gets the corresponding data: 543 long index= YGet_Ref(sp); 544 double *x= YGet_D(sp, 0, (Dimension **)0); 545 your_function(sp); 546 YPut_Result(sp, index); */ 547 PLUG_API long YGet_Ref(Symbol *s); 548 PLUG_API void YPut_Result(Symbol *s, long index); 549 550 /* generic temporary object has only a free method (zapper) 551 * its data structure must begin with 552 * int references; 553 * Operations *ops; 554 * void (*zapper)(void *to); 555 * pass sizeof(its structure) to y_new_tmpobj and it will 556 * be allocated and the first three elements initialized 557 * you can then use PushDataBlock to put it on the stack 558 * where Drop will call your zapper 559 */ 560 PLUG_API void *y_new_tmpobj(unsigned long size, void (*zapper)(void *to)); 561 PLUG_API Operations yo_tmpobj; 562 563 /* new improved (1.6) argument retrieval functions (no sp reference) 564 * all return 0 for iarg (=number of spots below top of stack) < 0 565 * need to check yarg_nil separately if required 566 */ 567 /* note that yarg_c, yarg_s, and yarg_f are nowhere referenced in yorick */ 568 PLUG_API char *yarg_c(int iarg, Dimension **dims); 569 PLUG_API short *yarg_s(int iarg, Dimension **dims); 570 PLUG_API int *yarg_i(int iarg, Dimension **dims); 571 PLUG_API long *yarg_l(int iarg, Dimension **dims); 572 PLUG_API float *yarg_f(int iarg, Dimension **dims); 573 PLUG_API double *yarg_d(int iarg, Dimension **dims); 574 PLUG_API double *yarg_z(int iarg, Dimension **dims); 575 PLUG_API char **yarg_q(int iarg, Dimension **dims); 576 PLUG_API void **yarg_p(int iarg, Dimension **dims); 577 #define yarg_sc(iarg) ((char)yarg_sl(iarg)) 578 #define yarg_ss(iarg) ((short)yarg_sl(iarg)) 579 #define yarg_si(iarg) ((int)yarg_sl(iarg)) 580 PLUG_API long yarg_sl(int iarg); 581 #define yarg_sf(iarg) ((float)yarg_sd(iarg)) 582 PLUG_API double yarg_sd(int iarg); 583 PLUG_API char *yarg_sq(int iarg); 584 #define yarg_sp(iarg) (yarg_p(iarg,0)[0]) 585 PLUG_API IOStream *yarg_file(int iarg); 586 PLUG_API Operand *yarg_op(int iarg, Operand *op); 587 /* yarg_keys returns next non-keyword iarg, or <0 if none */ 588 PLUG_API int yarg_keys(int iarg, char **knames, Symbol **ksymbols); 589 590 /*--------------------------------------------------------------------------*/ 591 592 typedef char *y_pkg_t(char ***ifiles, BuiltIn ***code, void ***data, 593 char ***varname); 594 PLUG_API void y_pkg_add(y_pkg_t *init); 595 PLUG_API y_pkg_t *y_pkg_lookup(char *name); 596 /* use name==0 to link or include all packages (static and dynamic) */ 597 PLUG_API void y_pkg_link(char *name); 598 PLUG_API void y_pkg_include(char *name, int now); 599 PLUG_API char *y_pkg_name(int i); 600 PLUG_API int y_pkg_count(int i); 601 602 /* called by on_launch generated by codger in yinit.c */ 603 PLUG_API int y_launch(int argc, char *argv[], 604 char *home, char *site, y_pkg_t **pkgs); 605 606 PLUG_API int ym_argc; 607 PLUG_API char **ym_argv; 608 609 #ifdef Y_FOR_YORAPI 610 PLUG_API y_pkg_t yk_yor; 611 #endif 612 613 /*--------------------------------------------------------------------------*/ 614 615 #endif 616