summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnteru <bitbucket@ca.sh13.net>2018-11-26 20:14:49 +0000
committerAnteru <bitbucket@ca.sh13.net>2018-11-26 20:14:49 +0000
commitda957c6a2ae6f77f92e060e926627e762d6d6de9 (patch)
tree12f9487a5970864c35041cfb4a82fbf07cf671b0
parentf0c362e06640ebf20207edac5b34b953a0e68a37 (diff)
parent42f986a2427d9c572a33b8b4acef60245ab88536 (diff)
downloadpygments-da957c6a2ae6f77f92e060e926627e762d6d6de9.tar.gz
Merged in nwhetsell/pygments-main (pull request #684)
Update for Csound 6.09.0
-rw-r--r--pygments/lexers/_csound_builtins.py2990
-rw-r--r--pygments/lexers/csound.py453
-rw-r--r--tests/examplefiles/test.csd264
-rw-r--r--tests/examplefiles/test.orc306
-rw-r--r--tests/examplefiles/test.sco32
-rw-r--r--tests/test_csound.py480
6 files changed, 2500 insertions, 2025 deletions
diff --git a/pygments/lexers/_csound_builtins.py b/pygments/lexers/_csound_builtins.py
index e5a9aaf7..56b5a452 100644
--- a/pygments/lexers/_csound_builtins.py
+++ b/pygments/lexers/_csound_builtins.py
@@ -3,1344 +3,1658 @@
pygments.lexers._csound_builtins
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
+ :copyright: Copyright 2006-2018 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
-# Opcodes in Csound 6.05 from
-# csound --list-opcodes
-# except
-# cggoto <http://www.csounds.com/manual/html/cggoto.html>
-# cigoto <http://www.csounds.com/manual/html/cigoto.html>
-# cingoto (undocumented)
-# ckgoto <http://www.csounds.com/manual/html/ckgoto.html>
-# cngoto <http://www.csounds.com/manual/html/cngoto.html>
-# endin <http://www.csounds.com/manual/html/endin.html
-# endop <http://www.csounds.com/manual/html/endop.html
-# goto <http://www.csounds.com/manual/html/goto.html>
-# igoto <http://www.csounds.com/manual/html/igoto.html>
-# instr <http://www.csounds.com/manual/html/instr.html>
-# kgoto <http://www.csounds.com/manual/html/kgoto.html>
-# loop_ge <http://www.csounds.com/manual/html/loop_ge.html>
-# loop_gt <http://www.csounds.com/manual/html/loop_gt.html>
-# loop_le <http://www.csounds.com/manual/html/loop_le.html>
-# loop_lt <http://www.csounds.com/manual/html/loop_lt.html>
-# opcode <http://www.csounds.com/manual/html/opcode.html>
-# return <http://www.csounds.com/manual/html/return.html>
-# rigoto <http://www.csounds.com/manual/html/rigoto.html>
-# tigoto <http://www.csounds.com/manual/html/tigoto.html>
-# timout <http://www.csounds.com/manual/html/timout.html>
-# which are treated as keywords; the scoreline opcodes
-# scoreline <http://www.csounds.com/manual/html/scoreline.html>
-# scoreline_i <http://www.csounds.com/manual/html/scoreline_i.html>
-# which allow Csound Score highlighting; the pyrun opcodes
-# <http://www.csounds.com/manual/html/pyrun.html>
-# pylrun
-# pylruni
-# pylrunt
-# pyrun
-# pyruni
-# pyrunt
-# which allow Python highlighting; and the Lua opcodes
-# lua_exec <http://www.csounds.com/manual/html/lua_exec.html>
-# lua_opdef <http://www.csounds.com/manual/html/lua_opdef.html>
-# which allow Lua highlighting.
-OPCODES = set((
- 'ATSadd',
- 'ATSaddnz',
- 'ATSbufread',
- 'ATScross',
- 'ATSinfo',
- 'ATSinterpread',
- 'ATSpartialtap',
- 'ATSread',
- 'ATSreadnz',
- 'ATSsinnoi',
- 'FLbox',
- 'FLbutBank',
- 'FLbutton',
- 'FLcloseButton',
- 'FLcolor',
- 'FLcolor2',
- 'FLcount',
- 'FLexecButton',
- 'FLgetsnap',
- 'FLgroup',
- 'FLgroupEnd',
- 'FLgroup_end',
- 'FLhide',
- 'FLhvsBox',
- 'FLhvsBoxSetValue',
- 'FLjoy',
- 'FLkeyIn',
- 'FLknob',
- 'FLlabel',
- 'FLloadsnap',
- 'FLmouse',
- 'FLpack',
- 'FLpackEnd',
- 'FLpack_end',
- 'FLpanel',
- 'FLpanelEnd',
- 'FLpanel_end',
- 'FLprintk',
- 'FLprintk2',
- 'FLroller',
- 'FLrun',
- 'FLsavesnap',
- 'FLscroll',
- 'FLscrollEnd',
- 'FLscroll_end',
- 'FLsetAlign',
- 'FLsetBox',
- 'FLsetColor',
- 'FLsetColor2',
- 'FLsetFont',
- 'FLsetPosition',
- 'FLsetSize',
- 'FLsetSnapGroup',
- 'FLsetText',
- 'FLsetTextColor',
- 'FLsetTextSize',
- 'FLsetTextType',
- 'FLsetVal',
- 'FLsetVal_i',
- 'FLsetVali',
- 'FLsetsnap',
- 'FLshow',
- 'FLslidBnk',
- 'FLslidBnk2',
- 'FLslidBnk2Set',
- 'FLslidBnk2Setk',
- 'FLslidBnkGetHandle',
- 'FLslidBnkSet',
- 'FLslidBnkSetk',
- 'FLslider',
- 'FLtabs',
- 'FLtabsEnd',
- 'FLtabs_end',
- 'FLtext',
- 'FLupdate',
- 'FLvalue',
- 'FLvkeybd',
- 'FLvslidBnk',
- 'FLvslidBnk2',
- 'FLxyin',
- 'MixerClear',
- 'MixerGetLevel',
- 'MixerReceive',
- 'MixerSend',
- 'MixerSetLevel',
- 'MixerSetLevel_i',
- 'OSCinit',
- 'OSClisten',
- 'OSCsend',
- 'a',
- 'abs',
- 'active',
- 'adsr',
- 'adsyn',
- 'adsynt',
- 'adsynt2',
- 'aftouch',
- 'alpass',
- 'alwayson',
- 'ampdb',
- 'ampdbfs',
- 'ampmidi',
- 'ampmidid',
- 'areson',
- 'aresonk',
- 'array',
- 'atone',
- 'atonek',
- 'atonex',
- 'babo',
- 'balance',
- 'bamboo',
- 'barmodel',
- 'bbcutm',
- 'bbcuts',
- 'betarand',
- 'bexprnd',
- 'bformdec',
- 'bformdec1',
- 'bformenc',
- 'bformenc1',
- 'binit',
- 'biquad',
- 'biquada',
- 'birnd',
- 'bqrez',
- 'buchla',
- 'butbp',
- 'butbr',
- 'buthp',
- 'butlp',
- 'butterbp',
- 'butterbr',
- 'butterhp',
- 'butterlp',
- 'button',
- 'buzz',
- 'c2r',
- 'cabasa',
- 'cauchy',
- 'cauchyi',
- 'ceil',
- 'cell',
- 'cent',
- 'centroid',
- 'ceps',
- #'cggoto',
- 'chanctrl',
- 'changed',
- 'chani',
- 'chano',
- 'chebyshevpoly',
- 'checkbox',
- 'chn_S',
- 'chn_a',
- 'chn_k',
- 'chnclear',
- 'chnexport',
- 'chnget',
- 'chnmix',
- 'chnparams',
- 'chnset',
- 'chuap',
- #'cigoto',
- #'cingoto',
- #'ckgoto',
- 'clear',
- 'clfilt',
- 'clip',
- 'clockoff',
- 'clockon',
- 'cmplxprod',
- #'cngoto',
- 'comb',
- 'combinv',
- 'compilecsd',
- 'compileorc',
- 'compilestr',
- 'compress',
- 'connect',
- 'control',
- 'convle',
- 'convolve',
- 'copy2ftab',
- 'copy2ttab',
- 'copya2ftab',
- 'copyf2array',
- 'cos',
- 'cosh',
- 'cosinv',
- 'cosseg',
- 'cossegb',
- 'cossegr',
- 'cps2pch',
- 'cpsmidi',
- 'cpsmidib',
- 'cpsmidinn',
- 'cpsoct',
- 'cpspch',
- 'cpstmid',
- 'cpstun',
- 'cpstuni',
- 'cpsxpch',
- 'cpuprc',
- 'cross2',
- 'crossfm',
- 'crossfmi',
- 'crossfmpm',
- 'crossfmpmi',
- 'crosspm',
- 'crosspmi',
- 'crunch',
- 'ctlchn',
- 'ctrl14',
- 'ctrl21',
- 'ctrl7',
- 'ctrlinit',
- 'cuserrnd',
- 'dam',
- 'date',
- 'dates',
- 'db',
- 'dbamp',
- 'dbfsamp',
- 'dcblock',
- 'dcblock2',
- 'dconv',
- 'delay',
- 'delay1',
- 'delayk',
- 'delayr',
- 'delayw',
- 'deltap',
- 'deltap3',
- 'deltapi',
- 'deltapn',
- 'deltapx',
- 'deltapxw',
- 'denorm',
- 'diff',
- 'diskgrain',
- 'diskin',
- 'diskin2',
- 'dispfft',
- 'display',
- 'distort',
- 'distort1',
- 'divz',
- 'doppler',
- 'downsamp',
- 'dripwater',
- 'dumpk',
- 'dumpk2',
- 'dumpk3',
- 'dumpk4',
- 'duserrnd',
- 'dust',
- 'dust2',
- #'endin',
- #'endop',
- 'envlpx',
- 'envlpxr',
- 'ephasor',
- 'eqfil',
- 'evalstr',
- 'event',
- 'event_i',
- 'exciter',
- 'exitnow',
- 'exp',
- 'expcurve',
- 'expon',
- 'exprand',
- 'exprandi',
- 'expseg',
- 'expsega',
- 'expsegb',
- 'expsegba',
- 'expsegr',
- 'fareylen',
- 'fareyleni',
- 'faustaudio',
- 'faustcompile',
- 'faustctl',
- 'faustgen',
- 'fft',
- 'fftinv',
- 'ficlose',
- 'filebit',
- 'filelen',
- 'filenchnls',
- 'filepeak',
- 'filesr',
- 'filevalid',
- 'fillarray',
- 'filter2',
- 'fin',
- 'fini',
- 'fink',
- 'fiopen',
- 'flanger',
- 'flashtxt',
- 'flooper',
- 'flooper2',
- 'floor',
- 'fluidAllOut',
- 'fluidCCi',
- 'fluidCCk',
- 'fluidControl',
- 'fluidEngine',
- 'fluidLoad',
- 'fluidNote',
- 'fluidOut',
- 'fluidProgramSelect',
- 'fluidSetInterpMethod',
- 'fmb3',
- 'fmbell',
- 'fmmetal',
- 'fmpercfl',
- 'fmrhode',
- 'fmvoice',
- 'fmwurlie',
- 'fof',
- 'fof2',
- 'fofilter',
- 'fog',
- 'fold',
- 'follow',
- 'follow2',
- 'foscil',
- 'foscili',
- 'fout',
- 'fouti',
- 'foutir',
- 'foutk',
- 'fprintks',
- 'fprints',
- 'frac',
- 'fractalnoise',
- 'freeverb',
- 'ftchnls',
- 'ftconv',
- 'ftcps',
- 'ftfree',
- 'ftgen',
- 'ftgenonce',
- 'ftgentmp',
- 'ftlen',
- 'ftload',
- 'ftloadk',
- 'ftlptim',
- 'ftmorf',
- 'ftresize',
- 'ftresizei',
- 'ftsave',
- 'ftsavek',
- 'ftsr',
- 'gain',
- 'gainslider',
- 'gauss',
- 'gaussi',
- 'gausstrig',
- 'gbuzz',
- 'genarray',
- 'genarray_i',
- 'gendy',
- 'gendyc',
- 'gendyx',
- 'getcfg',
- 'getcol',
- 'getrow',
- 'gogobel',
- #'goto',
- 'grain',
- 'grain2',
- 'grain3',
- 'granule',
- 'guiro',
- 'harmon',
- 'harmon2',
- 'harmon3',
- 'harmon4',
- 'hdf5read',
- 'hdf5write',
- 'hilbert',
- 'hrtfearly',
- 'hrtfer',
- 'hrtfmove',
- 'hrtfmove2',
- 'hrtfreverb',
- 'hrtfstat',
- 'hsboscil',
- 'hvs1',
- 'hvs2',
- 'hvs3',
- 'i',
- 'iceps',
- #'igoto',
- 'ihold',
- 'imagecreate',
- 'imagefree',
- 'imagegetpixel',
- 'imageload',
- 'imagesave',
- 'imagesetpixel',
- 'imagesize',
- 'in',
- 'in32',
- 'inch',
- 'inh',
- 'init',
- 'initc14',
- 'initc21',
- 'initc7',
- 'inleta',
- 'inletf',
- 'inletk',
- 'inletkid',
- 'inletv',
- 'ino',
- 'inq',
- 'inrg',
- 'ins',
- 'insglobal',
- 'insremot',
- #'instr',
- 'int',
- 'integ',
- 'interp',
- 'invalue',
- 'inx',
- 'inz',
- 'jitter',
- 'jitter2',
- 'jspline',
- 'k',
- #'kgoto',
- 'ktableseg',
- 'lenarray',
- 'lentab',
- 'lfo',
- 'limit',
- 'line',
- 'linen',
- 'linenr',
- 'lineto',
- 'linrand',
- 'linseg',
- 'linsegb',
- 'linsegr',
- 'locsend',
- 'locsig',
- 'log',
- 'log10',
- 'log2',
- 'logbtwo',
- 'logcurve',
- #'loop_ge',
- #'loop_gt',
- #'loop_le',
- #'loop_lt',
- 'loopseg',
- 'loopsegp',
- 'looptseg',
- 'loopxseg',
- 'lorenz',
- 'loscil',
- 'loscil3',
- 'loscilx',
- 'lowpass2',
- 'lowres',
- 'lowresx',
- 'lpf18',
- 'lpform',
- 'lpfreson',
- 'lphasor',
- 'lpinterp',
- 'lposcil',
- 'lposcil3',
- 'lposcila',
- 'lposcilsa',
- 'lposcilsa2',
- 'lpread',
- 'lpreson',
- 'lpshold',
- 'lpsholdp',
- 'lpslot',
- #'lua_exec',
- 'lua_ikopcall',
- #'lua_opdef',
- 'mac',
- 'maca',
- 'madsr',
- 'mags',
- 'mandel',
- 'mandol',
- 'maparray',
- 'maparray_i',
- 'marimba',
- 'massign',
- 'max',
- 'max_k',
- 'maxabs',
- 'maxabsaccum',
- 'maxaccum',
- 'maxalloc',
- 'maxarray',
- 'maxtab',
- 'mclock',
- 'mdelay',
- 'median',
- 'mediank',
- 'metro',
- 'midglobal',
- 'midic14',
- 'midic21',
- 'midic7',
- 'midichannelaftertouch',
- 'midichn',
- 'midicontrolchange',
- 'midictrl',
- 'mididefault',
- 'midifilestatus',
- 'midiin',
- 'midinoteoff',
- 'midinoteoncps',
- 'midinoteonkey',
- 'midinoteonoct',
- 'midinoteonpch',
- 'midion',
- 'midion2',
- 'midiout',
- 'midipgm',
- 'midipitchbend',
- 'midipolyaftertouch',
- 'midiprogramchange',
- 'miditempo',
- 'midremot',
- 'min',
- 'minabs',
- 'minabsaccum',
- 'minaccum',
- 'minarray',
- 'mincer',
- 'mintab',
- 'mirror',
- 'mode',
- 'modmatrix',
- 'monitor',
- 'moog',
- 'moogladder',
- 'moogvcf',
- 'moogvcf2',
- 'moscil',
- 'mp3bitrate',
- 'mp3in',
- 'mp3len',
- 'mp3nchnls',
- 'mp3sr',
- 'mpulse',
- 'mrtmsg',
- 'multitap',
- 'mute',
- 'mxadsr',
- 'nestedap',
- 'nlalp',
- 'nlfilt',
- 'nlfilt2',
- 'noise',
- 'noteoff',
- 'noteon',
- 'noteondur',
- 'noteondur2',
- 'notnum',
- 'nreverb',
- 'nrpn',
- 'nsamp',
- 'nstance',
- 'nstrnum',
- 'ntrpol',
- 'octave',
- 'octcps',
- 'octmidi',
- 'octmidib',
- 'octmidinn',
- 'octpch',
- #'opcode',
- 'oscbnk',
- 'oscil',
- 'oscil1',
- 'oscil1i',
- 'oscil3',
- 'oscili',
- 'oscilikt',
- 'osciliktp',
- 'oscilikts',
- 'osciln',
- 'oscils',
- 'oscilx',
- 'out',
- 'out32',
- 'outc',
- 'outch',
- 'outh',
- 'outiat',
- 'outic',
- 'outic14',
- 'outipat',
- 'outipb',
- 'outipc',
- 'outkat',
- 'outkc',
- 'outkc14',
- 'outkpat',
- 'outkpb',
- 'outkpc',
- 'outleta',
- 'outletf',
- 'outletk',
- 'outletkid',
- 'outletv',
- 'outo',
- 'outq',
- 'outq1',
- 'outq2',
- 'outq3',
- 'outq4',
- 'outrg',
- 'outs',
- 'outs1',
- 'outs2',
- 'outvalue',
- 'outx',
- 'outz',
- 'p',
- 'pan',
- 'pan2',
- 'pareq',
- 'partials',
- 'partikkel',
- 'partikkelget',
- 'partikkelset',
- 'partikkelsync',
- 'passign',
- 'pcauchy',
- 'pchbend',
- 'pchmidi',
- 'pchmidib',
- 'pchmidinn',
- 'pchoct',
- 'pconvolve',
- 'pcount',
- 'pdclip',
- 'pdhalf',
- 'pdhalfy',
- 'peak',
- 'pgmassign',
- 'pgmchn',
- 'phaser1',
- 'phaser2',
- 'phasor',
- 'phasorbnk',
- 'phs',
- 'pindex',
- 'pinker',
- 'pinkish',
- 'pitch',
- 'pitchac',
- 'pitchamdf',
- 'planet',
- 'platerev',
- 'plltrack',
- 'pluck',
- 'poisson',
- 'pol2rect',
- 'polyaft',
- 'polynomial',
- 'pop',
- 'pop_f',
- 'port',
- 'portk',
- 'poscil',
- 'poscil3',
- 'pow',
- 'powershape',
- 'powoftwo',
- 'prealloc',
- 'prepiano',
- 'print',
- 'print_type',
- 'printf',
- 'printf_i',
- 'printk',
- 'printk2',
- 'printks',
- 'printks2',
- 'prints',
- 'product',
- 'pset',
- 'ptable',
- 'ptable3',
- 'ptablei',
- 'ptableiw',
- 'ptablew',
- 'ptrack',
- 'push',
- 'push_f',
- 'puts',
- 'pvadd',
- 'pvbufread',
- 'pvcross',
- 'pvinterp',
- 'pvoc',
- 'pvread',
- 'pvs2array',
- 'pvs2tab',
- 'pvsadsyn',
- 'pvsanal',
- 'pvsarp',
- 'pvsbandp',
- 'pvsbandr',
- 'pvsbin',
- 'pvsblur',
- 'pvsbuffer',
- 'pvsbufread',
- 'pvsbufread2',
- 'pvscale',
- 'pvscent',
- 'pvsceps',
- 'pvscross',
- 'pvsdemix',
- 'pvsdiskin',
- 'pvsdisp',
- 'pvsenvftw',
- 'pvsfilter',
- 'pvsfread',
- 'pvsfreeze',
- 'pvsfromarray',
- 'pvsftr',
- 'pvsftw',
- 'pvsfwrite',
- 'pvsgain',
- 'pvsgendy',
- 'pvshift',
- 'pvsifd',
- 'pvsin',
- 'pvsinfo',
- 'pvsinit',
- 'pvslock',
- 'pvsmaska',
- 'pvsmix',
- 'pvsmooth',
- 'pvsmorph',
- 'pvsosc',
- 'pvsout',
- 'pvspitch',
- 'pvstanal',
- 'pvstencil',
- 'pvsvoc',
- 'pvswarp',
- 'pvsynth',
- 'pwd',
- 'pyassign',
- 'pyassigni',
- 'pyassignt',
- 'pycall',
- 'pycall1',
- 'pycall1i',
- 'pycall1t',
- 'pycall2',
- 'pycall2i',
- 'pycall2t',
- 'pycall3',
- 'pycall3i',
- 'pycall3t',
- 'pycall4',
- 'pycall4i',
- 'pycall4t',
- 'pycall5',
- 'pycall5i',
- 'pycall5t',
- 'pycall6',
- 'pycall6i',
- 'pycall6t',
- 'pycall7',
- 'pycall7i',
- 'pycall7t',
- 'pycall8',
- 'pycall8i',
- 'pycall8t',
- 'pycalli',
- 'pycalln',
- 'pycallni',
- 'pycallt',
- 'pyeval',
- 'pyevali',
- 'pyevalt',
- 'pyexec',
- 'pyexeci',
- 'pyexect',
- 'pyinit',
- 'pylassign',
- 'pylassigni',
- 'pylassignt',
- 'pylcall',
- 'pylcall1',
- 'pylcall1i',
- 'pylcall1t',
- 'pylcall2',
- 'pylcall2i',
- 'pylcall2t',
- 'pylcall3',
- 'pylcall3i',
- 'pylcall3t',
- 'pylcall4',
- 'pylcall4i',
- 'pylcall4t',
- 'pylcall5',
- 'pylcall5i',
- 'pylcall5t',
- 'pylcall6',
- 'pylcall6i',
- 'pylcall6t',
- 'pylcall7',
- 'pylcall7i',
- 'pylcall7t',
- 'pylcall8',
- 'pylcall8i',
- 'pylcall8t',
- 'pylcalli',
- 'pylcalln',
- 'pylcallni',
- 'pylcallt',
- 'pyleval',
- 'pylevali',
- 'pylevalt',
- 'pylexec',
- 'pylexeci',
- 'pylexect',
- #'pylrun',
- #'pylruni',
- #'pylrunt',
- #'pyrun',
- #'pyruni',
- #'pyrunt',
- 'qinf',
- 'qnan',
- 'r2c',
- 'rand',
- 'randh',
- 'randi',
- 'random',
- 'randomh',
- 'randomi',
- 'rbjeq',
- 'readclock',
- 'readf',
- 'readfi',
- 'readk',
- 'readk2',
- 'readk3',
- 'readk4',
- 'readks',
- 'readscore',
- 'readscratch',
- 'rect2pol',
- 'reinit',
- 'release',
- 'remoteport',
- 'remove',
- 'repluck',
- 'reson',
- 'resonk',
- 'resonr',
- 'resonx',
- 'resonxk',
- 'resony',
- 'resonz',
- 'resyn',
- #'return',
- 'reverb',
- 'reverb2',
- 'reverbsc',
- 'rewindscore',
- 'rezzy',
- 'rfft',
- 'rifft',
- #'rigoto',
- 'rireturn',
- 'rms',
- 'rnd',
- 'rnd31',
- 'round',
- 'rspline',
- 'rtclock',
- 's16b14',
- 's32b14',
- 'samphold',
- 'sandpaper',
- 'scale',
- 'scalearray',
- 'scalet',
- 'scanhammer',
- 'scans',
- 'scantable',
- 'scanu',
- 'schedkwhen',
- 'schedkwhennamed',
- 'schedule',
- 'schedwhen',
- #'scoreline',
- #'scoreline_i',
- 'seed',
- 'sekere',
- 'semitone',
- 'sense',
- 'sensekey',
- 'seqtime',
- 'seqtime2',
- 'serialBegin',
- 'serialEnd',
- 'serialFlush',
- 'serialPrint',
- 'serialRead',
- 'serialWrite',
- 'serialWrite_i',
- 'setcol',
- 'setctrl',
- 'setksmps',
- 'setrow',
- 'setscorepos',
- 'sfilist',
- 'sfinstr',
- 'sfinstr3',
- 'sfinstr3m',
- 'sfinstrm',
- 'sfload',
- 'sflooper',
- 'sfpassign',
- 'sfplay',
- 'sfplay3',
- 'sfplay3m',
- 'sfplaym',
- 'sfplist',
- 'sfpreset',
- 'shaker',
- 'shiftin',
- 'shiftout',
- 'signalflowgraph',
- 'signum',
- 'sin',
- 'sinh',
- 'sininv',
- 'sinsyn',
- 'sleighbells',
- 'slicearray',
- 'slider16',
- 'slider16f',
- 'slider16table',
- 'slider16tablef',
- 'slider32',
- 'slider32f',
- 'slider32table',
- 'slider32tablef',
- 'slider64',
- 'slider64f',
- 'slider64table',
- 'slider64tablef',
- 'slider8',
- 'slider8f',
- 'slider8table',
- 'slider8tablef',
- 'sliderKawai',
- 'sndload',
- 'sndloop',
- 'sndwarp',
- 'sndwarpst',
- 'sockrecv',
- 'sockrecvs',
- 'socksend',
- 'socksends',
- 'soundin',
- 'soundout',
- 'soundouts',
- 'space',
- 'spat3d',
- 'spat3di',
- 'spat3dt',
- 'spdist',
- 'specaddm',
- 'specdiff',
- 'specdisp',
- 'specfilt',
- 'spechist',
- 'specptrk',
- 'specscal',
- 'specsum',
- 'spectrum',
- 'splitrig',
- 'sprintf',
- 'sprintfk',
- 'spsend',
- 'sqrt',
- 'stack',
- 'statevar',
- 'stix',
- 'strcat',
- 'strcatk',
- 'strchar',
- 'strchark',
- 'strcmp',
- 'strcmpk',
- 'strcpy',
- 'strcpyk',
- 'strecv',
- 'streson',
- 'strfromurl',
- 'strget',
- 'strindex',
- 'strindexk',
- 'strlen',
- 'strlenk',
- 'strlower',
- 'strlowerk',
- 'strrindex',
- 'strrindexk',
- 'strset',
- 'strsub',
- 'strsubk',
- 'strtod',
- 'strtodk',
- 'strtol',
- 'strtolk',
- 'strupper',
- 'strupperk',
- 'stsend',
- 'subinstr',
- 'subinstrinit',
- 'sum',
- 'sumarray',
- 'sumtab',
- 'svfilter',
- 'syncgrain',
- 'syncloop',
- 'syncphasor',
- 'system',
- 'system_i',
- 'tab',
- 'tab2pvs',
- 'tab_i',
- 'tabgen',
- 'table',
- 'table3',
- 'table3kt',
- 'tablecopy',
- 'tablefilter',
- 'tablefilteri',
- 'tablegpw',
- 'tablei',
- 'tableicopy',
- 'tableigpw',
- 'tableikt',
- 'tableimix',
- 'tableiw',
- 'tablekt',
- 'tablemix',
- 'tableng',
- 'tablera',
- 'tableseg',
- 'tableshuffle',
- 'tableshufflei',
- 'tablew',
- 'tablewa',
- 'tablewkt',
- 'tablexkt',
- 'tablexseg',
- 'tabmap',
- 'tabmap_i',
- 'tabmorph',
- 'tabmorpha',
- 'tabmorphak',
- 'tabmorphi',
- 'tabplay',
- 'tabrec',
- 'tabslice',
- 'tabsum',
- 'tabw',
- 'tabw_i',
- 'tambourine',
- 'tan',
- 'tanh',
- 'taninv',
- 'taninv2',
- 'tb0',
- 'tb0_init',
- 'tb1',
- 'tb10',
- 'tb10_init',
- 'tb11',
- 'tb11_init',
- 'tb12',
- 'tb12_init',
- 'tb13',
- 'tb13_init',
- 'tb14',
- 'tb14_init',
- 'tb15',
- 'tb15_init',
- 'tb1_init',
- 'tb2',
- 'tb2_init',
- 'tb3',
- 'tb3_init',
- 'tb4',
- 'tb4_init',
- 'tb5',
- 'tb5_init',
- 'tb6',
- 'tb6_init',
- 'tb7',
- 'tb7_init',
- 'tb8',
- 'tb8_init',
- 'tb9',
- 'tb9_init',
- 'tbvcf',
- 'tempest',
- 'tempo',
- 'temposcal',
- 'tempoval',
- #'tigoto',
- 'timedseq',
- 'timeinstk',
- 'timeinsts',
- 'timek',
- 'times',
- #'timout',
- 'tival',
- 'tlineto',
- 'tone',
- 'tonek',
- 'tonex',
- 'tradsyn',
- 'trandom',
- 'transeg',
- 'transegb',
- 'transegr',
- 'trcross',
- 'trfilter',
- 'trhighest',
- 'trigger',
- 'trigseq',
- 'trirand',
- 'trlowest',
- 'trmix',
- 'trscale',
- 'trshift',
- 'trsplit',
- 'turnoff',
- 'turnoff2',
- 'turnon',
- 'unirand',
- 'unwrap',
- 'upsamp',
- 'urd',
- 'vactrol',
- 'vadd',
- 'vadd_i',
- 'vaddv',
- 'vaddv_i',
- 'vaget',
- 'valpass',
- 'vaset',
- 'vbap',
- 'vbap16',
- 'vbap4',
- 'vbap4move',
- 'vbap8',
- 'vbap8move',
- 'vbapg',
- 'vbapgmove',
- 'vbaplsinit',
- 'vbapmove',
- 'vbapz',
- 'vbapzmove',
- 'vcella',
- 'vco',
- 'vco2',
- 'vco2ft',
- 'vco2ift',
- 'vco2init',
- 'vcomb',
- 'vcopy',
- 'vcopy_i',
- 'vdel_k',
- 'vdelay',
- 'vdelay3',
- 'vdelayk',
- 'vdelayx',
- 'vdelayxq',
- 'vdelayxs',
- 'vdelayxw',
- 'vdelayxwq',
- 'vdelayxws',
- 'vdivv',
- 'vdivv_i',
- 'vecdelay',
- 'veloc',
- 'vexp',
- 'vexp_i',
- 'vexpseg',
- 'vexpv',
- 'vexpv_i',
- 'vibes',
- 'vibr',
- 'vibrato',
- 'vincr',
- 'vlimit',
- 'vlinseg',
- 'vlowres',
- 'vmap',
- 'vmirror',
- 'vmult',
- 'vmult_i',
- 'vmultv',
- 'vmultv_i',
- 'voice',
- 'vosim',
- 'vphaseseg',
- 'vport',
- 'vpow',
- 'vpow_i',
- 'vpowv',
- 'vpowv_i',
- 'vpvoc',
- 'vrandh',
- 'vrandi',
- 'vsubv',
- 'vsubv_i',
- 'vtaba',
- 'vtabi',
- 'vtabk',
- 'vtable1k',
- 'vtablea',
- 'vtablei',
- 'vtablek',
- 'vtablewa',
- 'vtablewi',
- 'vtablewk',
- 'vtabwa',
- 'vtabwi',
- 'vtabwk',
- 'vwrap',
- 'waveset',
- 'weibull',
- 'wgbow',
- 'wgbowedbar',
- 'wgbrass',
- 'wgclar',
- 'wgflute',
- 'wgpluck',
- 'wgpluck2',
- 'wguide1',
- 'wguide2',
- 'wiiconnect',
- 'wiidata',
- 'wiirange',
- 'wiisend',
- 'window',
- 'wrap',
- 'writescratch',
- 'wterrain',
- 'xadsr',
- 'xin',
- 'xout',
- 'xscanmap',
- 'xscans',
- 'xscansmap',
- 'xscanu',
- 'xtratim',
- 'xyin',
- 'zacl',
- 'zakinit',
- 'zamod',
- 'zar',
- 'zarg',
- 'zaw',
- 'zawm',
- 'zfilter2',
- 'zir',
- 'ziw',
- 'ziwm',
- 'zkcl',
- 'zkmod',
- 'zkr',
- 'zkw',
- 'zkwm'
-))
+# Opcodes in Csound 6.12.0 at commit 6ca322bd31f1ca907c008616b40a5f237ff449db using
+# python -c "
+# import re, subprocess
+# output = subprocess.Popen(['csound', '--list-opcodes0'], stderr=subprocess.PIPE).communicate()[1]
+# opcodes = output[re.search(r'^$', output, re.M).end():re.search(r'^\d+ opcodes$', output, re.M).start()].split()
+# output = subprocess.Popen(['csound', '--list-opcodes2'], stderr=subprocess.PIPE).communicate()[1]
+# all_opcodes = output[re.search(r'^$', output, re.M).end():re.search(r'^\d+ opcodes$', output, re.M).start()].split()
+# deprecated_opcodes = [opcode for opcode in all_opcodes if opcode not in opcodes]
+# print '''OPCODES = set(\'''
+# {}
+# \'''.split())
+#
+# DEPRECATED_OPCODES = set(\'''
+# {}
+# \'''.split())
+# '''.format('\n'.join(opcodes), '\n'.join(deprecated_opcodes))
+# "
+# except for
+# cggoto csound.com/docs/manual/cggoto.html
+# cigoto csound.com/docs/manual/cigoto.html
+# cingoto (undocumented)
+# ckgoto csound.com/docs/manual/ckgoto.html
+# cngoto csound.com/docs/manual/cngoto.html
+# cnkgoto (undocumented)
+# endin csound.com/docs/manual/endin.html
+# endop csound.com/docs/manual/endop.html
+# goto csound.com/docs/manual/goto.html
+# igoto csound.com/docs/manual/igoto.html
+# instr csound.com/docs/manual/instr.html
+# kgoto csound.com/docs/manual/kgoto.html
+# loop_ge csound.com/docs/manual/loop_ge.html
+# loop_gt csound.com/docs/manual/loop_gt.html
+# loop_le csound.com/docs/manual/loop_le.html
+# loop_lt csound.com/docs/manual/loop_lt.html
+# opcode csound.com/docs/manual/opcode.html
+# reinit csound.com/docs/manual/reinit.html
+# return csound.com/docs/manual/return.html
+# rireturn csound.com/docs/manual/rireturn.html
+# rigoto csound.com/docs/manual/rigoto.html
+# tigoto csound.com/docs/manual/tigoto.html
+# timout csound.com/docs/manual/timout.html
+# which are treated as keywords in csound.py.
+
+OPCODES = set('''
+ATSadd
+ATSaddnz
+ATSbufread
+ATScross
+ATSinfo
+ATSinterpread
+ATSpartialtap
+ATSread
+ATSreadnz
+ATSsinnoi
+FLbox
+FLbutBank
+FLbutton
+FLcloseButton
+FLcolor
+FLcolor2
+FLcount
+FLexecButton
+FLgetsnap
+FLgroup
+FLgroupEnd
+FLgroup_end
+FLhide
+FLhvsBox
+FLhvsBoxSetValue
+FLjoy
+FLkeyIn
+FLknob
+FLlabel
+FLloadsnap
+FLmouse
+FLpack
+FLpackEnd
+FLpack_end
+FLpanel
+FLpanelEnd
+FLpanel_end
+FLprintk
+FLprintk2
+FLroller
+FLrun
+FLsavesnap
+FLscroll
+FLscrollEnd
+FLscroll_end
+FLsetAlign
+FLsetBox
+FLsetColor
+FLsetColor2
+FLsetFont
+FLsetPosition
+FLsetSize
+FLsetSnapGroup
+FLsetText
+FLsetTextColor
+FLsetTextSize
+FLsetTextType
+FLsetVal
+FLsetVal_i
+FLsetVali
+FLsetsnap
+FLshow
+FLslidBnk
+FLslidBnk2
+FLslidBnk2Set
+FLslidBnk2Setk
+FLslidBnkGetHandle
+FLslidBnkSet
+FLslidBnkSetk
+FLslider
+FLtabs
+FLtabsEnd
+FLtabs_end
+FLtext
+FLupdate
+FLvalue
+FLvkeybd
+FLvslidBnk
+FLvslidBnk2
+FLxyin
+JackoAudioIn
+JackoAudioInConnect
+JackoAudioOut
+JackoAudioOutConnect
+JackoFreewheel
+JackoInfo
+JackoInit
+JackoMidiInConnect
+JackoMidiOut
+JackoMidiOutConnect
+JackoNoteOut
+JackoOn
+JackoTransport
+K35_hpf
+K35_lpf
+MixerClear
+MixerGetLevel
+MixerReceive
+MixerSend
+MixerSetLevel
+MixerSetLevel_i
+OSCbundle
+OSCcount
+OSCinit
+OSCinitM
+OSClisten
+OSCraw
+OSCsend
+OSCsend_lo
+S
+STKBandedWG
+STKBeeThree
+STKBlowBotl
+STKBlowHole
+STKBowed
+STKBrass
+STKClarinet
+STKDrummer
+STKFlute
+STKFMVoices
+STKHevyMetl
+STKMandolin
+STKModalBar
+STKMoog
+STKPercFlut
+STKPlucked
+STKResonate
+STKRhodey
+STKSaxofony
+STKShakers
+STKSimple
+STKSitar
+STKStifKarp
+STKTubeBell
+STKVoicForm
+STKWhistle
+STKWurley
+a
+abs
+active
+adsr
+adsyn
+adsynt
+adsynt2
+aftouch
+alpass
+alwayson
+ampdb
+ampdbfs
+ampmidi
+ampmidid
+areson
+aresonk
+atone
+atonek
+atonex
+babo
+balance
+balance2
+bamboo
+barmodel
+bbcutm
+bbcuts
+beadsynt
+beosc
+betarand
+bexprnd
+bformdec1
+bformenc1
+binit
+biquad
+biquada
+birnd
+bpf
+bpfcos
+bqrez
+butbp
+butbr
+buthp
+butlp
+butterbp
+butterbr
+butterhp
+butterlp
+button
+buzz
+c2r
+cabasa
+cauchy
+cauchyi
+cbrt
+ceil
+cell
+cent
+centroid
+ceps
+cepsinv
+chanctrl
+changed
+changed2
+chani
+chano
+chebyshevpoly
+checkbox
+chn_S
+chn_a
+chn_k
+chnclear
+chnexport
+chnget
+chngetks
+chnmix
+chnparams
+chnset
+chnsetks
+chuap
+clear
+clfilt
+clip
+clockoff
+clockon
+cmp
+cmplxprod
+comb
+combinv
+compilecsd
+compileorc
+compilestr
+compress
+compress2
+connect
+control
+convle
+convolve
+copya2ftab
+copyf2array
+cos
+cosh
+cosinv
+cosseg
+cossegb
+cossegr
+cps2pch
+cpsmidi
+cpsmidib
+cpsmidinn
+cpsoct
+cpspch
+cpstmid
+cpstun
+cpstuni
+cpsxpch
+cpumeter
+cpuprc
+cross2
+crossfm
+crossfmi
+crossfmpm
+crossfmpmi
+crosspm
+crosspmi
+crunch
+ctlchn
+ctrl14
+ctrl21
+ctrl7
+ctrlinit
+cuserrnd
+dam
+date
+dates
+db
+dbamp
+dbfsamp
+dcblock
+dcblock2
+dconv
+dct
+dctinv
+deinterleave
+delay
+delay1
+delayk
+delayr
+delayw
+deltap
+deltap3
+deltapi
+deltapn
+deltapx
+deltapxw
+denorm
+diff
+diode_ladder
+directory
+diskgrain
+diskin
+diskin2
+dispfft
+display
+distort
+distort1
+divz
+doppler
+dot
+downsamp
+dripwater
+dssiactivate
+dssiaudio
+dssictls
+dssiinit
+dssilist
+dumpk
+dumpk2
+dumpk3
+dumpk4
+duserrnd
+dust
+dust2
+envlpx
+envlpxr
+ephasor
+eqfil
+evalstr
+event
+event_i
+exciter
+exitnow
+exp
+expcurve
+expon
+exprand
+exprandi
+expseg
+expsega
+expsegb
+expsegba
+expsegr
+fareylen
+fareyleni
+faustaudio
+faustcompile
+faustctl
+faustdsp
+faustgen
+faustplay
+fft
+fftinv
+ficlose
+filebit
+filelen
+filenchnls
+filepeak
+filescal
+filesr
+filevalid
+fillarray
+filter2
+fin
+fini
+fink
+fiopen
+flanger
+flashtxt
+flooper
+flooper2
+floor
+fmanal
+fmax
+fmb3
+fmbell
+fmin
+fmmetal
+fmod
+fmpercfl
+fmrhode
+fmvoice
+fmwurlie
+fof
+fof2
+fofilter
+fog
+fold
+follow
+follow2
+foscil
+foscili
+fout
+fouti
+foutir
+foutk
+fprintks
+fprints
+frac
+fractalnoise
+framebuffer
+freeverb
+ftaudio
+ftchnls
+ftconv
+ftcps
+ftfree
+ftgen
+ftgenonce
+ftgentmp
+ftlen
+ftload
+ftloadk
+ftlptim
+ftmorf
+ftom
+ftprint
+ftresize
+ftresizei
+ftsamplebank
+ftsave
+ftsavek
+ftslice
+ftsr
+gain
+gainslider
+gauss
+gaussi
+gausstrig
+gbuzz
+genarray
+genarray_i
+gendy
+gendyc
+gendyx
+getcfg
+getcol
+getftargs
+getrow
+getrowlin
+getseed
+gogobel
+grain
+grain2
+grain3
+granule
+guiro
+harmon
+harmon2
+harmon3
+harmon4
+hdf5read
+hdf5write
+hilbert
+hilbert2
+hrtfearly
+hrtfmove
+hrtfmove2
+hrtfreverb
+hrtfstat
+hsboscil
+hvs1
+hvs2
+hvs3
+hypot
+i
+ihold
+imagecreate
+imagefree
+imagegetpixel
+imageload
+imagesave
+imagesetpixel
+imagesize
+in
+in32
+inch
+inh
+init
+initc14
+initc21
+initc7
+inleta
+inletf
+inletk
+inletkid
+inletv
+ino
+inq
+inrg
+ins
+insglobal
+insremot
+int
+integ
+interleave
+interp
+invalue
+inx
+inz
+jacktransport
+jitter
+jitter2
+joystick
+jspline
+k
+la_i_add_mc
+la_i_add_mr
+la_i_add_vc
+la_i_add_vr
+la_i_assign_mc
+la_i_assign_mr
+la_i_assign_t
+la_i_assign_vc
+la_i_assign_vr
+la_i_conjugate_mc
+la_i_conjugate_mr
+la_i_conjugate_vc
+la_i_conjugate_vr
+la_i_distance_vc
+la_i_distance_vr
+la_i_divide_mc
+la_i_divide_mr
+la_i_divide_vc
+la_i_divide_vr
+la_i_dot_mc
+la_i_dot_mc_vc
+la_i_dot_mr
+la_i_dot_mr_vr
+la_i_dot_vc
+la_i_dot_vr
+la_i_get_mc
+la_i_get_mr
+la_i_get_vc
+la_i_get_vr
+la_i_invert_mc
+la_i_invert_mr
+la_i_lower_solve_mc
+la_i_lower_solve_mr
+la_i_lu_det_mc
+la_i_lu_det_mr
+la_i_lu_factor_mc
+la_i_lu_factor_mr
+la_i_lu_solve_mc
+la_i_lu_solve_mr
+la_i_mc_create
+la_i_mc_set
+la_i_mr_create
+la_i_mr_set
+la_i_multiply_mc
+la_i_multiply_mr
+la_i_multiply_vc
+la_i_multiply_vr
+la_i_norm_euclid_mc
+la_i_norm_euclid_mr
+la_i_norm_euclid_vc
+la_i_norm_euclid_vr
+la_i_norm_inf_mc
+la_i_norm_inf_mr
+la_i_norm_inf_vc
+la_i_norm_inf_vr
+la_i_norm_max_mc
+la_i_norm_max_mr
+la_i_norm1_mc
+la_i_norm1_mr
+la_i_norm1_vc
+la_i_norm1_vr
+la_i_print_mc
+la_i_print_mr
+la_i_print_vc
+la_i_print_vr
+la_i_qr_eigen_mc
+la_i_qr_eigen_mr
+la_i_qr_factor_mc
+la_i_qr_factor_mr
+la_i_qr_sym_eigen_mc
+la_i_qr_sym_eigen_mr
+la_i_random_mc
+la_i_random_mr
+la_i_random_vc
+la_i_random_vr
+la_i_size_mc
+la_i_size_mr
+la_i_size_vc
+la_i_size_vr
+la_i_subtract_mc
+la_i_subtract_mr
+la_i_subtract_vc
+la_i_subtract_vr
+la_i_t_assign
+la_i_trace_mc
+la_i_trace_mr
+la_i_transpose_mc
+la_i_transpose_mr
+la_i_upper_solve_mc
+la_i_upper_solve_mr
+la_i_vc_create
+la_i_vc_set
+la_i_vr_create
+la_i_vr_set
+la_k_a_assign
+la_k_add_mc
+la_k_add_mr
+la_k_add_vc
+la_k_add_vr
+la_k_assign_a
+la_k_assign_f
+la_k_assign_mc
+la_k_assign_mr
+la_k_assign_t
+la_k_assign_vc
+la_k_assign_vr
+la_k_conjugate_mc
+la_k_conjugate_mr
+la_k_conjugate_vc
+la_k_conjugate_vr
+la_k_current_f
+la_k_current_vr
+la_k_distance_vc
+la_k_distance_vr
+la_k_divide_mc
+la_k_divide_mr
+la_k_divide_vc
+la_k_divide_vr
+la_k_dot_mc
+la_k_dot_mc_vc
+la_k_dot_mr
+la_k_dot_mr_vr
+la_k_dot_vc
+la_k_dot_vr
+la_k_f_assign
+la_k_get_mc
+la_k_get_mr
+la_k_get_vc
+la_k_get_vr
+la_k_invert_mc
+la_k_invert_mr
+la_k_lower_solve_mc
+la_k_lower_solve_mr
+la_k_lu_det_mc
+la_k_lu_det_mr
+la_k_lu_factor_mc
+la_k_lu_factor_mr
+la_k_lu_solve_mc
+la_k_lu_solve_mr
+la_k_mc_set
+la_k_mr_set
+la_k_multiply_mc
+la_k_multiply_mr
+la_k_multiply_vc
+la_k_multiply_vr
+la_k_norm_euclid_mc
+la_k_norm_euclid_mr
+la_k_norm_euclid_vc
+la_k_norm_euclid_vr
+la_k_norm_inf_mc
+la_k_norm_inf_mr
+la_k_norm_inf_vc
+la_k_norm_inf_vr
+la_k_norm_max_mc
+la_k_norm_max_mr
+la_k_norm1_mc
+la_k_norm1_mr
+la_k_norm1_vc
+la_k_norm1_vr
+la_k_qr_eigen_mc
+la_k_qr_eigen_mr
+la_k_qr_factor_mc
+la_k_qr_factor_mr
+la_k_qr_sym_eigen_mc
+la_k_qr_sym_eigen_mr
+la_k_random_mc
+la_k_random_mr
+la_k_random_vc
+la_k_random_vr
+la_k_subtract_mc
+la_k_subtract_mr
+la_k_subtract_vc
+la_k_subtract_vr
+la_k_t_assign
+la_k_trace_mc
+la_k_trace_mr
+la_k_upper_solve_mc
+la_k_upper_solve_mr
+la_k_vc_set
+la_k_vr_set
+lenarray
+lfo
+limit
+limit1
+lincos
+line
+linen
+linenr
+lineto
+link_beat_force
+link_beat_get
+link_beat_request
+link_create
+link_enable
+link_is_enabled
+link_metro
+link_peers
+link_tempo_get
+link_tempo_set
+linlin
+linrand
+linseg
+linsegb
+linsegr
+liveconv
+locsend
+locsig
+log
+log10
+log2
+logbtwo
+logcurve
+loopseg
+loopsegp
+looptseg
+loopxseg
+lorenz
+loscil
+loscil3
+loscil3phs
+loscilphs
+loscilx
+lowpass2
+lowres
+lowresx
+lpf18
+lpform
+lpfreson
+lphasor
+lpinterp
+lposcil
+lposcil3
+lposcila
+lposcilsa
+lposcilsa2
+lpread
+lpreson
+lpshold
+lpsholdp
+lpslot
+lua_exec
+lua_iaopcall
+lua_iaopcall_off
+lua_ikopcall
+lua_ikopcall_off
+lua_iopcall
+lua_iopcall_off
+lua_opdef
+mac
+maca
+madsr
+mags
+mandel
+mandol
+maparray
+maparray_i
+marimba
+massign
+max
+max_k
+maxabs
+maxabsaccum
+maxaccum
+maxalloc
+maxarray
+mclock
+mdelay
+median
+mediank
+metro
+mfb
+midglobal
+midiarp
+midic14
+midic21
+midic7
+midichannelaftertouch
+midichn
+midicontrolchange
+midictrl
+mididefault
+midifilestatus
+midiin
+midinoteoff
+midinoteoncps
+midinoteonkey
+midinoteonoct
+midinoteonpch
+midion
+midion2
+midiout
+midiout_i
+midipgm
+midipitchbend
+midipolyaftertouch
+midiprogramchange
+miditempo
+midremot
+min
+minabs
+minabsaccum
+minaccum
+minarray
+mincer
+mirror
+mode
+modmatrix
+monitor
+moog
+moogladder
+moogladder2
+moogvcf
+moogvcf2
+moscil
+mp3bitrate
+mp3in
+mp3len
+mp3nchnls
+mp3scal
+mp3sr
+mpulse
+mrtmsg
+mtof
+mton
+multitap
+mute
+mvchpf
+mvclpf1
+mvclpf2
+mvclpf3
+mvclpf4
+mxadsr
+nchnls_hw
+nestedap
+nlalp
+nlfilt
+nlfilt2
+noise
+noteoff
+noteon
+noteondur
+noteondur2
+notnum
+nreverb
+nrpn
+nsamp
+nstance
+nstrnum
+ntom
+ntrpol
+nxtpow2
+octave
+octcps
+octmidi
+octmidib
+octmidinn
+octpch
+olabuffer
+oscbnk
+oscil
+oscil1
+oscil1i
+oscil3
+oscili
+oscilikt
+osciliktp
+oscilikts
+osciln
+oscils
+oscilx
+out
+out32
+outc
+outch
+outh
+outiat
+outic
+outic14
+outipat
+outipb
+outipc
+outkat
+outkc
+outkc14
+outkpat
+outkpb
+outkpc
+outleta
+outletf
+outletk
+outletkid
+outletv
+outo
+outq
+outq1
+outq2
+outq3
+outq4
+outrg
+outs
+outs1
+outs2
+outvalue
+outx
+outz
+p
+p5gconnect
+p5gdata
+pan
+pan2
+pareq
+part2txt
+partials
+partikkel
+partikkelget
+partikkelset
+partikkelsync
+passign
+paulstretch
+pcauchy
+pchbend
+pchmidi
+pchmidib
+pchmidinn
+pchoct
+pchtom
+pconvolve
+pcount
+pdclip
+pdhalf
+pdhalfy
+peak
+pgmassign
+pgmchn
+phaser1
+phaser2
+phasor
+phasorbnk
+phs
+pindex
+pinker
+pinkish
+pitch
+pitchac
+pitchamdf
+planet
+platerev
+plltrack
+pluck
+poisson
+pol2rect
+polyaft
+polynomial
+port
+portk
+poscil
+poscil3
+pow
+powershape
+powoftwo
+pows
+prealloc
+prepiano
+print
+print_type
+printarray
+printf
+printf_i
+printk
+printk2
+printks
+printks2
+prints
+product
+pset
+ptable
+ptable3
+ptablei
+ptableiw
+ptablew
+ptrack
+puts
+pvadd
+pvbufread
+pvcross
+pvinterp
+pvoc
+pvread
+pvs2array
+pvs2tab
+pvsadsyn
+pvsanal
+pvsarp
+pvsbandp
+pvsbandr
+pvsbin
+pvsblur
+pvsbuffer
+pvsbufread
+pvsbufread2
+pvscale
+pvscent
+pvsceps
+pvscross
+pvsdemix
+pvsdiskin
+pvsdisp
+pvsenvftw
+pvsfilter
+pvsfread
+pvsfreeze
+pvsfromarray
+pvsftr
+pvsftw
+pvsfwrite
+pvsgain
+pvshift
+pvsifd
+pvsin
+pvsinfo
+pvsinit
+pvslock
+pvsmaska
+pvsmix
+pvsmooth
+pvsmorph
+pvsosc
+pvsout
+pvspitch
+pvstanal
+pvstencil
+pvstrace
+pvsvoc
+pvswarp
+pvsynth
+pwd
+pyassign
+pyassigni
+pyassignt
+pycall
+pycall1
+pycall1i
+pycall1t
+pycall2
+pycall2i
+pycall2t
+pycall3
+pycall3i
+pycall3t
+pycall4
+pycall4i
+pycall4t
+pycall5
+pycall5i
+pycall5t
+pycall6
+pycall6i
+pycall6t
+pycall7
+pycall7i
+pycall7t
+pycall8
+pycall8i
+pycall8t
+pycalli
+pycalln
+pycallni
+pycallt
+pyeval
+pyevali
+pyevalt
+pyexec
+pyexeci
+pyexect
+pyinit
+pylassign
+pylassigni
+pylassignt
+pylcall
+pylcall1
+pylcall1i
+pylcall1t
+pylcall2
+pylcall2i
+pylcall2t
+pylcall3
+pylcall3i
+pylcall3t
+pylcall4
+pylcall4i
+pylcall4t
+pylcall5
+pylcall5i
+pylcall5t
+pylcall6
+pylcall6i
+pylcall6t
+pylcall7
+pylcall7i
+pylcall7t
+pylcall8
+pylcall8i
+pylcall8t
+pylcalli
+pylcalln
+pylcallni
+pylcallt
+pyleval
+pylevali
+pylevalt
+pylexec
+pylexeci
+pylexect
+pylrun
+pylruni
+pylrunt
+pyrun
+pyruni
+pyrunt
+qinf
+qnan
+r2c
+rand
+randh
+randi
+random
+randomh
+randomi
+rbjeq
+readclock
+readf
+readfi
+readk
+readk2
+readk3
+readk4
+readks
+readscore
+readscratch
+rect2pol
+release
+remoteport
+remove
+repluck
+reshapearray
+reson
+resonk
+resonr
+resonx
+resonxk
+resony
+resonz
+resyn
+reverb
+reverb2
+reverbsc
+rewindscore
+rezzy
+rfft
+rifft
+rms
+rnd
+rnd31
+round
+rspline
+rtclock
+s16b14
+s32b14
+samphold
+sandpaper
+sc_lag
+sc_lagud
+sc_phasor
+sc_trig
+scale
+scalearray
+scanhammer
+scans
+scantable
+scanu
+schedkwhen
+schedkwhennamed
+schedule
+schedwhen
+scoreline
+scoreline_i
+seed
+sekere
+select
+semitone
+sense
+sensekey
+seqtime
+seqtime2
+serialBegin
+serialEnd
+serialFlush
+serialPrint
+serialRead
+serialWrite
+serialWrite_i
+setcol
+setctrl
+setksmps
+setrow
+setscorepos
+sfilist
+sfinstr
+sfinstr3
+sfinstr3m
+sfinstrm
+sfload
+sflooper
+sfpassign
+sfplay
+sfplay3
+sfplay3m
+sfplaym
+sfplist
+sfpreset
+shaker
+shiftin
+shiftout
+signum
+sin
+sinh
+sininv
+sinsyn
+sleighbells
+slicearray
+slicearray_i
+slider16
+slider16f
+slider16table
+slider16tablef
+slider32
+slider32f
+slider32table
+slider32tablef
+slider64
+slider64f
+slider64table
+slider64tablef
+slider8
+slider8f
+slider8table
+slider8tablef
+sliderKawai
+sndloop
+sndwarp
+sndwarpst
+sockrecv
+sockrecvs
+socksend
+socksends
+sorta
+sortd
+soundin
+space
+spat3d
+spat3di
+spat3dt
+spdist
+splitrig
+sprintf
+sprintfk
+spsend
+sqrt
+squinewave
+statevar
+stix
+strcat
+strcatk
+strchar
+strchark
+strcmp
+strcmpk
+strcpy
+strcpyk
+strecv
+streson
+strfromurl
+strget
+strindex
+strindexk
+strlen
+strlenk
+strlower
+strlowerk
+strrindex
+strrindexk
+strset
+strsub
+strsubk
+strtod
+strtodk
+strtol
+strtolk
+strupper
+strupperk
+stsend
+subinstr
+subinstrinit
+sum
+sumarray
+svfilter
+syncgrain
+syncloop
+syncphasor
+system
+system_i
+tab
+tab2array
+tab2pvs
+tab_i
+tabifd
+table
+table3
+table3kt
+tablecopy
+tablefilter
+tablefilteri
+tablegpw
+tablei
+tableicopy
+tableigpw
+tableikt
+tableimix
+tableiw
+tablekt
+tablemix
+tableng
+tablera
+tableseg
+tableshuffle
+tableshufflei
+tablew
+tablewa
+tablewkt
+tablexkt
+tablexseg
+tabmorph
+tabmorpha
+tabmorphak
+tabmorphi
+tabplay
+tabrec
+tabrowlin
+tabsum
+tabw
+tabw_i
+tambourine
+tan
+tanh
+taninv
+taninv2
+tbvcf
+tempest
+tempo
+temposcal
+tempoval
+timedseq
+timeinstk
+timeinsts
+timek
+times
+tival
+tlineto
+tone
+tonek
+tonex
+tradsyn
+trandom
+transeg
+transegb
+transegr
+trcross
+trfilter
+trhighest
+trigger
+trigseq
+trim
+trim_i
+trirand
+trlowest
+trmix
+trscale
+trshift
+trsplit
+turnoff
+turnoff2
+turnon
+tvconv
+unirand
+unwrap
+upsamp
+urandom
+urd
+vactrol
+vadd
+vadd_i
+vaddv
+vaddv_i
+vaget
+valpass
+vaset
+vbap
+vbapg
+vbapgmove
+vbaplsinit
+vbapmove
+vbapz
+vbapzmove
+vcella
+vco
+vco2
+vco2ft
+vco2ift
+vco2init
+vcomb
+vcopy
+vcopy_i
+vdel_k
+vdelay
+vdelay3
+vdelayk
+vdelayx
+vdelayxq
+vdelayxs
+vdelayxw
+vdelayxwq
+vdelayxws
+vdivv
+vdivv_i
+vecdelay
+veloc
+vexp
+vexp_i
+vexpseg
+vexpv
+vexpv_i
+vibes
+vibr
+vibrato
+vincr
+vlimit
+vlinseg
+vlowres
+vmap
+vmirror
+vmult
+vmult_i
+vmultv
+vmultv_i
+voice
+vosim
+vphaseseg
+vport
+vpow
+vpow_i
+vpowv
+vpowv_i
+vpvoc
+vrandh
+vrandi
+vsubv
+vsubv_i
+vtaba
+vtabi
+vtabk
+vtable1k
+vtablea
+vtablei
+vtablek
+vtablewa
+vtablewi
+vtablewk
+vtabwa
+vtabwi
+vtabwk
+vwrap
+waveset
+websocket
+weibull
+wgbow
+wgbowedbar
+wgbrass
+wgclar
+wgflute
+wgpluck
+wgpluck2
+wguide1
+wguide2
+wiiconnect
+wiidata
+wiirange
+wiisend
+window
+wrap
+writescratch
+wterrain
+xadsr
+xin
+xout
+xscanmap
+xscans
+xscansmap
+xscanu
+xtratim
+xyscale
+zacl
+zakinit
+zamod
+zar
+zarg
+zaw
+zawm
+zdf_1pole
+zdf_1pole_mode
+zdf_2pole
+zdf_2pole_mode
+zdf_ladder
+zfilter2
+zir
+ziw
+ziwm
+zkcl
+zkmod
+zkr
+zkw
+zkwm
+'''.split())
+
+DEPRECATED_OPCODES = set('''
+array
+bformdec
+bformenc
+copy2ftab
+copy2ttab
+hrtfer
+ktableseg
+lentab
+maxtab
+mintab
+pop
+pop_f
+push
+push_f
+scalet
+sndload
+soundout
+soundouts
+specaddm
+specdiff
+specdisp
+specfilt
+spechist
+specptrk
+specscal
+specsum
+spectrum
+stack
+sumtab
+tabgen
+tabmap
+tabmap_i
+tabslice
+tb0
+tb0_init
+tb1
+tb10
+tb10_init
+tb11
+tb11_init
+tb12
+tb12_init
+tb13
+tb13_init
+tb14
+tb14_init
+tb15
+tb15_init
+tb1_init
+tb2
+tb2_init
+tb3
+tb3_init
+tb4
+tb4_init
+tb5
+tb5_init
+tb6
+tb6_init
+tb7
+tb7_init
+tb8
+tb8_init
+tb9
+tb9_init
+vbap16
+vbap4
+vbap4move
+vbap8
+vbap8move
+xyin
+'''.split())
diff --git a/pygments/lexers/csound.py b/pygments/lexers/csound.py
index 858aa348..b86de091 100644
--- a/pygments/lexers/csound.py
+++ b/pygments/lexers/csound.py
@@ -3,7 +3,7 @@
pygments.lexers.csound
~~~~~~~~~~~~~~~~~~~~~~
- Lexers for CSound languages.
+ Lexers for Csound languages.
:copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
@@ -12,9 +12,9 @@
import re
from pygments.lexer import RegexLexer, bygroups, default, include, using, words
-from pygments.token import Comment, Keyword, Name, Number, Operator, Punctuation, \
- String, Text
-from pygments.lexers._csound_builtins import OPCODES
+from pygments.token import Comment, Error, Keyword, Name, Number, Operator, Punctuation, \
+ String, Text, Whitespace
+from pygments.lexers._csound_builtins import OPCODES, DEPRECATED_OPCODES
from pygments.lexers.html import HtmlLexer
from pygments.lexers.python import PythonLexer
from pygments.lexers.scripting import LuaLexer
@@ -25,74 +25,104 @@ newline = (r'((?:(?:;|//).*)*)(\n)', bygroups(Comment.Single, Text))
class CsoundLexer(RegexLexer):
- # Subclasses must define a 'single-line string' state.
tokens = {
'whitespace': [
(r'[ \t]+', Text),
- (r'\\\n', Text),
- (r'/[*](.|\n)*?[*]/', Comment.Multiline)
+ (r'/[*](?:.|\n)*?[*]/', Comment.Multiline),
+ (r'(?:;|//).*$', Comment.Single),
+ (r'(\\)(\n)', bygroups(Whitespace, Text))
],
- 'macro call': [
- (r'(\$\w+\.?)(\()', bygroups(Comment.Preproc, Punctuation),
- 'function macro call'),
- (r'\$\w+(\.|\b)', Comment.Preproc)
- ],
- 'function macro call': [
- (r"((?:\\['\)]|[^'\)])+)(')", bygroups(Comment.Preproc, Punctuation)),
- (r"([^'\)]+)(\))", bygroups(Comment.Preproc, Punctuation), '#pop')
+ 'preprocessor directives': [
+ (r'#(?:e(?:nd(?:if)?|lse)\b|##)|@@?[ \t]*\d+', Comment.Preproc),
+ (r'#include', Comment.Preproc, 'include directive'),
+ (r'#[ \t]*define', Comment.Preproc, 'define directive'),
+ (r'#(?:ifn?def|undef)\b', Comment.Preproc, 'macro directive')
],
- 'whitespace or macro call': [
+ 'include directive': [
include('whitespace'),
- include('macro call')
+ (r'([^ \t]).*?\1', String, '#pop')
],
- 'preprocessor directives': [
- (r'#(e(nd(if)?|lse)|ifn?def|undef)\b|##', Comment.Preproc),
- (r'#include\b', Comment.Preproc, 'include'),
- (r'#[ \t]*define\b', Comment.Preproc, 'macro name'),
- (r'@+[ \t]*\d*', Comment.Preproc)
+ 'define directive': [
+ (r'\n', Text),
+ include('whitespace'),
+ (r'([A-Z_a-z]\w*)(\()', bygroups(Comment.Preproc, Punctuation),
+ ('#pop', 'macro parameter name list')),
+ (r'[A-Z_a-z]\w*', Comment.Preproc, ('#pop', 'before macro body'))
],
-
- 'include': [
+ 'macro parameter name list': [
include('whitespace'),
- (r'"', String, 'single-line string')
+ (r'[A-Z_a-z]\w*', Comment.Preproc),
+ (r"['#]", Punctuation),
+ (r'\)', Punctuation, ('#pop', 'before macro body'))
],
-
- 'macro name': [
+ 'before macro body': [
+ (r'\n', Text),
include('whitespace'),
- (r'(\w+)(\()', bygroups(Comment.Preproc, Text),
- 'function macro argument list'),
- (r'\w+', Comment.Preproc, 'object macro definition after name')
+ (r'#', Punctuation, ('#pop', 'macro body'))
+ ],
+ 'macro body': [
+ (r'(?:\\(?!#)|[^#\\]|\n)+', Comment.Preproc),
+ (r'\\#', Comment.Preproc),
+ (r'(?<!\\)#', Punctuation, '#pop')
],
- 'object macro definition after name': [
+
+ 'macro directive': [
include('whitespace'),
- (r'#', Punctuation, 'object macro replacement text')
+ (r'[A-Z_a-z]\w*', Comment.Preproc, '#pop')
+ ],
+
+ 'macro uses': [
+ (r'(\$[A-Z_a-z]\w*\.?)(\()', bygroups(Comment.Preproc, Punctuation),
+ 'macro parameter value list'),
+ (r'\$[A-Z_a-z]\w*(?:\.|\b)', Comment.Preproc)
],
- 'object macro replacement text': [
- (r'(\\#|[^#])+', Comment.Preproc),
- (r'#', Punctuation, '#pop:3')
+ 'macro parameter value list': [
+ (r'(?:[^\'#"{()]|\{(?!\{))+', Comment.Preproc),
+ (r"['#]", Punctuation),
+ (r'"', String, 'macro parameter value quoted string'),
+ (r'\{\{', String, 'macro parameter value braced string'),
+ (r'\(', Comment.Preproc, 'macro parameter value parenthetical'),
+ (r'\)', Punctuation, '#pop')
],
- 'function macro argument list': [
- (r"(\w+)(['#])", bygroups(Comment.Preproc, Punctuation)),
- (r'(\w+)(\))', bygroups(Comment.Preproc, Punctuation),
- 'function macro definition after name')
+ 'macro parameter value quoted string': [
+ (r"\\[#'()]", Comment.Preproc),
+ (r"[#'()]", Error),
+ include('quoted string')
],
- 'function macro definition after name': [
- (r'[ \t]+', Text),
- (r'#', Punctuation, 'function macro replacement text')
+ 'macro parameter value braced string': [
+ (r"\\[#'()]", Comment.Preproc),
+ (r"[#'()]", Error),
+ include('braced string')
+ ],
+ 'macro parameter value parenthetical': [
+ (r'(?:[^\\()]|\\\))+', Comment.Preproc),
+ (r'\(', Comment.Preproc, '#push'),
+ (r'\)', Comment.Preproc, '#pop')
],
- 'function macro replacement text': [
- (r'(\\#|[^#])+', Comment.Preproc),
- (r'#', Punctuation, '#pop:4')
+
+ 'whitespace and macro uses': [
+ include('whitespace'),
+ include('macro uses')
+ ],
+
+ 'numbers': [
+ (r'\d+[Ee][+-]?\d+|(\d+\.\d*|\d*\.\d+)([Ee][+-]?\d+)?', Number.Float),
+ (r'(0[Xx])([0-9A-Fa-f]+)', bygroups(Keyword.Type, Number.Hex)),
+ (r'\d+', Number.Integer)
+ ],
+
+ 'braced string': [
+ # Do nothing. This must be defined in subclasses.
]
}
class CsoundScoreLexer(CsoundLexer):
"""
- For `Csound <http://csound.github.io>`_ scores.
+ For `Csound <https://csound.github.io>`_ scores.
.. versionadded:: 2.1
"""
@@ -102,47 +132,77 @@ class CsoundScoreLexer(CsoundLexer):
filenames = ['*.sco']
tokens = {
- 'partial statement': [
+ 'root': [
+ (r'\n', Text),
+ include('whitespace and macro uses'),
include('preprocessor directives'),
- (r'\d+e[+-]?\d+|(\d+\.\d*|\d*\.\d+)(e[+-]?\d+)?', Number.Float),
- (r'0[xX][a-fA-F0-9]+', Number.Hex),
- (r'\d+', Number.Integer),
- (r'"', String, 'single-line string'),
- (r'[+\-*/%^!=<>|&#~.]', Operator),
- (r'[]()[]', Punctuation),
- (r'\w+', Comment.Preproc)
- ],
- 'statement': [
- include('whitespace or macro call'),
- newline + ('#pop',),
- include('partial statement')
+ (r'[abCdefiqstvxy]', Keyword),
+ # There is also a w statement that is generated internally and should not be
+ # used; see https://github.com/csound/csound/issues/750.
+
+ (r'z', Keyword.Constant),
+ # z is a constant equal to 800,000,000,000. 800 billion seconds is about
+ # 25,367.8 years. See also
+ # https://csound.github.io/docs/manual/ScoreTop.html and
+ # https://github.com/csound/csound/search?q=stof+path%3AEngine+filename%3Asread.c.
+
+ (r'([nNpP][pP])(\d+)', bygroups(Keyword, Number.Integer)),
+
+ (r'[mn]', Keyword, 'mark statement'),
+
+ include('numbers'),
+ (r'[!+\-*/^%&|<>#~.]', Operator),
+ (r'[()\[\]]', Punctuation),
+ (r'"', String, 'quoted string'),
+ (r'\{', Comment.Preproc, 'loop after left brace'),
],
- 'root': [
- newline,
- include('whitespace or macro call'),
- (r'[{}]', Punctuation, 'statement'),
- (r'[abefimq-tv-z]|[nN][pP]?', Keyword, 'statement')
+ 'mark statement': [
+ include('whitespace and macro uses'),
+ (r'[A-Z_a-z]\w*', Name.Label),
+ (r'\n', Text, '#pop')
],
- 'single-line string': [
+ 'quoted string': [
(r'"', String, '#pop'),
- (r'[^\\"]+', String)
+ (r'[^"$]+', String),
+ include('macro uses'),
+ (r'[$]', String)
+ ],
+
+ 'loop after left brace': [
+ include('whitespace and macro uses'),
+ (r'\d+', Number.Integer, ('#pop', 'loop after repeat count')),
+ ],
+ 'loop after repeat count': [
+ include('whitespace and macro uses'),
+ (r'[A-Z_a-z]\w*', Comment.Preproc, ('#pop', 'loop'))
+ ],
+ 'loop': [
+ (r'\}', Comment.Preproc, '#pop'),
+ include('root')
+ ],
+
+ # Braced strings are not allowed in Csound scores, but this is needed
+ # because the superclass includes it.
+ 'braced string': [
+ (r'\}\}', String, '#pop'),
+ (r'[^}]|\}(?!\})', String)
]
}
class CsoundOrchestraLexer(CsoundLexer):
"""
- For `Csound <http://csound.github.io>`_ orchestras.
+ For `Csound <https://csound.github.io>`_ orchestras.
.. versionadded:: 2.1
"""
name = 'Csound Orchestra'
aliases = ['csound', 'csound-orc']
- filenames = ['*.orc']
+ filenames = ['*.orc', '*.udo']
user_defined_opcodes = set()
@@ -152,13 +212,16 @@ class CsoundOrchestraLexer(CsoundLexer):
yield match.start(), Name.Function, opcode
def name_callback(lexer, match):
- name = match.group(0)
- if re.match('p\d+$', name) or name in OPCODES:
+ name = match.group(1)
+ if name in OPCODES or name in DEPRECATED_OPCODES:
yield match.start(), Name.Builtin, name
+ if match.group(2):
+ yield match.start(2), Punctuation, match.group(2)
+ yield match.start(3), Keyword.Type, match.group(3)
elif name in lexer.user_defined_opcodes:
yield match.start(), Name.Function, name
else:
- nameMatch = re.search(r'^(g?[aikSw])(\w+)', name)
+ nameMatch = re.search(r'^(g?[afikSw])(\w+)', name)
if nameMatch:
yield nameMatch.start(1), Keyword.Type, nameMatch.group(1)
yield nameMatch.start(2), Name, nameMatch.group(2)
@@ -166,145 +229,165 @@ class CsoundOrchestraLexer(CsoundLexer):
yield match.start(), Name, name
tokens = {
- 'label': [
- (r'\b(\w+)(:)', bygroups(Name.Label, Punctuation))
- ],
+ 'root': [
+ (r'\n', Text),
+
+ (r'^([ \t]*)(\w+)(:)(?:[ \t]+|$)', bygroups(Text, Name.Label, Punctuation)),
- 'partial expression': [
+ include('whitespace and macro uses'),
include('preprocessor directives'),
- (r'\b(0dbfs|k(r|smps)|nchnls(_i)?|sr)\b', Name.Variable.Global),
- (r'\d+e[+-]?\d+|(\d+\.\d*|\d*\.\d+)(e[+-]?\d+)?', Number.Float),
- (r'0[xX][a-fA-F0-9]+', Number.Hex),
- (r'\d+', Number.Integer),
- (r'"', String, 'single-line string'),
- (r'\{\{', String, 'multi-line string'),
- (r'[+\-*/%^!=&|<>#~¬]', Operator),
- (r'[](),?:[]', Punctuation),
+
+ (r'\binstr\b', Keyword.Declaration, 'instrument numbers and identifiers'),
+ (r'\bopcode\b', Keyword.Declaration, 'after opcode keyword'),
+ (r'\b(?:end(?:in|op))\b', Keyword.Declaration),
+
+ include('partial statements')
+ ],
+
+ 'partial statements': [
+ (r'\b(?:0dbfs|A4|k(?:r|smps)|nchnls(?:_i)?|sr)\b', Name.Variable.Global),
+
+ include('numbers'),
+
+ (r'\+=|-=|\*=|/=|<<|>>|<=|>=|==|!=|&&|\|\||[~¬]|[=!+\-*/^%&|<>#?:]', Operator),
+ (r'[(),\[\]]', Punctuation),
+
+ (r'"', String, 'quoted string'),
+ (r'\{\{', String, 'braced string'),
+
(words((
- # Keywords
'do', 'else', 'elseif', 'endif', 'enduntil', 'fi', 'if', 'ithen', 'kthen',
'od', 'then', 'until', 'while',
- # Opcodes that act as control structures
- 'return', 'timout'
), prefix=r'\b', suffix=r'\b'), Keyword),
- (words(('goto', 'igoto', 'kgoto', 'rigoto', 'tigoto'),
- prefix=r'\b', suffix=r'\b'), Keyword, 'goto label'),
- (words(('cggoto', 'cigoto', 'cingoto', 'ckgoto', 'cngoto'),
- prefix=r'\b', suffix=r'\b'), Keyword,
- ('goto label', 'goto expression')),
- (words(('loop_ge', 'loop_gt', 'loop_le', 'loop_lt'),
- prefix=r'\b', suffix=r'\b'), Keyword,
- ('goto label', 'goto expression', 'goto expression', 'goto expression')),
- (r'\bscoreline(_i)?\b', Name.Builtin, 'scoreline opcode'),
- (r'\bpyl?run[it]?\b', Name.Builtin, 'python opcode'),
- (r'\blua_(exec|opdef)\b', Name.Builtin, 'lua opcode'),
- (r'\b[a-zA-Z_]\w*\b', name_callback)
- ],
-
- 'expression': [
- include('whitespace or macro call'),
- newline + ('#pop',),
- include('partial expression')
- ],
+ (words(('return', 'rireturn'), prefix=r'\b', suffix=r'\b'), Keyword.Pseudo),
- 'root': [
- newline,
- include('whitespace or macro call'),
- (r'\binstr\b', Keyword, ('instrument block', 'instrument name list')),
- (r'\bopcode\b', Keyword, ('opcode block', 'opcode parameter list',
- 'opcode types', 'opcode types', 'opcode name')),
- include('label'),
- default('expression')
- ],
-
- 'instrument name list': [
- include('whitespace or macro call'),
- (r'\d+|\+?[a-zA-Z_]\w*', Name.Function),
- (r',', Punctuation),
- newline + ('#pop',)
+ (r'\b[ik]?goto\b', Keyword, 'goto label'),
+ (r'\b(r(?:einit|igoto)|tigoto)(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
+ 'goto label'),
+ (r'\b(c(?:g|in?|k|nk?)goto)(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
+ ('goto label', 'goto argument')),
+ (r'\b(timout)(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
+ ('goto label', 'goto argument', 'goto argument')),
+ (r'\b(loop_[gl][et])(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
+ ('goto label', 'goto argument', 'goto argument', 'goto argument')),
+
+ (r'\bprintk?s\b', Name.Builtin, 'prints opcode'),
+ (r'\b(?:readscore|scoreline(?:_i)?)\b', Name.Builtin, 'Csound score opcode'),
+ (r'\bpyl?run[it]?\b', Name.Builtin, 'Python opcode'),
+ (r'\blua_(?:exec|opdef)\b', Name.Builtin, 'Lua opcode'),
+ (r'\bp\d+\b', Name.Variable.Instance),
+ (r'\b([A-Z_a-z]\w*)(?:(:)([A-Za-z]))?\b', name_callback)
],
- 'instrument block': [
- newline,
- include('whitespace or macro call'),
- (r'\bendin\b', Keyword, '#pop'),
- include('label'),
- default('expression')
+
+ 'instrument numbers and identifiers': [
+ include('whitespace and macro uses'),
+ (r'\d+|[A-Z_a-z]\w*', Name.Function),
+ (r'[+,]', Punctuation),
+ (r'\n', Text, '#pop')
],
- 'opcode name': [
- include('whitespace or macro call'),
- (r'[a-zA-Z_]\w*', opcode_name_callback, '#pop')
+ 'after opcode keyword': [
+ include('whitespace and macro uses'),
+ (r'[A-Z_a-z]\w*', opcode_name_callback, ('#pop', 'opcode type signatures')),
+ (r'\n', Text, '#pop')
],
- 'opcode types': [
- include('whitespace or macro call'),
- (r'0|[]afijkKoOpPStV[]+', Keyword.Type, '#pop'),
- (r',', Punctuation)
+ 'opcode type signatures': [
+ include('whitespace and macro uses'),
+
+ # https://github.com/csound/csound/search?q=XIDENT+path%3AEngine+filename%3Acsound_orc.lex
+ (r'0|[afijkKoOpPStV\[\]]+', Keyword.Type),
+
+ (r',', Punctuation),
+ (r'\n', Text, '#pop')
],
- 'opcode parameter list': [
- include('whitespace or macro call'),
- newline + ('#pop',)
+
+ 'quoted string': [
+ (r'"', String, '#pop'),
+ (r'[^\\"$%)]+', String),
+ include('macro uses'),
+ include('escape sequences'),
+ include('format specifiers'),
+ (r'[\\$%)]', String)
],
- 'opcode block': [
- newline,
- include('whitespace or macro call'),
- (r'\bendop\b', Keyword, '#pop'),
- include('label'),
- default('expression')
+ 'braced string': [
+ (r'\}\}', String, '#pop'),
+ (r'(?:[^\\%)}]|\}(?!\}))+', String),
+ include('escape sequences'),
+ include('format specifiers'),
+ (r'[\\%)]', String)
+ ],
+ 'escape sequences': [
+ # https://github.com/csound/csound/search?q=unquote_string+path%3AEngine+filename%3Acsound_orc_compile.c
+ (r'\\(?:[\\abnrt"]|[0-7]{1,3})', String.Escape)
+ ],
+ # Format specifiers are highlighted in all strings, even though only
+ # fprintks https://csound.github.io/docs/manual/fprintks.html
+ # fprints https://csound.github.io/docs/manual/fprints.html
+ # printf/printf_i https://csound.github.io/docs/manual/printf.html
+ # printks https://csound.github.io/docs/manual/printks.html
+ # prints https://csound.github.io/docs/manual/prints.html
+ # sprintf https://csound.github.io/docs/manual/sprintf.html
+ # sprintfk https://csound.github.io/docs/manual/sprintfk.html
+ # work with strings that contain format specifiers. In addition, these
+ # opcodes’ handling of format specifiers is inconsistent:
+ # - fprintks, fprints, printks, and prints do accept %a and %A
+ # specifiers, but can’t accept %s specifiers.
+ # - printf, printf_i, sprintf, and sprintfk don’t accept %a and %A
+ # specifiers, but can accept %s specifiers.
+ # See https://github.com/csound/csound/issues/747 for more information.
+ 'format specifiers': [
+ (r'%[#0\- +]*\d*(?:\.\d+)?[diuoxXfFeEgGaAcs]', String.Interpol),
+ (r'%%', String.Escape)
+ ],
+
+ 'goto argument': [
+ include('whitespace and macro uses'),
+ (r',', Punctuation, '#pop'),
+ include('partial statements')
],
-
'goto label': [
- include('whitespace or macro call'),
+ include('whitespace and macro uses'),
(r'\w+', Name.Label, '#pop'),
default('#pop')
],
- 'goto expression': [
- include('whitespace or macro call'),
- (r',', Punctuation, '#pop'),
- include('partial expression')
- ],
- 'single-line string': [
- include('macro call'),
- (r'"', String, '#pop'),
- # From https://github.com/csound/csound/blob/develop/Opcodes/fout.c#L1405
- (r'%\d*(\.\d+)?[cdhilouxX]', String.Interpol),
- (r'%[!%nNrRtT]|[~^]|\\([\\aAbBnNrRtT"]|[0-7]{1,3})', String.Escape),
- (r'[^\\"~$%\^\n]+', String),
- (r'[\\"~$%\^\n]', String)
+ 'prints opcode': [
+ include('whitespace and macro uses'),
+ (r'"', String, 'prints quoted string'),
+ default('#pop')
],
- 'multi-line string': [
- (r'\}\}', String, '#pop'),
- (r'[^}]+|\}(?!\})', String)
+ 'prints quoted string': [
+ (r'\\\\[aAbBnNrRtT]', String.Escape),
+ (r'%[!nNrRtT]|[~^]{1,2}', String.Escape),
+ include('quoted string')
],
- 'scoreline opcode': [
- include('whitespace or macro call'),
- (r'\{\{', String, 'scoreline'),
- default('#pop')
+ 'Csound score opcode': [
+ include('whitespace and macro uses'),
+ (r'\{\{', String, 'Csound score'),
+ (r'\n', Text, '#pop')
],
- 'scoreline': [
+ 'Csound score': [
(r'\}\}', String, '#pop'),
(r'([^}]+)|\}(?!\})', using(CsoundScoreLexer))
],
- 'python opcode': [
- include('whitespace or macro call'),
- (r'\{\{', String, 'python'),
- default('#pop')
+ 'Python opcode': [
+ include('whitespace and macro uses'),
+ (r'\{\{', String, 'Python'),
+ (r'\n', Text, '#pop')
],
- 'python': [
+ 'Python': [
(r'\}\}', String, '#pop'),
(r'([^}]+)|\}(?!\})', using(PythonLexer))
],
- 'lua opcode': [
- include('whitespace or macro call'),
- (r'"', String, 'single-line string'),
- (r'\{\{', String, 'lua'),
- (r',', Punctuation),
- default('#pop')
+ 'Lua opcode': [
+ include('whitespace and macro uses'),
+ (r'\{\{', String, 'Lua'),
+ (r'\n', Text, '#pop')
],
- 'lua': [
+ 'Lua': [
(r'\}\}', String, '#pop'),
(r'([^}]+)|\}(?!\})', using(LuaLexer))
]
@@ -313,7 +396,7 @@ class CsoundOrchestraLexer(CsoundLexer):
class CsoundDocumentLexer(RegexLexer):
"""
- For `Csound <http://csound.github.io>`_ documents.
+ For `Csound <https://csound.github.io>`_ documents.
.. versionadded:: 2.1
"""
@@ -331,15 +414,18 @@ class CsoundDocumentLexer(RegexLexer):
# be XML files.
tokens = {
'root': [
- newline,
(r'/[*](.|\n)*?[*]/', Comment.Multiline),
- (r'[^<&;/]+', Text),
+ (r'(?:;|//).*$', Comment.Single),
+ (r'[^/;<]+|/(?!/)', Text),
+
(r'<\s*CsInstruments', Name.Tag, ('orchestra', 'tag')),
(r'<\s*CsScore', Name.Tag, ('score', 'tag')),
- (r'<\s*[hH][tT][mM][lL]', Name.Tag, ('HTML', 'tag')),
+ (r'<\s*[Hh][Tt][Mm][Ll]', Name.Tag, ('HTML', 'tag')),
+
(r'<\s*[\w:.-]+', Name.Tag, 'tag'),
(r'<\s*/\s*[\w:.-]+\s*>', Name.Tag)
],
+
'orchestra': [
(r'<\s*/\s*CsInstruments\s*>', Name.Tag, '#pop'),
(r'(.|\n)+?(?=<\s*/\s*CsInstruments\s*>)', using(CsoundOrchestraLexer))
@@ -349,9 +435,10 @@ class CsoundDocumentLexer(RegexLexer):
(r'(.|\n)+?(?=<\s*/\s*CsScore\s*>)', using(CsoundScoreLexer))
],
'HTML': [
- (r'<\s*/\s*[hH][tT][mM][lL]\s*>', Name.Tag, '#pop'),
- (r'(.|\n)+?(?=<\s*/\s*[hH][tT][mM][lL]\s*>)', using(HtmlLexer))
+ (r'<\s*/\s*[Hh][Tt][Mm][Ll]\s*>', Name.Tag, '#pop'),
+ (r'(.|\n)+?(?=<\s*/\s*[Hh][Tt][Mm][Ll]\s*>)', using(HtmlLexer))
],
+
'tag': [
(r'\s+', Text),
(r'[\w.:-]+\s*=', Name.Attribute, 'attr'),
diff --git a/tests/examplefiles/test.csd b/tests/examplefiles/test.csd
index 9122309b..6512d99e 100644
--- a/tests/examplefiles/test.csd
+++ b/tests/examplefiles/test.csd
@@ -1,260 +1,18 @@
+/*
+ * comment
+ */
+; comment
+// comment
+/
<CsoundSynthesizer>
<CsInstruments>
-// This is a Csound orchestra file for testing a Pygments <http://pygments.org>
-// lexer. Csound single-line comments can be preceded by a pair of forward
-// slashes...
-; ...or a semicolon.
-
-/* Block comments begin with /* and end with */
-
-// Orchestras begin with a header of audio parameters.
-nchnls = 1
-nchnls_i = 1
-sr = 44100
0dbfs = 1
-ksmps = 10
-
-// The control rate kr = sr / ksmps can be omitted when the number of audio
-// samples in a control period (ksmps) is set, but kr may appear in older
-// orchestras.
-kr = 4410
-
-// Orchestras contain instruments. These begin with the keyword instr followed
-// by a comma-separated list of numbers or names of the instrument. Instruments
-// end at the endin keyword and cannot be nested.
-instr 1, N_a_M_e_, +Name
- // Instruments contain statements. Here is a typical statement:
- aSignal oscil 0dbfs, 440, 1
- // Statements are terminated with a newline (possibly preceded by a comment).
- // To write a statement on several lines, precede the newline with a
- // backslash.
- prints \
- "hello, world\n";comment
-
- // Csound 6 introduced function syntax for opcodes with one or zero outputs.
- // The oscil statement above is the same as
- aSignal = oscil(0dbfs, 440, 1)
-
- // Instruments can contain control structures.
- kNote = p3
- if (kNote == 0) then
- kFrequency = 220
- elseif kNote == 1 then // Parentheses around binary expressions are optional.
- kFrequency = 440
- endif
-
- // Csound 6 introduced looping structures.
- iIndex = 0
- while iIndex < 5 do
- print iIndex
- iIndex += 1
- od
- iIndex = 0
- until iIndex >= 5 do
- print iIndex
- iIndex += 1
- enduntil
- // Both kinds of loops can be terminated by either od or enduntil.
-
- // Single-line strings are enclosed in double-quotes.
- prints "string\\\r\n\t\""
- // Multi-line strings are enclosed in pairs of curly braces.
- prints {{
- hello,
-
- world
- }}
-
- // Instruments often end with a statement containing an output opcode.
- outc aSignal
-endin
-
-// Orchestras can also contain user-defined opcodes (UDOs). Here is an
-// oscillator with one audio-rate output and two control-rate inputs:
-opcode anOscillator, a, kk
- kAmplitude, kFrequency xin
- aSignal vco2 kAmplitude, kFrequency
- xout aSignal
-endop
-instr TestOscillator
- outc(anOscillator(0dbfs, 110))
-endin
-
-// Python can be executed in Csound
-// <http://www.csounds.com/manual/html/pyrun.html>. So can Lua
-// <http://www.csounds.com/manual/html/lua.html>.
-pyruni {{
-import random
-
-pool = [(1 + i / 10.0) ** 1.2 for i in range(100)]
-
-def get_number_from_pool(n, p):
- if random.random() < p:
- i = int(random.random() * len(pool))
- pool[i] = n
- return random.choice(pool)
-}}
-
-// The Csound preprocessor supports conditional compilation and including files.
-#ifdef DEBUG
-#undef DEBUG
-#include "filename.orc"
-#endif
-
-// The preprocessor also supports object- and function-like macros. This is an
-// object-like macro that defines a number:
-#define A_HZ #440#
-
-// This is a function-like macro:
-#define OSCIL_MACRO(VOLUME'FREQUENCY'TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE#
-
-// Bodies of macros are enclosed in # and can contain newlines. The arguments of
-// function-like macros are separated by single-quotes. Uses of macros are
-// prefixed with a dollar sign.
-instr TestMacro
- aSignal $OSCIL_MACRO(1'$A_HZ'1)
- // Not unlike PHP, macros expand in double-quoted strings.
- prints "The frequency of the oscillator is $A_HZ Hz.\n"
- out aSignal
-endin
-
-// Here are other things to note about Csound.
-
-// There are two bitwise NOT operators, ~ and ¬ (U+00AC). The latter is common
-// on keyboards in the United Kingdom
-// <https://en.wikipedia.org/wiki/British_and_American_keyboards>.
-instr TestBitwiseNOT
- print ~42
- print ¬42
-endin
-
-// Csound uses # for bitwise XOR, which the Csound manual calls bitwise
-// non-equivalence <http://www.csounds.com/manual/html/opnonequiv.html>.
-instr TestBitwiseXOR
- print 0 # 0
- print 0 # 1
- print 1 # 0
- print 1 # 1
-endin
-
-// Loops and if-then statements are relatively recent additions to Csound. There
-// are many flow-control opcodes that involve goto and labels.
-instr TestGoto
- // This...
- if p3 > 0 goto if_label
- goto else_label
-if_label:
- prints "if branch\n"
- goto endif_label
-else_label:
- prints "else branch\n"
-endif_label:
-
- // ...is the same as this.
- if p3 > 0 then
- prints "if branch\n"
- else
- prints "else branch\n"
- endif
-
- // This...
- iIndex = 0
-loop_label:
- print iIndex
- iIndex += 1
- if iIndex < 10 goto loop_label
-
- // ...is the same as this...
- iIndex = 0
-loop_lt_label:
- print iIndex
- loop_lt iIndex, 1, 10, loop_lt_label
-
- // ...and this.
- iIndex = 0
- while iIndex < 10 do
- print iIndex
- iIndex += 1
- od
-endin
-
-// The prints and printks opcodes
-// <https://github.com/csound/csound/blob/develop/OOps/ugrw1.c#L831>, arguably
-// the primary methods of logging output, treat certain sequences of characters
-// different from printf in C.
-instr TestPrints
- // ^ prints an ESCAPE character (U+001B), not a CIRCUMFLEX ACCENT character
- // (U+005E). ^^ prints a CIRCUMFLEX ACCENT.
- prints "^^\n"
- // ~ prints an ESCAPE character (U+001B) followed by a [, not a TILDE
- // character (U+007E). ~~ prints a TILDE.
- prints "~~\n"
- // \A, \B, \N, \R, and \T correspond to the escaped lowercase characters (that
- // is, BELL (U+0007), BACKSPACE (U+0008), new line (U+000A), CARRIAGE RETURN
- // (U+000D), and tab (U+0009)).
- prints "\T\R\N"
- // %n, %r, and %t are the same as \n, \r, and \t, as are %N, %R, and %T.
- prints "%t%r%n"
- // %! prints a semicolon. This is a hold-over from old versions of Csound that
- // allowed comments to begin in strings.
- prints "; %!\n"
-endin
-
-// The arguments of function-like macros can be separated by # instead of '.
-// These two lines define the same macro.
-#define OSCIL_MACRO(VOLUME'FREQUENCY'TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE#
-#define OSCIL_MACRO(VOLUME#FREQUENCY#TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE#
-
-// Uses of macros can optionally be suffixed with a period.
-instr TestMacroPeriodSuffix
- aSignal $OSCIL_MACRO.(1'$A_HZ'1)
- prints "The frequency of the oscillator is $A_HZ.Hz.\n"
- out aSignal
-endin
-
-// Csound has @ and @@ operator-like macros that, when followed by a literal
-// non-negative integer, expand to the next power of 2 and the next power of 2
-// plus 1:
-// @x = 2^(ceil(log2(x + 1))), x >= 0
-// @@0 = 2
-// @@x = 2^(ceil(log2(x))) + 1, x > 0
-// These macros are in
-// <https://github.com/csound/csound/blob/develop/Engine/csound_orc.l#L542> (and
-// <https://github.com/csound/csound/blob/develop/Engine/csound_sco.lex#L202>)
-// and are described at <http://www.csounds.com/manual/html/ScoreEval.html>.
-instr TestAt
- prints "%d %2d %2d\n", 0, @0, @@0
- prints "%d %2d %2d\n", 1, @1, @@1
- prints "%d %2d %2d\n", 2, @2, @@2
- prints "%d %2d %2d\n", 3, @3, @@3
- prints "%d %2d %2d\n", 4, @4, @@4
- prints "%d %2d %2d\n", 5, @5, @@5
- prints "%d %2d %2d\n", 6, @6, @@6
- prints "%d %2d %2d\n", 7, @7, @@7
- prints "%d %2d %2d\n", 8, @8, @@8
- prints "%d %2d %2d\n", 9, @9, @@9
-endin
-
-// Including newlines in macros can lead to confusing code, but it tests the
-// lexer.
-instr MacroAbuse
- if 1 == 1 then
- prints "on\n"
-#define FOO#
-BAR
-#endif // This ends the if statement. It is not a preprocessor directive.
-endin
+prints "hello, world\n"
</CsInstruments>
<CsScore>
-f 1 0 16384 10 1
-i "N_a_M_e_" 0 2
-i "TestOscillator" 2 2
-i "TestBitwiseNOT" 0 1
-i "TestBitwiseXOR" 0 1
-i "TestGoto" 0 1
-i "TestMacroPeriodSuffix" 4 1
-i "TestAt" 0 1
-i "MacroAbuse" 0 1
-e
+i 1 0 0
</CsScore>
+<html>
+<!DOCTYPE html>
+</html>
</CsoundSynthesizer>
diff --git a/tests/examplefiles/test.orc b/tests/examplefiles/test.orc
index 36725342..d113303e 100644
--- a/tests/examplefiles/test.orc
+++ b/tests/examplefiles/test.orc
@@ -1,257 +1,81 @@
-// This is a Csound orchestra file for testing a Pygments <http://pygments.org>
-// lexer. Csound single-line comments can be preceded by a pair of forward
-// slashes...
-; ...or a semicolon.
-
-/* Block comments begin with /* and end with */
-
-// Orchestras begin with a header of audio parameters.
-nchnls = 1
-nchnls_i = 1
-sr = 44100
-0dbfs = 1
-ksmps = 10
-
-// The control rate kr = sr / ksmps can be omitted when the number of audio
-// samples in a control period (ksmps) is set, but kr may appear in older
-// orchestras.
-kr = 4410
-
-// Orchestras contain instruments. These begin with the keyword instr followed
-// by a comma-separated list of numbers or names of the instrument. Instruments
-// end at the endin keyword and cannot be nested.
-instr 1, N_a_M_e_, +Name
- // Instruments contain statements. Here is a typical statement:
- aSignal oscil 0dbfs, 440, 1
- // Statements are terminated with a newline (possibly preceded by a comment).
- // To write a statement on several lines, precede the newline with a
- // backslash.
- prints \
- "hello, world\n";comment
-
- // Csound 6 introduced function syntax for opcodes with one or zero outputs.
- // The oscil statement above is the same as
- aSignal = oscil(0dbfs, 440, 1)
-
- // Instruments can contain control structures.
- kNote = p3
- if (kNote == 0) then
- kFrequency = 220
- elseif kNote == 1 then // Parentheses around binary expressions are optional.
- kFrequency = 440
- endif
-
- // Csound 6 introduced looping structures.
- iIndex = 0
- while iIndex < 5 do
- print iIndex
- iIndex += 1
- od
- iIndex = 0
- until iIndex >= 5 do
- print iIndex
- iIndex += 1
- enduntil
- // Both kinds of loops can be terminated by either od or enduntil.
-
- // Single-line strings are enclosed in double-quotes.
- prints "string\\\r\n\t\""
- // Multi-line strings are enclosed in pairs of curly braces.
- prints {{
- hello,
-
- world
- }}
-
- // Instruments often end with a statement containing an output opcode.
- outc aSignal
+/*
+ * comment
+ */
+; comment
+// comment
+
+instr/**/1,/**/N_a_M_e_,/**/+Name/**///
+ iDuration = p3
+ outc:a(aSignal)
endin
-// Orchestras can also contain user-defined opcodes (UDOs). Here is an
-// oscillator with one audio-rate output and two control-rate inputs:
-opcode anOscillator, a, kk
- kAmplitude, kFrequency xin
- aSignal vco2 kAmplitude, kFrequency
- xout aSignal
+opcode/**/aUDO,/**/i[],/**/aik//
+ aUDO
endop
-instr TestOscillator
- outc(anOscillator(0dbfs, 110))
-endin
-// Python can be executed in Csound
-// <http://www.csounds.com/manual/html/pyrun.html>. So can Lua
-// <http://www.csounds.com/manual/html/lua.html>.
-pyruni {{
-import random
+123 0123456789
+0xabcdef0123456789 0XABCDEF
+1e2 3e+4 5e-6 7E8 9E+0 1E-2 3. 4.56 .789
-pool = [(1 + i / 10.0) ** 1.2 for i in range(100)]
+"characters$MACRO."
+"\\\a\b\n\r\t\012\345\67\""
-def get_number_from_pool(n, p):
- if random.random() < p:
- i = int(random.random() * len(pool))
- pool[i] = n
- return random.choice(pool)
+{{
+characters$MACRO.
}}
+{{\\\a\b\n\r\t\"\012\345\67}}
-// The Csound preprocessor supports conditional compilation and including files.
-#ifdef DEBUG
-#undef DEBUG
-#include "filename.orc"
-#endif
-
-// The preprocessor also supports object- and function-like macros. This is an
-// object-like macro that defines a number:
-#define A_HZ #440#
-
-// This is a function-like macro:
-#define OSCIL_MACRO(VOLUME'FREQUENCY'TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE#
-
-// Bodies of macros are enclosed in # and can contain newlines. The arguments of
-// function-like macros are separated by single-quotes. Uses of macros are
-// prefixed with a dollar sign.
-instr TestMacro
- aSignal $OSCIL_MACRO(1'$A_HZ'1)
- // Not unlike PHP, macros expand in double-quoted strings.
- prints "The frequency of the oscillator is $A_HZ Hz.\n"
- out aSignal
-endin
-
-// Here are other things to note about Csound.
++ - ~ ¬ ! * / ^ % << >> < > <= >= == != & # | && || ? : += -= *= /=
-// There are two bitwise NOT operators, ~ and ¬ (U+00AC). The latter is common
-// on keyboards in the United Kingdom
-// <https://en.wikipedia.org/wiki/British_and_American_keyboards>.
-instr TestBitwiseNOT
- print ~42
- print ¬42
-endin
-
-// Csound uses # for bitwise XOR, which the Csound manual calls bitwise
-// non-equivalence <http://www.csounds.com/manual/html/opnonequiv.html>.
-instr TestBitwiseXOR
- print 0 # 0
- print 0 # 1
- print 1 # 0
- print 1 # 1
-endin
+0dbfs A4 kr ksmps nchnls nchnls_i sr
-// Loops and if-then statements are relatively recent additions to Csound. There
-// are many flow-control opcodes that involve goto and labels.
-instr TestGoto
- // This...
- if p3 > 0 goto if_label
- goto else_label
-if_label:
- prints "if branch\n"
- goto endif_label
-else_label:
- prints "else branch\n"
-endif_label:
+do else elseif endif enduntil fi if ithen kthen od then until while
+return rireturn
- // ...is the same as this.
- if p3 > 0 then
- prints "if branch\n"
- else
- prints "else branch\n"
- endif
+aLabel:
+ label2:
- // This...
- iIndex = 0
-loop_label:
- print iIndex
- iIndex += 1
- if iIndex < 10 goto loop_label
+goto aLabel
+reinit aLabel
+cggoto 1==0, aLabel
+timout 0, 0, aLabel
+loop_ge 0, 0, 0, aLabel
- // ...is the same as this...
- iIndex = 0
-loop_lt_label:
- print iIndex
- loop_lt iIndex, 1, 10, loop_lt_label
-
- // ...and this.
- iIndex = 0
- while iIndex < 10 do
- print iIndex
- iIndex += 1
- od
-endin
+prints "%! %% %n%N %r%R %t%T \\a\\A \\b\\B \\n\\N \\r\\R \\t\\T"
+prints Soutput
-// The prints and printks opcodes
-// <https://github.com/csound/csound/blob/develop/OOps/ugrw1.c#L831>, arguably
-// the primary methods of logging output, treat certain sequences of characters
-// different from printf in C.
-instr TestPrints
- // ^ prints an ESCAPE character (U+001B), not a CIRCUMFLEX ACCENT character
- // (U+005E). ^^ prints a CIRCUMFLEX ACCENT.
- prints "^^\n"
- // ~ prints an ESCAPE character (U+001B) followed by a [, not a TILDE
- // character (U+007E). ~~ prints a TILDE.
- prints "~~\n"
- // \A, \B, \N, \R, and \T correspond to the escaped lowercase characters (that
- // is, BELL (U+0007), BACKSPACE (U+0008), new line (U+000A), CARRIAGE RETURN
- // (U+000D), and tab (U+0009)).
- prints "\T\R\N"
- // %n, %r, and %t are the same as \n, \r, and \t, as are %N, %R, and %T.
- prints "%t%r%n"
- // %! prints a semicolon. This is a hold-over from old versions of Csound that
- // allowed comments to begin in strings.
- prints "; %!\n"
-endin
-
-// The arguments of function-like macros can be separated by # instead of '.
-// These two lines define the same macro.
-#define OSCIL_MACRO(VOLUME'FREQUENCY'TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE#
-#define OSCIL_MACRO(VOLUME#FREQUENCY#TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE#
-
-// Uses of macros can optionally be suffixed with a period.
-instr TestMacroPeriodSuffix
- aSignal $OSCIL_MACRO.(1'$A_HZ'1)
- prints "The frequency of the oscillator is $A_HZ.Hz.\n"
- out aSignal
-endin
-
-// Csound has @ and @@ operator-like macros that, when followed by a literal
-// non-negative integer, expand to the next power of 2 and the next power of 2
-// plus 1:
-// @x = 2^(ceil(log2(x + 1))), x >= 0
-// @@0 = 2
-// @@x = 2^(ceil(log2(x))) + 1, x > 0
-// These macros are in
-// <https://github.com/csound/csound/blob/develop/Engine/csound_orc.l#L542> (and
-// <https://github.com/csound/csound/blob/develop/Engine/csound_sco.lex#L202>)
-// and are described at <http://www.csounds.com/manual/html/ScoreEval.html>.
-instr TestAt
- prints "%d %2d %2d\n", 0, @0, @@0
- prints "%d %2d %2d\n", 1, @1, @@1
- prints "%d %2d %2d\n", 2, @2, @@2
- prints "%d %2d %2d\n", 3, @3, @@3
- prints "%d %2d %2d\n", 4, @4, @@4
- prints "%d %2d %2d\n", 5, @5, @@5
- prints "%d %2d %2d\n", 6, @6, @@6
- prints "%d %2d %2d\n", 7, @7, @@7
- prints "%d %2d %2d\n", 8, @8, @@8
- prints "%d %2d %2d\n", 9, @9, @@9
-endin
+readscore {{
+i 1 0 0
+}}
+pyrun {{
+# Python
+}}
+lua_exec {{
+-- Lua
+}}
-// Including newlines in macros can lead to confusing code, but it tests the
-// lexer.
-instr MacroAbuse
- if 1 == 1 then
- prints "on\n"
-#define FOO#
-BAR
-#endif // This ends the if statement. It is not a preprocessor directive.
-endin
+#include/**/"file.udo"
+#include/**/|file.udo|
-scoreline_i {{
-f 1 0 16384 10 1
-i "N_a_M_e_" 0 2
-i "TestOscillator" 2 2
-i "TestBitwiseNOT" 0 1
-i "TestBitwiseXOR" 0 1
-i "TestGoto" 0 1
-i "TestMacroPeriodSuffix" 4 1
-i "TestAt" 0 1
-i "MacroAbuse" 0 1
-e
-}}
+#ifdef MACRO
+#else
+#ifndef MACRO
+#endif
+#undef MACRO
+
+# define MACRO#macro_body#
+#define/**/
+MACRO/**/
+#\#macro
+body\##
+
+#define MACRO(ARG1#ARG2) #macro_body#
+#define/**/
+MACRO(ARG1'ARG2'ARG3)/**/
+#\#macro
+body\##
+
+$MACRO $MACRO.
+$MACRO(x)
+@0
+@@ 1
diff --git a/tests/examplefiles/test.sco b/tests/examplefiles/test.sco
index a0b39251..d997c1b3 100644
--- a/tests/examplefiles/test.sco
+++ b/tests/examplefiles/test.sco
@@ -1,10 +1,22 @@
-f 1 0 16384 10 1
-i "N_a_M_e_" 0 2
-i "TestOscillator" 2 2
-i "TestBitwiseNOT" 0 1
-i "TestBitwiseXOR" 0 1
-i "TestGoto" 0 1
-i "TestMacroPeriodSuffix" 4 1
-i "TestAt" 0 1
-i "MacroAbuse" 0 1
-e
+/*
+ * comment
+ */
+; comment
+// comment
+a b C d e f i q s t v x y
+z
+np0 nP1 Np2 NP3
+m/**/label;
+n label
+123 0123456789
+0xabcdef0123456789 0XABCDEF
+1e2 3e+4 5e-6 7E8 9E+0 1E-2 3. 4.56 .789
+"characters$MACRO."
+{ 1 I
+ { 2 J
+ { 3 K
+ $I $J $K
+ }
+ }
+}
+#include "score.sco"
diff --git a/tests/test_csound.py b/tests/test_csound.py
new file mode 100644
index 00000000..4d10c267
--- /dev/null
+++ b/tests/test_csound.py
@@ -0,0 +1,480 @@
+# -*- coding: utf-8 -*-
+"""
+ Csound lexer tests
+ ~~~~~~~~~~~~~~~~~~~~
+
+ :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import unittest
+from textwrap import dedent
+
+from pygments.token import Comment, Error, Keyword, Name, Number, Operator, Punctuation, \
+ String, Text
+from pygments.lexers import CsoundOrchestraLexer
+
+
+class CsoundOrchestraTest(unittest.TestCase):
+
+ def setUp(self):
+ self.lexer = CsoundOrchestraLexer()
+ self.maxDiff = None
+
+ def testComments(self):
+ fragment = dedent('''\
+ /*
+ * comment
+ */
+ ; comment
+ // comment
+ ''')
+ tokens = [
+ (Comment.Multiline, u'/*\n * comment\n */'),
+ (Text, u'\n'),
+ (Comment.Single, u'; comment'),
+ (Text, u'\n'),
+ (Comment.Single, u'// comment'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testInstrumentBlocks(self):
+ fragment = dedent('''\
+ instr/**/1,/**/N_a_M_e_,/**/+Name/**///
+ iDuration = p3
+ outc:a(aSignal)
+ endin
+ ''')
+ tokens = [
+ (Keyword.Declaration, u'instr'),
+ (Comment.Multiline, u'/**/'),
+ (Name.Function, u'1'),
+ (Punctuation, u','),
+ (Comment.Multiline, u'/**/'),
+ (Name.Function, u'N_a_M_e_'),
+ (Punctuation, u','),
+ (Comment.Multiline, u'/**/'),
+ (Punctuation, u'+'),
+ (Name.Function, u'Name'),
+ (Comment.Multiline, u'/**/'),
+ (Comment.Single, u'//'),
+ (Text, u'\n'),
+ (Text, u' '),
+ (Keyword.Type, u'i'),
+ (Name, u'Duration'),
+ (Text, u' '),
+ (Operator, u'='),
+ (Text, u' '),
+ (Name.Variable.Instance, u'p3'),
+ (Text, u'\n'),
+ (Text, u' '),
+ (Name.Builtin, u'outc'),
+ (Punctuation, u':'),
+ (Keyword.Type, u'a'),
+ (Punctuation, u'('),
+ (Keyword.Type, u'a'),
+ (Name, u'Signal'),
+ (Punctuation, u')'),
+ (Text, u'\n'),
+ (Keyword.Declaration, u'endin'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testUserDefinedOpcodes(self):
+ fragment = dedent('''\
+ opcode/**/aUDO,/**/i[],/**/aik//
+ aUDO
+ endop
+ ''')
+ tokens = [
+ (Keyword.Declaration, u'opcode'),
+ (Comment.Multiline, u'/**/'),
+ (Name.Function, u'aUDO'),
+ (Punctuation, u','),
+ (Comment.Multiline, u'/**/'),
+ (Keyword.Type, u'i[]'),
+ (Punctuation, u','),
+ (Comment.Multiline, u'/**/'),
+ (Keyword.Type, u'aik'),
+ (Comment.Single, u'//'),
+ (Text, u'\n'),
+ (Text, u' '),
+ (Name.Function, u'aUDO'),
+ (Text, u'\n'),
+ (Keyword.Declaration, u'endop'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testNumbers(self):
+ fragment = '123 0123456789'
+ tokens = [
+ (Number.Integer, u'123'),
+ (Text, u' '),
+ (Number.Integer, u'0123456789'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ fragment = '0xabcdef0123456789 0XABCDEF'
+ tokens = [
+ (Keyword.Type, u'0x'),
+ (Number.Hex, u'abcdef0123456789'),
+ (Text, u' '),
+ (Keyword.Type, u'0X'),
+ (Number.Hex, u'ABCDEF'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ fragments = ['1e2', '3e+4', '5e-6', '7E8', '9E+0', '1E-2', '3.', '4.56', '.789']
+ for fragment in fragments:
+ tokens = [
+ (Number.Float, fragment),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testQuotedStrings(self):
+ fragment = '"characters$MACRO."'
+ tokens = [
+ (String, u'"'),
+ (String, u'characters'),
+ (Comment.Preproc, u'$MACRO.'),
+ (String, u'"'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testBracedStrings(self):
+ fragment = dedent('''\
+ {{
+ characters$MACRO.
+ }}
+ ''')
+ tokens = [
+ (String, u'{{'),
+ (String, u'\ncharacters$MACRO.\n'),
+ (String, u'}}'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testEscapeSequences(self):
+ for character in ['\\', 'a', 'b', 'n', 'r', 't', '"', '012', '345', '67']:
+ escapedCharacter = '\\' + character
+ fragment = '"' + escapedCharacter + '"'
+ tokens = [
+ (String, u'"'),
+ (String.Escape, escapedCharacter),
+ (String, u'"'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ fragment = '{{' + escapedCharacter + '}}'
+ tokens = [
+ (String, u'{{'),
+ (String.Escape, escapedCharacter),
+ (String, u'}}'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testOperators(self):
+ fragments = ['+', '-', '~', u'¬', '!', '*', '/', '^', '%', '<<', '>>', '<', '>',
+ '<=', '>=', '==', '!=', '&', '#', '|', '&&', '||', '?', ':', '+=',
+ '-=', '*=', '/=']
+ for fragment in fragments:
+ tokens = [
+ (Operator, fragment),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testGlobalValueIdentifiers(self):
+ for fragment in ['0dbfs', 'A4', 'kr', 'ksmps', 'nchnls', 'nchnls_i', 'sr']:
+ tokens = [
+ (Name.Variable.Global, fragment),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testKeywords(self):
+ fragments = ['do', 'else', 'elseif', 'endif', 'enduntil', 'fi', 'if', 'ithen',
+ 'kthen', 'od', 'then', 'until', 'while']
+ for fragment in fragments:
+ tokens = [
+ (Keyword, fragment),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ for fragment in ['return', 'rireturn']:
+ tokens = [
+ (Keyword.Pseudo, fragment),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testLabels(self):
+ fragment = dedent('''\
+ aLabel:
+ label2:
+ ''')
+ tokens = [
+ (Name.Label, u'aLabel'),
+ (Punctuation, u':'),
+ (Text, u'\n'),
+ (Text, u' '),
+ (Name.Label, u'label2'),
+ (Punctuation, u':'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testPrintksAndPrintsEscapeSequences(self):
+ escapedCharacters = ['%!', '%%', '%n', '%N', '%r', '%R', '%t', '%T', '\\\\a',
+ '\\\\A', '\\\\b', '\\\\B', '\\\\n', '\\\\N', '\\\\r',
+ '\\\\R', '\\\\t', '\\\\T']
+ for opcode in ['printks', 'prints']:
+ for escapedCharacter in escapedCharacters:
+ fragment = opcode + ' "' + escapedCharacter + '"'
+ tokens = [
+ (Name.Builtin, opcode),
+ (Text, u' '),
+ (String, u'"'),
+ (String.Escape, escapedCharacter),
+ (String, u'"'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testGotoStatements(self):
+ for keyword in ['goto', 'igoto', 'kgoto']:
+ fragment = keyword + ' aLabel'
+ tokens = [
+ (Keyword, keyword),
+ (Text, u' '),
+ (Name.Label, u'aLabel'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ for opcode in ['reinit', 'rigoto', 'tigoto']:
+ fragment = opcode + ' aLabel'
+ tokens = [
+ (Keyword.Pseudo, opcode),
+ (Text, u' '),
+ (Name.Label, u'aLabel'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ for opcode in ['cggoto', 'cigoto', 'cingoto', 'ckgoto', 'cngoto', 'cnkgoto']:
+ fragment = opcode + ' 1==0, aLabel'
+ tokens = [
+ (Keyword.Pseudo, opcode),
+ (Text, u' '),
+ (Number.Integer, u'1'),
+ (Operator, u'=='),
+ (Number.Integer, u'0'),
+ (Punctuation, u','),
+ (Text, u' '),
+ (Name.Label, u'aLabel'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ fragment = 'timout 0, 0, aLabel'
+ tokens = [
+ (Keyword.Pseudo, 'timout'),
+ (Text, u' '),
+ (Number.Integer, u'0'),
+ (Punctuation, u','),
+ (Text, u' '),
+ (Number.Integer, u'0'),
+ (Punctuation, u','),
+ (Text, u' '),
+ (Name.Label, u'aLabel'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+ for opcode in ['loop_ge', 'loop_gt', 'loop_le', 'loop_lt']:
+ fragment = opcode + ' 0, 0, 0, aLabel'
+ tokens = [
+ (Keyword.Pseudo, opcode),
+ (Text, u' '),
+ (Number.Integer, u'0'),
+ (Punctuation, u','),
+ (Text, u' '),
+ (Number.Integer, u'0'),
+ (Punctuation, u','),
+ (Text, u' '),
+ (Number.Integer, u'0'),
+ (Punctuation, u','),
+ (Text, u' '),
+ (Name.Label, u'aLabel'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testIncludeDirectives(self):
+ for character in ['"', '|']:
+ fragment = '#include/**/' + character + 'file.udo' + character
+ tokens = [
+ (Comment.Preproc, u'#include'),
+ (Comment.Multiline, u'/**/'),
+ (String, character + u'file.udo' + character),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testObjectLikeMacroDefinitions(self):
+ fragment = dedent('''\
+ # \tdefine MACRO#macro_body#
+ #define/**/
+ MACRO/**/
+ #\\#macro
+ body\\##
+ ''')
+ tokens = [
+ (Comment.Preproc, u'# \tdefine'),
+ (Text, u' '),
+ (Comment.Preproc, u'MACRO'),
+ (Punctuation, u'#'),
+ (Comment.Preproc, u'macro_body'),
+ (Punctuation, u'#'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'#define'),
+ (Comment.Multiline, u'/**/'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'MACRO'),
+ (Comment.Multiline, u'/**/'),
+ (Text, u'\n'),
+ (Punctuation, u'#'),
+ (Comment.Preproc, u'\\#'),
+ (Comment.Preproc, u'macro\nbody'),
+ (Comment.Preproc, u'\\#'),
+ (Punctuation, u'#'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testFunctionLikeMacroDefinitions(self):
+ fragment = dedent('''\
+ #define MACRO(ARG1#ARG2) #macro_body#
+ #define/**/
+ MACRO(ARG1'ARG2' ARG3)/**/
+ #\\#macro
+ body\\##
+ ''')
+ tokens = [
+ (Comment.Preproc, u'#define'),
+ (Text, u' '),
+ (Comment.Preproc, u'MACRO'),
+ (Punctuation, u'('),
+ (Comment.Preproc, u'ARG1'),
+ (Punctuation, u'#'),
+ (Comment.Preproc, u'ARG2'),
+ (Punctuation, u')'),
+ (Text, u' '),
+ (Punctuation, u'#'),
+ (Comment.Preproc, u'macro_body'),
+ (Punctuation, u'#'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'#define'),
+ (Comment.Multiline, u'/**/'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'MACRO'),
+ (Punctuation, u'('),
+ (Comment.Preproc, u'ARG1'),
+ (Punctuation, u"'"),
+ (Comment.Preproc, u'ARG2'),
+ (Punctuation, u"'"),
+ (Text, u' '),
+ (Comment.Preproc, u'ARG3'),
+ (Punctuation, u')'),
+ (Comment.Multiline, u'/**/'),
+ (Text, u'\n'),
+ (Punctuation, u'#'),
+ (Comment.Preproc, u'\\#'),
+ (Comment.Preproc, u'macro\nbody'),
+ (Comment.Preproc, u'\\#'),
+ (Punctuation, u'#'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testMacroPreprocessorDirectives(self):
+ for directive in ['#ifdef', '#ifndef', '#undef']:
+ fragment = directive + ' MACRO'
+ tokens = [
+ (Comment.Preproc, directive),
+ (Text, u' '),
+ (Comment.Preproc, u'MACRO'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testOtherPreprocessorDirectives(self):
+ fragment = dedent('''\
+ #else
+ #end
+ #endif
+ ###
+ @ \t12345
+ @@ \t67890
+ ''')
+ tokens = [
+ (Comment.Preproc, u'#else'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'#end'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'#endif'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'###'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'@ \t12345'),
+ (Text, u'\n'),
+ (Comment.Preproc, u'@@ \t67890'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
+
+ def testFunctionLikeMacros(self):
+ fragment = "$MACRO.(((x#y\\)))' \"(#'x)\\)x\\))\"# {{x\\))x)\\)(#'}});"
+ tokens = [
+ (Comment.Preproc, u'$MACRO.'),
+ (Punctuation, u'('),
+ (Comment.Preproc, u'('),
+ (Comment.Preproc, u'('),
+ (Comment.Preproc, u'x#y\\)'),
+ (Comment.Preproc, u')'),
+ (Comment.Preproc, u')'),
+ (Punctuation, u"'"),
+ (Comment.Preproc, u' '),
+ (String, u'"'),
+ (Error, u'('),
+ (Error, u'#'),
+ (Error, u"'"),
+ (String, u'x'),
+ (Error, u')'),
+ (Comment.Preproc, u'\\)'),
+ (String, u'x'),
+ (Comment.Preproc, u'\\)'),
+ (Error, u')'),
+ (String, u'"'),
+ (Punctuation, u'#'),
+ (Comment.Preproc, u' '),
+ (String, u'{{'),
+ (String, u'x'),
+ (Comment.Preproc, u'\\)'),
+ (Error, u')'),
+ (String, u'x'),
+ (Error, u')'),
+ (Comment.Preproc, u'\\)'),
+ (Error, u'('),
+ (Error, u'#'),
+ (Error, u"'"),
+ (String, u'}}'),
+ (Punctuation, u')'),
+ (Comment.Single, u';'),
+ (Text, u'\n')
+ ]
+ self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))