Skip to content

Instantly share code, notes, and snippets.

@kiliman
Created February 29, 2012 22:01
Show Gist options
  • Save kiliman/1944790 to your computer and use it in GitHub Desktop.
Save kiliman/1944790 to your computer and use it in GitHub Desktop.
LinqPadPrecompiler for CS-Script http://www.csscript.net/
// Written by Michael Carter (kiliman@systemex.net)
// Copyright (c) 2012. All rights reserved.
//
// Redistribution and use of this code WITHOUT MODIFICATIONS are permitted provided that
// the following conditions are met:
// 1. Redistributions must retain the above copyright notice, this list of conditions
// and the following disclaimer.
// 2. Neither the name of an author nor the names of the contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
//
// Redistribution and use of this code WITH MODIFICATIONS are permitted provided that all
// above conditions are met and software is not used or sold for profit.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
public class LinqPadPrecompiler
{
public static bool Compile(ref string code, string scriptFile, bool isPrimaryScript, Hashtable context)
{
var reQuery = new Regex(@"\<Query Kind=""Program"">(.*)\</Query>|\<Query Kind=""Program"" />",
RegexOptions.Singleline);
var reContents = new Regex(@"\<(?<type>Reference|Namespace)\>(?<content>.*?)\</\1\>", RegexOptions.Multiline);
var matchQuery = reQuery.Match(code);
if (!matchQuery.Success) return false;
var sb = new StringBuilder();
if (matchQuery.Groups.Count > 1)
{
var matchContent = reContents.Matches(code);
foreach (Match match in matchContent)
{
var type = match.Groups["type"].Value;
var content = match.Groups["content"].Value;
switch (type)
{
case "Namespace":
sb.AppendFormat("using {0};\r\n", content);
break;
case "Reference":
// remove <RuntimeDirectory> since these are GAC references
if (content.StartsWith("&lt;RuntimeDirectory&gt;\\"))
{
content = content.Replace("&lt;RuntimeDirectory&gt;\\", "");
}
var path = Path.GetDirectoryName(content);
var reference = Path.GetFileName(content);
if (path != "")
{
((IList<string>) context["NewSearchDirs"]).Add(path);
}
((IList<string>) context["NewReferences"]).Add(reference);
break;
}
}
}
// always add System.dll
((IList<string>)context["NewReferences"]).Add("System.dll");
// add default usings
sb.Append("using System;\r\n");
sb.Append("using System.IO;\r\n");
sb.Append("using System.Text;\r\n");
var remainingCode = code.Substring(matchQuery.Length);
sb.AppendFormat(@"public class ScriptClass {{ public static {0} }}", remainingCode);
code = sb.ToString();
return true;
}
}
@kiliman
Copy link
Author

kiliman commented Feb 29, 2012

LINQPad (http://www.linqpad.net/) is a great tool for creating simple programs without having to launch Visual Studio and cluttering your workspace with a bunch of console projects. However LINQPad does not have a way to run these programs outside of the IDE. Enter CS-Script (http://www.csscript.net/), which treats C# files like script files.

One issue with LINQPad (.linq) files is that they include a little header in XML that specifies the type of file and any references or namespaces needed.

This header prevents CS-Script from processing the file as it is not valid C#. However, CS-Script has a nice Precompiler feature that will pre-process the script file before compiling it. This LinqPadPrecompiler simply removes the header portion and adds the appropriate references and namespaces. It also wraps the file in a ScriptClass and prefixes the Main() method with public static. This is similar to what the built-in AutoclassPrecompiler does.

@kiliman
Copy link
Author

kiliman commented Feb 29, 2012

Added license identical to CS-Script source.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment