diff options
-rw-r--r-- | pygments/lexers/_mapping.py | 1 | ||||
-rw-r--r-- | pygments/lexers/basic.py | 99 | ||||
-rw-r--r-- | tests/examplefiles/example.bbc | 156 |
3 files changed, 254 insertions, 2 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py index e8838008..3fbb1df8 100644 --- a/pygments/lexers/_mapping.py +++ b/pygments/lexers/_mapping.py @@ -48,6 +48,7 @@ LEXERS = { 'AutoItLexer': ('pygments.lexers.automation', 'AutoIt', ('autoit',), ('*.au3',), ('text/x-autoit',)), 'AutohotkeyLexer': ('pygments.lexers.automation', 'autohotkey', ('ahk', 'autohotkey'), ('*.ahk', '*.ahkl'), ('text/x-autohotkey',)), 'AwkLexer': ('pygments.lexers.textedit', 'Awk', ('awk', 'gawk', 'mawk', 'nawk'), ('*.awk',), ('application/x-awk',)), + 'BBCBasicLexer': ('pygments.lexers.basic', 'BBC Basic', ('bbcbasic',), ('*.bbc',), ()), 'BBCodeLexer': ('pygments.lexers.markup', 'BBCode', ('bbcode',), (), ('text/x-bbcode',)), 'BCLexer': ('pygments.lexers.algebra', 'BC', ('bc',), ('*.bc',), ()), 'BSTLexer': ('pygments.lexers.bibtex', 'BST', ('bst', 'bst-pybtex'), ('*.bst',), ()), diff --git a/pygments/lexers/basic.py b/pygments/lexers/basic.py index b0409386..4d957c2b 100644 --- a/pygments/lexers/basic.py +++ b/pygments/lexers/basic.py @@ -18,7 +18,8 @@ from pygments.lexers import _vbscript_builtins __all__ = ['BlitzBasicLexer', 'BlitzMaxLexer', 'MonkeyLexer', 'CbmBasicV2Lexer', - 'QBasicLexer', 'VBScriptLexer'] + 'QBasicLexer', 'VBScriptLexer', 'BBCBasicLexer'] + class BlitzMaxLexer(RegexLexer): @@ -561,4 +562,98 @@ class VBScriptLexer(RegexLexer): (r'"', String.Double, '#pop'), (r'\n', Error, '#pop'), # Unterminated string ], - }
\ No newline at end of file + } + + +class BBCBasicLexer(RegexLexer): + """ + BBC Basic was supplied on the BBC Micro, and later Acorn RISC OS. + It is also used by BBC Basic For Windows. + + .. versionadded:: 2.4???? + """ + base_keywords = ['OTHERWISE', 'AND', 'DIV', 'EOR', 'MOD', 'OR', 'ERROR', + 'LINE', 'OFF', 'STEP', 'SPC', 'TAB', 'ELSE', 'THEN', + 'OPENIN', 'PTR', 'PAGE', 'TIME', 'LOMEM', 'HIMEM', 'ABS', + 'ACS', 'ADVAL', 'ASC', 'ASN', 'ATN', 'BGET', 'COS', 'COUNT', + 'DEG', 'ERL', 'ERR', 'EVAL', 'EXP', 'EXT', 'FALSE', 'FN', + 'GET', 'INKEY', 'INSTR', 'INT', 'LEN', 'LN', 'LOG', 'NOT', + 'OPENUP', 'OPENOUT', 'PI', 'POINT', 'POS', 'RAD', 'RND', + 'SGN', 'SIN', 'SQR', 'TAN', 'TO', 'TRUE', 'USR', 'VAL', + 'VPOS', 'CHR$', 'GET$', 'INKEY$', 'LEFT$', 'MID$', + 'RIGHT$', 'STR$', 'STRING$', 'EOF', 'PTR', 'PAGE', 'TIME', + 'LOMEM', 'HIMEM', 'SOUND', 'BPUT', 'CALL', 'CHAIN', 'CLEAR', + 'CLOSE', 'CLG', 'CLS', 'DATA', 'DEF', 'DIM', 'DRAW', 'END', + 'ENDPROC', 'ENVELOPE', 'FOR', 'GOSUB', 'GOTO', 'GCOL', 'IF', + 'INPUT', 'LET', 'LOCAL', 'MODE', 'MOVE', 'NEXT', 'ON', + 'VDU', 'PLOT', 'PRINT', 'PROC', 'READ', 'REM', 'REPEAT', + 'REPORT', 'RESTORE', 'RETURN', 'RUN', 'STOP', 'COLOUR', + 'TRACE', 'UNTIL', 'WIDTH', 'OSCLI'] + + basic5_keywords = ['WHEN', 'OF', 'ENDCASE', 'ENDIF', 'ENDWHILE', 'CASE', + 'CIRCLE', 'FILL', 'ORIGIN', 'POINT', 'RECTANGLE', 'SWAP', + 'WHILE', 'WAIT', 'MOUSE', 'QUIT', 'SYS', 'INSTALL', + 'LIBRARY', 'TINT', 'ELLIPSE', 'BEATS', 'TEMPO', 'VOICES', + 'VOICE', 'STEREO', 'OVERLAY', 'APPEND', 'AUTO', 'CRUNCH', + 'DELETE', 'EDIT', 'HELP', 'LIST', 'LOAD', 'LVAR', 'NEW', + 'OLD', 'RENUMBER', 'SAVE', 'TEXTLOAD', 'TEXTSAVE', + 'TWIN', 'TWINO', 'INSTALL', 'SUM', 'BEAT'] + + + name = 'BBC Basic' + aliases = ['bbcbasic'] + filenames = ['*.bbc'] + + tokens = { + 'root': [ + (r"[0-9]+", Name.Label), + (r"(\*)([^\n]*)", + bygroups(Keyword.Pseudo, Comment.Special)), + (r"", Whitespace, 'code'), + ], + + 'code': [ + (r"(REM)([^\n]*)", + bygroups(Keyword.Declaration, Comment.Single)), + (r'\n', Whitespace, 'root'), + (r'\s+', Whitespace), + (r':', Comment.Preproc), + + # Some special cases to make functions come out nicer + (r'(DEF)(\s*)(FN|PROC)([A-Za-z_@][A-Za-z0-9_@]*)', + bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration, Name.Function)), + (r'(FN|PROC)([A-Za-z_@][A-Za-z0-9_@]*)', + bygroups(Keyword, Name.Function)), + + (r'(GOTO|GOSUB|THEN|RESTORE)(\s*)(\d+)', + bygroups(Keyword, Whitespace, Name.Label)), + + (r'(TRUE|FALSE)', Keyword.Constant), + (r'(PAGE|LOMEM|HIMEM|TIME|WIDTH|ERL|ERR|REPORT\$|POS|VPOS|VOICES)', Keyword.Pseudo), + + (words(base_keywords), Keyword), + (words(basic5_keywords), Keyword), + + ('"', String.Double, 'string'), + + ('%[01]{1,32}', Number.Bin), + ('&[0-9a-f]{1,8}', Number.Hex), + + (r'[+-]?[0-9]+\.[0-9]*(E[+-]?[0-9]+)?', Number.Float), + (r'[+-]?\.[0-9]+(E[+-]?[0-9]+)?', Number.Float), + (r'[+-]?[0-9]+E[+-]?[0-9]+', Number.Float), + (r'[+-]?\d+', Number.Integer), + + (r'([A-Za-z_@][A-Za-z0-9_@]*[%$]?)', Name.Variable), + (r'([+\-]=|[$!|?+\-*/%^=><();]|>=|<=|<>|<<|>>|>>>|,)', Operator), + ], + 'string': [ + (r'[^"\n]+', String.Double), + (r'"', String.Double, '#pop'), + (r'\n', Error, 'root'), # Unterminated string + ], + } + + def analyse_text(text): + if text.startswith('10REM >') or text.startswith('REM >'): + return 0.9 diff --git a/tests/examplefiles/example.bbc b/tests/examplefiles/example.bbc new file mode 100644 index 00000000..ebdb8537 --- /dev/null +++ b/tests/examplefiles/example.bbc @@ -0,0 +1,156 @@ +10REM >EIRC +20REM The simplest IRC client you can write. Maybe. +30REM (C) Justin Fletcher, 1998 +40: +50END=PAGE+1024*16 +60REM Change these if you wish +70host$="irc.stealth.net" +80port=6667 +90nick$="eirc" +100ourchan$="#acorn" +110: +120REM Start connecting to a host +130SYS "ESocket_ConnectToHost",host$,port TO handle +140REPEAT +150 SYS "ESocket_CheckState",handle TO state +160 IF state<-1 THENSYS "ESocket_Forget",handle:SYS "ESocket_DecodeState",state TO a$:ERROR 1,"Failed ("+a$+")" +170UNTIL state=4 +180: +190REM We are now connected +200PRINT"Connected" +210: +220REM Log on to the server +230SYS "ESocket_SendLine",handle,"USER "+nick$+" x x :"+nick$ +240SYS "ESocket_SendLine",handle,"NICK "+nick$ +250SYS "ESocket_SendLine",handle,"JOIN "+ourchan$ +260REM Install a monitor so that we don't waste time +270SYS "ESocket_Monitor",0,handle TO monitor +280SYS "ESocket_ResetMonitor",monitor,0 TO polladdr% +290: +300REM If we crash, we should tidy up after ourselves +310ON ERROR SYS "XESocket_Forget",handle:SYS "XESocket_Forget",monitor:ERROR EXT ERR,REPORT$+" at line "+STR$ERL +320: +330REM Memory buffer for our data +340bufsize%=1024 +350DIM buf% bufsize% +360: +370input$="":REM The input line +380REPEAT +390 REM In a taskwindow we should yield until there is data +400 SYS "OS_UpCall",6,polladdr% +410 IF !polladdr%<>0 THEN +420 REM Reset the monitor for the time being +430 SYS "ESocket_ResetMonitor",monitor,0 TO polladdr% +440 REPEAT +450 REM Read lines from the connection until this buffer is empty +460 SYS "ESocket_ReadLine",handle,buf%,bufsize%,%100 TO ,str,len +470 IF str<>0 AND $str<>"" THEN +480 line$=$str +490 IF LEFT$(line$,4)="PING" THEN +500 REM Ping's must be replied to immediately +510 SYS "ESocket_SendLine",handle,"PONG "+MID$(line$,6) +520 ELSE +530 REM Extract source info +540 from$=MID$(LEFT$(line$,INSTR(line$+" "," ")-1),2) +550 line$=MID$(line$,INSTR(line$+" "," ")+1) +560 uid$=LEFT$(from$,INSTR(from$+"!","!")-1) +570 com$=LEFT$(line$,INSTR(line$+" "," ")-1) +580 line$=MID$(line$,INSTR(line$+" "," ")+1) +590 REM remove the input line +600 IF input$<>"" THENFORI=1TOLEN(input$):VDU127:NEXT +610 CASE FNupper(com$) OF +620 WHEN "PRIVMSG" +630 REM Extract the destination +640 chan$=LEFT$(line$,INSTR(line$+" "," ")-1) +650 line$=MID$(line$,INSTR(line$+" "," ")+2):REM Skip : +660 IF LEFT$(line$,1)=CHR$1 THEN +670 REM CTCP, so respond to it +680 line$=MID$(line$,2,LEN(line$)-2) +690 com$=LEFT$(line$,INSTR(line$+" "," ")-1) +700 line$=MID$(line$,INSTR(line$+" "," ")+1) +710 CASE FNupper(com$) OF +720 WHEN "PING" +730 REM Ping lag timing +740 line$="PONG "+line$ +750 PRINTuid$;" pinged us" +760 WHEN "VERSION" +770 REM Version checking +780 line$="VERSION EIRC 1.00 (c) Justin Fletcher" +790 PRINTuid$;" wanted our version" +800 WHEN "ACTION" +810 PRINT"* ";uid$;" ";line$ +820 line$="" +830 OTHERWISE +840 REM everything else is an error +850 line$="ERRMSG "+com$+" not understood" +860 PRINT"CTCP '";com$;"' from ";uid$;" (";line$;")" +870 ENDCASE +880 IF line$<>"" THEN +890 SYS "ESocket_SendLine",handle,"NOTICE "+uid$+" :"+CHR$1+line$+CHR$1 +900 ENDIF +910 ELSE +920 REM Somebody said something... +930 PRINT"<";uid$;"> ";FNsafe(line$) +940 ENDIF +950 WHEN "JOIN" +960 REM We (or someone else) has joined the channel +970 chan$=LEFT$(line$,INSTR(line$+" "," ")):REM Skip : +980 IF LEFT$(chan$,1)=":" THENchan$=MID$(chan$,2) +990 PRINTuid$;" has joined ";chan$ +1000 WHEN "PART" +1010 REM Someone else has left the channel +1020 chan$=LEFT$(line$,INSTR(line$+" "," ")-1) +1030 IF LEFT$(chan$,1)=":" THENchan$=MID$(chan$,2) +1040 PRINTuid$;" has left ";chan$ +1050 WHEN "QUIT" +1060 REM Someone else has quit IRC +1070 PRINTuid$;" quit IRC" +1080 OTHERWISE +1090 REM Some unknown command +1100 PRINTuid$;":";com$;":";FNsafe(line$) +1110 ENDCASE +1120 REM Re-display our input line +1130 PRINTinput$; +1140 ENDIF +1150 ENDIF +1160 UNTIL str=0 +1170 ENDIF +1180 b$=INKEY$(0) +1190 IF b$<>"" THEN +1200 CASE b$ OF +1210 WHEN CHR$13 +1220 SYS "ESocket_SendLine",handle,"PRIVMSG "+ourchan$+" :"+input$ +1230 REM Remove the line +1240 IF input$<>"" THENFORI=1TOLEN(input$):VDU127:NEXT +1250 REM We said it... +1260 PRINT"<"+nick$+"> ";input$ +1270 input$="" +1280 WHEN CHR$127,CHR$8 +1290 REM Backspace +1300 IF input$<>"" THENVDU127 +1310 input$=LEFT$(input$) +1320 OTHERWISE +1330 REM Ad to current input +1340 input$+=b$ +1350 PRINTb$; +1360 ENDCASE +1370 ENDIF +1380 REM Has the socket closed +1390 SYS "ESocket_Closed",handle,%0 TO closed +1400UNTIL closed +1410SYS "ESocket_Forget",handle +1420SYS "ESocket_Forget",monitor +1430END +1440: +1450DEFFNupper(a$):LOCAL c$,b$,I +1460FORI=1TOLEN(a$) +1470c$=MID$(a$,I,1):IF c$>="a"ANDc$<="z"THENc$=CHR$(ASC(c$)-32) +1480b$+=c$:NEXT:=b$ +1490 +1500REM Remove control codes +1510DEFFNsafe(line$) +1520LOCAL I +1530FORI=1TOLEN(line$) +1540 IF MID$(line$,I,1)<" " THENMID$(line$,I,1)="*" +1550NEXT +1560=line$ |