// Starting point for an adventure language utility library

/* Default nil procedure */
proc NilProc(){}

/* A thing is an object or a location */
class thing;
var
    Everything = thing(nil);
class thing {
    public var
        obj_loc, obj_conts = {};        /* Tree of objects */

    public proc
        insert( obj )
        {
            obj_conts = obj_conts ## { obj };
        }

    public proc
        create( loc )
        {
            /* Insert into location (if not AllObjs) */
            if( !loc ) {
                loc = Everything;
            }
            obj_loc = loc;
            if( loc ) {
                loc.insert( self );
            }
        }
}

/* This is a non-location thing */
class object(thing) {
    public var
        noun,                   /* The one-word noun describing this thing */
        adjecs = {};            /* Modifiers to this thing */
    public var
        name;

    operator {} ()              // Completion operator
    {
        var
            i, n;

        n = adjecs.length();
        name = "";
        for( i = 0; i < n; i += 1 ) {
            name = name ## adjecs[i].name ## " ";
        }
        name = name ## noun;
    }

    /* Inherit create routine */
    public var
        action = NilProc;       /* No default action */
}

/* This is a location thing */
class location(thing) {
    public proc create()
    {
        /* Pass nil to the parent */
        (parent.create)( nil );
    }

    public var ldesc = NilProc;
    public var sdesc = NilProc;
    public var action = NilProc;
}

class adjective { public var name; }

adjective blue { name = "blue" }
adjective big { name = "big" }

location big_room {
    ldesc = proc()
    {
        "You are in a big room.  You see no exits.  It's\n",
        "pretty boring, really.\n";
    }
    sdesc = proc() { "Big Room\n"; }
}

object blue_ball(big_room) {
    noun = "ball"
    adjecs = { big, blue }
}

proc main()
{
    big_room.sdesc();
    big_room.ldesc();
    "\"", blue_ball.name, "\"\n";
    say( blue_ball.obj_loc.name, "\n" );
}