#include "escheme.h" #include "mathlink.h" #ifdef MZ_PRECISE_GC XFORM_START_SKIP; #endif int MLAbort = 0; int MLDone = 0; long MLSpecialCharacter = '\0'; MLINK stdlink = 0; MLEnvironment stdenv = 0; #if MLINTERFACE >= 3 MLYieldFunctionObject stdyielder = (MLYieldFunctionObject)0; MLMessageHandlerObject stdhandler = (MLMessageHandlerObject)0; #else MLYieldFunctionObject stdyielder = 0; MLMessageHandlerObject stdhandler = 0; #endif /* MLINTERFACE >= 3 */ /********************************* end header *********************************/ /* To launch this program from within Mathematica use: * In[1]:= link = Install["scheme.exe"] * * Or, launch this program from a shell and establish a * peer-to-peer connection. When given the prompt Create Link: * type a port name. ( On Unix platforms, a port name is a * number less than 65536. On Mac or Windows platforms, * it's an arbitrary word.) * Then, from within Mathematica use: * In[1]:= link = Install["portname", LinkMode->Connect] */ #define scheme_make_bool(i) (i ? scheme_true : scheme_false) static Scheme_Object *MathPutFunction(int argc, Scheme_Object **argv) { return scheme_make_bool( MLPutFunction( stdlink, SCHEME_SYM_VAL( argv[0]), SCHEME_INT_VAL( argv[1]))); } static Scheme_Object *MathPutString(int argc, Scheme_Object **argv) { unsigned short *s; long ulen; s = scheme_ucs4_to_utf16( SCHEME_CHAR_STR_VAL( argv[0]), 0, SCHEME_CHAR_STRLEN_VAL( argv[0]), s, -1, &ulen, 0); return scheme_make_bool( MLPutUnicodeString( stdlink, s, ulen)); } static Scheme_Object *MathPutByteString(int argc, Scheme_Object **argv) { return scheme_make_bool( MLPutByteString( stdlink, SCHEME_BYTE_STR_VAL( argv[0]), SCHEME_BYTE_STRLEN_VAL( argv[0]))); } static Scheme_Object *MathPutReal(int argc, Scheme_Object **argv) { return scheme_make_bool( MLPutReal( stdlink, SCHEME_DBL_VAL( argv[0]))); } static Scheme_Object *MathPutNext(int argc, Scheme_Object **argv) { return scheme_make_bool( MLPutNext( stdlink, SCHEME_INT_VAL( argv[0]))); } static Scheme_Object *MathNextPacket(int argc, Scheme_Object **argv) { return scheme_make_integer( MLNextPacket( stdlink)); } static Scheme_Object *MathNewPacket(int argc, Scheme_Object **argv) { return scheme_make_bool( MLNewPacket( stdlink)); } static Scheme_Object *MathGetString(int argc, Scheme_Object **argv) { unsigned short *s1; mzchar *s2; long n, ulen; MLGetUnicodeString( stdlink, &s1, &n); s2 = scheme_utf16_to_ucs4(s1, 0, n, s2, -1, &ulen, 1); MLDisownUnicodeString( stdlink, s1, n); s2[ulen] = 0; return scheme_make_sized_char_string( s2, ulen, 0); } static Scheme_Object *MathGetByteString(int argc, Scheme_Object **argv) { unsigned char *s; long n; Scheme_Object *ret; MLGetByteString( stdlink, &s, &n, 0L); ret = scheme_make_sized_byte_string(s, n, 1); MLDisownString( stdlink, s); return ret; } static Scheme_Object *MathGetSymbol(int argc, Scheme_Object **argv) { unsigned short *s1; char *s2; long n; int len; MLGetUnicodeSymbol( stdlink, &s1, &n); s2 = (char *)scheme_malloc_atomic( scheme_utf8_encode(s1, 0, n, NULL, 0, 1)); len = scheme_utf8_encode(s1, 0, n, s2, 0, 1); MLDisownUnicodeSymbol( stdlink, s1, n); return scheme_intern_exact_symbol( s2, len); } static Scheme_Object *MathGetCharString(int argc, Scheme_Object **argv) { char *s; Scheme_Object *ret; MLGetString( stdlink, &s); ret = scheme_make_byte_string(s); MLDisownString( stdlink, s); return ret; } static Scheme_Object *MathGetNext(int argc, Scheme_Object **argv) { return scheme_make_integer( MLGetNext( stdlink)); } static Scheme_Object *MathGetArgCount(int argc, Scheme_Object **argv) { long len; MLGetArgCount( stdlink, &len); return scheme_make_integer( len); } static Scheme_Object *MathErrorMessage(int argc, Scheme_Object **argv) { return scheme_make_byte_string_without_copying( MLErrorMessage( stdlink)); } static Scheme_Object *MathClearError(int argc, Scheme_Object **argv) { return scheme_make_bool( MLClearError( stdlink)); } static Scheme_Object *MathPutCharSymbol(int argc, Scheme_Object **argv) { return scheme_make_bool( MLPutSymbol( stdlink, SCHEME_SYM_VAL( argv[0]))); } static Scheme_Object *MathGetInteger(int argc, Scheme_Object **argv) { long x; MLGetLongInteger( stdlink, &x); return scheme_make_integer( x); } static Scheme_Object *set_immutable(int argc, Scheme_Object **argv) { SCHEME_SET_IMMUTABLE(argv[0]); return scheme_void; } static Scheme_Object *MathMain(int argc, Scheme_Object **argv) { char **arg; int i; argc = SCHEME_VEC_SIZE(argv[0]); arg = calloc(argc+1, sizeof(char*)); argv = SCHEME_VEC_ELS(argv[0]); arg[0] = "drlink"; for (i=0;i 0){ if( *s == 0) break; while( *s++ != 0){} } if( *s == 0) return 0; bytesleft = 0; charsleft = 0; p = s; while( *p){ t = *p; while( *t) ++t; bytesnow = t - *p; bytesleft += bytesnow; charsleft += bytesnow; #if !EVALSTRS_AS_BYTESTRINGS t = *p; charsleft -= MLCharacterOffset( &t, t + bytesnow, bytesnow); /* assert( t == *p + bytesnow); */ #endif ++p; } MLPutNext( mlp, MLTKSTR); #if EVALSTRS_AS_BYTESTRINGS p = s; while( *p){ t = *p; while( *t) ++t; bytesnow = t - *p; bytesleft -= bytesnow; MLPut8BitCharacters( mlp, bytesleft, (unsigned char*)*p, bytesnow); ++p; } #else MLPut7BitCount( mlp, charsleft, bytesleft); p = s; while( *p){ t = *p; while( *t) ++t; bytesnow = t - *p; bytesleft -= bytesnow; t = *p; charsnow = bytesnow - MLCharacterOffset( &t, t + bytesnow, bytesnow); /* assert( t == *p + bytesnow); */ charsleft -= charsnow; MLPut7BitCharacters( mlp, charsleft, *p, bytesnow, charsnow); ++p; } #endif return MLError( mlp) == MLEOK; } #endif /* CARDOF_EVALSTRS */ static int _definepattern( MLINK mlp, char *patt, char *args, int func_n) { MLPutFunction( mlp, "DefineExternal", (long)3); MLPutString( mlp, patt); MLPutString( mlp, args); MLPutInteger( mlp, func_n); return !MLError(mlp); } /* _definepattern */ #if WINDOWS_MATHLINK #if MLINTERFACE >= 3 MLMDEFN( void, MLDefaultHandler, ( MLINK mlp, int message, int n)) #else MLMDEFN( void, MLDefaultHandler, ( MLINK mlp, unsigned long message, unsigned long n)) #endif /* MLINTERFACE >= 3 */ #else #if MLINTERFACE >= 3 #if MLPROTOTYPES void MLDefaultHandler( MLINK mlp, int message, int n) #else void MLDefaultHandler( mlp, message, n) MLINK mlp; int message, n; #endif #else #if MLPROTOTYPES void MLDefaultHandler( MLINK mlp, unsigned long message, unsigned long n) #else void MLDefaultHandler( mlp, message, n) MLINK mlp; unsigned long message, n; #endif #endif /* MLINTERFACE >= 3 */ #endif { switch (message){ case MLTerminateMessage: MLDone = 1; case MLInterruptMessage: case MLAbortMessage: MLAbort = 1; default: return; } } #if MLINTERFACE >= 3 static int _MLMain( char **argv, char **argv_end, char *commandline) #else static int _MLMain( charpp_ct argv, charpp_ct argv_end, charp_ct commandline) #endif /* MLINTERFACE >= 3 */ { MLINK mlp; #if MLINTERFACE >= 3 int err; #else long err; #endif /* MLINTERFACE >= 3 */ if( !stdenv) stdenv = MLInitialize( (MLParametersPointer)0); if( stdenv == (MLEnvironment)0) goto R0; #if MLINTERFACE >= 3 if( !stdhandler) stdhandler = (MLMessageHandlerObject)MLDefaultHandler; #else if( !stdhandler) stdhandler = MLCreateMessageHandler( stdenv, MLDefaultHandler, 0); #endif /* MLINTERFACE >= 3 */ mlp = commandline ? MLOpenString( stdenv, commandline, &err) : MLOpenArgcArgv( stdenv, (int)(argv_end - argv), argv, &err); if( mlp == (MLINK)0){ MLAlert( stdenv, MLErrorString( stdenv, err)); goto R1; } if( stdyielder) MLSetYieldFunction( mlp, stdyielder); if( stdhandler) MLSetMessageHandler( mlp, stdhandler); MLInstall( mlp); stdlink = mlp; return 1; R1: MLDeinitialize( stdenv); stdenv = (MLEnvironment)0; R0: return 0; } /* _MLMain */ #if MLINTERFACE >= 3 int MLMain( int argc, char **argv) #else int MLMain( int argc, charpp_ct argv) #endif /* MLINTERFACE >= 3 */ { #if MLINTERFACE >= 3 return _MLMain( argv, argv + argc, (char *)0); #else return _MLMain( argv, argv + argc, (charp_ct)0); #endif /* MLINTERFACE >= 3 */ } #ifdef MZ_PRECISE_GC XFORM_END_SKIP; #endif