dykstrom / basic-mode

Emacs major mode for editing BASIC code
GNU General Public License v3.0
7 stars 10 forks source link

Syntax highlighting categories #21

Open hackerb9 opened 1 year ago

hackerb9 commented 1 year ago

What are the conventions for syntax highlighting of BASIC code? While working on issue #20 (derived modes), I have run into a problem that I do not know the meaning of groupings like basic-builtin-regexp and basic-keyword-regexp.

If there is a "typical" convention, it would be helpful to have it in the comments in basic-mode.el. If there is not, and I suspect there isn't yet, it may be good to see what others have done and look at what makes sense.


Note that not all of the categories are confusing. Comments, constants, strings, and so on are self-explanatory. The ones that I'd like to get nailed down are:

hackerb9 commented 1 year ago

Possibly of use: I see that the QuickBasic manual breaks its statements into the following groups:

I do not know if these categories overlap or if they have any relationship to what is actually used in syntax highlighting systems. I will say that I think it is a very good feature that basic-mode makes control-flow distinct.


Update: after reading through that chapter, I think it actually contains some very useful divisions for syntax highlighting and it is not too different from how basic-mode currently works. In particular, Control-Flow (GOTO, IF...THEN, FOR..NEXT) is fundamental to BASIC programmers and is already prominently shown.

Less common, but perhaps even more important to shine a spotlight on are the Trapping Statements (ON ERR GOTO...) which can change a program's flow of control asynchronously. (For example, ON COM GOSUB is used on the Tandy 200 to run a BASIC routine when data comes in on the serial port.) Currently traps are shown the same as control-flow in basic-mode, but I suggest that they ought to be even more vivid.

Statements Used in Procedures (SUB, FUNCTION, DEF FN) are also currently shown in the same face as Control-Flow, but if there are any spare font-lock categories left, it may look better if they were subtly different.

I do not have problem with mushing together Standard I/O and File I/O and Graphics Statements, but I'm not opposed to keeping them separate as the QuickBasic manual has them either. String-Processing Functions do make some sense to show with a slight variation from normal statements, but I do not know if it is worth going out of the way to do.

hackerb9 commented 1 year ago

Samples of other syntax highlighting for BASIC:

Github GFM

Github's MarkDown attempts to syntax highlight fenced code blocks. For example:

```BASIC
0 DEFINT X=32768, Y=RND(-1)  ' SALT
10 PRINT "HELLO, WORLD! "; TIME$; 
20 Y=(31*Y+PEEK(X)) MOD 257: REM PRIME HASH
30 X=X+1: GOSUB 10
Becomes, 
```BASIC
0 DEFINT X=32768, Y=RND(-1)  ' SALT
10 PRINT "HELLO, WORLD! "; TIME$; 
20 Y=(31*Y+PEEK(X)) MOD 257: REM PRIME HASH
30 X=X+1: GOSUB 10

Telnet23's language-basic

Github actually relies on telnet23's language-basic syntax highlighting. Like basic-mode.el, it properly marks control-flow as being important. Unfortunately, the way Github has used it, control-flow and operators are both shown in red, so in practice, control-flow is not distinct.

One feature it has that basic-mode.el should steal acquire is highlighting line numbers when they are referenced by statements like GOTO 10 in the line number color.

The main categories appear to be BASIC's typical functions, statements, and operators, but interestingly, it separates string functions from other functions. I suppose the reasoning is that it shows the type the function is returning. Is that an idea that would be helpful to programmers?

The regexps are succinctly defined in .CSON format:

Click to see the regexps ```CSON scopeName: 'source.basic' name: 'BASIC' fileTypes: [ 'bas' ] patterns: [ { # line number definition match: '^\\s*\\d+' name: 'entity.name.tag.basic' } { # line number reference match: '\\b((?i)THEN|ELSE|GO\\s*TO|GOSUB)\\s*(\\d+)' captures: 1: name: 'keyword.control.basic' 2: name: 'entity.name.tag.basic' } { # number match: '\\b(?:\\d\\.|\\d+\\.\\d+|\\.\\d+|\\d+)(?:[Ee][-+]?\\d+)?\\b' name: 'constant.numeric.basic' } { # string match: '"[^"]*"' name: 'string.quoted.double.basic' } { # comment match: '(?i:REM.*)' name: 'comment.line.basic' } { # flow control statement match: '\\b(?i:FOR|TO|NEXT|IF|THEN|ELSE|GO\\s*TO|GOSUB|RETURN)\\b' name: 'keyword.control.basic' } { # other statement match: '\\b(?i:\\?|\\&|\\!|\'|ABSOLUTE|ACCESS|AS|BASE|BEEP|BLOAD|BSAVE|CALL|CASE|CHAIN|CHDIR|CIRCLE|CLEAR|CLOSE|CLS|COLOR|COM|COMMON|CONST|DATA|DECLARE|DEF|DEFDBL|DEFINT|DEFLNG|DEFSNG|DEFSTR|DIM|DO|DRAW|END|ENVIRON|ERASE|ERROR|EXIT|FIELD|FILES|FUNCTION|GET|HOME|IF|INPUT|INPUT#|IOCTL|KEY|KILL|LET|LINE|LOCATE|LOCK|LOOP|LPRINT|LSET|MKDIR|NAME|NEW|ON|OPEN|OPTION|OUT|PAINT|PALETTE|PCLEAR0|PCLEAR1|PCOPY|PEN|PLAY|PMAP|PMODE0|POKE|PRESET|PRINT|PRINT#|PSET|PUT|RANDOMIZE|READ|REDIM|REM|RESET|RESTORE|RESUME|RMDIR|RSET|RUN|SCREEN|SEEK|SELECT|SHARED|SHELL|SLEEP|SOUND|SOUNDRND|STATIC|STOP|STRIG|SUB|SWAP|SYSTEM|TIMER|TROFF|TRON|TYPE|UNLOCK|USING|VIEW|WAIT|WEND|WHILE|WINDOW|WRITE)\\b' name: 'entity.name.type.basic' } { # string function match: '\\b(?i:BIN|CHR|COMMAND|DATE|ENVIRON|ERDEV|HEX|INKEY|INPUT|IOCTL|LAFT|LCASES|LEFT|LTRIM|MID|MKD|MKDMBF|MKI|MKL|MKS|MKSMBF|OCT|RIGHT|RTRIM|SPACE|SPC|STR|STRING|TAB|TIME|UCASE|UPS|VARPTR)\\$' name: 'entity.name.function.basic' } { # non-string function match: '\\b(?i:ABS|ASC|ATN|BRK|CDBL|CINT|CLNG|COS|CSNG|CSRLIN|CTL|CVD|CVDMBF|CVI|CVL|CVS|CVSMBF|D2R|EOF|ERDEV|ERL|ERR|EXP|FILEATTR|FIX|FRE|FREEFILE|HEIGHT|INP|INSTR|INT|ITM|LBOUND|LEN|LG|LIN|LN|LOC|LOF|LOG|LOG10|LPOS|NINT|NUM|PEEK|PEN|POINT|POS|R2D|REC|RND|SADD|SCREEN|SEEK|SETMEM|SGN|SIN|SPA|SPC|SQR|SQRT|STICK|STRIG|SYS|TAB|TAN|TIM|TIMER|TYP|UBOUND|VAL|VALPTR|VALSEG|VARPTR|VARSEG|WIDTH)\\b' name: 'entity.name.function.basic' } # { # # other function # match: '\\b(\\w+[\\$%!]?)\\(' # captures: # 1: name: 'entity.name.function.basic' # } { # operator match: '\\^|\\+|-|\\*\\*|\\*|/|=|<>|<=|=<|>=|=>|<|>|\\b(?i:MOD|NOT|AND|OR)\\b' name: 'keyword.operator.basic' } ] ```

KATE editor

hackerb9 commented 1 year ago

Just for reference, here are the categories into which Bill Crider's “BASIC Programming Conversion” puts the reserved words from several dialects of BASIC. Actually, "tags" would be a better description, as each word can fit in multiple boxes.

1. INPUT 1. Human: Keyboard, Joystick, Paddle, Light Pen 1. CMD 1. GET 1. GET# 1. IN# 1. INKEY$ 1. INPUT 1. INPUT LINE 1. INPUT# 1. INPUT$ 1. JOYSTK 1. KEY 1. KEY$ 1. LINE INPUT 1. LINE INPUT# 1. PDL 1. PEEK 1. PEN 1. POKE (for input?) 1. PR# 1. READ 1. READ# 1. STICK 1. STRIG 1. Storage: Cassette, Sequential/Random file access, Disk 1. APPEND 1. AUDIO 1. B-A: 1. B-F: 1. B-P: 1. B-R: 1. B-W: 1. BACKUP 1. BLOAD 1. BLOCK-ALLOCATE: 1. BLOCK-EXECUTE: 1. BLOCK-FREE: 1. BLOCK-READ: 1. BLOCK-WRITE: 1. BSAVE 1. BUFFER-POINTER 1. CATALOG 1. CHAIN 1. CHDIR 1. CLOAD 1. CLOADM 1. CLOSE 1. CMD 1. COPY 1. CSAVE 1. CSAVEM 1. DCLOSE 1. DELETE 1. DIR 1. DIRECTORY 1. DLOAD 1. DLOADM 1. DOPEN 1. DRIVE 1. DSAVE 1. DSKI$ 1. DSKINI 1. DSKO$ 1. EOF 1. ERASE 1. FIELD 1. FILE 1. FILES 1. FORMAT 1. FRE 1. FREE 1. GET 1. GET# 1. IN# 1. INP 1. INPUT 1. INPUT # 1. INPUT$ 1. KILL 1. LINE INPUT 1. LINE INPUT# 1. LOAD 1. LOADM 1. LOF 1. LPOS 1. M-E: 1. M-R: 1. M-W: 1. MEMORY-EXECUTE: 1. MEMORY-READ: 1. MEMORY-WRITE: 1. MERGE 1. MKDIR 1. MOTOR 1. NAME 1. NEW 1. OPEN 1. OUT 1. OUTPUT 1. POINTER 1. PR # 1. PRINT 1. PRINT # 1. PRINT #USING 1. PRINT USING 1. PUT 1. PUT# 1. READ 1. READ# 1. RECALL 1. RECORD 1. RESTORE 1. RMDIR 1. RUN 1. SAVE 1. SAVEM 1. SCRATCH 1. SHLOAD 1. SKIPF 1. ST 1. STATUS 1. STORE 1. UNLOAD 1. WRITE 1. WRITE# 1. External Input: Display, Serial/Modem, Printer, A/D Converter 1. COM 1. CMD 1. CSRLIN 1. IN# 1. IN 1. INP 1. LPOS 1. PEEK 1. POINT 1. POSN 1. PPOINT 1. ST 1. STATUS 1. WAIT 1. SCREEN 1. PROCESSING 1. Program Flow 1. AUTO 1. BUFFER-POINTER 1. CHAIN 1. CHDIR 1. CMD 1. DATA 1. DELETE 1. ELSE 1. END 1. ERASE 1. ERL 1. ERR 1. ERROR 1. ERRS$ 1. FOR 1. GOSUB 1. GOTO 1. IF 1. IF-THEN 1. IF-THEN-ELSE 1. KILL 1. LIST 1. LLIST 1. M-E 1. ON ERR 1. POINTER 1. REM 1. REN 1. RENAME 1. RENUM 1. RENUMBER 1. RESTORE 1. RESUME 1. MEMORY-EXECUTE 1. RESUME NEXT 1. RETURN 1. RMDIR 1. MKDIR 1. NEXT 1. NOTRACE 1. ON ERR GOTO 1. ON ERROR GOTO 1. RUN 1. SCRATCH 1. SHELL 1. SKIPF 1. SPEED= 1. STOP 1. THEN 1. TO 1. TRACE OFF 1. TRACE ON 1. TRACE 1. TROFF 1. TRON 1. WAIT 1. WEND 1. WHILE 1. Functions 1. ABS 1. ASC 1. ATN 1. CDBL 1. CHR$ 1. CINT 1. COS 1. CSRLIN 1. CVD 1. CVI 1. CVN 1. CVS 1. EOF 1. ERL 1. ERR 1. ERRS$ 1. EXP 1. FIX 1. FRE 1. HEXS 1. INKEY$ 1. INP 1. INPUT$ 1. JOYSTK 1. LEFT$ 1. LOC 1. LOF 1. LOG 1. LPOS 1. M-R: 1. MEM 1. MEMORY-READ: 1. MID$ 1. MKD$ 1. MKI$ 1. MKN$ 1. MKS$ 1. OCT$ 1. PDL 1. PEEK 1. PEN 1. POINT 1. POS 1. PPOINT 1. RIGHT$ 1. RND 1. ROW 1. SCREEN 1. SGN 1. SQR 1. STRIG 1. TIME$ 1. SIN 1. SPACE$ 1. STATUS 1. STICK 1. STRING$ 1. TANVAL 1. VARPTR 1. SPC( 1. STR$ 1. TI$ 1. VARPTR$ 1. Operators 1. ^ Exponentiation 1. \- Negation 1. \* Multiplication 1. / Floating-Point Division 1. \ Integer Division 1. MOD Modulo Arithmetic 1. \+ Addition 1. \- Subtraction 1. = Equality 1. < Less Than 1. > Greater Than 1. NOT 1. AND 1. OR 1. XOR 1. EQV 1. IMP 1. Data Types: Constants, Variables, Strings, Numerics, Arrays 1. CDBL 1. CHR$ 1. CINT 1. COMMON 1. CONCAT 1. CSNG 1. CVD 1. CVI 1. CVN 1. CVS 1. DATA 1. DEFDBL 1. DEFFN 1. DEFINT 1. DEFSNG 1. DEFSTR 1. DIM 1. FIX 1. HEX$ 1. INT 1. LET 1. MKD$ 1. MKI$ 1. MKN$ 1. MKS$ 1. OCT$ 1. OPTION BASE 1. STR$ 1. STRING$ 1. SWAP 1. VAL 1. VARPTR 1. VARPTR$ 1. Machine & Memory Interface 1. B-A: 1. B-F: 1. B-P: 1. B-R: 1. B-W: 1. BLOAD 1. BLOCK-ALLOCATE: 1. BLOCK-EXECUTE: 1. BLOCK-FREE: 1. BLOCK-READ: 1. BLOCK-WRITE: 1. BSAVE 1. BUFFER-POINTER: 1. CALL 1. DEF SEG 1. FRE 1. HIMEM: 1. INP 1. LOADM 1. LOMEM: 1. M-E: 1. M-R: 1. M-W: 1. MEM 1. MEMORY-EXECUTE: 1. MEMORY-READ: 1. MEMORY-WRITE: 1. OUT 1. PCLEAR 1. PCLS 1. PCOPY 1. PEEK 1. PMODE 1. POKE 1. POP 1. PR # 1. SAVEM 1. SHLOAD 1. SPEED= 1. STATUS 1. SYS 1. SYSTEM 1. UNLOAD 1. USER 1. USR 1. VARPTR 1. VARPTR$ 1. OUTPUT 1. Display output 1. CIRCLE 1. CLS 1. CMD 1. COLOR 1. COLOR= 1. CSRLIN 1. DRAW 1. DRAWTO 1. FLASH 1. GET 1. GR 1. HCOLOR 1. HCOLOR= 1. HGR 1. HGR2 1. HLIN 1. HLIN-AT 1. HPLOT 1. HTAB 1. INVERSE 1. KEY 1. LINE 1. LOCATE 1. NORMAL 1. PAGE 1. PAINT 1. PALETTE 1. PALETTE USING 1. PCLEAR 1. PCLS 1. PCOPY 1. PEEK 1. PEN 1. PLOT 1. PMAP 1. PMODE 1. POINT 1. POINTER 1. POKE 1. PPOINT 1. PR # 1. PRESET 1. PRINT 1. PRINT # 1. PRINT #USING 1. PRINT @ 1. PRINT AT 1. PRINT USING 1. PSET 1. PUT 1. RESET 1. ROT= 1. SCALE 1. SCALE= 1. SCREEN 1. SCRN( 1. SET 1. SHLOAD 1. VIEW 1. VLIN 1. VLIN-AT 1. VPOS 1. VTAB 1. WIDTH 1. WINDOW 1. WRITE 1. WRITE # 1. XDRAW 1. XPLOT 1. Sound 1. AUDIO 1. BEEP 1. MOTOR 1. NOISE 1. PEEK 1. PLAY 1. POKE 1. SOUND 1. Printer 1. CMD 1. LLIST 1. LPOS 1. LPRINT 1. LPRINT USING 1. POSN 1. PR # 1. PRINT 1. PRINT @ 1. PRINT # 1. PRINT #USING 1. PRINT USING 1. ST 1. STATUS 1. TAB 1. TAB( 1. WRITE 1. WRITE# 1. Storage output 1. APPEND 1. B-A: 1. B-F: 1. B-P: 1. B-R: 1. B-W: 1. BACKUP 1. BLOCK-READ: 1. BLOCK-WRITE: 1. BLOCK-ALLOCATE: 1. BLOCK-EXECUTE: 1. BLOCK-FREE: 1. BUFFER-POINTER 1. BSAVE 1. CATALOG 1. CHDIR 1. CLOSE 1. DSKI$ 1. DSKO$ 1. PRINT USING 1. PUT 1. CMD 1. COLLECT 1. COPY 1. CSAVE 1. CSAVEM 1. DCLOSE 1. DELETE 1. DIR 1. DIRECTORY 1. DOPEN 1. DRIVE 1. DSAVE 1. DSKINI 1. ERASE 1. FIELD 1. FILES 1. KILL 1. LOF 1. MKDIR 1. MOTOR 1. OPEN 1. OUTPUT 1. PR # 1. PRINT 1. PUT # 1. PRINT # 1. PRINT #USING 1. RENAME 1. RMDIR 1. SAVE 1. SAVEM 1. SCRATCH 1. SYSTEM 1. TAB 1. TAB( 1. STORE 1. UNLOAD 1. WRITE 1. WRITE# 1. External Communications 1. AUDIO 1. CMD 1. COM 1. MOTOR 1. OFF 1. ON 1. OUT 1. PEEK 1. POKE 1. PR # 1. WAIT

Crider says that he is covering BASIC for "Apple, IBM PC, IBM PCjr, Commodore 64, TRS-80 Model III, and TRS-80 Color Computer". However, I noticed that his list of all 551 reserved words one should avoid using in identifiers as they are defined in one BASIC or another actually includes more keywords than were listed in the categories above. They appear to be from Atari BASIC (e.g., PTRIG) and Tektronix 4051 Graphic System BASIC Language (e.g., BAPPEN).

```BASIC ABS ACS ACSD ACSG ADR AND APPEND ARCOS ARCSIN ARCTAN ASC ASCII ASN ASND ASNG AT ATAN ATN ATND ATNG AUDIO AUTO AXIS B-A: B-F: B-P: B-R: B-W: BACKUP BAPPEN BASE BEEP BGET BLOAD BLOCK-ALLOCATE: BLOCK-EXECUTE: BLOCK-FREE: BLOCK-READ: BLOCK-WRITE: BUFFER-POINTER BOLD BPUT BREAK BRIGHTNESS BSAVE BUTTON BYE CALL CATALOG CDBL CH CHAIN CHANGE CHAR CHAR$ CHARSIZE CHDIR CHR CHR$ CINT CIRCLE CLEAR CLG CLK$ CLK CLOAD CLOADM CLOCK CLOG CLOSE CLR CLRDOT CLS CMD CO CODE COLLECT COLOR COLOR= COM COMMON CON CONCAT CONSOLE CONT COPY COS COSD COSG COSH COUNT CSAVE CSAVEM CSH CSNG CSRLIN CUR CVD CVI CVN CVS CVT$% CVT$F CVT%$ CVTF$ DASH DAT DATA DATE$ DCLOSE DEBUG DEF DEFDBL DEFFN DEFINT DEF SEG DEFSNG DEFSTR DEFUSR DEG DEGREE DEL DELETE DET DIGITS DIM DIR DIRECTORY DLOAD DLOADM DMS DOPEN DOS DOT DRAW DRAWTO DRIVE DS DSAVE DSKI$ DSKINI DSKO$ DSP EDIT ELSE END ENTER ENVIRON ENVIRON$ EOF EQ EQV ERASE ERDEV ERDEV$ ERL ERR ERRL ERRN ERROR ERRS$ EXAM EXCHANGE EXEC EXIT EXP EXT FDIM FETCH FGET FIELD FIF FILE FILES FILL FIN FIND FINPUT FIX FLASH FLOW FLT FMT FN FNEND FONT FOR FORMAT FOUT FPRINT FPUT FRAC FRE FREE FUNTIL FUZZ GE GET GET# GIN GO GO TO GOODBYE GOSUB GOSUB-OF GOT GOTO GOTO-OF GR GRAD GRAPHICS GT HCOLOR HCOLOR= HEADER HEX$ HGR HGR2 HIMEM: HLIN HLIN-AT HOME HPLOT HSCRN HTAB IF IF-GOT IF-GOTO IF-LET IF-THE IF-THEN IF-THEN-ELSE IMAGE IMP IN# INCH INCHAR INDEX INIT INKEY$ INP INPUT INPUT# INPUT$ INPUT1 INPUTLINE INSTR INT INTER$ INVERSE IOCTL IOCTL$ JOYSTK KEY KEY$ KILL LE LEFT LEFT$ LEN LET LGT LI LIN LINE LINE INPUT# LINEINPUT LINK LINPUT LIS LIST LLIST LN LOAD LOADM LOC LOCATE LOF LOG LOG10 LOGE LOMEM: LPOS LPRINT LPRINTUSING LSET LT M-E: M-R: M-W: MAN MARK MAT * MAT + MAT - MAT = MAT CON MAT IDN MAT INPUT MAT INV MAT PRINT MAT READ MAT TRN MAT ZER MAX MDD MEM MEMORY-EXECUTE: MEMORY-READ: MEMORY-WRITE: MERGE MID MID$ MIN MKD$ MKDIR MKI$ MKN$ MKS$ MOD MONITOR MOTOR MPY MTPACK NAME NE NEW NEX NEXT NOFLOW NOISE NORMAL NOT NOTE NOTRACE NULL NUM NUM$ OCT$ OFF OLD ON ON ERR GOTO ON ERROR GOTO ON-GOSUB ON-GOT ON-GOTO ONERR OPEN OPTION OPTION BASE OR OUT OUTPUT PADDLE PAGE PAINT PALETTE PALETTE USING PAUSE PCLEAR PCLS PCOPY PDL PEEK PEN PI PIN PLAY PLOT PMAP PMODE POINT POINTER POKE POLL POP POS POSITION POSN PPOINT PR# PRECISION PRESET PRI PRINT PRINT #USING PRINT AT PRINT USING PRINT # PRINT @ PSET PTR PTRIG PUT PUT# RAD RADIAN RAN RANDOM RANDOMIZE RBYTE RDRAW REA READ READ# RECALL RECORD REM REMARK REN RENAME RENUM RENUMBER REP REPEAT$ RES RESET RESTORE RESUME RESUME NEXT RET RETURN RIGHT RIGHT$ RMDIR RMOVE RND ROT= ROTATE ROW RSET RU RUN SAVE SAVEM SCALE SCALE= SCR SCRATCH SCREEN SCRN SCRN( SECRET SEG SEG$ SET SETCOLOR SETDOT SGET SGN SHELL SHLOAD SHUT SIN SIND SING SINH SKIPF SLEEP SNH SORT SOUND SPA SPACE SPACE$ SPC SPC( SPEED= SPUT SQR SQRT ST STATUS STE STEP STICK STO STOP STORE STR STR$ STRIG STRING STRING$ STUFF SUB SUBEND SUM SWAP SYS SYSTEM TAB TAB( TAN TAND TANG TANH TAPPEND TEXT THE THEN TI TI$ TIM TIME TIME$ TIMER TLIST TLOAD TNH TO TOP TRACE TRACE OFF TRACE ON TRAP TROFF TRON TSAVE TYP TYPE UNLOAD UNTIL USER USING USR VAL VARPTR VARPTR$ VERIFY VIEW VIEWPORT VLIN VLIN-AT VPOS VTAB WAIT WBYTE WEAVE WEND WHILE WIDTH WINDOW WRITE WRITE# XDRAW XIO XOR XPLOT XRA ```
dykstrom commented 1 year ago

Statements Used in Procedures (SUB, FUNCTION, DEF FN) are also currently shown in the same face as Control-Flow, but if there are any spare font-lock categories left, it may look better if they were subtly different.

It is also possible to create new font-lock categories. I don't know if that is considered good style though. One could do something like this:

(defface font-lock-operator-face
  '((((class grayscale) (background light)) :foreground "Gray90" :weight bold)
    (((class grayscale) (background dark))  :foreground "DimGray" :weight bold)
    (((class color) (min-colors 88) (background light)) :foreground "ForestGreen")
    (((class color) (min-colors 88) (background dark))  :foreground "PaleGreen")
    (((class color) (min-colors 16) (background light)) :foreground "ForestGreen")
    (((class color) (min-colors 16) (background dark))  :foreground "PaleGreen")
    (((class color) (min-colors 8)) :foreground "green")
    (t :weight bold :underline t))
  "Font Lock mode face used to highlight operators."
  :group 'font-lock-faces)

(defvar font-lock-operator-face 'font-lock-operator-face
  "Face name to use for operators.")
dykstrom commented 1 year ago

One feature it has that basic-mode.el should steal acquire is highlighting line numbers when they are referenced by statements like GOTO 10 in the line number color.

This is a good idea. But maybe it should be a separate issue, because it has nothing to do with highlighting categories?

hackerb9 commented 1 year ago

It is also possible to create new font-lock categories. I don't know if that is considered good style though.

I like that idea. I also don't know about the style guidelines, but I think it should be fine since it would only affect BASIC mode.

Creating new categories and aliasing the existing ones (functions/keywords/builtins) would allow categories that make sense for BASIC. I think the QBASIC manual is a good starting point, but I'd suggest merging some of the similar categories:

Of course, the categories from that particular appendix are not exhaustive as they do not cover the more day-to-day categories:

Click to see the full list of QBASIC reserved words. ```BASIC ABS ACCESS ALIAS AND ANY APPEND AS ASC ATN BASE BEEP BINARY BLOAD BSAVE BYVAL CALL CALLS CASE CDBL CDECL CHAIN CHDIR CHR$ CINT CIRCLE CLEAR CLNG CLOSE CLS COLOR COM COMMANDS COMMON CONST COS CSNG CSRLIN CVD CVDMBF CVI CVL CVS CVSMBF DATA DATES DECLARE DEF DEFDBL DEFINT DEFLNG DEFSNG DEFSTR DIM DO DOUBLE DRAW ELSE ELSEIF END ENDIF ENVIRON ENVIRONS EOF EQV ERASE ERDEV ERDEVS ERL ERR ERROR EXIT EXP FIELD FILEATTR FILES FIX FOR FRE FREEFILE FUNCTION GET GOSUB GOTO HEX$ IF IMP INKEYS INP INPUT INPUTS INSTR INT INTEGER IOCTL IOCTLS IS KEY KILL LBOUND LCASES LEFTS LEN LET LINE LIST LOC LOCAL LOCATE LOCK LOF LOG LONG LOOP LPOS LPRINT LSET LTRIMS MID$ MKD$ MKDIR MKDMBFS MKI$ MKL$ MKSMBFS MKSS MOD NAME NEXT NOT OCT$ OFF ON OPEN OPTION OR OUT OUTPUT PAINT PALETTE PCOPY PEEK PEN PLAY PMAP POINT POKE POS PRESET PRINT PSET PUT RANDOM RANDOMIZE READ REDIM REM RESET RESTORE RESUME RETURN RIGHTS RMDIR RND RSET RTRIMS RUN SADD SCREEN SEEK SEG SELECT SETMEM SGN SHARED SHELL SIGNAL SIN SINGLE SLEEP SOUND SPACES SPC SQR STATIC STEP STICK STOP STR$ STRIG STRING STRINGS SUB SWAP SYSTEM TAB TAN THEN TIMER TIMES TO TROFF TRON TYPE UBOUND UCASES UEVENT UNLOCK UNTIL USING VAL VARPTR VARPTRS VARSEG VIEW WAIT WEND WHILE WIDTH WINDOW WRITE XOR ```