summaryrefslogtreecommitdiff
path: root/pygments/lexers
diff options
context:
space:
mode:
authorAndrew Schmidt <andrewschmidt-a@users.noreply.github.com>2023-02-14 12:29:42 -0600
committerGitHub <noreply@github.com>2023-02-14 19:29:42 +0100
commit0ae4bc83d352b46152e1e52525302209c8f4f869 (patch)
tree0178adbbb04c2e2248e0f922a9fdce9dd2480451 /pygments/lexers
parent972f6182da42c396143a8f33a88d691a64df6190 (diff)
downloadpygments-git-0ae4bc83d352b46152e1e52525302209c8f4f869.tar.gz
Add X++ support (#2339)
Co-authored-by: Jean Abou Samra <jean@abou-samra.fr>
Diffstat (limited to 'pygments/lexers')
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/dotnet.py113
2 files changed, 113 insertions, 1 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index ccc1b84d..6608f30f 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -541,6 +541,7 @@ LEXERS = {
'XmlPhpLexer': ('pygments.lexers.templates', 'XML+PHP', ('xml+php',), (), ('application/xml+php',)),
'XmlSmartyLexer': ('pygments.lexers.templates', 'XML+Smarty', ('xml+smarty',), (), ('application/xml+smarty',)),
'XorgLexer': ('pygments.lexers.xorg', 'Xorg', ('xorg.conf',), ('xorg.conf',), ()),
+ 'XppLexer': ('pygments.lexers.dotnet', 'X++', ('xpp', 'x++'), ('*.xpp',), ()),
'XsltLexer': ('pygments.lexers.html', 'XSLT', ('xslt',), ('*.xsl', '*.xslt', '*.xpl'), ('application/xsl+xml', 'application/xslt+xml')),
'XtendLexer': ('pygments.lexers.jvm', 'Xtend', ('xtend',), ('*.xtend',), ('text/x-xtend',)),
'XtlangLexer': ('pygments.lexers.lisp', 'xtlang', ('extempore',), ('*.xtm',), ()),
diff --git a/pygments/lexers/dotnet.py b/pygments/lexers/dotnet.py
index 0778ffef..b20e7e15 100644
--- a/pygments/lexers/dotnet.py
+++ b/pygments/lexers/dotnet.py
@@ -19,7 +19,7 @@ from pygments import unistring as uni
from pygments.lexers.html import XmlLexer
__all__ = ['CSharpLexer', 'NemerleLexer', 'BooLexer', 'VbNetLexer',
- 'CSharpAspxLexer', 'VbNetAspxLexer', 'FSharpLexer']
+ 'CSharpAspxLexer', 'VbNetAspxLexer', 'FSharpLexer', 'XppLexer']
class CSharpLexer(RegexLexer):
@@ -727,3 +727,114 @@ class FSharpLexer(RegexLexer):
result += 0.05
return result
+
+class XppLexer(RegexLexer):
+
+ """
+ For X++ source code. This is based loosely on the CSharpLexer
+
+ .. versionadded:: 2.15.0
+ """
+
+ name = 'X++'
+ url = 'https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-ref/xpp-language-reference'
+ aliases = ['xpp', 'x++']
+ filenames = ['*.xpp']
+
+ flags = re.MULTILINE
+
+ XPP_CHARS = ('@?(?:_|[^' +
+ uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl') + '])' +
+ '[^' + uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl',
+ 'Nd', 'Pc', 'Cf', 'Mn', 'Mc') + ']*');
+ # Temporary, see
+ # https://github.com/thatch/regexlint/pull/49
+ XPP_CHARS = XPP_CHARS.replace('\x00', '\x01')
+
+ OPERATORS = (
+ '<=', '>=', '+=', '-=', '*=', '/=', '!=', '==',
+ '&&', '||', '>>', '<<', '++', '--', '+', '-', '*',
+ '/', '%', '&', '|', '^', '<', '>', '?', '!', '~', '=',
+ )
+ KEYWORDS = ('abstract','anytype','as','async','asc','at','avg','break','breakpoint','by','byref','case','catch',
+ 'changecompany','client','container','continue','count','crosscompany','default','delegate',
+ 'delete_from','desc','display','div','do','edit','else','element','eventhandler','exists','false','final',
+ 'firstfast','firstonly','firstonly10','firstonly100','firstonly1000','flush','for','forceliterals',
+ 'forcenestedloop','forceplaceholders','forceselectorder','forupdate','from','group','if','insert_recordset',
+ 'interface','is','join','like','maxof','minof','mod','new','next','nofetch','notexists','null','optimisticlock','order',
+ 'outer','pause','pessimisticlock','print','private','protected','public','repeatableread','retry','return',
+ 'reverse','select','server','setting','static','sum','super','switch','tablelock','this','throw','true','try','ttsabort','ttsbegin',
+ 'ttscommit','update_recordset','validtimestate','void','where','while','window')
+ RUNTIME_FUNCTIONS = ('_duration','abs','acos','any2Date','any2Enum','any2Guid','any2Int','any2Int64','any2Real','any2Str','anytodate',
+ 'anytoenum','anytoguid','anytoint','anytoint64','anytoreal','anytostr','asin','atan','beep','cTerm','char2Num','classIdGet',
+ 'corrFlagGet','corrFlagSet','cos','cosh','curExt','curUserId','date2Num','date2Str','datetime2Str','dayName','dayOfMth',
+ 'dayOfWk','dayOfYr','ddb','decRound','dg','dimOf','endMth','enum2str','exp','exp10','fV','fieldId2Name','fieldId2PName',
+ 'fieldName2Id','frac','funcName','getCurrentPartition','getCurrentPartitionRecId','getPrefix','guid2Str','idg','indexId2Name',
+ 'indexName2Id','int2Str','int642Str','intvMax','intvName','intvNo','intvNorm','log10','logN','match','max','min','mkDate','mthName',
+ 'mthOfYr','newGuid','nextMth','nextQtr','nextYr','num2Char','num2Date','num2Str','pmt','power','prevMth','prevQtr','prevYr',
+ 'prmIsDefault','pt','pv','rate','refPrintAll','round','runAs','sessionId','setPrefix','sin','sinh','sleep','sln','str2Date',
+ 'str2Datetime','str2Enum','str2Guid','str2Int','str2Int64','str2Num','str2Time','strAlpha','strCmp','strColSeq','strDel',
+ 'strFind','strFmt','strIns','strKeep','strLTrim','strLen','strLine','strLwr','strNFind','strPoke','strPrompt','strRTrim',
+ 'strRem','strRep','strScan','strUpr','subStr','syd','systemDateGet','systemDateSet','tableId2Name',
+ 'tableId2PName','tableName2Id','tan','tanh','term','time2Str','timeNow','today','trunc','typeOf','uint2Str','wkOfYr','year')
+ COMPILE_FUNCTIONS = ('attributeStr','classNum','classStr','configurationKeyNum','configurationKeyStr','dataEntityDataSourceStr','delegateStr',
+ 'dimensionHierarchyLevelStr','dimensionHierarchyStr','dimensionReferenceStr','dutyStr','enumCnt','enumLiteralStr','enumNum','enumStr',
+ 'extendedTypeNum','extendedTypeStr','fieldNum','fieldPName','fieldStr','formControlStr','formDataFieldStr','formDataSourceStr',
+ 'formMethodStr','formStr','identifierStr','indexNum','indexStr','licenseCodeNum','licenseCodeStr','literalStr','maxDate','maxInt',
+ 'measureStr','measurementStr','menuItemActionStr','menuItemDisplayStr','menuItemOutputStr','menuStr','methodStr','minInt','privilegeStr',
+ 'queryDatasourceStr','queryMethodStr','queryStr','reportStr','resourceStr','roleStr','ssrsReportStr','staticDelegateStr','staticMethodStr',
+ 'tableCollectionStr','tableFieldGroupStr','tableMethodStr','tableNum','tablePName','tableStaticMethodStr','tableStr','tileStr','varStr',
+ 'webActionItemStr','webDisplayContentItemStr','webFormStr','webMenuStr','webOutputContentItemStr','webReportStr','webSiteTempStr',
+ 'webStaticFileStr','webUrlItemStr','webWebPartStr','webletItemStr','webpageDefStr','websiteDefStr','workflowApprovalStr',
+ 'workflowCategoryStr','workflowTaskStr','workflowTypeStr')
+
+ tokens = {}
+
+ tokens = {
+ 'root': [
+ # method names
+ (r'(\s*)\b(else|if)\b([^\n])', bygroups(Whitespace, Keyword, using(this))), # ensure that if is not treated like a function
+ (r'^([ \t]*)((?:' + XPP_CHARS + r'(?:\[\])?\s+)+?)' # return type
+ r'(' + XPP_CHARS + ')' # method name
+ r'(\s*)(\()', # signature start
+ bygroups(Whitespace, using(this), Name.Function, Whitespace,
+ Punctuation)),
+ (r'^(\s*)(\[)([^\n]*?)(\])', bygroups(Whitespace, Name.Attribute, Name.Variable.Class, Name.Attribute)),
+ (r'[^\S\n]+', Whitespace),
+ (r'(\\)(\n)', bygroups(Text, Whitespace)), # line continuation
+ (r'//[^\n]*?\n', Comment.Single),
+ (r'/[*][^\n]*?[*]/', Comment.Multiline),
+ (r'\n', Whitespace),
+ (words(OPERATORS), Operator),
+ (r'=~|!=|==|<<|>>|[-+/*%=<>&^|]', Operator),
+ (r'[()\[\];:,.#@]', Punctuation),
+ (r'[{}]', Punctuation),
+ (r'@"(""|[^"])*"', String),
+ (r'\$?"(\\\\|\\[^\\]|[^"\\\n])*["\n]', String),
+ (r"'\\.'|'[^\\]'", String.Char),
+ (r"[0-9]+(\.[0-9]*)?([eE][+-][0-9]+)?"
+ r"[flFLdD]?|0[xX][0-9a-fA-F]+[Ll]?", Number),
+ (words(KEYWORDS, suffix=r'\b'), Keyword),
+ (r'(boolean|int|int64|str|real|guid|date)\b\??', Keyword.Type),
+ (r'(class|struct|extends|implements)(\s+)', bygroups(Keyword, Whitespace), 'class'),
+ (r'('+XPP_CHARS+')(::)', bygroups(Name.Variable.Class, Punctuation)),
+ (r'(\s*)(\w+)(\s+\w+(,|=)?[^\n]*;)', bygroups(Whitespace, Name.Variable.Class, using(this))), # declaration
+ # x++ specific function to get field should highlight the classname
+ (r'(fieldNum\()('+XPP_CHARS+r')(\s*,\s*)('+XPP_CHARS+r')(\s*\))',
+ bygroups(using(this), Name.Variable.Class, using(this), Name.Property, using(this))),
+ # x++ specific function to get table should highlight the classname
+ (r'(tableNum\()('+XPP_CHARS+r')(\s*\))',
+ bygroups(using(this), Name.Variable.Class, using(this))),
+ (words(RUNTIME_FUNCTIONS, suffix=r'(?=\()'), Name.Function.Magic),
+ (words(COMPILE_FUNCTIONS, suffix=r'(?=\()'), Name.Function.Magic),
+ (XPP_CHARS, Name),
+ ],
+ 'class': [
+ (XPP_CHARS, Name.Class, '#pop'),
+ default('#pop'),
+ ],
+ 'namespace': [
+ (r'(?=\()', Text, '#pop'), # using (resource)
+ ('(' + XPP_CHARS + r'|\.)+', Name.Namespace, '#pop'),
+ ]
+ }