Files
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

419 lines
12 KiB
Objective-C

;**
;** BRIEF -- Basic Reconfigurable Interactive Editing Facility
;**
;** Written by Dave Nanian and Michael Strickman.
;**
;**
;** language.m:
;**
;** This file contains the support modules for BRIEF's language package
;** system.
;**
;** Revision history:
;** -----------------
(extern escape_re)
(macro _init
(
(string _curr_active)
(int _package_buf)
(global _curr_active
_package_buf
)
(register_macro 1 "_call_on_packages")
(register_macro 6 "_call_first_packages")
(= _package_buf (create_buffer "Packages" NULL 1))
)
)
(macro _call_on_packages
(_call_packages "_on")
)
(macro _call_first_packages
(
(string filename)
(inq_names NULL NULL filename)
(if (== (inq_message) (+ "New file (unable to open " (+ filename ").")))
(_call_packages "_new")
)
(_call_packages "_first")
)
)
;**
;** _call_packages:
;**
;** This macro is the main event parser and dispatcher for the BRIEF
;** language package system. It calls packages specified in the BPACKAGES
;** environment variable in response to events generated by the system or
;** by the user. It then maintains some housekeeping information that allows
;** rapid access to these pacakages in the future.
;**
(macro _call_packages
(
(string bpackages
to_call
mac_name
file_ext
escaped_ext
event_name
pattern
)
(int loc
pass
file_buf
already_parsed
)
;**
;** First, we get the event type and the extension of the file. If
;** there are any "off" macro to call (saved in the _curr_active global
;** string), we reset them before continuing.
;**
(get_parm 0 event_name)
(inq_names NULL file_ext)
(= escaped_ext (escape_re file_ext))
(_reset_packages)
;**
;** The global _package_buf contains housekeeping information that
;** allows the language system to keep parsed event information around
;** for the duration of the editing session. Each event occupies one
;** line in the buffer (per extension), and one additional line is
;** taken per extension to save the pre-parsed packages and arguments.
;**
;** Extensions are always found together in the package buffer; the
;** events come first, followed by the pre-parsed information. This
;** allows the search pattern to fall through to the pre-parsed
;** information if the event hasn't occurred yet.
;**
;** The format of the strings is:
;**
;** .[extension][event name, or nothing if pre_parse];[information]
;**
(= file_buf (inq_buffer))
(set_buffer _package_buf)
(top_of_buffer)
;**
;** This search locates any string in the buffer that corresponds
;** to the current extension. If the event is in the buffer, the length
;** returned by search will include the event name length (which is always
;** non-0). Otherwise, search will return 2 -- this indicates the string
;** contains pre-parse information.
;**
(if (= already_parsed (search_fwd (+ "<." (+ escaped_ext (+ "\\c{" (+ event_name "}@;"))))))
(
(next_char (-- already_parsed))
(= to_call (trim (read)))
)
;else
(
;**
;** If no information is present in the buffer for the given
;** extension, the BPACKAGES string must be retrieved from the
;** environment and parsed. Note that this will only happen
;** once per extension.
;**
;** Since the BPACKAGES string is quite complex, and a given
;** extension can appear more than once (and with a number of
;** different packages), the parser loops and search for the
;** extension until it can't be located any more.
;**
;** If the extension isn't found at all, the "default" extension
;** is used and a second pass is made over the BPACKAGES string.
;**
;** If neither the extension nor the "default" extension is
;** found, no events are generated for this extension.
;**
(int located)
(= pattern (+ (+ "<|[,;] @" escaped_ext) " @{,[~,;]@}@:\\c[~:\n;]@[\n;]"))
(= bpackages (+ (trim (ltrim (compress (inq_environment "BPACKAGES")))) "\n"))
(while (!= pass 2)
(
(while (= loc (search_string pattern bpackages NULL NULL 0))
(
(++ located)
(= bpackages (substr bpackages loc))
(if (! (= loc (index bpackages ";")))
(= loc (strlen bpackages))
)
;**
;** All of the pre-expansion packages for the current
;** extension are combined together in the to_call string
;** separated by commas. This string is used later to
;** expand and call the individual package macros, and
;** is inserted into the buffer as pre-parse information
;** once the parse has been completed.
;**
(+= to_call (+ (if (strlen to_call) "," "") (substr bpackages 1 (- loc 1))))
(= bpackages (substr bpackages (+ loc 1)))
)
)
;**
;** If we can't find the extension any more and we've located
;** some packages to call, then the parse is over. Otherwise,
;** we use "default" as the extension and try one more time.
;**
(if located
(break)
;else
(
(= pattern "<|[,;] @default @{,[~,;]@}@:\\c[~:\n;]+[\n;]")
(++ pass)
)
)
)
)
)
)
(= file_ext (+ "." file_ext))
;**
;** If the package buffer didn't contain any information about
;** the current file extension, we insert the pre-parse information
;** at the top of the buffer. This information can be used later
;** to avoid doing an additional BPACKAGES parse.
;**
(beginning_of_line)
(if (! already_parsed)
(
(insert (+ file_ext (+ ";" (+ to_call "\n"))))
;**
;** We move up here because the event information must
;** appear before the pre-parse information, and the "\n"
;** that was inserted moves us down a line.
;**
(up)
)
;else
;**
;** As you may recall, locating the pre-parse information will
;** set already_parsed to 2, and locating specific event information
;** will set it to some number above that (depending on the length
;** of the event name). Decrementing already_parsed at this point
;** will force the insertion of event-specific information if only
;** pre-parse information had been located in the package buffer search.
;**
(-- already_parsed)
)
(set_buffer file_buf)
(= bpackages "")
;**
;** At this point, we've got a list of pre-expanded package
;** names that look something like "s,pvcs,wp". These have to
;** be expanded and converted into the event and extension
;** specific variety. Each individual package is separated and
;** passed to process_package, which expands the name (if
;** necessary), handles extension-specific and generic naming
;** convensions, deals with parameters, and the like. Once
;** completed, the expanded package name (if any) is returned
;** and saved in another string that will be inserted as the
;** event-specific information in the package buffer.
;**
(while (strlen to_call)
(
(if (! (= loc (index to_call ",")))
(= loc (+ (strlen to_call) 1))
)
(= mac_name (process_package event_name (ltrim (trim (substr to_call 1 (- loc 1)))) already_parsed))
(if (strlen mac_name)
(+= bpackages (+ (if (strlen bpackages) "," "") mac_name))
)
(= to_call (substr to_call (+ loc 1)))
)
)
;**
;** If the event-specific information wasn't found in the buffer,
;** it's inserted here.
;**
(if (! already_parsed)
(
(= file_buf (inq_buffer))
(set_buffer _package_buf)
(insert (+ file_ext (+ event_name (+ ";" (+ bpackages "\n")))))
(set_buffer file_buf)
)
)
)
)
;**
;** process_package:
;**
;** This macro converts generic package names into their generic or
;** extension-specific macro name counterparts.
;**
(macro process_package
(
(string file_ext
event_name
mac_name
initial_mac
parms
)
(int loc
length
processed
)
(get_parm 0 event_name)
(get_parm 1 mac_name)
(get_parm 2 processed)
;**
;** If the names haven't already been parsed and expanded by
;** this routine, we have a lot of work to do. This work is
;** skipped once it has been done once.
;**
(if (! processed)
(
(inq_names NULL file_ext)
(= file_ext (+ "." file_ext))
(if (= loc (index mac_name " "))
(
(= parms (substr mac_name (+ loc 1)))
(= mac_name (substr mac_name 1 (- loc 1)))
)
)
;**
;** If part of the package name is found in the
;** abbreviation list, the full name is retrieved and used
;** instead. Note that the macros in the abbreviation list
;** could be demotable groups (separated by commas).
;**
(= initial_mac (_package_abbrev))
(if (= loc (search_string (+ "[,;]" (+ mac_name "*;")) initial_mac length))
(= initial_mac (substr initial_mac (+ loc 1) (- length 2)))
;else
(= initial_mac mac_name)
)
;**
;** This loop searches for specific and generic event
;** handler macros. First, specific macros are searched
;** for. If none are found, the last member of the
;** demotable group is searched for generically. This is
;** because generic higher level demotion macros don't
;** make any sense (they'd override anything else, and
;** wouldn't leave anything to demote to).
;**
(while (! processed)
(
(if (! (= loc (index initial_mac ",")))
(= loc (+ (strlen initial_mac) 1))
)
(= mac_name (substr initial_mac 1 (- loc 1)))
(= initial_mac (substr initial_mac (+ loc 1)))
(= mac_name (+ "_" (+ mac_name event_name)))
(if (= processed (inq_macro (+ file_ext mac_name)))
(= mac_name (+ file_ext mac_name))
;else
(if (! (strlen initial_mac))
(
(= processed (inq_macro mac_name))
(break)
)
)
)
)
)
)
)
;**
;** If the macro has been processed & located, we call it with its
;** parameters.
;**
(if processed
(
(if (strlen parms)
(+= mac_name (+ " " parms))
)
;**
;** If current event is an "on" event, we retain the return
;** value (if non-null) as an "off" event macro name.
;**
(if (&& (!= (= initial_mac (execute_macro mac_name)) "") (== event_name "_on"))
(+= _curr_active (+ (if (strlen _curr_active) ";" "") initial_mac))
)
(returns mac_name)
)
;else
(returns "")
)
)
)
;**
;** _reset_packages:
;**
;** This macro processes the "off" event. Any macros that returned
;** "off" event macros from their event handles have those strings kept
;** in the _curr_active global variable. These macros are called here.
;**
;** Note that "off" macro strings should never contain semicolons.
;**
(macro _reset_packages
(
(int loc)
(while (strlen _curr_active)
(
(if (! (= loc (index _curr_active ";")))
(= loc (+ (strlen _curr_active) 1))
)
(execute_macro (substr _curr_active 1 (- loc 1)))
(= _curr_active (substr _curr_active (+ loc 1)))
)
)
)
)
;**
;** _package_abbrev:
;**
;** This macro is at the terminus of the chain. It returns a string
;** consisting of the abbreviations and demotable groups for the built-in
;** BRIEF packages (indenting, word processing and pvcs).
;**
(macro _package_abbrev
(returns ";template,smart,regular;pvcs;wp;")
)