An example script written in The K+ Programming Language

I somehow found myself the other day writing code in a fictitious computer language that has no platform to run on, no compiler, and no reason to exist.

I decided to call it K+. It's part of my grand vision for a secure, microkernel-based OS with incredible hackability. The language itself is heavily Object Oriented, and it clearly borrows some syntax from C but I would say they have little to do with each other. I've actually found myself creating more never-to-be-compiled killer apps with this lovely language than I ever did with C.

Here's a short sample of the marvels of Dynamic K+. It's a short script that's embedded in the desktop (making it an embedded object, not a script, but I am sacrificing semantics in favor of clarity here) and serves one unique little purpose: to randomly select a Drum and Bass track for playing in my fictitous platform's obviously open source music player, "Jungle Amp". (no bias there ;]) I have also coded a Hello World app that's about 5 pages long but posting that might just cause the polar ice caps to melt.

I threw in some comments in the code to illustrate the nonexistent processes running on the figment of a kernel on an imaginary boxen.

!k+_runtime

*/ DesktopSelecta is a small embedded desktop object which, when selected, will pick a Drum and Bass track
*/ at random from your collection and have JungleAmp play it.  It serves as a simple demonstration of using
*/ K+ application events to automate other processes.
*/    coded by dely :teeth:

The first part of object code defines which K+ APIs the object will be accessing.

!k+_params {
    dialects [                */ Gonna need a bunch of these
        k+_kernel+process\    */ Kernel API - Need this to link, run, and quit this object
        k+_events\            */ Events API - Need this to handle and send events
        k+_logic\            */ Mathematics/Logic API - Need this to find a random number
        k+_fs\]\            */ File System API - Need this to query the contents of a directory

This is an event-based object. Here we define whether the object can receive and send events and which event types it can handle or send (with their associated parameters).

    receives_events:    YES\
    event_receive_list [
        k+_GUI:widgets:desktop_enhancements [
            execute_desktop_script (#pid my_pid)\]\    */ From dust...
        k+_kernel:object_handler:embedded_obj [
            relinquish_object (void)\]\]\            */ To dust...
    sends_events:    YES\
    event_send_list [
        k+_application_events:automate [
            send_event_to_app (#path Application_Path, struct Event)\]\
        k+_kernel:object_handler:embedded_obj [
            terminate_and_free_resources (void)\]\]\

This is where the object's parent/child relations to other objects are defined.

    belongs_to [
        k+_gui:workspace:desktop\]\    */ DesktopSelecta is solely spawned by the desktop
    owns [\]\

List of all procedures and variables the object will define.

    procedures [
        #int Tune_ID #OBJ-LOCAL Pick_Tune (void)\
        void #OBJ-GLOBAL Die (void)\
        void #OBJ-GLOBAL main (void)\]\
    main_runtime [
        void #OBJ-GLOBAL main (void)\]\
    global_params [
        #pid my_pid\                */ How the kernel knows my name
        #int Tune_ID\
        #int Jungle_Playlist_Count\
        #path Jungle_Amp_Path\
        struct Event:JungleAmpEvent\]\}\

This is where any initial values for the object's variables are defined.

*/ JungleAmp follows the default K+ spec for application events; in its particular implementation,
*/ the two #ints represent the playlist and track, respectively
!object_presets {
    #path Jungle_Amp_Path:    /scsi1/Applications/Entertainment/JungleAmp\
    struct Event:JungleAmpEvent [
        #string    Header:    JungleAmp_Automation
        #string    Event_Type:    Play_Song_From_Library
        #int       Event_Var1:    12
        #int       Event_Var2:    0 ]\}\

The event handler section is where the majority of the object's logic (decision-making) will take place. Here, the object defines its response to each receivable event. Each response ends with the line LINK#SUB:event_loop\]\ which returns to the event handler in the main procedure.

!event_handlers {
    k+_GUI:widgets:desktop_enhancements:execute_desktop_script (#pid my_pid) [
        STORE #pid my_pid >> #pid my_pid\]\
        LINK#OBJ-LOCAL Pick_Tune (void)\
        LINK#SUB:event_loop\]\
    k+_kernel:object_handler:embedded_obj:relinquish_object (void) [
        LINK#OBJ-GLOBAL Die (void)\
        LINK#SUB:event_loop\]\}\

This procedure is called when the object receives an event from its parent process, the desktop, to perform its function. This is where the object performs the actual work of querying the file system, finding a random integer that can be associated with a Drum and Bass track, and passing this integer in a struct to JungleAmp via an application event.

#int Tune_ID #OBJ-LOCAL Pick_Tune (void) {
    #int Jungle_Playlist_Count QUERY K+_fs:file_manager:directory_info (Files_In_Dir?:/ata2/me_filez/Drum And Bass)\
*/ Query the file system to find the current number of files in the Drum and Bass directory
    #int Tune_ID QUERY K+_logic:mathematics:generate_random_number (Int Between?: 1, #int Jungle_Playlist_Count)\
*/ Use the mathematics engine to calculate a random number in the range of possible DNB tracks
    STORE #int Tune_ID >> struct Event:JungleAmpEvent(#int Event_Var2)\
*/ Send the event with selected track number to JungleAmp
    EVENT k+_application_events:automate:send_event_to_app (#path Jungle_Amp_Path, struct Event:JungleAmpEvent)\
    LINK#SUB:event_loop\}\

This procedure is called when the object receives an event from the kernel indicating that it is being terminated. It sends an event back to the kernel that it is ready to cease operation, and to redistribute its resources.

Void #OBJ-GLOBAL Die (void) {
    EVENT K+_kernel:object_handler:embedded_obj:terminate_and_free_resources (void)\
    LINK#SUB:event_loop\}\

The main procedure allocates the RAM necessary to handle events and variables, initializes the variables and events and then starts an event loop which constantly queries the kernel for any new events and sends any it finds to the event handler.

*/ Boring Kernel bizniss here...

Void #OBJ-GLOBAL Main (void) {
    *varsPtr REQUEST kernel:memory_manager:allocate_RAM (_bytes_4096)\    */ Allocate RAM for variables
    INITALIZE_PARAMS (*varsPtr)\
    *evtsPtr REQUEST kernel:memory_manager:allocate_RAM (_bytes_1024)\    */ Allocate RAM for events
    INITALIZE_EVENTS (*evtsPtr)\
    #SUB event_loop {
        #bool Is_Event QUERY kernel:event_manager:notify (IsThereAnEvent)\    */ Query the kernel to see if there is an event
        if is_event: {
            CALL kernel:event_manager:get_event (*evtsPtr, #pid my_pid)\     */ Have kernel fetch the event
*/ And then process it in the !event_handlers section
            CALL kernel:event_manager:handle_event (*evtsPtr, !event_handlers, #pid my_pid)\
        else: {
            REPEAT #SUB event_loop\}\
        if errorFlag: {
            BRIDGE kernel:debugger:interrupt_my_process\}\}\     */ Even an imaginary OS is not error-free

So there you have it. A useful script in a syntactically-interesting, yet non-existent programming language. I am going to be expanding the K+ language in the next few weeks until I have something of a useful completeness, at which point I will bemoan the fact that I haven't written a line of real code since 1995.

(resubmitted after being viciously (n' justly) Klaproth'ed due to some major formatting errors - remember, folks: always use your scratch pad unless you want to lose some major timê like yours truly)

Log in or registerto write something here or to contact authors.