• Baja arrays

    From U. CraZy Diamond@TALAMASC/SPORT! to All on Saturday, July 10, 1999 12:12:00
    Okay, folks, here it is!
    Did some digging and came up with this post from yesteryear FYI:


    Subj : Baja Arrays?
    To : All
    From : Angus McLeod (VERT/ANJO)
    Date : Mon Dec 02 1996 01:57 am AST

    Until DM comes out of hibernation, we are stuck with Sync's PCMS
    (Programmable Command & Menu System) at it's present state of the
    art, and have to live with the fact that improvements (like arrays)
    are simply not possible until then. Right?

    Well... maybe!

    Notice I spoke of the PCMS and _didn't_ say "Baja". Baja is a
    programming language which is compiled by the BAJA.EXE compiler
    into a Synchronet .BINary file. In fact, it's closer to an
    assembler than a compiler. The point being, there is nothing to
    prevent some _other_ compiler being written for a totally different
    language, like PL/S (Programming Language/Smeg). PL/S can be as
    sophisticated as we like. So long as the PL/S compiler generates
    valid .BIN files, then the PL/S programs will run.

    PL/S might easily parse statements like:

    offset = ((rec_no - 1) * rec_size) + field_offset

    and translate this to:

    opy offset rec_no
    sub offset 1
    mul offset rec_size
    add offset field_offset

    or more correctly, direct into the corresponding binary and written
    straight to the .BIN file. Nothing wonderful about this - compilers
    have been doing this since Backus gave us FORTRAN in 1956.

    What about:

    function My_Func ( str local_str ) returns int
    local_int result
    ...
    return result
    end_function

    ...

    result = My_Func ( some_str )

    being translated to:

    # declare function
    goto skip.My_Func
    :My_Func
    # declare arguments, return value and locals
    str My_Func.local_str
    int My_Func.result My_Func.return_val
    # do whatever
    ...
    # return
    copy My_Func.return_val My_Func.result
    return
    :skip.My_Func

    ...

    # call function, copying arguments in and return value out
    copy My_Func.local_str some_str
    call My_Func
    copy result My_Func.return_al

    A compiler that would allow the first notation instead of forcing us
    to use the second would be some considerable convenience.

    But so far, our proposed PL/S compiler gives us only the notational conveniences of expressing calculations in infix notation, or
    cleaning up function definition and call. But that does not actually
    give us the power to do anything new! So what about those arrays?

    Well suppose the PL/S compiler interprets:

    int My_Array[10]

    to mean:

    int My_Array.1 My_Array.2 My_Array.3 ... My_Array.10

    (which Baja will compile for us today) and generates ten
    appropriately named integer variables for us. That looks like a good
    start. But how would we actually ACCESS a particular variable at RUN-
    TIME? If the indexes were known at compile-time it would be easy, but
    we want to access the array with indexes that are not known until run-
    time.

    Suppose it were possible, even if it were very ugly, then we would be
    in the home stretch. Because our PL/Scompiler would hide the ugliness
    from us.

    Please observe the following code, which I hope is simple enough to be self-explanatory:

    ------[TSTARRAY.SRC]------------
    # declare Pseudo-"array" and cursor variable
    global_int Array.1 Array.2 Array.3 Cursor

    # declare loop counter
    int loop

    # stuff some data into our "array"
    set Array.1 10101
    set Array.2 22002
    set Array.3 30033

    # access each element by NAME
    set loop 1
    :next_element
    # the next two lines are the ugly ones!
    sprintf str "Cursor Array.%ld" loop
    exec *getint
    # we now have the array element value in the cursor!
    printf "the value of Array.%ld = %ld\r\n" loop Cursor

    add loop 1
    compare loop 3
    if_less_or_equal
    goto next_element
    end_if

    # wait for a screen-capture
    pause
    --------------------------------

    Observe that the array has been declared as GLOBAL, as has the
    "cursor variable used to access the values in this array. If we were
    using PL/S, it might declare our cursor variable(s) behind the scenes
    for us, concealing from us the very necessity for a cursor variable.

    Also observe the two key lines here, the SPRINTF which specifies the destination and source variables _by name_ and the EXEC which calls a
    Magic Module. And here is the output captured from my screen:

    ■ Main ■ 0:02:04 [4] DOVE-Net [13] Sync Programming: ;EXEC *TSTARRAY
    the value of Array.1 = 10101
    the value of Array.2 = 22002
    the value of Array.3 = 30033
    [Hit a key] └

    Obviously, we have been able to access the values in the array
    elements! Writing to these elements would require only the reversal of
    the order of the variable names in the SPRINTF statement. Note that
    PL/S could have coded our "getint" module as a subroutine at the end of
    our TSTARRAY program or even embedded the code inline.

    Here for the strong-of-stomach is the nasty, nasty, Magic Module:

    ------[GTINT.SRC]------------
    !include FILE_IO.INC

    # declare some variables
    int argc dest32 source32 handle glob_int glob_str copy_int
    str tmp dest source

    # define some BAJA op-codes
    set glob_int 3711
    set glob_str 3455
    set copy_int 9343

    # set name of source and destination
    # variables to null-strings
    set source ""
    set dest ""

    # extract variable names from command string
    # (stolen piece-meal from QNET.SRC)
    set argc 0
    :process_args
    compare_str ""
    if_true
    goto end_args
    end_if
    sprintf tmp "%.1s" str
    shift_str 1
    compare tmp " "
    if_true
    add argc 1
    goto process_args
    end_if
    switch argc
    case 0
    strcat dest tmp
    end_case
    case 1
    strcat source tmp
    end_case
    default
    goto end_args
    end_switch
    goto process_args
    :end_args

    # THIS is the interesting part! # make uppercase and find out the CRC32 of variables
    strupr source
    crc32 source32 source
    strupr dest
    crc32 dest32 dest

    #open .BIN file for writing
    fopen handle O_WRONLY+O_CREAT+O_TRUNC "%!otf%#.bin"
    if_true
    fwrite handle glob_int 2
    fwrite handle source32 4
    fwrite handle glob_int 2
    fwrite handle dest32 4
    fwrite handle copy_int 2
    fwrite handle dest32 4
    fwrite handle source32 4
    fflush handle
    fclose handle
    exec_bin "otf%#"
    end_if
    ------------------------------

    What this module basically does is create a .BIN file on-the-fly and
    then immediately execute it. It will copy an GLOBAL_INT to any other GLOBAL_INT but it does so _by name_ allowing the name to change at run-
    time thus giving access to "array" elements. Notice that a large part
    of this would not be needed if we placed the code as a subroutine in
    our main module or embedded the relevant parts "inline" ince we would
    not have to parse the variable names.

    The BAJA program we create on the fly is the following two-liner:

    global_int <source_name> <dest_name>
    copy <dest_name> <source_name>

    but it is created directly as a .BIN file (no source ever exists).
    For string elements, only a minor change us needed. Yes, I know it's
    ugly, and slow and 'orrible, but it's interesting.

    So, Smeg! Get to work on PL/S right away! Or we'll change the name
    to Programming Language/Synchronet... :)

    Seriously, I am interested in any comments on the academic or practical
    aspects of developing a new language translator as a replacement for
    the venerable BAJA compiler. The objective of any such efforts being
    to make programming for Synchronet easier, by means of notational
    conveniences not available in BAJA, and if/when possible, by the
    introduction of new features.

    +---
    ■ Synchronet ■ The ANJO BBS ■ Barbados ■ (246) 435-2235



    ...and in a nutshell, that's it. :)


    ---
    ■ Synchronet ■ ░▒▓ The Serial Port ▓▒░ »807∙547∙2134
  • From Angus Netfoot@TALAMASC to U. CraZy Diamond on Saturday, July 10, 1999 11:13:00
    RE: Baja arrays
    BY: U. CraZy Diamond to All on Sat Jul 10 1999 07:12 pm

    Okay, folks, here it is!
    Did some digging and came up with this post from yesteryear FYI:


    Subj : Baja Arrays?
    To : All
    From : Angus McLeod (VERT/ANJO)
    Date : Mon Dec 02 1996 01:57 am AST

    Uh-oh! You're going to drive everybody crazy!


    ---
    ■ Synchronet ■ telnet://talamasca-bbs.com http://www.talamasca-bbs.com
  • From Reaper Man@TALAMASC/TIME/FLAMINT to U. CraZy Diamond on Sunday, July 11, 1999 02:48:00
    RE: Baja arrays
    BY: U. CraZy Diamond to All on Sat Jul 10 1999 19:12:00

    (which Baja will compile for us today) and generates ten
    appropriately named integer variables for us. That looks like a good
    start. But how would we actually ACCESS a particular variable at RUN-
    TIME? If the indexes were known at compile-time it would be easy, but
    we want to access the array with indexes that are not known until run-
    time.

    I don't know about you, but I would be absolutly overjoyed if I had a fixed array, (which is what C deals with) that is unless you get into memory malloc and stuff like that...

    If you can do dynamic arrays, what address can I send my soul to?

    ---
    ■ Synchronet ■ Flamin' Torch BBS - The Board on Fire
  • From U. CraZy Diamond@TALAMASC/SPORT! to Angus Netfoot on Sunday, July 11, 1999 10:45:00
    RE: Baja arrays
    BY: Angus Netfoot to U. CraZy Diamond on Sat Jul 10 1999 06:13 pm

    From : Angus McLeod (VERT/ANJO)
    Date : Mon Dec 02 1996 01:57 am AST

    Uh-oh! You're going to drive everybody crazy!

    ::heh heh:: Ain't I a stinker?
    Just doing my part. ;)

    UCD

    ---
    ■ Synchronet ■ ░▒▓ The Serial Port ▓▒░ »807∙547∙2134