Skip to content

Commit

Permalink
Update C# lexer: new keywords and numeric literal syntax improvements (
Browse files Browse the repository at this point in the history
…#1660)

* C# lexer: add keywords from newer language versions

 * `and` (pattern matching in C# 9)
 * `init` (records in C# 9)
 * `unmanaged` (new type constraint in C# 7)
 * `nint` (native sized integers in C# 9)
 * `nuint` (native sized integers in C# 9)
 * `not` (pattern matching in C# 9)
 * `notnull` (nullable reference types in C# 8)
 * `#nullable` (nullable reference types in C# 8)
 * `or` (pattern matching in C# 9)
 * `record` (records in C# 9)
 * `with` (records in C# 9)
 * `when` (exception filters in C# 6, pattern matching in C# 7)

* C# lexer: numeric literal improvements

 * add C# 7 binary literals, e.g. `0b0010`
 * add C# 7 digit separators in all numeric literals, e.g. `123_567_890`
 * add missing `M` type suffix designating `decimal`
 * make the exponent sign optional
  • Loading branch information
stakx authored Jan 4, 2023
1 parent 43d346c commit fb9a3d9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
25 changes: 13 additions & 12 deletions lib/rouge/lexers/csharp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ class CSharp < RegexLexer
static switch this throw true try typeof unchecked unsafe
virtual void volatile while
add alias async await get global partial remove set value where
yield nameof
ascending by descending equals from group in into join let on
orderby select
yield nameof notnull
ascending by descending equals from group in init into join let
on orderby select unmanaged when and not or with
)

keywords_type = %w(
bool byte char decimal double dynamic float int long object
sbyte short string uint ulong ushort var
bool byte char decimal double dynamic float int long nint nuint
object sbyte short string uint ulong ushort var
)

cpp_keywords = %w(
if endif else elif define undef line error warning region
endregion pragma
endregion pragma nullable
)

state :whitespace do
Expand Down Expand Up @@ -81,14 +81,15 @@ class CSharp < RegexLexer
rule %r/@"(""|[^"])*"/m, Str
rule %r/"(\\.|.)*?["\n]/, Str
rule %r/'(\\.|.)'/, Str::Char
rule %r/0x[0-9a-f]+[lu]?/i, Num
rule %r/0b[_01]+[lu]?/i, Num
rule %r/0x[_0-9a-f]+[lu]?/i, Num
rule %r(
[0-9]
([.][0-9]*)? # decimal
(e[+-][0-9]+)? # exponent
[fldu]? # type
[0-9](?:[_0-9]*[0-9])?
([.][0-9](?:[_0-9]*[0-9])?)? # decimal
(e[+-]?[0-9](?:[_0-9]*[0-9])?)? # exponent
[fldum]? # type
)ix, Num
rule %r/\b(?:class|struct|interface)\b/, Keyword, :class
rule %r/\b(?:class|record|struct|interface)\b/, Keyword, :class
rule %r/\b(?:namespace|using)\b/, Keyword, :namespace
rule %r/^#[ \t]*(#{cpp_keywords.join('|')})\b.*?\n/,
Comment::Preproc
Expand Down
34 changes: 33 additions & 1 deletion spec/visual/samples/csharp
Original file line number Diff line number Diff line change
Expand Up @@ -376,5 +376,37 @@ namespace Diva.Core {
var m = $"interpolation with nested strings: { @"Ooga\" } and { "booga\"" }".Length;
}
}


public static class Csharp7And8And9Tests
{
const int BinaryConstant = 0b0100_1101;
const int HexadecimalConstant = 0x1245_78ab;

public const double AvogadroConstant = 6.022_140_857_747_474e23;
public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;

record NamedEntity(string Name);

record Person(string Name) : NamedEntity("Mr " + Name)
{
public nint Age { get; init; }

public static void WeaveSomeBobbins()
{
Person bob = new("Bob");
var bobbin = bob with { Name = "Bobbin" };
var birthdayBobbin = bobbin.OneYearOlder();
}
}

static Person OneYearOlder<T>(this T person)
where T : notnull, Person
{
return person switch
{
Person p when p.Age is > 5 and < 10 => p with { Age = p.Age + 1 },
_ => person,
};
}
}
}

0 comments on commit fb9a3d9

Please sign in to comment.