diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..159cd6d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+**/bin/Debug/
+**/obj/Debug/
+Irony_All.2012.sln.DotSettings
+Irony_All.2012.sln.DotSettings.user
+Irony_All.2012.v11.suo
+**/bin/Release/
+**/obj/Release/
diff --git a/Irony.GrammarExplorer/030.Irony.GrammarExplorer.2012.csproj b/Irony.GrammarExplorer/030.Irony.GrammarExplorer.2012.csproj
new file mode 100644
index 0000000..5ea3300
--- /dev/null
+++ b/Irony.GrammarExplorer/030.Irony.GrammarExplorer.2012.csproj
@@ -0,0 +1,165 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}
+ WinExe
+ Properties
+ Irony.GrammarExplorer
+ Irony.GrammarExplorer
+
+
+ 3.5
+
+
+ v4.0
+
+
+
+
+
+
+
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+ Client
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ fmGrammarExplorer.cs
+
+
+ Form
+
+
+ fmSelectGrammars.cs
+
+
+
+
+
+
+
+ fmGrammarExplorer.cs
+ Designer
+
+
+ fmSelectGrammars.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ Designer
+ fmShowException.cs
+
+
+ True
+ Resources.resx
+ True
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+ Form
+
+
+ fmShowException.cs
+
+
+
+
+
+
+
+
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}
+ 010.Irony.2010
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/Irony.Samples.Console/025.Irony.Samples.Console.2012.csproj b/Irony.Samples.Console/025.Irony.Samples.Console.2012.csproj
new file mode 100644
index 0000000..1941977
--- /dev/null
+++ b/Irony.Samples.Console/025.Irony.Samples.Console.2012.csproj
@@ -0,0 +1,121 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}
+ Exe
+ Properties
+ Irony.Samples.Console
+ Irony.Samples.Console
+ v4.0
+ 512
+
+
+
+
+
+
+
+
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}
+ 020.Irony.Samples.2010
+
+
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}
+ 010.Irony.2010
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Irony.Samples/020.Irony.Samples.2012.csproj b/Irony.Samples/020.Irony.Samples.2012.csproj
new file mode 100644
index 0000000..538a75a
--- /dev/null
+++ b/Irony.Samples/020.Irony.Samples.2012.csproj
@@ -0,0 +1,164 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}
+ Library
+ Properties
+ Irony.Samples
+ Irony.Samples
+
+
+ 3.5
+
+
+ v4.0
+
+
+
+
+
+
+
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+ AllRules.ruleset
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}
+ 010.Irony.2010
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/Irony.Tests/040.Irony.Tests.VsTest.2012.csproj b/Irony.Tests/040.Irony.Tests.VsTest.2012.csproj
new file mode 100644
index 0000000..98f2958
--- /dev/null
+++ b/Irony.Tests/040.Irony.Tests.VsTest.2012.csproj
@@ -0,0 +1,127 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}
+ Library
+ Properties
+ Irony.Tests
+ Irony.Tests.VSTest
+ v4.0
+ 512
+ {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+
+
+
+
+
+
+
+
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}
+ 010.Irony.2010
+
+
+
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/Irony.Tests/050.Irony.Tests.NUnit.2012.csproj b/Irony.Tests/050.Irony.Tests.NUnit.2012.csproj
new file mode 100644
index 0000000..0660695
--- /dev/null
+++ b/Irony.Tests/050.Irony.Tests.NUnit.2012.csproj
@@ -0,0 +1,132 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}
+ Library
+ Properties
+ Irony.Tests
+ Irony.Tests.NUnit
+ v4.0
+ 512
+
+
+
+
+
+
+
+
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+ Client
+
+
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG;USE_NUNIT
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+ False
+ ..\..\..\..\..\..\Temp\NUnit-2.5.8.10295\bin\net-2.0\framework\nunit.framework.dll
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}
+ 010.Irony.2010
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/Irony.Tests/Ast/IdentifierNodeTests.cs b/Irony.Tests/Ast/IdentifierNodeTests.cs
new file mode 100644
index 0000000..93340e5
--- /dev/null
+++ b/Irony.Tests/Ast/IdentifierNodeTests.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Irony.Ast;
+using Irony.Interpreter;
+using Irony.Parsing;
+using NUnit.Framework;
+
+namespace Irony.Tests.Ast
+{
+ [TestFixture]
+ public class IdentifierNodeTests
+ {
+ [Test]
+ public void EvaluateNodeReadsFromTopMostSymbolInFrameStack() {
+ // Create context
+ var context = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("id");
+ // Insert value in lower frame
+ context.SetLocalValue(symbol, 24);
+ context.PushFrame("x", null, context.CurrentFrame);
+ // Insert value in top frame
+ context.SetLocalValue(symbol, 42);
+ context.PushFrame("y", null, context.CurrentFrame);
+
+ // Try evaluating
+ var sut = new IdentifierNode();
+ var token = new TestToken(symbol);
+ sut.Init(null, new ParseTreeNode(token));
+ sut.EvaluateNode(context, AstMode.Read);
+
+ var actual = context.LastResult;
+ Assert.That(actual, Is.EqualTo(42));
+ }
+
+ [Test]
+ public void EvaluateNodeWritesToTopMostSymbolInFrameStack() {
+ // Create context
+ var context = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("id");
+ // Insert value in lower frame
+ context.SetLocalValue(symbol, 24);
+ context.PushFrame("x", null, context.CurrentFrame);
+ // Insert value in top frame
+ context.SetLocalValue(symbol, 42);
+ context.PushFrame("y", null, context.CurrentFrame);
+
+ context.Data.Push(100);
+
+ // Try evaluating
+ var sut = new IdentifierNode();
+ var token = new TestToken(symbol);
+ sut.Init(null, new ParseTreeNode(token));
+ sut.EvaluateNode(context, AstMode.Write);
+
+ var actual = context.CurrentFrame.Parent.Values[symbol];
+ Assert.That(actual, Is.EqualTo(100));
+ }
+
+ private static EvaluationContext CreateContext() {
+ return new EvaluationContext(new LanguageRuntime(new LanguageData(new Grammar())));
+ }
+
+ private class TestToken : Token {
+ public TestToken(Symbol symbol) : base(new Terminal("testTerminal"), new SourceLocation(), "token", "value") {
+ Symbol = symbol;
+ }
+ }
+ }
+}
diff --git a/Irony.Tests/Ast/LocalIdentifierNodeTests.cs b/Irony.Tests/Ast/LocalIdentifierNodeTests.cs
new file mode 100644
index 0000000..f3d07cd
--- /dev/null
+++ b/Irony.Tests/Ast/LocalIdentifierNodeTests.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Irony.Ast;
+using Irony.Interpreter;
+using Irony.Parsing;
+using NUnit.Framework;
+
+namespace Irony.Tests.Ast
+{
+ [TestFixture]
+ public class LocalIdentifierNodeTests
+ {
+ [Test]
+ public void EvaluateNodeReadsFromTopMostSymbolInFrameStack() {
+ // Create context
+ var context = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("id");
+ // Insert value in lower frame
+ context.SetLocalValue(symbol, 24);
+ context.PushFrame("x", null, context.CurrentFrame);
+ // Insert value in top frame
+ context.SetLocalValue(symbol, 42);
+ context.PushFrame("y", null, context.CurrentFrame);
+
+ // Try evaluating
+ var sut = new LocalIdentifierNode();
+ var token = new TestToken(symbol);
+ sut.Init(null, new ParseTreeNode(token));
+ sut.EvaluateNode(context, AstMode.Read);
+
+ var actual = context.LastResult;
+ Assert.That(actual, Is.EqualTo(42));
+ }
+
+ [Test]
+ public void EvaluateNodeWritesToTopFrameStack() {
+ // Create context
+ var context = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("id");
+ // Insert value in lower frame
+ context.SetLocalValue(symbol, 24);
+ context.PushFrame("x", null, context.CurrentFrame);
+ // Insert value in top frame
+ context.SetLocalValue(symbol, 42);
+ context.PushFrame("y", null, context.CurrentFrame);
+
+ context.Data.Push(100);
+
+ // Try evaluating
+ var sut = new LocalIdentifierNode();
+ var token = new TestToken(symbol);
+ sut.Init(null, new ParseTreeNode(token));
+ sut.EvaluateNode(context, AstMode.Write);
+
+ var actual = context.CurrentFrame.Values[symbol];
+ Assert.That(actual, Is.EqualTo(100));
+ // Check that parent value is untouched. This is what differentiate LocalIdentifierNode from IdentifierNode
+ Assert.That(context.CurrentFrame.Parent.Values[symbol], Is.EqualTo(42));
+ }
+
+ private static EvaluationContext CreateContext() {
+ return new EvaluationContext(new LanguageRuntime(new LanguageData(new Grammar())));
+ }
+
+ private class TestToken : Token {
+ public TestToken(Symbol symbol) : base(new Terminal("testTerminal"), new SourceLocation(), "token", "value") {
+ Symbol = symbol;
+ }
+ }
+ }
+}
diff --git a/Irony.Tests/Interpreter/EvaluateAsyncTests.cs b/Irony.Tests/Interpreter/EvaluateAsyncTests.cs
new file mode 100644
index 0000000..749d422
--- /dev/null
+++ b/Irony.Tests/Interpreter/EvaluateAsyncTests.cs
@@ -0,0 +1,213 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using Irony.Ast;
+using Irony.Interpreter;
+using Irony.Parsing;
+using NUnit.Framework;
+
+namespace Irony.Tests.Interpreter
+{
+ public class MiniGrammar : Grammar
+ {
+ public MiniGrammar()
+ {
+ // 1. Terminals
+ var identifier = new IdentifierTerminal("id");
+ var number = new NumberLiteral("number");
+
+ // 2. Non-terminals
+ var StmtList = new NonTerminal("StmtList", typeof(StatementListNode));
+ var Stmt = new NonTerminal("Stmt");
+ var Expr = new NonTerminal("Expr");
+ var FunctionCall = new NonTerminal("FunctionCall", typeof (FunctionCallNode));
+
+ // 3. BNF rules
+ StmtList.Rule = MakePlusRule(StmtList, Stmt);
+ Stmt.Rule = Expr + ToTerm(";");
+ Expr.Rule = FunctionCall | number;
+ FunctionCall.Rule = identifier + "(" + ")";
+
+ MarkPunctuation("(", ")", ";");
+ RegisterBracePair("(", ")");
+ MarkTransient(Stmt, Expr);
+
+ Root = StmtList;
+ LanguageFlags = LanguageFlags.CreateAst;
+ }
+ }
+
+ [TestFixture]
+ public class EvaluateAsyncTests
+ {
+ [Test]
+ public void MiniGrammarFunctionCall()
+ {
+ AssertAstTree(new MiniGrammar(), "func1();func2();",
+ NewNode(),
+ NewNode(),
+ NewNode("func1"),
+ NewNode(),
+ NewNode("func2"));
+ }
+ [Test]
+ public void ScriptCanBeCanceled()
+ {
+ var interpreter = new ScriptInterpreter(new MiniGrammar());
+ bool func2IsCalled = false;
+ interpreter.EvaluationContext.SetValue(SymbolTable.Symbols.TextToSymbol("func1"), new ActionCallTarget(() => Thread.Sleep(500)));
+ interpreter.EvaluationContext.SetValue(SymbolTable.Symbols.TextToSymbol("func2"), new ActionCallTarget(() => func2IsCalled = true));
+ interpreter.EvaluateAsync("func1();func2();");
+ Thread.Sleep(100); // Give the parser time to finish and evaluation to start.
+ interpreter.Abort(TimeSpan.FromMilliseconds(1000));
+
+ Assert.That(interpreter.Status, Is.EqualTo(InterpreterStatus.Canceled));
+ Assert.That(func2IsCalled, Is.False);
+ }
+
+ [Test]
+ public void ScriptIsAbortedIfNotCanceledWithinTimeout()
+ {
+ var interpreter = new ScriptInterpreter(new MiniGrammar());
+ bool func2IsCalled = false;
+ interpreter.EvaluationContext.SetValue(SymbolTable.Symbols.TextToSymbol("func1"), new ActionCallTarget(() => Thread.Sleep(500)));
+ interpreter.EvaluationContext.SetValue(SymbolTable.Symbols.TextToSymbol("func2"), new ActionCallTarget(() => func2IsCalled = true));
+ interpreter.EvaluateAsync("func1();func2();");
+ Thread.Sleep(100); // Give the parser time to finish and evaluation to start.
+ interpreter.Abort(TimeSpan.FromMilliseconds(1));
+
+ Assert.That(interpreter.Status, Is.EqualTo(InterpreterStatus.Aborted));
+ Assert.That(func2IsCalled, Is.False);
+ }
+
+ [Test]
+ public void WaitHandleWillBeSetWhenScriptCompletes()
+ {
+ var interpreter = new ScriptInterpreter(new MiniGrammar());
+ bool func2IsCalled = false;
+ interpreter.EvaluationContext.SetValue(SymbolTable.Symbols.TextToSymbol("func1"), new ActionCallTarget(() => Thread.Sleep(0)));
+ interpreter.EvaluationContext.SetValue(SymbolTable.Symbols.TextToSymbol("func2"), new ActionCallTarget(() => func2IsCalled = true));
+ interpreter.EvaluateAsync("func1();func2();");
+ interpreter.WaitHandle.WaitOne();
+
+ Assert.That(interpreter.Status, Is.EqualTo(InterpreterStatus.Ready));
+ Assert.That(func2IsCalled, Is.True);
+ }
+
+ [Test]
+ public void LastResultContainsLastExpressionWhenScriptCompletes()
+ {
+ var interpreter = new ScriptInterpreter(new MiniGrammar());
+ interpreter.EvaluateAsync("5;42;");
+ interpreter.WaitHandle.WaitOne();
+
+ Assert.That(interpreter.Status, Is.EqualTo(InterpreterStatus.Ready));
+ Assert.That(interpreter.EvaluationContext.LastResult, Is.EqualTo(42));
+ }
+
+ [Test]
+ public void StatusIsRunTimeErrorIfExecutionFails()
+ {
+ var interpreter = new ScriptInterpreter(new MiniGrammar());
+ interpreter.EvaluationContext.SetValue(SymbolTable.Symbols.TextToSymbol("func1"), new ActionCallTarget(() => { throw new Exception(); }));
+ interpreter.EvaluateAsync("func1();");
+ interpreter.WaitHandle.WaitOne();
+
+ Assert.That(interpreter.Status, Is.EqualTo(InterpreterStatus.RuntimeError));
+ }
+
+
+ public class ActionCallTarget : ICallTarget
+ {
+ private readonly Action _action;
+
+ public ActionCallTarget(Action action)
+ {
+ _action = action;
+ }
+
+ public void Call(EvaluationContext context)
+ {
+ _action();
+ }
+ }
+
+ protected ParseTree AssertAstTree(Grammar grammar, string script, params ComparableAstNode[] nodes)
+ {
+ var parser = new Parser(grammar);
+ var parseTree = parser.Parse(script);
+
+ Assert.That(parseTree.Status, Is.EqualTo(ParseTreeStatus.Parsed), FormatParseError(parseTree));
+ var astNodes = UnfoldAstTree((AstNode)parseTree.Root.AstNode);
+ var comparableNodes = astNodes.Select(x => new ComparableAstNode(x.GetType(), x.AsString)).ToArray();
+ Assert.That(comparableNodes, Is.EqualTo(nodes));
+ return parseTree;
+ }
+
+ protected IEnumerable UnfoldAstTree(AstNode node)
+ {
+ yield return node;
+ foreach (var childNode in node.ChildNodes)
+ {
+ var subNodes = UnfoldAstTree(childNode);
+ foreach (var subNode in subNodes)
+ {
+ yield return subNode;
+ }
+ }
+ }
+
+ protected class ComparableAstNode : IEquatable
+ {
+ private readonly Type _astType;
+ private readonly string _value;
+
+ public ComparableAstNode(Type astType, string value)
+ {
+ this._astType = astType;
+ this._value = value;
+ }
+
+ public bool Equals(ComparableAstNode other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ if (_value != null)
+ return Equals(_astType, other._astType) && string.Equals(_value, other._value);
+ return Equals(_astType, other._astType);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj is ComparableAstNode)
+ return Equals((ComparableAstNode)obj);
+ if (obj is AstNode)
+ return Equals(new ComparableAstNode(obj.GetType(), ((AstNode)obj).AsString));
+ return false;
+ }
+
+ public override string ToString()
+ {
+ if (_value == null)
+ return _astType.FullName;
+ return string.Format("{0}:{1}", _astType.FullName, _value);
+ }
+ }
+
+ protected ComparableAstNode NewNode(string value = null)
+ {
+ return new ComparableAstNode(typeof(T), value);
+ }
+
+ protected string FormatParseError(ParseTree result)
+ {
+ if (!result.HasErrors()) return string.Empty;
+ return string.Join("\n", result.ParserMessages);
+ }
+
+ }
+}
diff --git a/Irony.Tests/Interpreter/EvaluationContextTests.cs b/Irony.Tests/Interpreter/EvaluationContextTests.cs
new file mode 100644
index 0000000..672c18c
--- /dev/null
+++ b/Irony.Tests/Interpreter/EvaluationContextTests.cs
@@ -0,0 +1,153 @@
+using Irony.Interpreter;
+using Irony.Parsing;
+using NUnit.Framework;
+
+namespace Irony.Tests.Interpreter
+{
+ [TestFixture]
+ public class EvaluationContextTests
+ {
+ [Test]
+ public void SetValueCreatesGlobalValueIfFrameStackEmpty() {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.SetValue(symbol, 42);
+ var actual = sut.Globals[symbol];
+ Assert.That(actual, Is.EqualTo(42));
+ }
+
+ [Test]
+ public void SetValueOverwritesGlobalValueIfFrameStackEmpty() {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.SetValue(symbol, 42);
+ sut.SetValue(symbol, 24);
+ var actual = sut.Globals[symbol];
+ Assert.That(actual, Is.EqualTo(24));
+ }
+
+ [Test]
+ public void SetValueOverwritesGlobalValueIfStackNotEmpty() {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.SetValue(symbol, 42);
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ sut.SetValue(symbol, 24);
+ var actual = sut.Globals[symbol];
+ Assert.That(actual, Is.EqualTo(24));
+ Assert.That(sut.CurrentFrame.Values.ContainsKey(symbol), Is.False);
+ }
+
+ [Test]
+ public void SetValueCreatesLocalValueIfNotFound() {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ sut.SetValue(symbol, 42);
+ Assert.That(sut.Globals.ContainsKey(symbol), Is.False);
+ Assert.That(sut.CurrentFrame.Values[symbol], Is.EqualTo(42));
+ }
+
+ [Test]
+ public void SetValueOverwritesValueAtSameStackFrame()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ sut.SetValue(symbol, 24);
+ sut.SetValue(symbol, 42);
+ Assert.That(sut.CurrentFrame.Values[symbol], Is.EqualTo(42));
+ }
+
+ [Test]
+ public void SetValueOverwritesValueAtLowerStackFrame()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ sut.SetValue(symbol, 24);
+ sut.PushFrame("y", null, sut.CurrentFrame);
+ sut.SetValue(symbol, 42);
+ Assert.That(sut.CurrentFrame.Values.ContainsKey(symbol), Is.False);
+ Assert.That(sut.CurrentFrame.Parent.Values[symbol], Is.EqualTo(42));
+ }
+
+ [Test]
+ public void SetLocalValueCreatesLocalValueEvenIfSymbolExistsInLowerFrame()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ sut.SetValue(symbol, 24);
+ sut.PushFrame("y", null, sut.CurrentFrame);
+ sut.SetLocalValue(symbol, 42);
+ Assert.That(sut.CurrentFrame.Values[symbol], Is.EqualTo(42));
+ Assert.That(sut.CurrentFrame.Parent.Values[symbol], Is.EqualTo(24));
+ }
+
+ [Test]
+ public void SetLocalValueOverwritesValueAtSameStackFrame()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ sut.SetLocalValue(symbol, 24);
+ sut.SetLocalValue(symbol, 42);
+ Assert.That(sut.CurrentFrame.Values[symbol], Is.EqualTo(42));
+ }
+
+ [Test]
+ public void TryGetValueReturnsTrueIfValueExistsInCurrentFrame()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.SetLocalValue(symbol, 12);
+ object value;
+ var actual = sut.TryGetValue(symbol, out value);
+ Assert.That(actual, Is.True);
+ }
+
+ [Test]
+ public void TryGetValueReturnsTrueIfValueExistsInLowerFrame()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.SetLocalValue(symbol, 12);
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ object value;
+ var actual = sut.TryGetValue(symbol, out value);
+ Assert.That(actual, Is.True);
+ }
+
+ [Test]
+ public void TryGetValueReturnsFalseIfValueDoesNotExists()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ object value;
+ var actual = sut.TryGetValue(symbol, out value);
+ Assert.That(actual, Is.False);
+ }
+
+ [Test]
+ public void TryGetValueReadsValueFromTopFrameWhereFound()
+ {
+ var sut = CreateContext();
+ var symbol = SymbolTable.Symbols.TextToSymbol("test");
+ sut.SetLocalValue(symbol, 12);
+ sut.PushFrame("x", null, sut.CurrentFrame);
+ sut.SetLocalValue(symbol, 24);
+ sut.PushFrame("y", null, sut.CurrentFrame);
+ sut.SetLocalValue(symbol, 42);
+ sut.PushFrame("z", null, sut.CurrentFrame);
+ object actual;
+ sut.TryGetValue(symbol, out actual);
+ Assert.That(actual, Is.EqualTo(42));
+ }
+
+ private static EvaluationContext CreateContext()
+ {
+ return new EvaluationContext(new LanguageRuntime(new LanguageData(new Grammar())));
+ }
+ }
+}
diff --git a/Irony/010.Irony.2012.csproj b/Irony/010.Irony.2012.csproj
new file mode 100644
index 0000000..62faf7e
--- /dev/null
+++ b/Irony/010.Irony.2012.csproj
@@ -0,0 +1,230 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}
+ Library
+ Properties
+ Irony
+ Irony
+
+
+ 3.5
+
+
+ v4.0
+
+
+
+
+
+
+
+
+ true
+ irony.snk
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+
+
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MathResources.resx
+ True
+ True
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ ResXFileCodeGenerator
+ MathResources.Designer.cs
+ Designer
+ Microsoft.Scripting.Math
+
+
+ PublicResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/Irony/100.IronySilverlight.2012.csproj b/Irony/100.IronySilverlight.2012.csproj
new file mode 100644
index 0000000..4ae6514
--- /dev/null
+++ b/Irony/100.IronySilverlight.2012.csproj
@@ -0,0 +1,227 @@
+
+
+
+ v3.5
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {B945A137-E4C4-4DD5-9598-261F466549FE}
+ {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
+ Library
+ Properties
+ Irony
+ IronySL
+ v5.0
+ false
+ true
+ true
+ true
+ irony.snk
+
+
+
+
+
+
+
+
+ Silverlight
+ $(TargetFrameworkVersion)
+
+
+ 4.0
+
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ true
+ full
+ false
+ Bin\Debug
+ DEBUG;TRACE;SILVERLIGHT
+ true
+ true
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ Bin\Release
+ TRACE;SILVERLIGHT
+ true
+ true
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Irony/Ast/Base/AstNode.cs b/Irony/Ast/Base/AstNode.cs
index 6ed6158..a9e7f25 100644
--- a/Irony/Ast/Base/AstNode.cs
+++ b/Irony/Ast/Base/AstNode.cs
@@ -14,6 +14,7 @@
using System.Collections.Generic;
using System.Text;
using System.CodeDom;
+using System.Threading;
using System.Xml;
using System.IO;
using Irony.Parsing;
@@ -61,9 +62,20 @@ public virtual void Init(ParsingContext context, ParseTreeNode treeNode) {
// exception handling implementation in base method. Otherwise, put all derived functionality
// in EvaluateNode, or create other method(s) and set reference to it in EvaluateRef
public virtual void Evaluate(EvaluationContext context, AstMode mode) {
- try {
- EvaluateRef(context, mode);
- } catch (RuntimeException) {
+ try
+ {
+ context.CancellationToken.ThrowIfCancellationRequested();
+ EvaluateRef(context, mode);
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch (ThreadAbortException)
+ {
+ throw;
+ }
+ catch (RuntimeException) {
throw;
} catch (Exception ex) {
throw new RuntimeException(ex.Message, ex, this.GetErrorAnchor());
diff --git a/Irony/Ast/Functions/FunctionCallNode.cs b/Irony/Ast/Functions/FunctionCallNode.cs
index 73dde86..b8d0572 100644
--- a/Irony/Ast/Functions/FunctionCallNode.cs
+++ b/Irony/Ast/Functions/FunctionCallNode.cs
@@ -29,7 +29,9 @@ public override void Init(ParsingContext context, ParseTreeNode treeNode) {
base.Init(context, treeNode);
TargetRef = AddChild("Target", treeNode.ChildNodes[0]);
_targetName = treeNode.ChildNodes[0].FindTokenAndGetText();
- Arguments = AddChild("Args", treeNode.ChildNodes[1]);
+ // Arguments are optionally
+ if (treeNode.ChildNodes.Count > 1)
+ Arguments = AddChild("Args", treeNode.ChildNodes[1]);
AsString = "Call " + _targetName;
}
@@ -38,7 +40,8 @@ public override void EvaluateNode(EvaluationContext context, AstMode mode) {
var target = context.Data.Pop() as ICallTarget;
if (target == null)
context.ThrowError(Resources.ErrVarIsNotCallable, _targetName);
- Arguments.Evaluate(context, AstMode.Read);
+ if (Arguments != null)
+ Arguments.Evaluate(context, AstMode.Read);
target.Call(context);
}
diff --git a/Irony/Ast/PrimitiveNodes/LocalIdentifierNode.cs b/Irony/Ast/PrimitiveNodes/LocalIdentifierNode.cs
new file mode 100644
index 0000000..7a99699
--- /dev/null
+++ b/Irony/Ast/PrimitiveNodes/LocalIdentifierNode.cs
@@ -0,0 +1,56 @@
+#region License
+/* **********************************************************************************
+ * Copyright (c) Roman Ivantsov
+ * This source code is subject to terms and conditions of the MIT License
+ * for Irony. A copy of the license can be found in the License.txt file
+ * at the root of this distribution.
+ * By using this source code in any fashion, you are agreeing to be bound by the terms of the
+ * MIT License.
+ * You must not remove this notice from this software.
+ * **********************************************************************************/
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using Irony.Parsing;
+using Irony.Interpreter;
+
+namespace Irony.Ast
+{
+
+ public class LocalIdentifierNode : AstNode
+ {
+ public Symbol Symbol;
+
+ public LocalIdentifierNode() { }
+
+ public override void Init(ParsingContext context, ParseTreeNode treeNode)
+ {
+ base.Init(context, treeNode);
+ Symbol = treeNode.Token.Symbol;
+ AsString = Symbol.Text;
+ }
+
+
+ public override void EvaluateNode(EvaluationContext context, AstMode mode)
+ {
+ switch (mode)
+ {
+ case AstMode.Read:
+ object value;
+ if (context.TryGetValue(Symbol, out value))
+ context.Data.Push(value);
+ else
+ context.ThrowError(Resources.ErrVarNotDefined, Symbol);
+ break;
+ case AstMode.Write:
+ context.SetLocalValue(Symbol, context.Data.Pop());
+ break;
+ }
+ }
+
+ }//class
+}//namespace
diff --git a/Irony/Interpreter/EvaluationContext.cs b/Irony/Interpreter/EvaluationContext.cs
index 8d33fbc..ad2499f 100644
--- a/Irony/Interpreter/EvaluationContext.cs
+++ b/Irony/Interpreter/EvaluationContext.cs
@@ -48,6 +48,7 @@ public partial class EvaluationContext {
public StackFrame TopFrame, CurrentFrame;
public StringBuilder OutputBuffer = new StringBuilder();
public int EvaluationTime;
+ public CancellationToken CancellationToken { get; set; }
public EvaluationContext(LanguageRuntime runtime) {
Runtime = runtime;
@@ -72,7 +73,7 @@ public bool HasLastResult {
get { return LastResult != Runtime.Unassigned; }
}
- public void PushFrame(string methodName, AstNode node, StackFrame parent) {
+ public void PushFrame(string methodName, AstNode node, StackFrame parent) {
CurrentFrame = new StackFrame(this, methodName, CurrentFrame, parent);
}
public void PopFrame() {
@@ -91,11 +92,36 @@ public bool TryGetValue(Symbol symbol, out object value) {
return false;
}
+ ///
+ /// Finds first occurrence of symbol in frame stack and overwrites the value.
+ /// If the symbol is not found, a new symbol will be created on the current frame.
+ ///
public void SetValue(Symbol symbol, object value) {
var keySymbol = LanguageCaseSensitive ? symbol : symbol.LowerSymbol;
+
+ // Find topmost frame with symbol and assign value
+ var frame = CurrentFrame;
+ while (frame != null) {
+ if (frame.Values.ContainsKey(keySymbol)) {
+ frame.Values[keySymbol] = value;
+ return;
+ }
+ frame = frame.Parent;
+ }
+ // Value not found in frame stack, assign value as new local value
CurrentFrame.Values[keySymbol] = value;
}
+ ///
+ /// Sets value in current frame. If the symbol already exists it will be overwritten.
+ /// This method will not look for existing symbol down the frame stack.
+ ///
+ public void SetLocalValue(Symbol symbol, object value) {
+ var keySymbol = LanguageCaseSensitive ? symbol : symbol.LowerSymbol;
+ CurrentFrame.Values[keySymbol] = value;
+ }
+
+
public void Write(string text) {
OutputBuffer.Append(text);
}
diff --git a/Irony/Interpreter/ScriptInterpreter.cs b/Irony/Interpreter/ScriptInterpreter.cs
index 9d64068..b23edcd 100644
--- a/Irony/Interpreter/ScriptInterpreter.cs
+++ b/Irony/Interpreter/ScriptInterpreter.cs
@@ -26,6 +26,7 @@ public enum InterpreterStatus {
WaitingMoreInput, //command line only
SyntaxError,
RuntimeError,
+ Canceled,
Aborted
}
@@ -42,7 +43,13 @@ public class ScriptInterpreter {
public InterpreterStatus Status { get; private set; }
public bool RethrowExceptions = true;
- public bool PrintParseErrors = true;
+ public bool PrintParseErrors = true;
+
+ private CancellationTokenSource _cancellationTokenSource;
+
+ private readonly ManualResetEvent _waitHandle = new ManualResetEvent(true);
+ public WaitHandle WaitHandle { get { return _waitHandle; } }
+
public ParseMode ParseMode {
get { return Parser.Context.Mode; }
set { Parser.Context.Mode = value; }
@@ -51,7 +58,7 @@ public ValuesTable Globals {
get { return EvaluationContext.TopFrame.Values; }
}
//internal, real status of interpreter. The public Status field gets updated only on exit from public methods
- // We want to make sure external code sees interpeter as BUSY until we actually completed operation internally
+ // We want to make sure external code sees interpreter as BUSY until we actually completed operation internally
private InterpreterStatus _internalStatus;
#endregion
@@ -78,10 +85,12 @@ public void Evaluate(ParseTree parsedScript) {
}
public void Evaluate() {
try {
+ _waitHandle.Reset();
_internalStatus = Status = InterpreterStatus.Evaluating;
ParseAndEvaluate();
} finally {
Status = _internalStatus;
+ _waitHandle.Set();
}
}
@@ -94,7 +103,8 @@ public void EvaluateAsync(ParseTree parsedScript) {
EvaluateAsync();
}
public void EvaluateAsync() {
- CheckNotBusy();
+ CheckNotBusy();
+ _waitHandle.Reset();
Status = _internalStatus = InterpreterStatus.Evaluating;
WorkerThread = new Thread(AsyncThreadStart);
WorkerThread.Start(null);
@@ -117,7 +127,9 @@ public ParseTree ParsedScript {
_parsedScript = value;
_script = (_parsedScript == null ? null : _parsedScript.SourceText);
}
- } ParseTree _parsedScript;
+ }
+
+ ParseTree _parsedScript;
public bool IsBusy() {
return Status == InterpreterStatus.Evaluating;
@@ -137,13 +149,27 @@ public ParserMessageList GetParserMessages() {
return ParsedScript.ParserMessages;
}
- public void Abort() {
+ ///
+ /// Signals the interpreter to cancel at the next AstNode evaluation.
+ /// The script will be aborted if the is exceeded.
+ /// Use to determine if the script was canceled, aborted or terminated before abortion.
+ ///
+ public void Abort(TimeSpan cancelTimeout) {
try {
+ if (_cancellationTokenSource != null)
+ _cancellationTokenSource.Cancel();
+ _cancellationTokenSource = null;
if (WorkerThread == null) return;
- WorkerThread.Abort();
- WorkerThread.Join(50);
+ WorkerThread.Join((int) cancelTimeout.TotalMilliseconds);
+ if (WorkerThread.IsAlive) WorkerThread.Abort();
} catch { }
WorkerThread = null;
+ WaitHandle.WaitOne();
+ }
+
+ public void Abort()
+ {
+ Abort(TimeSpan.FromSeconds(5));
}
#endregion
@@ -151,8 +177,14 @@ public void Abort() {
private void AsyncThreadStart(object data) {
try {
ParseAndEvaluate();
- } finally {
+ }
+ catch {
+ // Eat rethrown runtime exceptions. Uncaught thread exceptions may bring the whole application down.
+ // The user should check Status and LastException instead.
+ }
+ finally {
Status = _internalStatus;
+ _waitHandle.Set();
}
}
private void CheckNotBusy() {
@@ -162,20 +194,32 @@ private void CheckNotBusy() {
private void ParseAndEvaluate() {
EvaluationContext.EvaluationTime = 0;
- try {
+ try
+ {
LastException = null;
- if(ParsedScript == null) {
+ if (ParsedScript == null)
+ {
//don't evaluate empty strings, just return
if (Script == null || Script.Trim() == string.Empty && Status == InterpreterStatus.Ready) return;
ParsedScript = this.Parser.Parse(Script, "source");
CheckParseStatus();
- if(_internalStatus != InterpreterStatus.Evaluating) return;
+ if (_internalStatus != InterpreterStatus.Evaluating) return;
}
- if(ParsedScript == null)
+ if (ParsedScript == null)
return;
EvaluateParsedScript();
_internalStatus = InterpreterStatus.Ready;
- } catch (Exception ex) {
+ _cancellationTokenSource = null;
+ }
+ catch (OperationCanceledException)
+ {
+ _internalStatus = InterpreterStatus.Canceled;
+ }
+ catch (ThreadAbortException)
+ {
+ _internalStatus = InterpreterStatus.Aborted;
+ }
+ catch (Exception ex) {
LastException = ex;
_internalStatus = InterpreterStatus.RuntimeError;
if (LastException != null && RethrowExceptions)
@@ -187,6 +231,8 @@ private void EvaluateParsedScript() {
var iRoot = GetAstInterface();
if (iRoot == null) return;
EvaluationContext.ClearLastResult();
+ _cancellationTokenSource = new CancellationTokenSource();
+ EvaluationContext.CancellationToken = _cancellationTokenSource.Token;
var start = Environment.TickCount;
iRoot.Evaluate(EvaluationContext, AstMode.Read);
EvaluationContext.EvaluationTime = Environment.TickCount - start;
diff --git a/Irony/Interpreter/StackFrame.cs b/Irony/Interpreter/StackFrame.cs
index f3ff64d..d6ff38e 100644
--- a/Irony/Interpreter/StackFrame.cs
+++ b/Irony/Interpreter/StackFrame.cs
@@ -23,7 +23,7 @@ public class StackFrame {
public string MethodName; //for debugging purposes
public StackFrame Parent; //Lexical parent - not the same as the caller
public StackFrame Caller;
- internal ValuesTable Values; //global values for top frame; parameters and local variables for method frame
+ public ValuesTable Values; //global values for top frame; parameters and local variables for method frame
public StackFrame(EvaluationContext context, ValuesTable globals) {
Context = context;
diff --git a/Irony/Properties/AssemblyInfo.cs b/Irony/Properties/AssemblyInfo.cs
index fb3d231..50948d1 100644
--- a/Irony/Properties/AssemblyInfo.cs
+++ b/Irony/Properties/AssemblyInfo.cs
@@ -55,5 +55,5 @@
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.0.3.0")]
+[assembly: AssemblyFileVersion("1.0.3.0")]
diff --git a/Irony_All.2012.sln b/Irony_All.2012.sln
new file mode 100644
index 0000000..27a82b9
--- /dev/null
+++ b/Irony_All.2012.sln
@@ -0,0 +1,119 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{05F0AC0D-AD43-45B4-8A98-00C54CF5280D}"
+ ProjectSection(SolutionItems) = preProject
+ License.txt = License.txt
+ ReadMe.txt = ReadMe.txt
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "010.Irony.2012", "Irony\010.Irony.2012.csproj", "{D81F5C91-D7DB-46E5-BC99-49488FB6814C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "020.Irony.Samples.2012", "Irony.Samples\020.Irony.Samples.2012.csproj", "{AD263C0B-99D3-40A9-9DBF-9086CC524A0B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "030.Irony.GrammarExplorer.2012", "Irony.GrammarExplorer\030.Irony.GrammarExplorer.2012.csproj", "{AE1C04A8-B03D-4144-98E9-BF66C50265E7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "040.Irony.Tests.VsTest.2012", "Irony.Tests\040.Irony.Tests.VsTest.2012.csproj", "{0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "025.Irony.Samples.Console.2012", "Irony.Samples.Console\025.Irony.Samples.Console.2012.csproj", "{5A31B964-CDFA-4406-9316-32A0F04CE149}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "050.Irony.Tests.NUnit.2012", "Irony.Tests\050.Irony.Tests.NUnit.2012.csproj", "{1A98BEDA-DF53-49B7-A366-2ED7606036BD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "100.IronySilverlight.2012", "Irony\100.IronySilverlight.2012.csproj", "{B945A137-E4C4-4DD5-9598-261F466549FE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ FxCop|Any CPU = FxCop|Any CPU
+ Release|Any CPU = Release|Any CPU
+ Silverlight Debug|Any CPU = Silverlight Debug|Any CPU
+ Silverlight Release|Any CPU = Silverlight Release|Any CPU
+ SpecSharp|Any CPU = SpecSharp|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Silverlight Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Silverlight Release|Any CPU.Build.0 = Release|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.SpecSharp|Any CPU.ActiveCfg = Release|Any CPU
+ {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.SpecSharp|Any CPU.Build.0 = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Silverlight Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.Silverlight Release|Any CPU.Build.0 = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.SpecSharp|Any CPU.ActiveCfg = Release|Any CPU
+ {AD263C0B-99D3-40A9-9DBF-9086CC524A0B}.SpecSharp|Any CPU.Build.0 = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Silverlight Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.Silverlight Release|Any CPU.Build.0 = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.SpecSharp|Any CPU.ActiveCfg = Release|Any CPU
+ {AE1C04A8-B03D-4144-98E9-BF66C50265E7}.SpecSharp|Any CPU.Build.0 = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.Silverlight Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.Silverlight Release|Any CPU.Build.0 = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.SpecSharp|Any CPU.ActiveCfg = Release|Any CPU
+ {0CFA8CEE-0110-49C1-93E5-CB7BE3A5716B}.SpecSharp|Any CPU.Build.0 = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Silverlight Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.Silverlight Release|Any CPU.Build.0 = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.SpecSharp|Any CPU.ActiveCfg = Release|Any CPU
+ {5A31B964-CDFA-4406-9316-32A0F04CE149}.SpecSharp|Any CPU.Build.0 = Release|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.Silverlight Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.Silverlight Release|Any CPU.Build.0 = Release|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.SpecSharp|Any CPU.ActiveCfg = Release|Any CPU
+ {1A98BEDA-DF53-49B7-A366-2ED7606036BD}.SpecSharp|Any CPU.Build.0 = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.Silverlight Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.Silverlight Release|Any CPU.Build.0 = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.SpecSharp|Any CPU.ActiveCfg = Release|Any CPU
+ {B945A137-E4C4-4DD5-9598-261F466549FE}.SpecSharp|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal