//// Managed C++ wrapper class around the Hugs server API.//#using <mscorlib.dll>extern "C" {#include "prelude.h"#include "storage.h"#include "machdep.h"#include "connect.h"};#include "prim.h"#include "HugsServ.h" #define ToCharString(str) \ static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str).ToPointer())#define FreeCharString(pstr) System::Runtime::InteropServices::Marshal::FreeHGlobal(pstr) extern "C" {extern char* lastError;extern char* ClearError();extern Void setError (char*);extern Bool safeEval (Cell c);extern Void startEval (Void);}; /* All server entry points set CStackBase for the benefit of the (conservative) * GC and do error catching. Any calls to Hugs functions should be "protected" * by being placed inside this macro. * * void entryPoint(arg1, arg2, result) * T1 arg1; * T2 arg2; * T3 *result; * { * protect(doNothing(), * ... * ); * } * * Macro decomposed into BEGIN_PROTECT and END_PROTECT pieces so that i * can be used on some compilers (Mac?) that have limits on the size of * macro arguments. */#define BEGIN_PROTECT \ if (NULL == lastError) { \ Cell dummy; \ CStackBase = &dummy; /* Save stack base for use in gc */ \ consGC = TRUE; /* conservative GC is the default */ \ if (1) {#define END_PROTECT \ } else { \ setError("Error occurred"); \ normalTerminal(); \ } \ }#define protect(s) BEGIN_PROTECT s; END_PROTECT static Void MkObject Args((System::Object*));static Object* EvalObject Args((Void));static Int DoIO_Object Args((Object* __gc&)); /* Push an Object/DotNetPtr onto the stack */static Void MkObject(Object* a) {#ifndef NO_DYNAMIC_TYPES Cell d = getTypeableDict(type); if (isNull(d)) { setError("MkObject: can't create Typeable instance"); return 0; } protect(push(ap(ap(nameToDynamic,d),mkDotNetPtr(a,freeNetPtr))));#else protect(push(mkDotNetPtr(a,freeNetPtr)));#endif} static Object* EvalObject() /* Evaluate a cell (:: Object) */{ Cell d; BEGIN_PROTECT startEval();#ifndef NO_DYNAMIC_TYPES d = getTypeableDict(type); if (isNull(d)) { setError("EvalObject: can't create Typeable instance"); return 0; } safeEval(ap(ap(nameToDynamic,d),pop()));#else safeEval(pop());#endif normalTerminal(); return getNP(whnfHead); END_PROTECT return 0;} /* * Evaluate a cell (:: IO DotNetPtr) return exit status */static Int DoIO_Object(Object* __gc& phval){ BEGIN_PROTECT Int exitCode = 0; Bool ok; StackPtr oldsp = sp; startEval();#ifndef NO_DYNAMIC_TYPES ok = safeEval(ap(nameIORun,ap(nameRunDyn,pop())));#else ok = safeEval(ap(nameIORun,pop()));#endif if (!ok) { sp = oldsp-1; exitCode = 1; } else if (whnfHead == nameLeft) { safeEval(pop()); exitCode = whnfInt; } else { if (phval) { safeEval(pop()); phval = getNP(whnfHead); } else { drop(); } exitCode = 0; } normalTerminal(); if (sp != oldsp-1) { setError("doIO: unbalanced stack"); return 1; } return exitCode; END_PROTECT; return -1; /* error code */} namespace Hugs { System::String* Server::ClearError() { char* s = m_server->clearError(); return new System::String(s);} //// Method: SetHugsArgs(String* argv[])//// Purpose: Configure the argument vector which// H98's System.getArgs returns.// void Server::SetHugsArgs(System::String* argv[]) { char __nogc* __nogc* args = new char*[argv.Length]; int len = argv.Length; for (int i=0; i < len; i++) { args[i] = new char[argv[i]->Length + 1]; args[i] = ToCharString(argv[i]); } m_server->setHugsArgs(len,args); /* Looks kind of silly; a better way? */ for (int i=0; i < len; i++) { delete args[i]; } delete args; return;} int Server::GetNumScripts() { return m_server->getNumScripts();} void Server::Reset(int i) { m_server->reset(i); return;} void Server::SetOutputEnable (int i) { m_server->setOutputEnable(i); return;} void Server::ChangeDir(System::String* dir) { char __nogc* dirStr = ToCharString(dir); m_server->changeDir(dirStr); FreeCharString(dirStr); return;} void Server::LoadProject(System::String* proj) { char __nogc* projStr = ToCharString(proj); m_server->loadProject(projStr); FreeCharString(projStr); return;} void Server::LoadFile(System::String* fname) { char __nogc* fnameStr = ToCharString(fname); m_server->loadProject(fnameStr); FreeCharString(fnameStr); return;} void Server::LoadFromBuffer(System::String* haskMod) { char __nogc* hStr = ToCharString(haskMod); m_server->loadFromBuffer(hStr); FreeCharString(hStr); return;} void Server::SetOptions(System::String* opts) { char __nogc* hStr = ToCharString(opts); m_server->setOptions(hStr); FreeCharString(hStr); return;} System::String* Server::GetOptions() { char* r = m_server->getOptions(); return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(r);} HVal Server::CompileExpr(System::String* mo,System::String* v) { char __nogc* moStr = ToCharString(mo); char __nogc* vStr = ToCharString(v); HVal res = m_server->compileExpr(moStr,vStr); FreeCharString(moStr); FreeCharString(vStr); return res;} void Server::GarbageCollect() { m_server->garbageCollect(); return;} void Server::LookupName(System::String* mo,System::String* v) { char __nogc* moStr = ToCharString(mo); char __nogc* vStr = ToCharString(v); m_server->lookupName(moStr,vStr); FreeCharString(moStr); FreeCharString(vStr); return;} void Server::mkInt(int i) { m_server->mkInt(i); return;} void Server::mkAddr(void* ptr) { m_server->mkAddr(ptr); return;} void Server::mkObject(Object* obj) { MkObject(obj); return;} void Server::mkString(System::String* s) { char* str = ToCharString(s); m_server->mkString(str); FreeCharString(str); return;} void Server::apply() { m_server->apply(); return;} int Server::evalInt() { return m_server->evalInt();} void* Server::evalAddr() { return m_server->evalAddr();} Object* Server::evalObject() { return EvalObject();} System::String* Server::evalString() { char* str = m_server->evalString(); return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(str);} int Server::doIO() { return m_server->doIO();} int Server::doIO_Int(int* pRes) { return 0;} int Server::doIO_Addr(void** pRes) { return 0;}int Server::doIO_Object(Object* __gc& pRes) { return DoIO_Object(pRes);} HVal Server::popHVal() { HVal h = m_server->popHVal(); return h;} void Server::pushHVal(HVal arg) { m_server->pushHVal(arg); return;} void Server::freeHVal(HVal arg) { m_server->freeHVal(arg); return;}};
//
// Managed C++ wrapper class around the Hugs server API.
//
#using <mscorlib.dll>
extern "C" {
#include "prelude.h"
#include "storage.h"
#include "machdep.h"
#include "connect.h"
};
#include "prim.h"
#include "HugsServ.h"
#define ToCharString(str) \
static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str).ToPointer())
#define FreeCharString(pstr) System::Runtime::InteropServices::Marshal::FreeHGlobal(pstr)
extern "C" {
extern char* lastError;
extern char* ClearError();
extern Void setError (char*);
extern Bool safeEval (Cell c);
extern Void startEval (Void);
};
/* All server entry points set CStackBase for the benefit of the (conservative)
* GC and do error catching. Any calls to Hugs functions should be "protected"
* by being placed inside this macro.
*
* void entryPoint(arg1, arg2, result)
* T1 arg1;
* T2 arg2;
* T3 *result;
* {
* protect(doNothing(),
* ...
* );
* }
*
* Macro decomposed into BEGIN_PROTECT and END_PROTECT pieces so that i
* can be used on some compilers (Mac?) that have limits on the size of
* macro arguments.
*/
#define BEGIN_PROTECT \
if (NULL == lastError) { \
Cell dummy; \
CStackBase = &dummy; /* Save stack base for use in gc */ \
consGC = TRUE; /* conservative GC is the default */ \
if (1) {
#define END_PROTECT \
} else { \
setError("Error occurred"); \
normalTerminal(); \
} \
}
#define protect(s) BEGIN_PROTECT s; END_PROTECT
static Void MkObject Args((System::Object*));
static Object* EvalObject Args((Void));
static Int DoIO_Object Args((Object* __gc&));
/* Push an Object/DotNetPtr onto the stack */
static Void MkObject(Object* a)
{
#ifndef NO_DYNAMIC_TYPES
Cell d = getTypeableDict(type);
if (isNull(d)) {
setError("MkObject: can't create Typeable instance");
return 0;
}
protect(push(ap(ap(nameToDynamic,d),mkDotNetPtr(a,freeNetPtr))));
#else
protect(push(mkDotNetPtr(a,freeNetPtr)));
#endif
}
static Object* EvalObject() /* Evaluate a cell (:: Object) */
{
Cell d;
BEGIN_PROTECT
startEval();
#ifndef NO_DYNAMIC_TYPES
d = getTypeableDict(type);
if (isNull(d)) {
setError("EvalObject: can't create Typeable instance");
return 0;
}
safeEval(ap(ap(nameToDynamic,d),pop()));
#else
safeEval(pop());
#endif
normalTerminal();
return getNP(whnfHead);
END_PROTECT
return 0;
}
/*
* Evaluate a cell (:: IO DotNetPtr) return exit status
*/
static Int DoIO_Object(Object* __gc& phval)
{
BEGIN_PROTECT
Int exitCode = 0;
Bool ok;
StackPtr oldsp = sp;
startEval();
#ifndef NO_DYNAMIC_TYPES
ok = safeEval(ap(nameIORun,ap(nameRunDyn,pop())));
#else
ok = safeEval(ap(nameIORun,pop()));
#endif
if (!ok)
{
sp = oldsp-1;
exitCode = 1;
} else if (whnfHead == nameLeft) {
safeEval(pop());
exitCode = whnfInt;
} else {
if (phval) {
safeEval(pop());
phval = getNP(whnfHead);
} else {
drop();
}
exitCode = 0;
}
normalTerminal();
if (sp != oldsp-1) {
setError("doIO: unbalanced stack");
return 1;
}
return exitCode;
END_PROTECT;
return -1; /* error code */
}
namespace Hugs {
System::String* Server::ClearError() {
char* s = m_server->clearError();
return new System::String(s);
}
//
// Method: SetHugsArgs(String* argv[])
//
// Purpose: Configure the argument vector which
// H98's System.getArgs returns.
//
void Server::SetHugsArgs(System::String* argv[]) {
char __nogc* __nogc* args = new char*[argv.Length];
int len = argv.Length;
for (int i=0; i < len; i++) {
args[i] = new char[argv[i]->Length + 1];
args[i] = ToCharString(argv[i]);
}
m_server->setHugsArgs(len,args);
/* Looks kind of silly; a better way? */
for (int i=0; i < len; i++) {
delete args[i];
}
delete args;
return;
}
int Server::GetNumScripts() {
return m_server->getNumScripts();
}
void Server::Reset(int i) {
m_server->reset(i);
return;
}
void Server::SetOutputEnable (int i) {
m_server->setOutputEnable(i);
return;
}
void Server::ChangeDir(System::String* dir) {
char __nogc* dirStr = ToCharString(dir);
m_server->changeDir(dirStr);
FreeCharString(dirStr);
return;
}
void Server::LoadProject(System::String* proj) {
char __nogc* projStr = ToCharString(proj);
m_server->loadProject(projStr);
FreeCharString(projStr);
return;
}
void Server::LoadFile(System::String* fname) {
char __nogc* fnameStr = ToCharString(fname);
m_server->loadProject(fnameStr);
FreeCharString(fnameStr);
return;
}
void Server::LoadFromBuffer(System::String* haskMod) {
char __nogc* hStr = ToCharString(haskMod);
m_server->loadFromBuffer(hStr);
FreeCharString(hStr);
return;
}
void Server::SetOptions(System::String* opts) {
char __nogc* hStr = ToCharString(opts);
m_server->setOptions(hStr);
FreeCharString(hStr);
return;
}
System::String* Server::GetOptions() {
char* r = m_server->getOptions();
return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(r);
}
HVal Server::CompileExpr(System::String* mo,System::String* v) {
char __nogc* moStr = ToCharString(mo);
char __nogc* vStr = ToCharString(v);
HVal res = m_server->compileExpr(moStr,vStr);
FreeCharString(moStr);
FreeCharString(vStr);
return res;
}
void Server::GarbageCollect() {
m_server->garbageCollect();
return;
}
void Server::LookupName(System::String* mo,System::String* v) {
char __nogc* moStr = ToCharString(mo);
char __nogc* vStr = ToCharString(v);
m_server->lookupName(moStr,vStr);
FreeCharString(moStr);
FreeCharString(vStr);
return;
}
void Server::mkInt(int i) {
m_server->mkInt(i);
return;
}
void Server::mkAddr(void* ptr) {
m_server->mkAddr(ptr);
return;
}
void Server::mkObject(Object* obj) {
MkObject(obj);
return;
}
void Server::mkString(System::String* s) {
char* str = ToCharString(s);
m_server->mkString(str);
FreeCharString(str);
return;
}
void Server::apply() {
m_server->apply();
return;
}
int Server::evalInt() {
return m_server->evalInt();
}
void* Server::evalAddr() {
return m_server->evalAddr();
}
Object* Server::evalObject() {
return EvalObject();
}
System::String* Server::evalString() {
char* str = m_server->evalString();
return System::Runtime::InteropServices::Marshal::PtrToStringAnsi(str);
}
int Server::doIO() {
return m_server->doIO();
}
int Server::doIO_Int(int* pRes) {
return 0;
}
int Server::doIO_Addr(void** pRes) {
return 0;
}
int Server::doIO_Object(Object* __gc& pRes) {
return DoIO_Object(pRes);
}
HVal Server::popHVal() {
HVal h = m_server->popHVal();
return h;
}
void Server::pushHVal(HVal arg) {
m_server->pushHVal(arg);
return;
}
void Server::freeHVal(HVal arg) {
m_server->freeHVal(arg);
return;
}
};