| HaskellScript | |
| ScriptServer Interface |
| HaskellScript Documentation Download Questions History Acknowledgements HaskellAgent HaskellDirect HaskellObject Example Documentation ScriptServer Interface |
Daan Leijen, "Nov 22 1999", under construction. This document specifies the Script Server interface. The Script Server interface is a language independent interface allowing any programming language to be invoked and programmed from another application. Any language implementing this interface is called a Script Server. The interface represents the minimal functionality needed to make a language programmable from another application. This functionality can be used to implement programming language independent applications like:
I have implemented a Script Server interface around the Hugs interpreter. The rest of the document uses Haskell as the example language but nothing in the interface is Haskell specific; the interface can be written for any other language just as well, which could than directly be used by any application which uses the Script Server interface. All the code that is language independent can immediately be reused. The developer of a small language only has to implement the (minimal) Script Server interface to take advantage of those applications. For example, I have implemented a generic ActiveX scripting engine that uses the Script Server interface. Any language that implements the Script Server interface can now directly be used from any ActiveX scripting host (Internet Explorer, MS Word, Windows). This allows the language to be embedded inside Web pages (just like JavaScript), windows scripts or Active Server pages (deluxe CGI scripts).I am currently looking at implementing the Script Server interface for GHC generated libraries and even for arbitrary dynamic link libraries (DLL's). Many different designs have been tried before arriving at the Script Server interfaces (see: HaskellServer) and we think that the current design gives applications just the functionality they need while preserving the minimal amount of work needed for a language developer to implement the interfaces. Since the interfaces are minimal, some applications may need more (language specific) functionality. The Script Server interfaces are defined in such a way that it is easy to extend them with more functionality The protocol It should be possible to implement the Script Server interfaces for any language and interfaces should be used from any language. We therefore need a language independent standard to implement the interfaces. Currently, only COM and CORBA offer the desired requirements. Both COM and CORBA allow the interface to be specified in the interface description language (IDL). By specifying the interface in IDL and using a platform/language specific IDL compiler, the interface can be used on both COM and CORBA implementations. We have currently only used COM to test and use the Script Server interfaces. The rest of the document therefore uses some COM specific structures and terminology. However, since the interfaces and the associated data structures are all specified in IDL, there would be no problem if you would like to use CORBA. The Script Server interface only uses very basic COM technology and can therefore immediately be used through a COM-CORBA bridge, included with most CORBA implementations. Technical details... The IDL specificationA Script Server consists of just 3 interfaces: IScriptServer, IScriptItem and IScript, with together only 8 methods! The complete IDL description can be found at the end of this document, the short version consists of:
interface IScriptItem : IDispatch
{
HRESULT Eval( [in] int cArgs,
[in,size_is(cArgs)] VARIANT* args,
[out,retval] VARIANT* result );
};
interface IScript : IDispatch
{
HRESULT AddHostItem( [in] BSTR itemName,
[in] IDispatch* item );
HRESULT GetScriptItem( [in] BSTR name,
[out,retval] IScriptItem** item );
HRESULT Expr( [in] BSTR expr,
[out,retval] IScriptItem** item );
};
interface IScriptServer : IDispatch
{
HRESULT LoadScript( [in] VARIANT* source,
[out,retval] IScript** script );
HRESULT AddHostItem( [in] BSTR itemName,
[in] IDispatch* item );
HRESULT AddSearchDir( [in] BSTR dir );
HRESULT ProgID( [out,retval] BSTR* progID );
};
Method specifications...
Haskell specific interfaces...
The EventSink interfaces...
Complete IDL specification
[ uuid(934A7CA0-1003-11d2-803E-00C04FA91355)
, helpstring("Script server type library")
, version(1.0)
]
library ScriptServer
{
importlib("stdole.tlb");
[ uuid(934A7CA1-1003-11d2-803E-00C04FA91355)
, helpstring("Script item interface")
, oleautomation
]
interface IScriptItem : IDispatch
{
[helpstring("Evaluate an item, default member")
,id(0x60020000)
]
HRESULT Eval( [in] int cArgs
, [in,size_is(cArgs)] VARIANT* args
, [out,retval] VARIANT* result );
};
[ uuid(934A7CA6-1003-11d2-803E-00C04FA91355)
, helpstring("Haskell Script item interface")
, oleautomation
, dual
]
interface IHaskellItem : IScriptItem
{
[helpstring("Make untyped calls possible")
]
HRESULT SetType(
[in,optional,defaultvalue(VT_EMPTY)] int Result,
[in,optional,defaultvalue(TRUE)] BOOL Pure,
[in,optional,defaultvalue(FALSE)] BOOL typed);
[helpstring("Retrieve the stable pointer
, if you know the magic heapID")
]
HRESULT GetStablePtr( [in] BSTR heapID
, [out,retval] int* stableptr );
};
[ uuid(934A7CA2-1003-11d2-803E-00C04FA91355)
, helpstring("Script/module interface")
, oleautomation
, dual
]
interface IScript : IDispatch
{
[helpstring("Start the script (run 'main')")
]
HRESULT Start( void );
[helpstring("Make external object model visible")
,id(0x60020001)
]
HRESULT AddHostItem( [in] BSTR itemName
, [in] IDispatch* item );
[helpstring("Load an item in the context of this script
, default member; result is an IScriptItem")
,id(0x60020002)
]
HRESULT GetScriptItem( [in] BSTR name
, [out,retval] IScriptItem** item );
[helpstring("Load an expression in the context of this script
; result is an IScriptItem")
,id(0x60020003)
]
HRESULT Expr( [in] BSTR expr
, [out,retval] IScriptItem** item );
};
[ uuid(934A7CA7-1003-11d2-803E-00C04FA91355)
, helpstring("Script Server interface")
, oleautomation
, dual
]
interface IScriptServer : IDispatch
{
[helpstring("Load a script")
,id(0x60020000)]
HRESULT LoadScript( [in] VARIANT* source
, [out,retval] IScript** script );
[helpstring("Add a path to the search path")
]
HRESULT AddSearchDir( [in] BSTR dir );
[propget]
HRESULT ProgID( [out,retval] BSTR* progID );
};
typedef int HVal;
[ uuid(934A7CA8-1003-11d2-803E-00C04FA91355)
, helpstring("Haskell Script interface")
, oleautomation
, dual
]
interface IHaskellScript : IScript
{
HRESULT AddScriptItem( [in] BSTR name
, [in] HVal hval );
HRESULT GetHostItem( [in] BSTR name
, [out,retval] IDispatch** disp );
HRESULT MakeScriptItem( [in] HVal hval
, [out,retval] IScriptItem** item );
HRESULT UseScriptItem( [in] IScriptItem* item
, [out,retval] HVal* hval );
};
[ uuid(934A7CA3-1003-11d2-803E-00C04FA91355)
, helpstring("generic event sink")
, oleautomation
, dual
]
interface IEventSink : IDispatch
{
[helpstring("Connect to an object")
]
HRESULT Connect( [in] IDispatch* source,
[in,optional,defaultvalue(NULL)] BSTR prefix );
[helpstring("Break the connection")
]
HRESULT Disconnect(void);
[helpstring("Sink all possible events")
]
HRESULT SinkEvents( [in] IDispatch* sink );
[helpstring("Install an event sink")
]
HRESULT SinkEvent( [in] DISPID eventID
, [in] IDispatch* eventSink );
[helpstring("Translate an event name to its dispatch identifier")
]
HRESULT GetEventID( [in] BSTR eventName
, [out,retval] DISPID* eventID );
};
[ uuid(934A7CA4-1003-11d2-803E-00C04FA91355)
, helpstring("Script server for Hugs")
]
coclass HugsScript
{
interface IScriptServer;
};
[ uuid(934A7CA5-1003-11d2-803E-00C04FA91355)
, helpstring("Generic event sink")
]
coclass EventSink
{
interface IEventSink;
}
};
|