Subj : Baja arrays To : All From : U. CraZy Diamond Date : Sat Jul 10 1999 12: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 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 copy 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 .