Releases: qwertie/ecsharp
VS2022-compatible EC#/LeMP/LLLPG extension
Easy macros and much more!
Allow me to showcase this release with an example. It's a slightly complicated example, but it does something cool: it converts expressions into human-readable strings. For example the expression UserIsLoggedIn && CartIsEmpty
. becomes "User Is Logged In and Cart Is Empty". Then, I use a macro to combine an executable expression with its string description - all at compile-time. See here for documentation of the macro
macro.
compileTime
{
using System.Text.RegularExpressions;
static string DescribeIdentifier(string id) =>
new Regex("(?!^)[A-Z0-9]+").Replace(id, new MatchEvaluator(m => {
string s = m.ToString();
return s.Length > 1
? " " + s.Substring(0, s.Length - 1) + " " + s.Substring(s.Length - 1)
: " " + s;
}));
static string DescribeExpr(LNode expr) {
matchCode(expr) {
case $left && $right:
return $"{DescribeExpr(left)} and {DescribeExpr(right)}";
case $left || $right:
return $"{DescribeExpr(left)} or {DescribeExpr(right)}";
case $left == $right:
return $"{DescribeExpr(left)} is {DescribeExpr(right)}";
case $(lit when lit.IsLiteral):
return lit.Value?.ToString() ?? "null";
case $_.$id:
return DescribeIdentifier(id.Name.Name);
default:
return DescribeIdentifier(expr.Name.Name);
}
}
}
macro DocumentedExpr($expr) {
var descr = LNode.Literal(DescribeExpr(expr));
return quote(($descr, new Func<object>(() => $expr)));
}
class Information
{
// These are variables, so you can change the facts to fit your taste
static bool BidenWasElected = true, ElectionWasStolen = false;
static (string,Func<object>)[] Parameters = new [] {
DocumentedExpr(Environment.CurrentDirectory),
DocumentedExpr(Environment.Is64BitProcess || Environment.Is64BitOperatingSystem),
DocumentedExpr(BidenWasElected && ElectionWasStolen),
DocumentedExpr(null == null),
};
}
The generated code looks like this:
class Information
{
// These are variables, so you can change the facts to fit your taste
static bool BidenWasElected = true, ElectionWasStolen = false;
static (string, Func<object>)[] Factoids = new[] {
("Current Directory", new Func<object>(() => Environment.CurrentDirectory)),
("Is 64 Bit Process or Is 64 Bit Operating System", new Func<object>(() => Environment.Is64BitProcess || Environment.Is64BitOperatingSystem)),
("Biden Was Elected and Election Was Stolen", new Func<object>(() => BidenWasElected && ElectionWasStolen)),
("null is null", new Func<object>(() => null == null))
};
}
The list of changes (including potentially breaking changes) is fairly massive, especially in the Loyc Core libraries. The semantic version has increased from 28 to 29, and the internal version number 2.9.0 will increase to 30.0 in the next major release, so that the semantic version will be the same as the internal version.
As always, the full list of changes is here:
Plus, you can see me talking about some of the recent changes on my YouTube channel.
v2.9.0 Preview Release
There are numerous changes in this release. One of the most notable is a new macro
macro for writing macros. Example:
using System.Text.RegularExpressions;
macro countDigits($(str && str.Value is string strValue))
{
var regex = new Regex("[0-9]");
return LNode.Literal(regex.Matches(strValue).Count);
}
int i = countDigits("I have 25 apples an 7 bananas");
// Generated from Demo.ecs by LeMP 2.9.0.0.
using System.Text.RegularExpressions;
int i = 3;
Run C# code at compile time (updated)
Run C# code at compile time!
This release integrates the Roslyn Scripting engine behind C# Interactive, making it much easier to do arbitrary code transformations at compile time. There are a few new macros, most notably compileTime
and precompute
, which together let you do almost anything. See issue 112 for the design discussion. Here's an example.
compileTime {
#r "bin\Debug\Loyc.Utilities.dll"
using System.Collections.Generic;
var d = new Dictionary<int,string> { [2] = "Two" };
var stat = new Loyc.Utilities.Statistic();
stat.Add(5);
stat.Add(7);
}
public class Class
{
// Yeah baby.
const string Two = precompute(d[2]);
const int Six = precompute((int) stat.Avg());
double Talk() {
precompute(new List<LNode> {
quote(Console.WriteLine("hello")),
quote { return $(LNode.Literal(Math.PI)); }
});
}
}
Output:
public class Class
{
// Yeah baby.
const string Two = "Two";
const int Six = 6;
double Talk() {
Console.WriteLine("hello");
return 3.14159265358979;
}
}
2020/07/09: .config files were added to the zip file to fix an error about System.Runtime.CompilerServices.Unsafe
.
Tweak the previous release
See changelist at http://core.loyc.net/version-history
This is probably the last release before support for .NET 3.5 and .NET 4 is dropped.
Quite a few changes since last GitHub release
This is probably the last release before support for .NET 3.5 and .NET 4 is dropped. .NET 4.5 build attached. Other builds available via NuGet.
Added .NET Standard version. Extension now installs on VS 2019.
Minor improvements described on these pages:
.NET 4.5 build attached. Other builds available via NuGet.
Message sink & localization APIs edited; LESv3 nearly finalized; EC# supports LINQ; bug fixes
NEW: LeMP and syntax highlighting has been combined into a single Visual Studio extension! If you're using Visual Studio 2015 or Visual Studio 2017, just download and run LeMP_VisualStudio.vsix (be sure to uninstall any older versions first). If you're using an old version of Visual Studio, download LeMP2.6.2.zip instead and use LoycFileGeneratorForVs.exe which supports VS2008 through VS2015; v2.6.2 will probably be the last release that supports your old version.
LeMP2.6.2.zip contains the Loyc library DLLs for version 2.6.2; generally it is recommended to use NuGet packages instead, but AppVeyor's automatic updating of NuGet packages is broken at the moment. The zip file also contains two installers for older versions of Visual Studio: LoycFileGeneratorForVs.exe installs the single-file generator and LoycSyntaxForVs.vsix installs syntax highlighting only.
Please visit the following links to learn about recent changes:
Attempting auto-upload of NuGet packages
This release is virtually the same as the previous one. Testing whether AppVeyor will automatically publish NuGet packages.