summaryrefslogtreecommitdiff
path: root/ipl/cfuncs/icall.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/cfuncs/icall.h')
-rw-r--r--ipl/cfuncs/icall.h46
1 files changed, 38 insertions, 8 deletions
diff --git a/ipl/cfuncs/icall.h b/ipl/cfuncs/icall.h
index 2718dfa..14089a5 100644
--- a/ipl/cfuncs/icall.h
+++ b/ipl/cfuncs/icall.h
@@ -7,7 +7,7 @@
#
# Author: Gregg M. Townsend
#
-# Date: November 17, 2004
+# Date: October 29, 2009
#
############################################################################
#
@@ -15,7 +15,7 @@
#
############################################################################
#
-# Contributor: Kostas Oikonomou
+# Contributors: Kostas Oikonomou, Carl Sturtivant
#
############################################################################
#
@@ -38,14 +38,14 @@
#
############################################################################
#
-# IconType(d) returns one of the characters {cfinprsCILRST} indicating
-# the type of a value according to the key on page 247 of the Red Book
-# or page 273 of the Blue Book (The Icon Programming Language).
+# IconType(d) returns one of the characters {cfinprsCEILRST} indicating
+# the type of a value based on the key on page 273 of the Blue Book (The
+# Icon Programming Language). The character E indicates external data;
# The character I indicates a large (multiprecision) integer.
#
-# Only a few of these types (i, r, f, s) are easily manipulated in C.
+# Only a few of these types (i, r, f, s, E) are easily manipulated in C.
# Given that the type has been verified, the following macros return
-# the value of a descriptor in C terms:
+# a value from a descriptor in C terms:
#
# IntegerVal(d) value of a integer (type 'i') as a C long
# RealVal(d) value of a real (type 'r') as a C double
@@ -58,6 +58,7 @@
# StringLen(d) length of string
#
# ListLen(d) length of list
+# ExternalBlock(d) address of heap block for external data
#
# These macros check the type of an argument, converting if necessary,
# and returning an error code if the argument is wrong:
@@ -66,6 +67,7 @@
# ArgReal(i) check that argv[i] is a real number
# ArgString(i) check that argv[i] is a string
# ArgList(i) check that argv[i] is a list
+# ArgExternal(i,f) check that argv[i] is an external w/ funcblock f
#
# Caveats:
# Allocation failure is not detected.
@@ -80,6 +82,7 @@
# RetInteger(i) return integer value i
# RetReal(v) return real value v
# RetFile(fp,status,name) return (newly opened) file
+# RetExternal(e) return block at addr e made by alcexternal()
# RetString(s) return null-terminated string s
# RetStringN(s, n) return string s whose length is n
# RetAlcString(s, n) return already-allocated string
@@ -121,11 +124,13 @@
#define T_Integer 1 /* integer */
#define T_Real 3 /* real number */
#define T_File 5 /* file, including window */
+#define T_External 19 /* externally defined data */
#define D_Null (T_Null | D_Typecode)
#define D_Integer (T_Integer | D_Typecode)
#define D_Real (T_Real | D_Typecode | F_Ptr)
#define D_File (T_File | D_Typecode | F_Ptr)
+#define D_External (T_External | D_Typecode | F_Ptr)
#define Fs_Read 0001 /* file open for reading */
#define Fs_Write 0002 /* file open for writing */
@@ -139,10 +144,25 @@ typedef struct { word title; double rval; } realblock;
typedef struct { word title; FILE *fp; word stat; descriptor fname; } fileblock;
typedef struct { word title, size, id; void *head, *tail; } listblock;
+typedef struct externalblock {
+ word title, size, id;
+ struct funclist *funcs;
+ word data[];
+} externalblock;
+
+typedef struct funclist {
+ int (*extlcmp) (int argc, descriptor argv[]);
+ int (*extlcopy) (int argc, descriptor argv[]);
+ int (*extlname) (int argc, descriptor argv[]);
+ int (*extlimage)(int argc, descriptor argv[]);
+} funclist;
+
char *alcstr(char *s, word len);
realblock *alcreal(double v);
fileblock *alcfile(FILE *fp, int stat, descriptor *name);
+externalblock *alcexternal(long nbytes, funclist *f, void *data);
+
int cnv_c_str(descriptor *s, descriptor *d);
int cnv_int(descriptor *s, descriptor *d);
int cnv_real(descriptor *s, descriptor *d);
@@ -152,7 +172,7 @@ double getdbl(descriptor *d);
extern descriptor nulldesc; /* null descriptor */
-#define IconType(d) ((d).dword>=0 ? 's' : "niIrcfpRL.S.T.....C"[(d).dword&31])
+#define IconType(d) ((d).dword>=0 ? 's' : "niIrcfpRL.S.T.....CE"[(d).dword&31])
#define IntegerVal(d) ((d).vword)
@@ -170,6 +190,8 @@ extern descriptor nulldesc; /* null descriptor */
#define ListLen(d) (((listblock *)((d).vword))->size)
+#define ExternalBlock(d) ((externalblock *)(d).vword)
+
#define ArgInteger(i) do { if (argc < (i)) Error(101); \
if (!cnv_int(&argv[i],&argv[i])) ArgError(i,101); } while (0)
@@ -184,6 +206,12 @@ if (!cnv_str(&argv[i],&argv[i])) ArgError(i,103); } while (0)
do {if (argc < (i)) Error(108); \
if (IconType(argv[i]) != 'L') ArgError(i,108); } while(0)
+#define ArgExternal(i,f) \
+do {if (argc < (i)) Error(131); \
+if (IconType(argv[i]) != 'E') ArgError(i,131); \
+if (ExternalBlock(argv[i])->funclist != (f)) ArgError(i,132); \
+} while(0)
+
#define RetArg(i) return (argv[0] = argv[i], 0)
@@ -198,6 +226,8 @@ do { descriptor dd; dd.vword = (word)alcstr(name, dd.dword = strlen(name)); \
argv->dword = D_File; argv->vword = (word)alcfile(fp, stat, &dd); \
return 0; } while (0)
+#define RetExternal(e) return (argv->dword=D_External, argv->vword=(word)(e), 0)
+
#define RetString(s) \
do { word n = strlen(s); \
argv->dword = n; argv->vword = (word)alcstr(s,n); return 0; } while (0)