CLM question

53 views
Skip to first unread message

Tim Gray

unread,
May 14, 2022, 4:36:49 PM5/14/22
to BBEdit Talk
I'm trying to write a codeless language module for an obscure 'language' - keystroke program listings for an HP42S calculator (or the Free42 program as the case may be). I think I've got all the keywords and special characters figured out but am struggling with two things. First, here's a sample program listing:

00 { 37-Byte Prgm }
01▸LBL "FAC"
02 X≠0?
03 GTO 00
04 SIGN
05 RTN
06▸LBL 00
07 R↑
08 LSTO "T"
09 R↓
10 LSTO "N"
11 1
12 -
13 XEQ "FAC"
14 RCL "N"
15 ×
16 RCL "T"
17 R↓
18 END

I'd like to have the 'LBL' lines show up in the function popup with the correct label ("FAC" or "00"). Code folding for each section would be nice, but not necessary. I'm not sure the best way to implement this - I tried "Prefix for Functions" but I'm assuming I need "Function Pattern" instead.

My second question pertains to the line numbers. The line numbers are often part of a listing, but are not actually part of the program. I'd like some way to highlight those if possible. Is that doable in a CLM? The regex is easy: '^\d+( |▸)' but I don't know if there is anyway to implement it...

Thanks,
Tim

jj

unread,
May 15, 2022, 5:11:35 AM5/15/22
to BBEdit Talk
Hi Tim,

Here is an attempt for you special case CLM.

Save it as ~/Library/Application\ Support/BBEdit/Language\ Modules/free42.plist
and restart BBEdit.

You should now have a 'Free42' language module that highlights files with the .free42 extension.

HTH,

Jean Jourdain

--

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>BBEditDocumentType</key>
        <string>CodelessLanguageModule</string>
        <key>BBLMColorsSyntax</key>
        <true/>
        <key>BBLMIsCaseSensitive</key>
        <true/>
        <key>BBLMSupportsTextCompletion</key>
        <true/>
        <key>BBLMKeywordList</key>
        <array>
            <string>GTO</string>
            <string>RTN</string>
            <string>LSTO</string>
            <string>RCL</string>
            <string>END</string>
            <string>SIGN</string>
            <string>R</string>
            <string>XEQ</string>
        </array>
        <key>BBLMLanguageCode</key>
        <string>FR42</string>
        <key>BBLMLanguageDisplayName</key>
        <string>Free42</string>
        <key>BBLMScansFunctions</key>
        <true/>
        <key>BBLMFunctionScannerDoesFoldsToo</key>
        <true/>
        <key>BBLMSuffixMap</key>
        <array>
            <dict>
                <key>BBLMLanguageSuffix</key>
                <string>.free42</string>
            </dict>
        </array>
        <key>Language Features</key>
        <dict>
            <key>Close Block Comments</key>
            <false/>
            <key>Close Statement Blocks</key>
            <false/>
            <key>End-of-line Ends Strings 1</key>
            <false/>
            <key>End-of-line Ends Strings 2</key>
            <false/>
            <key>Escape Char in Strings 1</key>
            <string>\</string>
            <key>Escape Char in Strings 2</key>
            <string>\</string>
            <key>Identifier and Keyword Character Class</key>
            <string>\p{Xwd}</string>
            <key>Open Block Comments</key>
            <false/>
            <key>Open Line Comments</key>
            <false/>
            <key>Open Statement Blocks</key>
            <false/>
            <key>Close Strings 1</key>
            <false/>
            <key>Close Strings 2</key>
            <false/>
            <key>Open Strings 1</key>
            <false/>
            <key>Open Strings 2</key>
            <false/>
            <key>String Pattern</key>
            <string><![CDATA[(?x)
    ^\d+
    ]]></string>
            <key>Function Pattern</key>
            <string><![CDATA[(?x)(?n)
                ^\d+▸LBL\h
                (?P<function_name>                
                    (
                       "[^"]+?"
                    |
                        \d+
                    )
                )
                (?P<function>
                    \h*\n
                    (\d+\h.+(\n|\z))*
                    \d+\h.+
                )
    ]]></string>
        </dict>
    </dict>
    </plist>

--

Tim Gray

unread,
May 15, 2022, 7:37:30 PM5/15/22
to BBEdit Talk
Thank you!  This is great. 

Can I bother you for an explanation for the folding part of the pattern?  I assume this is the second part of the function pattern (the part named ‘function’).
--
This is the BBEdit Talk public discussion group. If you have a feature request or need technical support, please email "sup...@barebones.com" rather than posting here. Follow @bbedit on Twitter: <https://twitter.com/bbedit>
---
You received this message because you are subscribed to the Google Groups "BBEdit Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bbedit+un...@googlegroups.com.

jj

unread,
May 16, 2022, 2:43:57 AM5/16/22
to BBEdit Talk
Hi Tim,

Good to know it worked.

Here is the commented regular expression.

(?P<function>   (?# FUNCTION NAMED CAPTURE GROUP used by BBEdit for FOLDS.                                 )
    \h*             (?# Zero or more horizontal whitespace.                                                )
    \n              (?# One linefeed.                                                                      )
    (               (?# LINE GROUP.                                                                        )
        \d+             (?# One or more digits.                                                            )
        \h              (?# One horizontal space. Important: means line is in function body.               )
        .+              (?# Rest of the line. By default, dot is not allowed to match EOL.                 )
        (               (?# EOL options group. See comment below.                                          )
            \n              (?# One linefeed.                                                              )
        |               (?# or                                                                             )
            \z              (?# EOF. Needed for catching the last line.                                    )
        )               (?# End of LINE GROUP.                                                             )
    )*              (?# Zero or more LINEs.                                                                )
                    (?# A Mandatory last LINE.                                                             )
    \d+             (?# One or more digits.                                                                )
    \h              (?# One horizontal space. Important: means line is in function body.                   )
    .+              (?# Rest of the line. Not including EOL.                                               )
)               (?# The FOLD should end before the optional next linefeed as it is the functions separator.)

The secret sauce is in catching only lines that start by digits followed by a space as they are function body lines.

Rethinking it, the `EOL options group` is overkill, a single "\n" will suffice as those lines are never the last line of the file.

    (?P<function>
        \h*\n
        (\d+\h.+\n)*
        \d+\h.+
    )

Regards,

Jean
Reply all
Reply to author
Forward
0 new messages