···11-/* The following code was generated by CSFlex 1.4 on 27.05.2017 */
11+/* The following code was generated by CSFlex 1.4 on 16.04.2018 */
2233#line 1 "Prexonite.lex"
44/*
···4141/**
4242 * This class is a scanner generated by <a href="http://www.sourceforge.net/projects/csflex/">C# Flex</a>, based on
4343 * <a href="http://www.jflex.de/">JFlex</a>, version 1.4
4444- * on 27.05.2017 from the specification file
4444+ * on 16.04.2018 from the specification file
4545 * <tt>Prexonite.lex</tt>
4646 */
4747class Lexer: Prexonite.Internal.IScanner {
···11-// Runtime component of the Prexonite shell scripting extensions
22-Name sh/0.0;
33-References {
44- sys/0.0
55-};
66-77-namespace sh {
88-99- function stdout = "sh.stdout";
1010- function stdin = "sh.stdin";
1111- function stderr = "sh.stderr";
1212-} export(stdout, stdin, stderr, (|>), (<|.), (|>.), stream, lines, which, create_command, call\sh);
11+// Runtime component of the Prexonite shell scripting extensions
22+Name sh/0.0;
33+References {
44+ sys/0.0
55+};
66+77+namespace sh {
88+99+ function stdout = "sh.stdout";
1010+ function stdin = "sh.stdin";
1111+ function stderr = "sh.stderr";
1212+} export(stdout, stdin, stderr, stream, lines, words, which, create_command, call\sh, (|>), (<|.), (|>.));
1313+1414+{
1515+ var time = new command(which("time"));
1616+ var grep = new command(which("grep"));
1717+ var tr = new command(which("tr"));
1818+ var cut = new command(which("cut"));
1919+}
2020+
+121-152
PrexoniteTests/Meta.cs
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using NUnit.Framework.Constraints;
2828-using Prexonite;
2929-3030-namespace PrexoniteTests
3131-{
3232- public static class Meta
3333- {
3434- public static Constraint ContainsKey(string key)
3535- {
3636- return new ContainsKeyConstraint(key);
3737- }
3838-3939- public static Constraint Contains(string key, MetaEntry value)
4040- {
4141- return new ExactEqualityConstraint(key, value);
4242- }
4343-4444- public static Constraint ContainsExact(string key, MetaEntry value)
4545- {
4646- return
4747- new ContainsKeyConstraint(key).And.Matches(new ExactEqualityConstraint(key, value));
4848- }
4949-5050- private class ExactEqualityConstraint : Constraint
5151- {
5252- private readonly string _key;
5353- private readonly MetaEntry _expectedEntry;
5454- private MetaEntry _actualEntry;
5555- private bool _typeMismatch;
5656-5757- public ExactEqualityConstraint(string key, MetaEntry expectedEntry)
5858- {
5959- if (key == null)
6060- throw new ArgumentNullException(nameof(key));
6161- if (expectedEntry == null)
6262- throw new ArgumentNullException(nameof(expectedEntry));
6363-6464- _key = key;
6565- _expectedEntry = expectedEntry;
6666- }
6767-6868- #region Overrides of Constraint
6969-7070- public override bool Matches(object actual)
7171- {
7272- this.actual = actual;
7373-7474- var ihmt = actual as IHasMetaTable;
7575- if (ihmt == null)
7676- {
7777- this.actual = null;
7878- return false;
7979- }
8080-8181- _actualEntry = ihmt.Meta[_key];
8282-8383- if (_actualEntry.EntryType != _expectedEntry.EntryType)
8484- {
8585- _typeMismatch = true;
8686- return false;
8787- }
8888-8989- _typeMismatch = false;
9090- return _actualEntry.Equals(_expectedEntry);
9191- }
9292-9393- public override void WriteDescriptionTo(MessageWriter writer)
9494- {
9595- if (actual == null)
9696- {
9797- writer.WriteMessageLine("Actual value does not have a meta table.");
9898- }
9999- else if (_typeMismatch)
100100- {
101101- writer.WriteMessageLine("Meta entry type doesn't match.");
102102- writer.WriteExpectedValue(_expectedEntry.EntryType);
103103- writer.WriteActualValue(_actualEntry.EntryType);
104104- }
105105- else
106106- {
107107- writer.WriteMessageLine(
108108- "actual meta entry {0} should match expected entry {1}", _actualEntry,
109109- _expectedEntry);
110110- }
111111- }
112112-113113- #endregion
114114- }
115115-116116- private class ContainsKeyConstraint : Constraint
117117- {
118118- private readonly string _key;
119119-120120- public ContainsKeyConstraint(string key)
121121- {
122122- if (key == null)
123123- throw new ArgumentNullException(nameof(key));
124124- _key = key;
125125- }
126126-127127- #region Overrides of Constraint
128128-129129- public override bool Matches(object actual)
130130- {
131131- this.actual = actual;
132132-133133- IHasMetaTable ihmt;
134134- MetaTable mt;
135135- if ((ihmt = actual as IHasMetaTable) != null)
136136- mt = ihmt.Meta;
137137- else
138138- return false;
139139-140140- return mt.ContainsKey(_key);
141141- }
142142-143143- public
144144- override void WriteDescriptionTo(MessageWriter writer)
145145- {
146146- writer.WriteMessageLine(
147147- "meta table of object {0} should contain an entry for key \"{1}\"", actual, _key);
148148- }
149149-150150- #endregion
151151- }
152152- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using NUnit.Framework.Constraints;
2828+using Prexonite;
2929+3030+namespace PrexoniteTests
3131+{
3232+ public static class Meta
3333+ {
3434+ public static Constraint ContainsKey(string key)
3535+ {
3636+ return new ContainsKeyConstraint(key);
3737+ }
3838+3939+ public static Constraint Contains(string key, MetaEntry value)
4040+ {
4141+ return new ExactEqualityConstraint(key, value);
4242+ }
4343+4444+ public static Constraint ContainsExact(string key, MetaEntry value)
4545+ {
4646+ return
4747+ new ContainsKeyConstraint(key).And.Matches(new ExactEqualityConstraint(key, value));
4848+ }
4949+5050+ private class ExactEqualityConstraint : Constraint
5151+ {
5252+ private readonly string _key;
5353+ private readonly MetaEntry _expectedEntry;
5454+5555+ public ExactEqualityConstraint(string key, MetaEntry expectedEntry) : base(key, expectedEntry)
5656+ {
5757+ if (expectedEntry == null)
5858+ throw new ArgumentNullException(nameof(expectedEntry));
5959+6060+ _key = key ?? throw new ArgumentNullException(nameof(key));
6161+ _expectedEntry = expectedEntry;
6262+ }
6363+6464+ #region Overrides of Constraint
6565+6666+ public override ConstraintResult ApplyTo<TActual>(TActual actual)
6767+ {
6868+ object actualObj = actual;
6969+ return new ConstraintResult(this, actualObj, _matches(actualObj));
7070+ }
7171+7272+ private bool _matches(object actual)
7373+ {
7474+ var ihmt = actual as IHasMetaTable;
7575+ if (ihmt == null)
7676+ {
7777+ return false;
7878+ }
7979+8080+ var actualEntry = ihmt.Meta[_key];
8181+8282+ return actualEntry.EntryType == _expectedEntry.EntryType && actualEntry.Equals(_expectedEntry);
8383+ }
8484+8585+ #endregion
8686+ }
8787+8888+ private class ContainsKeyConstraint : Constraint
8989+ {
9090+ private readonly string _key;
9191+9292+ public ContainsKeyConstraint(string key) : base(key)
9393+ {
9494+ if (key == null)
9595+ throw new ArgumentNullException(nameof(key));
9696+ _key = key;
9797+ }
9898+9999+ #region Overrides of Constraint
100100+101101+ public override ConstraintResult ApplyTo<TActual>(TActual actual)
102102+ {
103103+ var actualValue = actual;
104104+ return new ConstraintResult(this, actualValue, _matches(actualValue));
105105+ }
106106+107107+ private bool _matches(object actual)
108108+ {
109109+ IHasMetaTable ihmt;
110110+ MetaTable mt;
111111+ if ((ihmt = actual as IHasMetaTable) != null)
112112+ mt = ihmt.Meta;
113113+ else
114114+ return false;
115115+116116+ return mt.ContainsKey(_key);
117117+ }
118118+119119+ #endregion
120120+ }
121121+ }
153122}
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using System.Collections;
2828-using System.Diagnostics;
2929-using System.Linq;
3030-using NUnit.Framework;
3131-using Prexonite;
3232-using Prexonite.Commands.Core;
3333-using Prexonite.Compiler;
3434-using Prexonite.Compiler.Symbolic;
3535-using Prexonite.Modular;
3636-3737-namespace PrexoniteTests.Tests
3838-{
3939- [TestFixture]
4040- public class ApplicationLinking : AssertionHelper
4141- {
4242- [Test]
4343- public void NoLocalButCount()
4444- {
4545- var s1 = SymbolStore.Create();
4646- var s = Symbol.CreateCall(EntityRef.Command.Create("print"), NoSourcePosition.Instance);
4747- s1.Declare("print",s);
4848- var s2 = SymbolStore.Create(s1);
4949- Assert.That(s2.IsEmpty,Is.False,"Expected s2.IsEmpty to be false.");
5050- }
5151-5252- [Test]
5353- public void SimpleLinkUnlink()
5454- {
5555- var a1 = new Application();
5656- var a2 = new Application();
5757-5858- Assert.That(a1.IsLinked,Is.False,"a1 should not be linked initially");
5959- Assert.That(a2.IsLinked, Is.False,"a2 should not be linked initially");
6060-6161- Application.Link(a1,a2);
6262-6363- Assert.That(a1.IsLinked, Is.True,"a1 should be linked");
6464- Assert.That(a2.IsLinked, Is.True,"a2 should be linked");
6565-6666- a1.Unlink();
6767-6868- Assert.That(a1.IsLinked,Is.False,"a1 should not be linked afterwards");
6969- Assert.That(a2.IsLinked, Is.False, "a2 should not be linked afterwards");
7070- }
7171-7272- [Test]
7373- public void CompoundLinking()
7474- {
7575- var aps =
7676- Enumerable.Range(1, 3)
7777- .Select(i => new Application("a" + i))
7878- .ToList();
7979-8080- var bps =
8181- Enumerable.Range(1, 4)
8282- .Select(i => new Application("b" + i))
8383- .ToList();
8484-8585- var ps = aps.Append(bps).ToList();
8686-8787- foreach (var a in ps)
8888- Assert.That(a.IsLinked, Is.False,
8989- string.Format("Application {0} should not be linked initially.", a));
9090-9191- //Link a's and b's, respectively
9292- foreach (var a in aps.Skip(1))
9393- Application.Link(a, aps[0]);
9494- foreach (var a in bps.Skip(1))
9595- Application.Link(a, bps[0]);
9696-9797- Assert.That(aps[0].Compound,Is.Not.Contains(bps[0]));
9898- Assert.That(bps[0].Compound, Is.Not.Contains(aps[0]));
9999-100100- Application.Link(aps[0],bps[1]);
101101-102102- foreach (var a in ps)
103103- Assert.That(a.IsLinked, Is.True,
104104- string.Format("Application {0} should be linked afterwards.", a));
105105-106106- var c = aps[0].Compound;
107107- foreach (var a in ps)
108108- {
109109- Assert.That(a.Compound, Is.SameAs(c),
110110- string.Format(
111111- "Compound object of application {0} should be " +
112112- "identical with that of application {1}.",
113113- a, aps[0]));
114114- }
115115-116116- Assert.That(aps[0].Compound.Count,Is.EqualTo(aps.Count + bps.Count));
117117-118118- Assert.That(aps[0].Compound,Is.SubsetOf(ps), "Compound contains elements not in the original set.");
119119- Assert.That(ps, Is.SubsetOf(aps[0].Compound), "Not all elements of the original set are in the compound.");
120120-121121- var p = aps[0];
122122- p.Unlink();
123123- Assert.That(p.IsLinked,Is.False,"p should now be unlinked.");
124124- Assert.That(aps[1].Compound.Count,Is.EqualTo(aps.Count + bps.Count - 1),"Compound is not the right size.");
125125-126126- foreach (var a in ps.Where(x => x != p))
127127- Assert.That(a.IsLinked, Is.True,
128128- string.Format("Application {0} should still be linked afterwards.", a));
129129- c = aps[1].Compound;
130130- foreach (var a in ps.Where(x => x != p))
131131- {
132132- Assert.That(a.Compound, Is.SameAs(c),
133133- string.Format(
134134- "Compound object of application {0} should be " +
135135- "identical with that of application {1}.",
136136- a, aps[1]));
137137- }
138138- }
139139-140140- [Test]
141141- public void MergeLinking()
142142- {
143143- var cps =
144144- Enumerable.Range(1, 3)
145145- .Select(i => new Application("common" + i))
146146- .ToList();
147147-148148- var aps =
149149- Enumerable.Range(1, 3)
150150- .Select(i => new Application("a" + i))
151151- .Append(cps)
152152- .ToList();
153153-154154- var bps =
155155- Enumerable.Range(1, 4)
156156- .Select(i => new Application("b" + i))
157157- .Append(cps)
158158- .ToList();
159159-160160- var ps = aps.Union(bps).ToList();
161161-162162- foreach (var a in ps)
163163- Assert.That(a.IsLinked, Is.False,
164164- string.Format("Application {0} should not be linked initially.", a));
165165-166166- //Link a's and b's, respectively
167167- foreach (var a in aps.Skip(1))
168168- Application.Link(a, aps[0]);
169169- foreach (var a in bps.Skip(1))
170170- Application.Link(a, bps[0]);
171171-172172- Assert.That(aps[0].Compound, Not.Member(bps));
173173- Assert.That(bps[0].Compound, Not.Member(aps));
174174-175175- Application.Link(aps[0],bps[1]);
176176-177177- foreach (var a in ps)
178178- Assert.That(a.IsLinked, Is.True,
179179- string.Format("Application {0} should be linked afterwards.", a.Module.Name));
180180-181181- var c = aps[0].Compound;
182182- foreach (var a in ps)
183183- {
184184- Assert.That(a.Compound, Is.SameAs(c),
185185- string.Format(
186186- "Compound object of application {0} should be " +
187187- "identical with that of application {1}.",
188188- a, aps[0]));
189189- }
190190-191191- Assert.That(aps[0].Compound.Count,Is.EqualTo(ps.Count));
192192-193193- Assert.That(aps[0].Compound,Is.EquivalentTo(ps), "Compound is not equivalent to aps ∪ bps.");
194194-195195- var p = cps[0];
196196- p.Unlink();
197197- Assert.That(p.IsLinked,Is.False,"p should now be unlinked.");
198198- Assert.That(aps[1].Compound.Count,Is.EqualTo(ps.Count - 1),"Compound is not the right size.");
199199-200200- foreach (var a in ps.Where(x => x != p))
201201- Assert.That(a.IsLinked, Is.True,
202202- string.Format("Application {0} should still be linked afterwards.", a));
203203- c = aps[1].Compound;
204204- foreach (var a in ps.Where(x => x != p))
205205- {
206206- Assert.That(a.Compound, Is.SameAs(c),
207207- string.Format(
208208- "Compound object of application {0} should be " +
209209- "identical with that of application {1}.",
210210- a, aps[1]));
211211- }
212212- }
213213-214214- [Test]
215215- public void DryCrossModuleCall()
216216- {
217217- var m1 = Module.Create(new ModuleName("dragon", new Version(1, 2)));
218218- var m2 = Module.Create(new ModuleName("std", new Version(1, 3, 1)));
219219-220220- var a1 = new Application(m1);
221221- var a2 = new Application(m2);
222222-223223- var f1 = a1.CreateFunction(Application.DefaultEntryFunction);
224224-225225- var f2 = a2.CreateFunction("sayHello");
226226-227227- f1.Code.Add(new Instruction(OpCode.func, 0, f2.Id, m2.Name));
228228- f1.Code.Add(new Instruction(OpCode.ret_value));
229229-230230- const string helloModules = "Hello Modules";
231231- f2.Code.Add(new Instruction(OpCode.ldc_string,helloModules));
232232- f2.Code.Add(new Instruction(OpCode.ret_value));
233233-234234- Console.WriteLine("=========== Module {0} ==========", m1.Name);
235235- a1.Store(Console.Out);
236236- Console.WriteLine();
237237- Console.WriteLine("=========== Module {0} ==========", m2.Name);
238238- a2.Store(Console.Out);
239239-240240- var eng = new Engine();
241241-242242- try
243243- {
244244- a1.Run(eng);
245245- Assert.Fail("Should not succeed as applications are not linked.");
246246- }
247247- catch (PrexoniteRuntimeException e)
248248- {
249249- Console.WriteLine("EXPECTED EXCEPTION");
250250- Console.WriteLine(e.Message);
251251- Console.WriteLine("END OF EXPECTED EXCEPTION");
252252- }
253253-254254- Application.Link(a1, a2);
255255- var r = a1.Run(eng);
256256- Expect(r.Value,Is.InstanceOf<string>());
257257- Expect(r.Value,Is.EqualTo(helloModules));
258258- }
259259-260260- [Test]
261261- public void CreateModuleNameCommand()
262262- {
263263- var cmd = CreateModuleName.Instance;
264264- var eng = new Engine();
265265- var app = new Application("cmnc");
266266- var sctx = new NullContext(eng, app, Enumerable.Empty<string>());
267267- var rawMn = cmd.Run(sctx, new[] {sctx.CreateNativePValue(new MetaEntry(new MetaEntry[]{"sys","1.0"}))});
268268- Assert.That(rawMn.Value,Is.InstanceOf<ModuleName>());
269269- var mn = (ModuleName) rawMn.Value;
270270- Assert.That(mn.Id,Is.EqualTo("sys"));
271271- Assert.That(mn.Version,Is.EqualTo(new Version(1,0)));
272272- }
273273- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using System.Linq;
2828+using NUnit.Framework;
2929+using Prexonite;
3030+using Prexonite.Commands.Core;
3131+using Prexonite.Compiler;
3232+using Prexonite.Compiler.Symbolic;
3333+using Prexonite.Modular;
3434+3535+namespace PrexoniteTests.Tests
3636+{
3737+ [TestFixture]
3838+ public class ApplicationLinking
3939+ {
4040+ [Test]
4141+ public void NoLocalButCount()
4242+ {
4343+ var s1 = SymbolStore.Create();
4444+ var s = Symbol.CreateCall(EntityRef.Command.Create("print"), NoSourcePosition.Instance);
4545+ s1.Declare("print",s);
4646+ var s2 = SymbolStore.Create(s1);
4747+ Assert.That(s2.IsEmpty,Is.False,"Expected s2.IsEmpty to be false.");
4848+ }
4949+5050+ [Test]
5151+ public void SimpleLinkUnlink()
5252+ {
5353+ var a1 = new Application();
5454+ var a2 = new Application();
5555+5656+ Assert.That(a1.IsLinked,Is.False,"a1 should not be linked initially");
5757+ Assert.That(a2.IsLinked, Is.False,"a2 should not be linked initially");
5858+5959+ Application.Link(a1,a2);
6060+6161+ Assert.That(a1.IsLinked, Is.True,"a1 should be linked");
6262+ Assert.That(a2.IsLinked, Is.True,"a2 should be linked");
6363+6464+ a1.Unlink();
6565+6666+ Assert.That(a1.IsLinked,Is.False,"a1 should not be linked afterwards");
6767+ Assert.That(a2.IsLinked, Is.False, "a2 should not be linked afterwards");
6868+ }
6969+7070+ [Test]
7171+ public void CompoundLinking()
7272+ {
7373+ var aps =
7474+ Enumerable.Range(1, 3)
7575+ .Select(i => new Application("a" + i))
7676+ .ToList();
7777+7878+ var bps =
7979+ Enumerable.Range(1, 4)
8080+ .Select(i => new Application("b" + i))
8181+ .ToList();
8282+8383+ var ps = aps.Append(bps).ToList();
8484+8585+ foreach (var a in ps)
8686+ Assert.That(a.IsLinked, Is.False,
8787+ string.Format("Application {0} should not be linked initially.", a));
8888+8989+ //Link a's and b's, respectively
9090+ foreach (var a in aps.Skip(1))
9191+ Application.Link(a, aps[0]);
9292+ foreach (var a in bps.Skip(1))
9393+ Application.Link(a, bps[0]);
9494+9595+ Assert.That(aps[0].Compound,Is.Not.Contains(bps[0]));
9696+ Assert.That(bps[0].Compound, Is.Not.Contains(aps[0]));
9797+9898+ Application.Link(aps[0],bps[1]);
9999+100100+ foreach (var a in ps)
101101+ Assert.That(a.IsLinked, Is.True,
102102+ string.Format("Application {0} should be linked afterwards.", a));
103103+104104+ var c = aps[0].Compound;
105105+ foreach (var a in ps)
106106+ {
107107+ Assert.That(a.Compound, Is.SameAs(c),
108108+ string.Format(
109109+ "Compound object of application {0} should be " +
110110+ "identical with that of application {1}.",
111111+ a, aps[0]));
112112+ }
113113+114114+ Assert.That(aps[0].Compound.Count,Is.EqualTo(aps.Count + bps.Count));
115115+116116+ Assert.That(aps[0].Compound,Is.SubsetOf(ps), "Compound contains elements not in the original set.");
117117+ Assert.That(ps, Is.SubsetOf(aps[0].Compound), "Not all elements of the original set are in the compound.");
118118+119119+ var p = aps[0];
120120+ p.Unlink();
121121+ Assert.That(p.IsLinked,Is.False,"p should now be unlinked.");
122122+ Assert.That(aps[1].Compound.Count,Is.EqualTo(aps.Count + bps.Count - 1),"Compound is not the right size.");
123123+124124+ foreach (var a in ps.Where(x => x != p))
125125+ Assert.That(a.IsLinked, Is.True,
126126+ string.Format("Application {0} should still be linked afterwards.", a));
127127+ c = aps[1].Compound;
128128+ foreach (var a in ps.Where(x => x != p))
129129+ {
130130+ Assert.That(a.Compound, Is.SameAs(c),
131131+ string.Format(
132132+ "Compound object of application {0} should be " +
133133+ "identical with that of application {1}.",
134134+ a, aps[1]));
135135+ }
136136+ }
137137+138138+ [Test]
139139+ public void MergeLinking()
140140+ {
141141+ var cps =
142142+ Enumerable.Range(1, 3)
143143+ .Select(i => new Application("common" + i))
144144+ .ToList();
145145+146146+ var aps =
147147+ Enumerable.Range(1, 3)
148148+ .Select(i => new Application("a" + i))
149149+ .Append(cps)
150150+ .ToList();
151151+152152+ var bps =
153153+ Enumerable.Range(1, 4)
154154+ .Select(i => new Application("b" + i))
155155+ .Append(cps)
156156+ .ToList();
157157+158158+ var ps = aps.Union(bps).ToList();
159159+160160+ foreach (var a in ps)
161161+ Assert.That(a.IsLinked, Is.False,
162162+ string.Format("Application {0} should not be linked initially.", a));
163163+164164+ //Link a's and b's, respectively
165165+ foreach (var a in aps.Skip(1))
166166+ Application.Link(a, aps[0]);
167167+ foreach (var a in bps.Skip(1))
168168+ Application.Link(a, bps[0]);
169169+170170+ Assert.That(aps[0].Compound, !Contains.Item(bps));
171171+ Assert.That(bps[0].Compound, !Contains.Item(aps));
172172+173173+ Application.Link(aps[0],bps[1]);
174174+175175+ foreach (var a in ps)
176176+ Assert.That(a.IsLinked, Is.True,
177177+ string.Format("Application {0} should be linked afterwards.", a.Module.Name));
178178+179179+ var c = aps[0].Compound;
180180+ foreach (var a in ps)
181181+ {
182182+ Assert.That(a.Compound, Is.SameAs(c),
183183+ string.Format(
184184+ "Compound object of application {0} should be " +
185185+ "identical with that of application {1}.",
186186+ a, aps[0]));
187187+ }
188188+189189+ Assert.That(aps[0].Compound.Count,Is.EqualTo(ps.Count));
190190+191191+ Assert.That(aps[0].Compound,Is.EquivalentTo(ps), "Compound is not equivalent to aps ∪ bps.");
192192+193193+ var p = cps[0];
194194+ p.Unlink();
195195+ Assert.That(p.IsLinked,Is.False,"p should now be unlinked.");
196196+ Assert.That(aps[1].Compound.Count,Is.EqualTo(ps.Count - 1),"Compound is not the right size.");
197197+198198+ foreach (var a in ps.Where(x => x != p))
199199+ Assert.That(a.IsLinked, Is.True,
200200+ string.Format("Application {0} should still be linked afterwards.", a));
201201+ c = aps[1].Compound;
202202+ foreach (var a in ps.Where(x => x != p))
203203+ {
204204+ Assert.That(a.Compound, Is.SameAs(c),
205205+ string.Format(
206206+ "Compound object of application {0} should be " +
207207+ "identical with that of application {1}.",
208208+ a, aps[1]));
209209+ }
210210+ }
211211+212212+ [Test]
213213+ public void DryCrossModuleCall()
214214+ {
215215+ var m1 = Module.Create(new ModuleName("dragon", new Version(1, 2)));
216216+ var m2 = Module.Create(new ModuleName("std", new Version(1, 3, 1)));
217217+218218+ var a1 = new Application(m1);
219219+ var a2 = new Application(m2);
220220+221221+ var f1 = a1.CreateFunction(Application.DefaultEntryFunction);
222222+223223+ var f2 = a2.CreateFunction("sayHello");
224224+225225+ f1.Code.Add(new Instruction(OpCode.func, 0, f2.Id, m2.Name));
226226+ f1.Code.Add(new Instruction(OpCode.ret_value));
227227+228228+ const string helloModules = "Hello Modules";
229229+ f2.Code.Add(new Instruction(OpCode.ldc_string,helloModules));
230230+ f2.Code.Add(new Instruction(OpCode.ret_value));
231231+232232+ Console.WriteLine("=========== Module {0} ==========", m1.Name);
233233+ a1.Store(Console.Out);
234234+ Console.WriteLine();
235235+ Console.WriteLine("=========== Module {0} ==========", m2.Name);
236236+ a2.Store(Console.Out);
237237+238238+ var eng = new Engine();
239239+240240+ try
241241+ {
242242+ a1.Run(eng);
243243+ Assert.Fail("Should not succeed as applications are not linked.");
244244+ }
245245+ catch (PrexoniteRuntimeException e)
246246+ {
247247+ Console.WriteLine("EXPECTED EXCEPTION");
248248+ Console.WriteLine(e.Message);
249249+ Console.WriteLine("END OF EXPECTED EXCEPTION");
250250+ }
251251+252252+ Application.Link(a1, a2);
253253+ var r = a1.Run(eng);
254254+ Assert.That(r.Value,Is.InstanceOf<string>());
255255+ Assert.That(r.Value,Is.EqualTo(helloModules));
256256+ }
257257+258258+ [Test]
259259+ public void CreateModuleNameCommand()
260260+ {
261261+ var cmd = CreateModuleName.Instance;
262262+ var eng = new Engine();
263263+ var app = new Application("cmnc");
264264+ var sctx = new NullContext(eng, app, Enumerable.Empty<string>());
265265+ var rawMn = cmd.Run(sctx, new[] {sctx.CreateNativePValue(new MetaEntry(new MetaEntry[]{"sys","1.0"}))});
266266+ Assert.That(rawMn.Value,Is.InstanceOf<ModuleName>());
267267+ var mn = (ModuleName) rawMn.Value;
268268+ Assert.That(mn.Id,Is.EqualTo("sys"));
269269+ Assert.That(mn.Version,Is.EqualTo(new Version(1,0)));
270270+ }
271271+ }
274272}
+165-163
PrexoniteTests/Tests/AstTests.cs
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using System.Collections.Generic;
2828-using System.Linq;
2929-using NUnit.Framework;
3030-using Prexonite;
3131-using Prexonite.Compiler.Ast;
3232-3333-namespace PrexoniteTests.Tests
3434-{
3535- [TestFixture]
3636- public class AstTests
3737- {
3838- private static AstPlaceholder _createPlaceholder(int? index = null)
3939- {
4040- return new AstPlaceholder("-file", -1, -2) {Index = index};
4141- }
4242-4343- [Test]
4444- public void DeterminePlaceholderIndicesNormalTets()
4545- {
4646- //(?,?2,?,?2,?1)
4747- var placeholders = new List<AstPlaceholder>
4848- {
4949- _createPlaceholder(),
5050- _createPlaceholder(1),
5151- _createPlaceholder(),
5252- _createPlaceholder(1),
5353- _createPlaceholder(0)
5454- };
5555-5656- var copy = placeholders.ToList();
5757- Assert.AreNotSame(copy, placeholders);
5858-5959- AstPlaceholder.DeterminePlaceholderIndices(placeholders);
6060-6161- //First assert that the list itself has not been altered
6262- Assert.AreEqual(placeholders.Count, copy.Count);
6363- for (var i = 0; i < placeholders.Count; i++)
6464- Assert.AreSame(copy[i], placeholders[i], "List itself must not be altered.");
6565-6666- //Expexted mapping (0-based):
6767- // ?2, ?1, ?3, ?1, ?0
6868- foreach (var placeholder in placeholders)
6969- Assert.IsTrue(placeholder.Index.HasValue,
7070- "All placeholders should be assigned afterwards.");
7171-7272- // ReSharper disable PossibleInvalidOperationException
7373- Assert.AreEqual(2, placeholders[0].Index.Value,
7474- "Placeholder at source position 0 is not mapped correctly");
7575- Assert.AreEqual(1, placeholders[1].Index.Value,
7676- "Placeholder at source position 1 is not mapped correctly");
7777- Assert.AreEqual(3, placeholders[2].Index.Value,
7878- "Placeholder at source position 2 is not mapped correctly");
7979- Assert.AreEqual(1, placeholders[3].Index.Value,
8080- "Placeholder at source position 3 is not mapped correctly");
8181- Assert.AreEqual(0, placeholders[4].Index.Value,
8282- "Placeholder at source position 4 is not mapped correctly");
8383- // ReSharper restore PossibleInvalidOperationException
8484- }
8585-8686- [Test]
8787- public void DeterminePlaceholderIndicesEmptyTets()
8888- {
8989- AstPlaceholder.DeterminePlaceholderIndices(Enumerable.Empty<AstPlaceholder>());
9090- }
9191-9292- [Test, ExpectedException(typeof (NullReferenceException))]
9393- public void DeterminePlaceholderIndicesRejectNullTets()
9494- {
9595- AstPlaceholder.DeterminePlaceholderIndices(Extensions.Singleton<AstPlaceholder>(null));
9696- }
9797-9898- [Test]
9999- public void RemoveRedundant1()
100100- {
101101- const string file = "THE_FILE";
102102- const int line = 666;
103103- const int col = 555;
104104- //test case from MissingMapped
105105- var subject = new AstNull(file, line, col);
106106- var argv = new List<AstExpr>
107107- {
108108- subject,
109109- _createPlaceholder(1),
110110- _createPlaceholder(2)
111111- };
112112- var originalArgv = argv.ToList();
113113-114114- _placeholderArgvProcessing(argv);
115115-116116- Assert.AreEqual(3, argv.Count, "argc changed");
117117- for (var i = 0; i < argv.Count; i++)
118118- Assert.AreSame(originalArgv[i], argv[i]);
119119- }
120120-121121- private static void _placeholderArgvProcessing(List<AstExpr> argv)
122122- {
123123- Console.WriteLine("ARGV implicit:");
124124- foreach (var expr in argv)
125125- Console.WriteLine("\t{0}", expr);
126126-127127- AstPlaceholder.DeterminePlaceholderIndices(argv.MapMaybe(x => x as AstPlaceholder));
128128-129129- Console.WriteLine("ARGV explicit:");
130130- foreach (var expr in argv)
131131- Console.WriteLine("\t{0}", expr);
132132-133133- AstPartiallyApplicable.RemoveRedundantPlaceholders(argv);
134134-135135- Console.WriteLine("ARGV minimal:");
136136- foreach (var expr in argv)
137137- Console.WriteLine("\t{0}", expr);
138138- }
139139-140140- [Test]
141141- public void RemoveRedundant2()
142142- {
143143- const string file = "THE_FILE";
144144- const int line = 666;
145145- const int col = 555;
146146- //test case from MissingMapped
147147- var subject = new AstNull(file, line, col);
148148- var argv = new List<AstExpr>
149149- {
150150- subject,
151151- _createPlaceholder(2),
152152- _createPlaceholder(),
153153- _createPlaceholder(1)
154154- };
155155- var originalArgv = argv.GetRange(0, 2);
156156-157157- _placeholderArgvProcessing(argv);
158158-159159- Assert.AreEqual(originalArgv.Count, argv.Count, "argc not correct");
160160- for (var i = 0; i < originalArgv.Count; i++)
161161- Assert.AreSame(originalArgv[i], argv[i]);
162162- }
163163- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using System.Collections.Generic;
2828+using System.Linq;
2929+using NUnit.Framework;
3030+using Prexonite;
3131+using Prexonite.Compiler.Ast;
3232+3333+namespace PrexoniteTests.Tests
3434+{
3535+ [TestFixture]
3636+ public class AstTests
3737+ {
3838+ private static AstPlaceholder _createPlaceholder(int? index = null)
3939+ {
4040+ return new AstPlaceholder("-file", -1, -2) {Index = index};
4141+ }
4242+4343+ [Test]
4444+ public void DeterminePlaceholderIndicesNormalTets()
4545+ {
4646+ //(?,?2,?,?2,?1)
4747+ var placeholders = new List<AstPlaceholder>
4848+ {
4949+ _createPlaceholder(),
5050+ _createPlaceholder(1),
5151+ _createPlaceholder(),
5252+ _createPlaceholder(1),
5353+ _createPlaceholder(0)
5454+ };
5555+5656+ var copy = placeholders.ToList();
5757+ Assert.AreNotSame(copy, placeholders);
5858+5959+ AstPlaceholder.DeterminePlaceholderIndices(placeholders);
6060+6161+ //First assert that the list itself has not been altered
6262+ Assert.AreEqual(placeholders.Count, copy.Count);
6363+ for (var i = 0; i < placeholders.Count; i++)
6464+ Assert.AreSame(copy[i], placeholders[i], "List itself must not be altered.");
6565+6666+ //Expexted mapping (0-based):
6767+ // ?2, ?1, ?3, ?1, ?0
6868+ foreach (var placeholder in placeholders)
6969+ Assert.IsTrue(placeholder.Index.HasValue,
7070+ "All placeholders should be assigned afterwards.");
7171+7272+ // ReSharper disable PossibleInvalidOperationException
7373+ Assert.AreEqual(2, placeholders[0].Index.Value,
7474+ "Placeholder at source position 0 is not mapped correctly");
7575+ Assert.AreEqual(1, placeholders[1].Index.Value,
7676+ "Placeholder at source position 1 is not mapped correctly");
7777+ Assert.AreEqual(3, placeholders[2].Index.Value,
7878+ "Placeholder at source position 2 is not mapped correctly");
7979+ Assert.AreEqual(1, placeholders[3].Index.Value,
8080+ "Placeholder at source position 3 is not mapped correctly");
8181+ Assert.AreEqual(0, placeholders[4].Index.Value,
8282+ "Placeholder at source position 4 is not mapped correctly");
8383+ // ReSharper restore PossibleInvalidOperationException
8484+ }
8585+8686+ [Test]
8787+ public void DeterminePlaceholderIndicesEmptyTets()
8888+ {
8989+ AstPlaceholder.DeterminePlaceholderIndices(Enumerable.Empty<AstPlaceholder>());
9090+ }
9191+9292+ [Test]
9393+ public void DeterminePlaceholderIndicesRejectNullTets()
9494+ {
9595+ Assert.Throws<NullReferenceException>(() =>
9696+ AstPlaceholder.DeterminePlaceholderIndices(Extensions.Singleton<AstPlaceholder>(null))
9797+ );
9898+ }
9999+100100+ [Test]
101101+ public void RemoveRedundant1()
102102+ {
103103+ const string file = "THE_FILE";
104104+ const int line = 666;
105105+ const int col = 555;
106106+ //test case from MissingMapped
107107+ var subject = new AstNull(file, line, col);
108108+ var argv = new List<AstExpr>
109109+ {
110110+ subject,
111111+ _createPlaceholder(1),
112112+ _createPlaceholder(2)
113113+ };
114114+ var originalArgv = argv.ToList();
115115+116116+ _placeholderArgvProcessing(argv);
117117+118118+ Assert.AreEqual(3, argv.Count, "argc changed");
119119+ for (var i = 0; i < argv.Count; i++)
120120+ Assert.AreSame(originalArgv[i], argv[i]);
121121+ }
122122+123123+ private static void _placeholderArgvProcessing(List<AstExpr> argv)
124124+ {
125125+ Console.WriteLine("ARGV implicit:");
126126+ foreach (var expr in argv)
127127+ Console.WriteLine("\t{0}", expr);
128128+129129+ AstPlaceholder.DeterminePlaceholderIndices(argv.MapMaybe(x => x as AstPlaceholder));
130130+131131+ Console.WriteLine("ARGV explicit:");
132132+ foreach (var expr in argv)
133133+ Console.WriteLine("\t{0}", expr);
134134+135135+ AstPartiallyApplicable.RemoveRedundantPlaceholders(argv);
136136+137137+ Console.WriteLine("ARGV minimal:");
138138+ foreach (var expr in argv)
139139+ Console.WriteLine("\t{0}", expr);
140140+ }
141141+142142+ [Test]
143143+ public void RemoveRedundant2()
144144+ {
145145+ const string file = "THE_FILE";
146146+ const int line = 666;
147147+ const int col = 555;
148148+ //test case from MissingMapped
149149+ var subject = new AstNull(file, line, col);
150150+ var argv = new List<AstExpr>
151151+ {
152152+ subject,
153153+ _createPlaceholder(2),
154154+ _createPlaceholder(),
155155+ _createPlaceholder(1)
156156+ };
157157+ var originalArgv = argv.GetRange(0, 2);
158158+159159+ _placeholderArgvProcessing(argv);
160160+161161+ Assert.AreEqual(originalArgv.Count, argv.Count, "argc not correct");
162162+ for (var i = 0; i < originalArgv.Count; i++)
163163+ Assert.AreSame(originalArgv[i], argv[i]);
164164+ }
165165+ }
164166}
+647-645
PrexoniteTests/Tests/CilCompilerTests.cs
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System.Collections.Generic;
2727-using System.Linq;
2828-using NUnit.Framework;
2929-using Prexonite;
3030-using Prexonite.Compiler;
3131-using Prexonite.Compiler.Cil;
3232-3333-namespace PrexoniteTests.Tests
3434-{
3535- [TestFixture]
3636- public class CilCompilerTests : VMTestsBase
3737- {
3838- [Test]
3939- public void SetCilHintTest()
4040- {
4141- Compile(@"
4242-function main() {
4343- foreach(var x in var args)
4444- println(x);
4545-}");
4646-4747- var main = target.Functions["main"];
4848-4949- var cilExt1 = new CilExtensionHint(new List<int> {1, 5, 9});
5050- var existingHints = _getCilHints(main, true);
5151- Assert.AreEqual(1, existingHints.Length);
5252-5353- //Add, none existing
5454- Compiler.SetCilHint(main, cilExt1);
5555- var hints1 = _getCilHints(main, true);
5656- Assert.AreNotSame(existingHints, hints1);
5757- Assert.AreEqual(2, hints1.Length);
5858- Assert.IsTrue(hints1[1].IsList);
5959- var cilExt1P = CilExtensionHint.FromMetaEntry(hints1[1].List);
6060- Assert.IsTrue(
6161- cilExt1P.Offsets.All(offset => cilExt1.Offsets.Contains(offset)),
6262- "deserialized contains elements not in original");
6363- Assert.IsTrue(cilExt1.Offsets.All(offset => cilExt1P.Offsets.Contains(offset)),
6464- "original contains elements not in deserialized");
6565-6666- //Add, one existing
6767- var cilExt2 = new CilExtensionHint(new List<int> {2, 4, 8, 16});
6868- Compiler.SetCilHint(main, cilExt2);
6969- var hints2 = _getCilHints(main, true);
7070- Assert.AreSame(hints1, hints2);
7171- Assert.AreEqual(2, hints2.Length);
7272- Assert.IsTrue(hints2[1].IsList);
7373- var cilExt2P = CilExtensionHint.FromMetaEntry(hints2[1].List);
7474- Assert.IsTrue(
7575- cilExt2P.Offsets.All(offset => cilExt2.Offsets.Contains(offset)),
7676- "deserialized contains elements not in original");
7777- Assert.IsTrue(cilExt2.Offsets.All(offset => cilExt2P.Offsets.Contains(offset)),
7878- "original contains elements not in deserialized");
7979-8080- //Add, many existing
8181- var cilExts = new List<CilExtensionHint>
8282- {
8383- new CilExtensionHint(new List<int> {1, 6, 16, 66}),
8484- new CilExtensionHint(new List<int> {7, 77, 777}),
8585- new CilExtensionHint(new List<int> {9, 88, 777, 6666}),
8686- };
8787- foreach (var cilExt in cilExts)
8888- Compiler.AddCilHint(main, cilExt);
8989- var hints3 = _getCilHints(main, true);
9090- Assert.AreNotSame(hints2, hints3);
9191- Assert.AreEqual(5, hints3.Length);
9292- var cilExt3 = new CilExtensionHint(new List<int> {44, 55, 66, 77, 88});
9393- Compiler.SetCilHint(main, cilExt3);
9494- var hints4 = _getCilHints(main, true);
9595- Assert.AreNotSame(hints3, hints4);
9696- Assert.AreEqual(2, hints4.Length);
9797- Assert.IsTrue(hints4[1].IsList);
9898- var cilExt3P = CilExtensionHint.FromMetaEntry(hints4[1].List);
9999- Assert.IsTrue(
100100- cilExt3P.Offsets.All(offset => cilExt3.Offsets.Contains(offset)),
101101- "deserialized contains elements not in original");
102102- Assert.IsTrue(cilExt3.Offsets.All(offset => cilExt3P.Offsets.Contains(offset)),
103103- "original contains elements not in deserialized");
104104-105105-106106- //Add, no cil hints key yet
107107- var emptyFunc = target.CreateFunction();
108108- emptyFunc.Meta[PFunction.IdKey] = "empty";
109109- Compiler.SetCilHint(main, cilExt3);
110110- var hints5 = _getCilHints(main, true);
111111- Assert.AreEqual(2, hints5.Length);
112112- Assert.IsTrue(hints5[0].IsList);
113113- var cilExt4P = CilExtensionHint.FromMetaEntry(hints5[1].List);
114114- Assert.IsTrue(
115115- cilExt4P.Offsets.All(offset => cilExt3.Offsets.Contains(offset)),
116116- "deserialized contains elements not in original");
117117- Assert.IsTrue(cilExt3.Offsets.All(offset => cilExt4P.Offsets.Contains(offset)),
118118- "original contains elements not in deserialized");
119119- }
120120-121121- private static MetaEntry[] _getCilHints(IHasMetaTable table, bool keyMustExist)
122122- {
123123- MetaEntry cilHintsEntry;
124124- if (table.Meta.TryGetValue(Loader.CilHintsKey, out cilHintsEntry))
125125- {
126126- Assert.IsTrue(cilHintsEntry.IsList, "CIL hints entry must be a list.");
127127- return cilHintsEntry.List;
128128- }
129129- else if (keyMustExist)
130130- {
131131- Assert.Fail("Meta table of {0} does not contain cil hints.", table);
132132- return null;
133133- }
134134- else
135135- {
136136- table.Meta[Loader.CilHintsKey] = (MetaEntry) new MetaEntry[0];
137137- return _getCilHints(table, true);
138138- }
139139- }
140140-141141- [Test]
142142- public void UnbindCommandTest()
143143- {
144144- Compile(
145145- @"
146146-function main()
147147-{
148148- var result = [];
149149- var x = 1;
150150- ref y = ->x;
151151- result[] = x == 1;
152152- result[] = ->x == ->y;
153153- new var x;
154154- result[] = x == 1;
155155- result[] = not System::Object.ReferenceEquals(->x, ->y);
156156-157157- result[] = var x == new var x;
158158- result[] = x == 1;
159159- result[] = not System::Object.ReferenceEquals(->x, ->y);
160160-161161- //behave like ordinary command
162162- result[] = unbind(->x) is null;
163163- result[] = x == 1;
164164- result[] = not System::Object.ReferenceEquals(->x, ->y);
165165-166166- return result;
167167-}
168168-");
169169- _expectCil();
170170- Expect(Enumerable.Range(1, 10).Select(_ => (PValue) true).ToList());
171171- }
172172-173173-174174- [Test]
175175- public void JumpBreaksCilExtensions()
176176- {
177177- Compile(
178178- @"
179179-function main(b)
180180-{asm{
181181- ldloc b
182182- ldc.int 4
183183- cmd.2 (==)
184184- jump.f L_else
185185-label L_if ldc.string ""IF""
186186- jump L_endif
187187-label L_else ldc.string ""ELSE""
188188-label L_endif ldc.string ""-branch""
189189- cmd.2 (+)
190190- ret
191191-}}
192192-");
193193- Assert.AreEqual(1, _getCilHints(target.Functions["main"], true).Length);
194194- _expectCil();
195195- Expect("IF-branch", 4);
196196- Expect("ELSE-branch", 3);
197197- Expect("ELSE-branch", 5);
198198- }
199199-200200- [Test]
201201- public void TryCatchFinallyCompiles()
202202- {
203203- Compile(
204204- @"
205205-var t = """";
206206-function trace(x) = t+=x;
207207-208208-function main()
209209-{
210210- try {
211211- trace(""t"");
212212- throw ""e"";
213213- }catch(var exc){
214214- trace(""c"");
215215- trace(exc.Message);
216216- }finally{
217217- trace(""f"");
218218- }
219219-220220- return t;
221221-}
222222-");
223223- _expectCil();
224224- Expect("tfce");
225225- }
226226-227227- private void _expectCil(string functionId = "main")
228228- {
229229- var func = target.Functions[functionId];
230230- Assert.IsNotNull(func, "Function " + functionId + " must exist");
231231- Assert.IsFalse(func.Meta[PFunction.VolatileKey].Switch,
232232- functionId + " must not be volatile.");
233233- }
234234-235235- [Test, ExpectedException(typeof (PrexoniteRuntimeException))]
236236- public void TryFinallyCondCompiles()
237237- {
238238- Compile(
239239- @"
240240-var t = """";
241241-function trace(x) = t+=x;
242242-243243-function main(x)
244244-{
245245- try {
246246- trace(""t"");
247247- if(x)
248248- throw ""e"";
249249- }finally{
250250- trace(""f"");
251251- }
252252-253253- return t;
254254-}
255255-");
256256- _expectCil();
257257- Expect("tf", true);
258258- }
259259-260260- [Test]
261261- public void TryCatchCondCompiles()
262262- {
263263- Compile(
264264- @"
265265-var t = """";
266266-function trace(x) = t+=x;
267267-268268-function main(x)
269269-{
270270- try {
271271- trace(""t"");
272272- if(x)
273273- throw ""e"";
274274- }catch(var exc){
275275- trace(""c"");
276276- trace(exc.Message);
277277- }
278278-279279- return t;
280280-}
281281-");
282282- _expectCil();
283283- Expect("tce", true);
284284- }
285285-286286- [Test]
287287- public void CatchInFinally1()
288288- {
289289- Compile(
290290- @"
291291-var t = """";
292292-function trace(x) = t+=x;
293293-294294-function main(x)
295295-{
296296- try {
297297- try {
298298- trace(""t"");
299299- if(x)
300300- throw ""e"";
301301- }catch(var exc){
302302- trace(""c"");
303303- trace(exc.Message);
304304- }
305305- } finally {
306306- trace(""f"");
307307- }
308308-309309- return t;
310310-}
311311-");
312312- _expectCil();
313313- Expect("tcef", true);
314314- }
315315-316316- [Test]
317317- public void CatchInFinally2()
318318- {
319319- Compile(
320320- @"
321321-var t = """";
322322-function trace(x) = t+=x;
323323-324324-function main(x)
325325-{
326326- try {
327327- try {
328328- trace(""t"");
329329- throw ""e"";
330330- }catch(var exc){
331331- if(x)
332332- trace(""x"");
333333- }
334334- } finally {
335335- trace(""f"");
336336- }
337337-338338- return t;
339339-}
340340-");
341341-342342- _expectCil();
343343- Expect("txf", true);
344344- }
345345-346346- [Test]
347347- public void CatchInFinally3()
348348- {
349349- Compile(
350350- @"
351351-var t = """";
352352-function trace(x) = t+=x;
353353-354354-function main(x)
355355-{
356356- try {
357357- try {
358358- trace(""t"");
359359- throw ""e"";
360360- }catch(var exc){
361361- if(x)
362362- trace(""x"");
363363- }
364364- } catch(var exc){
365365- trace(""e"");
366366- } finally {
367367- trace(""f"");
368368- }
369369-370370- return t;
371371-}
372372-");
373373- _expectCil();
374374- Expect("txf", true);
375375- }
376376-377377- [Test]
378378- public void CatchInFinally4()
379379- {
380380- Compile(
381381- @"
382382-var t = """";
383383-function trace(x) = t+=x;
384384-385385-function main(x) [store_debug_implementation enabled;]
386386-{
387387- for(var i = 1; i < 6; i++)
388388- try
389389- {
390390- try
391391- {
392392- throw i;
393393- }
394394- catch(var exc)
395395- {
396396- if(x)
397397- throw exc;
398398- }
399399- }
400400- catch(var exc)
401401- {
402402- trace(""e"");
403403- }
404404- finally
405405- {
406406- trace(""f"");
407407- }
408408- return t;
409409-}
410410-");
411411- _expectCil();
412412- Expect("fefefefefe", true);
413413- }
414414-415415- [Test]
416416- public void CatchInFinally5()
417417- {
418418- Compile(
419419- @"
420420-var t = """";
421421-function trace(x) = t+=x;
422422-423423-function main(x,y) [store_debug_implementation enabled;]
424424-{
425425- try
426426- {
427427- try
428428- {
429429- throw ""i""; //this must be a throw; won't work with trace
430430- }
431431- catch(var exc)
432432- {
433433- if(not x) //needs to be false (it's a runtime error after all)
434434- throw exc;
435435- }
436436- } //must be a nested block
437437- finally
438438- {
439439- trace(""f"");
440440- }
441441- return t;
442442-}
443443-");
444444- _expectCil();
445445- Expect("f", true, true);
446446- }
447447-448448- [Test]
449449- public void TryCatchFinallyCondCompiles()
450450- {
451451- Compile(
452452- @"
453453-var t = """";
454454-function trace(x) = t+=x;
455455-456456-function main(x) //[store_debug_implementation enabled;]
457457-{
458458- try {
459459- trace(""t"");
460460- if(x)
461461- throw ""e"";
462462- }catch(var exc){
463463- trace(""c"");
464464- trace(exc.Message);
465465- }finally{
466466- trace(""f"");
467467- }
468468-469469- return t;
470470-}
471471-");
472472- _expectCil();
473473- Expect("tfce", true);
474474- }
475475-476476- [Test,
477477- ExpectedException(typeof (PrexoniteRuntimeException),
478478- ExpectedMessage =
479479- @"Unexpected leave instruction. This happens when jumping to an instruction in a try block from the outside."
480480- )]
481481- public void LabelOnFirstNeLabelOnTry()
482482- {
483483- Compile(
484484- @"
485485-var t = """";
486486-function trace(x) = t+=x;
487487-488488-function main(x) //[store_debug_implementation enabled;]
489489-{
490490- try {
491491- trace(""t"");
492492- goto L1;
493493- trace(""z"");
494494- } finally {
495495- trace(""f"");
496496- }
497497-498498- try {
499499- trace(""g"");
500500- try {
501501-L1: trace(""b"");
502502- } finally {
503503- trace(""r"");
504504- }
505505- } finally {
506506- trace(""v"");
507507- }
508508-509509- return t;
510510-}
511511-");
512512- _expectSehDeficiency();
513513- Expect("undefined", true);
514514- }
515515-516516- [Test]
517517- public void TryFinallyShadowingNoBridge()
518518- {
519519- Compile(
520520- @"
521521-var t = """";
522522-function trace(x) = t+=x;
523523-524524-//This tets is expected not to compile to CIL
525525-function main(x) //[store_debug_implementation enabled;]
526526-{
527527- try {
528528- trace(""t"");
529529- goto L1;
530530- trace(""z"");
531531- } finally {
532532- trace(""f"");
533533- }
534534-535535- try {
536536- trace(""g"");
537537-L1: try {
538538- trace(""b"");
539539- } finally {
540540- trace(""r"");
541541- }
542542- } finally {
543543- trace(""v"");
544544- }
545545-546546- return t;
547547-}
548548-");
549549- _expectSehDeficiency();
550550- Expect("tbrv", true);
551551- }
552552-553553- [Test]
554554- public void TryFinallyShadowingBridge()
555555- {
556556- Compile(
557557- @"
558558-var t = """";
559559-function trace(x) = t+=x;
560560-561561-function main(x) //[store_debug_implementation enabled;]
562562-{
563563- try {
564564- trace(""k"");
565565- try {
566566- trace(""t"");
567567- goto L1;
568568- trace(""z"");
569569- } finally {
570570- trace(""f"");
571571- }
572572-573573- trace(""g"");
574574-L1: try {
575575- trace(""b"");
576576- } finally {
577577- trace(""r"");
578578- }
579579- } finally {
580580- trace(""v"");
581581- }
582582-583583- return t;
584584-}
585585-");
586586- _expectCil();
587587- Expect("ktfbrv", true);
588588- }
589589-590590- [Test]
591591- public void ReturnFromFinally()
592592- {
593593- Compile(
594594- @"
595595-var t = """";
596596-function trace(x) = t+=x;
597597-598598-function main(x) //[store_debug_implementation enabled;]
599599-{
600600- try {
601601- trace(""k"");
602602- } finally {
603603- trace(""f"");
604604- return t;
605605- trace(""v"");
606606- }
607607-608608- return t;
609609-}
610610-");
611611- _expectSehDeficiency();
612612- Expect("kf", true);
613613- }
614614-615615- private void _expectSehDeficiency(string name = "main")
616616- {
617617- _expectSehDeficiency(target.Functions[name]);
618618- }
619619-620620- private static void _expectSehDeficiency(PFunction function)
621621- {
622622- Assert.IsNotNull(function, "function not found");
623623- Assert.IsTrue(function.Meta[PFunction.VolatileKey].Switch,
624624- "Function is expected to be volatile.");
625625- Assert.IsTrue(function.Meta[PFunction.DeficiencyKey].Text.Contains("SEH"),
626626- "CIL deficiency is expected to be related to SEH.");
627627- }
628628-629629- [Test]
630630- public void MinimalTryCatch()
631631- {
632632- Compile(
633633- @"
634634-var t;
635635-function trace(x) = t+=x~String;
636636-function main(x) [store_debug_implementation enabled;]
637637-{
638638- try {trace(1);}
639639- finally{trace(2);}
640640- return t;
641641-}");
642642-643643- Expect("12", true);
644644- }
645645- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System.Collections.Generic;
2727+using System.Linq;
2828+using NUnit.Framework;
2929+using Prexonite;
3030+using Prexonite.Compiler;
3131+using Prexonite.Compiler.Cil;
3232+3333+namespace PrexoniteTests.Tests
3434+{
3535+ [TestFixture]
3636+ public class CilCompilerTests : VMTestsBase
3737+ {
3838+ [Test]
3939+ public void SetCilHintTest()
4040+ {
4141+ Compile(@"
4242+function main() {
4343+ foreach(var x in var args)
4444+ println(x);
4545+}");
4646+4747+ var main = target.Functions["main"];
4848+4949+ var cilExt1 = new CilExtensionHint(new List<int> {1, 5, 9});
5050+ var existingHints = _getCilHints(main, true);
5151+ Assert.AreEqual(1, existingHints.Length);
5252+5353+ //Add, none existing
5454+ Compiler.SetCilHint(main, cilExt1);
5555+ var hints1 = _getCilHints(main, true);
5656+ Assert.AreNotSame(existingHints, hints1);
5757+ Assert.AreEqual(2, hints1.Length);
5858+ Assert.IsTrue(hints1[1].IsList);
5959+ var cilExt1P = CilExtensionHint.FromMetaEntry(hints1[1].List);
6060+ Assert.IsTrue(
6161+ cilExt1P.Offsets.All(offset => cilExt1.Offsets.Contains(offset)),
6262+ "deserialized contains elements not in original");
6363+ Assert.IsTrue(cilExt1.Offsets.All(offset => cilExt1P.Offsets.Contains(offset)),
6464+ "original contains elements not in deserialized");
6565+6666+ //Add, one existing
6767+ var cilExt2 = new CilExtensionHint(new List<int> {2, 4, 8, 16});
6868+ Compiler.SetCilHint(main, cilExt2);
6969+ var hints2 = _getCilHints(main, true);
7070+ Assert.AreSame(hints1, hints2);
7171+ Assert.AreEqual(2, hints2.Length);
7272+ Assert.IsTrue(hints2[1].IsList);
7373+ var cilExt2P = CilExtensionHint.FromMetaEntry(hints2[1].List);
7474+ Assert.IsTrue(
7575+ cilExt2P.Offsets.All(offset => cilExt2.Offsets.Contains(offset)),
7676+ "deserialized contains elements not in original");
7777+ Assert.IsTrue(cilExt2.Offsets.All(offset => cilExt2P.Offsets.Contains(offset)),
7878+ "original contains elements not in deserialized");
7979+8080+ //Add, many existing
8181+ var cilExts = new List<CilExtensionHint>
8282+ {
8383+ new CilExtensionHint(new List<int> {1, 6, 16, 66}),
8484+ new CilExtensionHint(new List<int> {7, 77, 777}),
8585+ new CilExtensionHint(new List<int> {9, 88, 777, 6666}),
8686+ };
8787+ foreach (var cilExt in cilExts)
8888+ Compiler.AddCilHint(main, cilExt);
8989+ var hints3 = _getCilHints(main, true);
9090+ Assert.AreNotSame(hints2, hints3);
9191+ Assert.AreEqual(5, hints3.Length);
9292+ var cilExt3 = new CilExtensionHint(new List<int> {44, 55, 66, 77, 88});
9393+ Compiler.SetCilHint(main, cilExt3);
9494+ var hints4 = _getCilHints(main, true);
9595+ Assert.AreNotSame(hints3, hints4);
9696+ Assert.AreEqual(2, hints4.Length);
9797+ Assert.IsTrue(hints4[1].IsList);
9898+ var cilExt3P = CilExtensionHint.FromMetaEntry(hints4[1].List);
9999+ Assert.IsTrue(
100100+ cilExt3P.Offsets.All(offset => cilExt3.Offsets.Contains(offset)),
101101+ "deserialized contains elements not in original");
102102+ Assert.IsTrue(cilExt3.Offsets.All(offset => cilExt3P.Offsets.Contains(offset)),
103103+ "original contains elements not in deserialized");
104104+105105+106106+ //Add, no cil hints key yet
107107+ var emptyFunc = target.CreateFunction();
108108+ emptyFunc.Meta[PFunction.IdKey] = "empty";
109109+ Compiler.SetCilHint(main, cilExt3);
110110+ var hints5 = _getCilHints(main, true);
111111+ Assert.AreEqual(2, hints5.Length);
112112+ Assert.IsTrue(hints5[0].IsList);
113113+ var cilExt4P = CilExtensionHint.FromMetaEntry(hints5[1].List);
114114+ Assert.IsTrue(
115115+ cilExt4P.Offsets.All(offset => cilExt3.Offsets.Contains(offset)),
116116+ "deserialized contains elements not in original");
117117+ Assert.IsTrue(cilExt3.Offsets.All(offset => cilExt4P.Offsets.Contains(offset)),
118118+ "original contains elements not in deserialized");
119119+ }
120120+121121+ private static MetaEntry[] _getCilHints(IHasMetaTable table, bool keyMustExist)
122122+ {
123123+ MetaEntry cilHintsEntry;
124124+ if (table.Meta.TryGetValue(Loader.CilHintsKey, out cilHintsEntry))
125125+ {
126126+ Assert.IsTrue(cilHintsEntry.IsList, "CIL hints entry must be a list.");
127127+ return cilHintsEntry.List;
128128+ }
129129+ else if (keyMustExist)
130130+ {
131131+ Assert.Fail("Meta table of {0} does not contain cil hints.", table);
132132+ return null;
133133+ }
134134+ else
135135+ {
136136+ table.Meta[Loader.CilHintsKey] = (MetaEntry) new MetaEntry[0];
137137+ return _getCilHints(table, true);
138138+ }
139139+ }
140140+141141+ [Test]
142142+ public void UnbindCommandTest()
143143+ {
144144+ Compile(
145145+ @"
146146+function main()
147147+{
148148+ var result = [];
149149+ var x = 1;
150150+ ref y = ->x;
151151+ result[] = x == 1;
152152+ result[] = ->x == ->y;
153153+ new var x;
154154+ result[] = x == 1;
155155+ result[] = not System::Object.ReferenceEquals(->x, ->y);
156156+157157+ result[] = var x == new var x;
158158+ result[] = x == 1;
159159+ result[] = not System::Object.ReferenceEquals(->x, ->y);
160160+161161+ //behave like ordinary command
162162+ result[] = unbind(->x) is null;
163163+ result[] = x == 1;
164164+ result[] = not System::Object.ReferenceEquals(->x, ->y);
165165+166166+ return result;
167167+}
168168+");
169169+ _expectCil();
170170+ Expect(Enumerable.Range(1, 10).Select(_ => (PValue) true).ToList());
171171+ }
172172+173173+174174+ [Test]
175175+ public void JumpBreaksCilExtensions()
176176+ {
177177+ Compile(
178178+ @"
179179+function main(b)
180180+{asm{
181181+ ldloc b
182182+ ldc.int 4
183183+ cmd.2 (==)
184184+ jump.f L_else
185185+label L_if ldc.string ""IF""
186186+ jump L_endif
187187+label L_else ldc.string ""ELSE""
188188+label L_endif ldc.string ""-branch""
189189+ cmd.2 (+)
190190+ ret
191191+}}
192192+");
193193+ Assert.AreEqual(1, _getCilHints(target.Functions["main"], true).Length);
194194+ _expectCil();
195195+ Expect("IF-branch", 4);
196196+ Expect("ELSE-branch", 3);
197197+ Expect("ELSE-branch", 5);
198198+ }
199199+200200+ [Test]
201201+ public void TryCatchFinallyCompiles()
202202+ {
203203+ Compile(
204204+ @"
205205+var t = """";
206206+function trace(x) = t+=x;
207207+208208+function main()
209209+{
210210+ try {
211211+ trace(""t"");
212212+ throw ""e"";
213213+ }catch(var exc){
214214+ trace(""c"");
215215+ trace(exc.Message);
216216+ }finally{
217217+ trace(""f"");
218218+ }
219219+220220+ return t;
221221+}
222222+");
223223+ _expectCil();
224224+ Expect("tfce");
225225+ }
226226+227227+ private void _expectCil(string functionId = "main")
228228+ {
229229+ var func = target.Functions[functionId];
230230+ Assert.IsNotNull(func, "Function " + functionId + " must exist");
231231+ Assert.IsFalse(func.Meta[PFunction.VolatileKey].Switch,
232232+ functionId + " must not be volatile.");
233233+ }
234234+235235+ [Test]
236236+ public void TryFinallyCondCompiles()
237237+ {
238238+ Assert.Throws<PrexoniteRuntimeException>(() =>
239239+ {
240240+ Compile(
241241+ @"
242242+var t = """";
243243+function trace(x) = t+=x;
244244+245245+function main(x)
246246+{
247247+ try {
248248+ trace(""t"");
249249+ if(x)
250250+ throw ""e"";
251251+ }finally{
252252+ trace(""f"");
253253+ }
254254+255255+ return t;
256256+}
257257+");
258258+ _expectCil();
259259+ Expect("tf", true);
260260+ });
261261+ }
262262+263263+ [Test]
264264+ public void TryCatchCondCompiles()
265265+ {
266266+ Compile(
267267+ @"
268268+var t = """";
269269+function trace(x) = t+=x;
270270+271271+function main(x)
272272+{
273273+ try {
274274+ trace(""t"");
275275+ if(x)
276276+ throw ""e"";
277277+ }catch(var exc){
278278+ trace(""c"");
279279+ trace(exc.Message);
280280+ }
281281+282282+ return t;
283283+}
284284+");
285285+ _expectCil();
286286+ Expect("tce", true);
287287+ }
288288+289289+ [Test]
290290+ public void CatchInFinally1()
291291+ {
292292+ Compile(
293293+ @"
294294+var t = """";
295295+function trace(x) = t+=x;
296296+297297+function main(x)
298298+{
299299+ try {
300300+ try {
301301+ trace(""t"");
302302+ if(x)
303303+ throw ""e"";
304304+ }catch(var exc){
305305+ trace(""c"");
306306+ trace(exc.Message);
307307+ }
308308+ } finally {
309309+ trace(""f"");
310310+ }
311311+312312+ return t;
313313+}
314314+");
315315+ _expectCil();
316316+ Expect("tcef", true);
317317+ }
318318+319319+ [Test]
320320+ public void CatchInFinally2()
321321+ {
322322+ Compile(
323323+ @"
324324+var t = """";
325325+function trace(x) = t+=x;
326326+327327+function main(x)
328328+{
329329+ try {
330330+ try {
331331+ trace(""t"");
332332+ throw ""e"";
333333+ }catch(var exc){
334334+ if(x)
335335+ trace(""x"");
336336+ }
337337+ } finally {
338338+ trace(""f"");
339339+ }
340340+341341+ return t;
342342+}
343343+");
344344+345345+ _expectCil();
346346+ Expect("txf", true);
347347+ }
348348+349349+ [Test]
350350+ public void CatchInFinally3()
351351+ {
352352+ Compile(
353353+ @"
354354+var t = """";
355355+function trace(x) = t+=x;
356356+357357+function main(x)
358358+{
359359+ try {
360360+ try {
361361+ trace(""t"");
362362+ throw ""e"";
363363+ }catch(var exc){
364364+ if(x)
365365+ trace(""x"");
366366+ }
367367+ } catch(var exc){
368368+ trace(""e"");
369369+ } finally {
370370+ trace(""f"");
371371+ }
372372+373373+ return t;
374374+}
375375+");
376376+ _expectCil();
377377+ Expect("txf", true);
378378+ }
379379+380380+ [Test]
381381+ public void CatchInFinally4()
382382+ {
383383+ Compile(
384384+ @"
385385+var t = """";
386386+function trace(x) = t+=x;
387387+388388+function main(x) [store_debug_implementation enabled;]
389389+{
390390+ for(var i = 1; i < 6; i++)
391391+ try
392392+ {
393393+ try
394394+ {
395395+ throw i;
396396+ }
397397+ catch(var exc)
398398+ {
399399+ if(x)
400400+ throw exc;
401401+ }
402402+ }
403403+ catch(var exc)
404404+ {
405405+ trace(""e"");
406406+ }
407407+ finally
408408+ {
409409+ trace(""f"");
410410+ }
411411+ return t;
412412+}
413413+");
414414+ _expectCil();
415415+ Expect("fefefefefe", true);
416416+ }
417417+418418+ [Test]
419419+ public void CatchInFinally5()
420420+ {
421421+ Compile(
422422+ @"
423423+var t = """";
424424+function trace(x) = t+=x;
425425+426426+function main(x,y) [store_debug_implementation enabled;]
427427+{
428428+ try
429429+ {
430430+ try
431431+ {
432432+ throw ""i""; //this must be a throw; won't work with trace
433433+ }
434434+ catch(var exc)
435435+ {
436436+ if(not x) //needs to be false (it's a runtime error after all)
437437+ throw exc;
438438+ }
439439+ } //must be a nested block
440440+ finally
441441+ {
442442+ trace(""f"");
443443+ }
444444+ return t;
445445+}
446446+");
447447+ _expectCil();
448448+ Expect("f", true, true);
449449+ }
450450+451451+ [Test]
452452+ public void TryCatchFinallyCondCompiles()
453453+ {
454454+ Compile(
455455+ @"
456456+var t = """";
457457+function trace(x) = t+=x;
458458+459459+function main(x) //[store_debug_implementation enabled;]
460460+{
461461+ try {
462462+ trace(""t"");
463463+ if(x)
464464+ throw ""e"";
465465+ }catch(var exc){
466466+ trace(""c"");
467467+ trace(exc.Message);
468468+ }finally{
469469+ trace(""f"");
470470+ }
471471+472472+ return t;
473473+}
474474+");
475475+ _expectCil();
476476+ Expect("tfce", true);
477477+ }
478478+479479+ [Test]
480480+ public void LabelOnFirstNeLabelOnTry()
481481+ {
482482+ Assert.Throws<PrexoniteRuntimeException>(() =>
483483+ {
484484+ Compile(
485485+ @"
486486+var t = """";
487487+function trace(x) = t+=x;
488488+489489+function main(x) //[store_debug_implementation enabled;]
490490+{
491491+ try {
492492+ trace(""t"");
493493+ goto L1;
494494+ trace(""z"");
495495+ } finally {
496496+ trace(""f"");
497497+ }
498498+499499+ try {
500500+ trace(""g"");
501501+ try {
502502+L1: trace(""b"");
503503+ } finally {
504504+ trace(""r"");
505505+ }
506506+ } finally {
507507+ trace(""v"");
508508+ }
509509+510510+ return t;
511511+}
512512+");
513513+ _expectSehDeficiency();
514514+ Expect("undefined", true);
515515+ }, @"Unexpected leave instruction. This happens when jumping to an instruction in a try block from the outside.");
516516+ }
517517+518518+ [Test]
519519+ public void TryFinallyShadowingNoBridge()
520520+ {
521521+ Compile(
522522+ @"
523523+var t = """";
524524+function trace(x) = t+=x;
525525+526526+//This tets is expected not to compile to CIL
527527+function main(x) //[store_debug_implementation enabled;]
528528+{
529529+ try {
530530+ trace(""t"");
531531+ goto L1;
532532+ trace(""z"");
533533+ } finally {
534534+ trace(""f"");
535535+ }
536536+537537+ try {
538538+ trace(""g"");
539539+L1: try {
540540+ trace(""b"");
541541+ } finally {
542542+ trace(""r"");
543543+ }
544544+ } finally {
545545+ trace(""v"");
546546+ }
547547+548548+ return t;
549549+}
550550+");
551551+ _expectSehDeficiency();
552552+ Expect("tbrv", true);
553553+ }
554554+555555+ [Test]
556556+ public void TryFinallyShadowingBridge()
557557+ {
558558+ Compile(
559559+ @"
560560+var t = """";
561561+function trace(x) = t+=x;
562562+563563+function main(x) //[store_debug_implementation enabled;]
564564+{
565565+ try {
566566+ trace(""k"");
567567+ try {
568568+ trace(""t"");
569569+ goto L1;
570570+ trace(""z"");
571571+ } finally {
572572+ trace(""f"");
573573+ }
574574+575575+ trace(""g"");
576576+L1: try {
577577+ trace(""b"");
578578+ } finally {
579579+ trace(""r"");
580580+ }
581581+ } finally {
582582+ trace(""v"");
583583+ }
584584+585585+ return t;
586586+}
587587+");
588588+ _expectCil();
589589+ Expect("ktfbrv", true);
590590+ }
591591+592592+ [Test]
593593+ public void ReturnFromFinally()
594594+ {
595595+ Compile(
596596+ @"
597597+var t = """";
598598+function trace(x) = t+=x;
599599+600600+function main(x) //[store_debug_implementation enabled;]
601601+{
602602+ try {
603603+ trace(""k"");
604604+ } finally {
605605+ trace(""f"");
606606+ return t;
607607+ trace(""v"");
608608+ }
609609+610610+ return t;
611611+}
612612+");
613613+ _expectSehDeficiency();
614614+ Expect("kf", true);
615615+ }
616616+617617+ private void _expectSehDeficiency(string name = "main")
618618+ {
619619+ _expectSehDeficiency(target.Functions[name]);
620620+ }
621621+622622+ private static void _expectSehDeficiency(PFunction function)
623623+ {
624624+ Assert.IsNotNull(function, "function not found");
625625+ Assert.IsTrue(function.Meta[PFunction.VolatileKey].Switch,
626626+ "Function is expected to be volatile.");
627627+ Assert.IsTrue(function.Meta[PFunction.DeficiencyKey].Text.Contains("SEH"),
628628+ "CIL deficiency is expected to be related to SEH.");
629629+ }
630630+631631+ [Test]
632632+ public void MinimalTryCatch()
633633+ {
634634+ Compile(
635635+ @"
636636+var t;
637637+function trace(x) = t+=x~String;
638638+function main(x) [store_debug_implementation enabled;]
639639+{
640640+ try {trace(1);}
641641+ finally{trace(2);}
642642+ return t;
643643+}");
644644+645645+ Expect("12", true);
646646+ }
647647+ }
646648}
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using System.Collections.Generic;
2828-using System.IO;
2929-using System.Linq;
3030-using System.Threading.Tasks;
3131-using JetBrains.Annotations;
3232-using NUnit.Framework;
3333-using Prexonite;
3434-using Prexonite.Compiler;
3535-using Prexonite.Compiler.Build;
3636-using Prexonite.Compiler.Symbolic;
3737-using Prexonite.Modular;
3838-using Prexonite.Types;
3939-4040-namespace PrexoniteTests.Tests.Configurations
4141-{
4242- internal abstract class ScriptedUnitTestContainer
4343- {
4444- public Application Application { get; set; }
4545- public Engine Engine { get; set; }
4646- public Loader Loader { get; set; }
4747-4848- public List<string> Dependencies { get; set; }
4949-5050- public StackContext Root { get; set; }
5151-5252- public const string ListTestsId = @"test\list_test";
5353- public const string RunTestId = @"test\run_test";
5454- public const string PrexoniteUnitTestFramework = @"psr\test.pxs";
5555- public const string DumpRequestFlag = "request_dump";
5656-5757- protected abstract UnitTestConfiguration Runner { get; }
5858-5959- public void Initialize()
6060- {
6161- Application = new Application(ApplicationName);
6262- Engine = new Engine();
6363- Loader = new Loader(Engine, Application);
6464-6565- Dependencies = new List<string>();
6666- Root = new NullContext(Engine, Application, new string[0]);
6767-6868- var slnPath = Environment.CurrentDirectory;
6969- while (Directory.Exists(slnPath) && !File.Exists(Path.Combine(slnPath, "Prexonite.sln")))
7070- slnPath = Path.Combine(slnPath, @".." + Path.DirectorySeparatorChar);
7171-7272- if (Directory.Exists(slnPath))
7373- {
7474- var psrTestsPath =
7575- Path.GetFullPath(Path.Combine(slnPath, @"PrexoniteTests\psr-tests"));
7676- Console.WriteLine("inferred psr-tests path: " + psrTestsPath, "Engine.Path");
7777- Engine.Paths.Add(psrTestsPath);
7878-7979- var prxPath = Path.GetFullPath(Path.Combine(slnPath, @"Prx"));
8080- Console.WriteLine("inferred prx path: " + prxPath, "Engine.Path");
8181- Engine.Paths.Add(prxPath);
8282- }
8383- else
8484- {
8585- Console.WriteLine("CANNOT INFER solution PATH: " + slnPath, "Engine.Path");
8686- }
8787- }
8888-8989- public string ApplicationName
9090- {
9191- get { return GetType().Name; }
9292- }
9393-9494- protected void RunUnitTest(string testCaseId)
9595- {
9696- Console.WriteLine("---- SNIP end of stored representation ----");
9797-9898- var tc = Application.Functions[testCaseId];
9999- Assert.That(tc, Is.Not.Null, "Test case " + testCaseId + " not found.");
100100-101101- var rt = _findRunFunction();
102102- Assert.That(rt, Is.Not.Null,
103103- "Test case run function (part of testing framework) not found. Was looking for {0}.", RunTestId);
104104-105105- var resP = rt.Run(Engine, new[] {PType.Null, Root.CreateNativePValue(tc)});
106106- var success = (bool) resP.DynamicCall(Root, new PValue[0], PCall.Get, "Key").Value;
107107- if (success)
108108- return;
109109-110110- var eObj = resP
111111- .DynamicCall(Root, new PValue[0], PCall.Get, "Value")
112112- .DynamicCall(Root, new PValue[0], PCall.Get, "e")
113113- .Value;
114114- var e = eObj as Exception;
115115- if (e != null)
116116- {
117117- throw e;
118118- }
119119- else
120120- {
121121- Console.WriteLine("Test failed. Result:");
122122- Console.WriteLine(eObj);
123123- Assert.Fail("Test failed");
124124- }
125125- }
126126-127127- /// <summary>
128128- /// Prints a stored representation of each application in the compound that has its "request_dump" flag set.
129129- /// </summary>
130130- public void PrintCompound()
131131- {
132132- var tasks =
133133- Application.Compound.Where(app => app.Meta[DumpRequestFlag].Switch).Select(
134134- app =>
135135- new KeyValuePair<ModuleName, Task<ITarget>>(app.Module.Name, ModuleCache.BuildAsync(app.Module.Name)))
136136- .ToDictionary(k => k.Key, k => k.Value);
137137- foreach (var entry in tasks)
138138- {
139139- var name = entry.Key;
140140- var target = entry.Value.Result;
141141-142142- Console.WriteLine();
143143- Console.WriteLine("################################## begin of stored representation for {0} ",name);
144144-145145- var opt = new LoaderOptions(Engine, new Application(target.Module), target.Symbols)
146146- {ReconstructSymbols = false, RegisterCommands = false, StoreSymbols = true};
147147- var ldr = new Loader(opt);
148148- ldr.Store(Console.Out);
149149-150150- Console.WriteLine("################################## end of stored representation for {0} ----------", name);
151151- }
152152- }
153153-154154- private PFunction _findRunFunction()
155155- {
156156- return Application.Compound.Select(app =>
157157- {
158158- PFunction func;
159159- return app.Functions.TryGetValue(RunTestId, out func) ? func : null;
160160- }).SingleOrDefault(f => f != null);
161161- }
162162- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using System.Collections.Generic;
2828+using System.IO;
2929+using System.Linq;
3030+using System.Reflection;
3131+using System.Threading.Tasks;
3232+using JetBrains.Annotations;
3333+using NUnit.Framework;
3434+using Prexonite;
3535+using Prexonite.Compiler;
3636+using Prexonite.Compiler.Build;
3737+using Prexonite.Compiler.Symbolic;
3838+using Prexonite.Modular;
3939+using Prexonite.Types;
4040+4141+namespace PrexoniteTests.Tests.Configurations
4242+{
4343+ internal abstract class ScriptedUnitTestContainer
4444+ {
4545+ public Application Application { get; set; }
4646+ public Engine Engine { get; set; }
4747+ public Loader Loader { get; set; }
4848+4949+ public List<string> Dependencies { get; set; }
5050+5151+ public StackContext Root { get; set; }
5252+5353+ public const string ListTestsId = @"test\list_test";
5454+ public const string RunTestId = @"test\run_test";
5555+ public const string PrexoniteUnitTestFramework = @"psr\test.pxs";
5656+ public const string DumpRequestFlag = "request_dump";
5757+5858+ protected abstract UnitTestConfiguration Runner { get; }
5959+6060+ public void Initialize()
6161+ {
6262+ Application = new Application(ApplicationName);
6363+ Engine = new Engine();
6464+ Loader = new Loader(Engine, Application);
6565+6666+ Dependencies = new List<string>();
6767+ Root = new NullContext(Engine, Application, new string[0]);
6868+6969+ var slnPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
7070+ while (Directory.Exists(slnPath) && !File.Exists(Path.Combine(slnPath, "Prexonite.sln")))
7171+ slnPath = Path.Combine(slnPath, @".." + Path.DirectorySeparatorChar);
7272+7373+ if (Directory.Exists(slnPath))
7474+ {
7575+ var psrTestsPath =
7676+ Path.GetFullPath(Path.Combine(slnPath, @"PrexoniteTests\psr-tests"));
7777+ Console.WriteLine("inferred psr-tests path: " + psrTestsPath, "Engine.Path");
7878+ Engine.Paths.Add(psrTestsPath);
7979+8080+ var prxPath = Path.GetFullPath(Path.Combine(slnPath, @"Prx"));
8181+ Console.WriteLine("inferred prx path: " + prxPath, "Engine.Path");
8282+ Engine.Paths.Add(prxPath);
8383+ }
8484+ else
8585+ {
8686+ Console.WriteLine("CANNOT INFER solution PATH: " + slnPath, "Engine.Path");
8787+ }
8888+ }
8989+9090+ public string ApplicationName
9191+ {
9292+ get { return GetType().Name; }
9393+ }
9494+9595+ protected void RunUnitTest(string testCaseId)
9696+ {
9797+ Console.WriteLine("---- SNIP end of stored representation ----");
9898+9999+ var tc = Application.Functions[testCaseId];
100100+ Assert.That(tc, Is.Not.Null, "Test case " + testCaseId + " not found.");
101101+102102+ var rt = _findRunFunction();
103103+ Assert.That(rt, Is.Not.Null,
104104+ "Test case run function (part of testing framework) not found. Was looking for {0}.", RunTestId);
105105+106106+ var resP = rt.Run(Engine, new[] {PType.Null, Root.CreateNativePValue(tc)});
107107+ var success = (bool) resP.DynamicCall(Root, new PValue[0], PCall.Get, "Key").Value;
108108+ if (success)
109109+ return;
110110+111111+ var eObj = resP
112112+ .DynamicCall(Root, new PValue[0], PCall.Get, "Value")
113113+ .DynamicCall(Root, new PValue[0], PCall.Get, "e")
114114+ .Value;
115115+ var e = eObj as Exception;
116116+ if (e != null)
117117+ {
118118+ throw e;
119119+ }
120120+ else
121121+ {
122122+ Console.WriteLine("Test failed. Result:");
123123+ Console.WriteLine(eObj);
124124+ Assert.Fail("Test failed");
125125+ }
126126+ }
127127+128128+ /// <summary>
129129+ /// Prints a stored representation of each application in the compound that has its "request_dump" flag set.
130130+ /// </summary>
131131+ public void PrintCompound()
132132+ {
133133+ var tasks =
134134+ Application.Compound.Where(app => app.Meta[DumpRequestFlag].Switch).Select(
135135+ app =>
136136+ new KeyValuePair<ModuleName, Task<ITarget>>(app.Module.Name, ModuleCache.BuildAsync(app.Module.Name)))
137137+ .ToDictionary(k => k.Key, k => k.Value);
138138+ foreach (var entry in tasks)
139139+ {
140140+ var name = entry.Key;
141141+ var target = entry.Value.Result;
142142+143143+ Console.WriteLine();
144144+ Console.WriteLine("################################## begin of stored representation for {0} ",name);
145145+146146+ var opt = new LoaderOptions(Engine, new Application(target.Module), target.Symbols)
147147+ {ReconstructSymbols = false, RegisterCommands = false, StoreSymbols = true};
148148+ var ldr = new Loader(opt);
149149+ ldr.Store(Console.Out);
150150+151151+ Console.WriteLine("################################## end of stored representation for {0} ----------", name);
152152+ }
153153+ }
154154+155155+ private PFunction _findRunFunction()
156156+ {
157157+ return Application.Compound.Select(app =>
158158+ {
159159+ PFunction func;
160160+ return app.Functions.TryGetValue(RunTestId, out func) ? func : null;
161161+ }).SingleOrDefault(f => f != null);
162162+ }
163163+ }
163164}
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using System.Linq;
2828-using NUnit.Framework.Constraints;
2929-using Prexonite.Compiler.Build;
3030-using Prexonite.Modular;
3131-3232-namespace PrexoniteTests.Tests.Internal
3333-{
3434- public class DependingOnConstraint : Constraint
3535- {
3636- private readonly ModuleName _dependency;
3737-3838- public DependingOnConstraint(ModuleName dependency)
3939- {
4040- _dependency = dependency;
4141- }
4242-4343- public DependingOnConstraint(string name)
4444- {
4545- ModuleName moduleName;
4646- if (ModuleName.TryParse(name, out moduleName))
4747- _dependency = moduleName;
4848- else
4949- throw new ArgumentException(string.Format("The string {0} is not a valid module name.", name));
5050- }
5151-5252- public override bool Matches(object actualValue)
5353- {
5454- actual = actualValue;
5555- var desc = actualValue as ITargetDescription;
5656-5757- return desc != null && desc.Dependencies.Any(n => n.Equals(_dependency));
5858- }
5959-6060- public override void WriteDescriptionTo(MessageWriter writer)
6161- {
6262- writer.WritePredicate("build target description depending on ");
6363- writer.WriteExpectedValue(_dependency);
6464- }
6565- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using System.Linq;
2828+using NUnit.Framework.Constraints;
2929+using Prexonite.Compiler.Build;
3030+using Prexonite.Modular;
3131+3232+namespace PrexoniteTests.Tests.Internal
3333+{
3434+ public class DependingOnConstraint : Constraint
3535+ {
3636+ private readonly ModuleName _dependency;
3737+3838+ public DependingOnConstraint(ModuleName dependency) : base(dependency)
3939+ {
4040+ _dependency = dependency;
4141+ }
4242+4343+ public DependingOnConstraint(string name) : base(name)
4444+ {
4545+ ModuleName moduleName;
4646+ if (ModuleName.TryParse(name, out moduleName))
4747+ _dependency = moduleName;
4848+ else
4949+ throw new ArgumentException(string.Format("The string {0} is not a valid module name.", name));
5050+ }
5151+5252+ public override ConstraintResult ApplyTo<TActual>(TActual actual)
5353+ {
5454+ var actualValue = actual;
5555+ return new ConstraintResult(this, actualValue, _matches(actualValue));
5656+ }
5757+5858+ private bool _matches(object actualValue)
5959+ {
6060+ return actualValue is ITargetDescription desc && desc.Dependencies.Any(n => n.Equals(_dependency));
6161+ }
6262+ }
6663}
+565-565
PrexoniteTests/Tests/SelfAssemblingPlanTests.cs
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using System.Diagnostics;
2828-using System.IO;
2929-using System.Linq;
3030-using System.Text;
3131-using System.Threading;
3232-using JetBrains.Annotations;
3333-using NUnit.Framework;
3434-using Prexonite.Compiler.Build;
3535-using Prexonite.Compiler.Build.Internal;
3636-using Prexonite.Modular;
3737-3838-namespace PrexoniteTests.Tests
3939-{
4040- [TestFixture]
4141- public class SelfAssemblingPlanTests
4242- {
4343- protected static readonly TraceSource Trace = new TraceSource("PrexoniteTests.Tests.SelfAssemblingPlan");
4444-4545- private String _basePath;
4646-4747- protected ISelfAssemblingPlan Sam;
4848-4949- protected IDisposable MockFile(String path, String content)
5050- {
5151- var handle = new MockFileHandle(new FileInfo(Path.Combine(_basePath, path)), this);
5252- DirectoryInfo fileDir = handle.File.Directory;
5353- Debug.Assert(fileDir != null, "handle.File.Directory != null");
5454- fileDir.Create();
5555- using (var sw = new StreamWriter(handle.File.ToString(),false,Encoding.UTF8))
5656- {
5757- sw.Write(content);
5858- sw.Flush();
5959- sw.Close();
6060- }
6161- return handle;
6262- }
6363-6464- private class MockFileHandle : IDisposable
6565- {
6666- [NotNull]
6767- private readonly FileInfo _file;
6868- [NotNull]
6969- private readonly SelfAssemblingPlanTests _instance;
7070-7171- [NotNull]
7272- public FileInfo File
7373- {
7474- get { return _file; }
7575- }
7676-7777- [NotNull]
7878- public SelfAssemblingPlanTests Instance
7979- {
8080- get { return _instance; }
8181- }
8282-8383- public MockFileHandle([NotNull]FileInfo file, [NotNull]SelfAssemblingPlanTests instance)
8484- {
8585- _file = file;
8686- _instance = instance;
8787- }
8888-8989- public void Dispose()
9090- {
9191- GC.SuppressFinalize(this);
9292- Dispose(true);
9393- }
9494-9595- protected void Dispose(bool disposing)
9696- {
9797- if (disposing)
9898- {
9999-100100- }
101101- _tryDelete();
102102- }
103103-104104- private void _tryDelete()
105105- {
106106- try
107107- {
108108- _file.Delete();
109109- }
110110- catch (IOException e)
111111- {
112112- Trace.TraceEvent(TraceEventType.Error, 0, string.Format("Cannot delete file {0} because of {1}", _file, e));
113113- }
114114- }
115115-116116- ~MockFileHandle()
117117- {
118118- Dispose(false);
119119- }
120120- }
121121-122122- private String _prototypePath;
123123-124124- [TestFixtureSetUp]
125125- public void Init()
126126- {
127127- _prototypePath = Path.Combine(Path.GetTempPath(), "PrexoniteTests.SelfAssemblingPlanTests");
128128- }
129129-130130- [SetUp]
131131- public void Prepare()
132132- {
133133- _basePath = Path.Combine(_prototypePath, Guid.NewGuid().ToString("N"));
134134- if (Directory.Exists(_basePath))
135135- {
136136- Trace.TraceEvent(TraceEventType.Warning, 0,
137137- "Expected temporary directory at {0} not to exist. Using it anyway.", _basePath);
138138- }
139139- Sam = Plan.CreateSelfAssembling();
140140- Sam.SearchPaths.Add(_basePath);
141141- }
142142-143143- private void _tryTearDown()
144144- {
145145- try
146146- {
147147- Directory.Delete(_basePath, recursive: true);
148148- }
149149- catch (Exception e)
150150- {
151151- Trace.TraceEvent(TraceEventType.Error, 0, "Exception during tear down (deletion of temp dir): {0}", e);
152152- Console.WriteLine(e);
153153- }
154154- }
155155-156156- [TearDown]
157157- public void TearDown()
158158- {
159159- _tryTearDown();
160160- }
161161-162162- [TestFixtureTearDown]
163163- public void LastDitchEffort()
164164- {
165165- try
166166- {
167167- Directory.Delete(_prototypePath,recursive:true);
168168- }
169169- catch (Exception e)
170170- {
171171- Trace.TraceEvent(TraceEventType.Error, 0, "Exception during fixture tear down (last ditch effort, deletion of temp dir): {0}", e);
172172- Console.WriteLine(e);
173173- }
174174- }
175175-176176- [Test]
177177- public void EmptyInMemory()
178178- {
179179- var desc = Sam.AssembleAsync(Source.FromString(""), CancellationToken.None).Result;
180180- Assert.That(desc,Is.Not.Null);
181181- Assert.That(desc.BuildMessages,Is.Empty,"Should not have build (error) messages");
182182- }
183183-184184- [Test]
185185- public void Empty()
186186- {
187187- const string path = "empty.pxs";
188188- using (MockFile(path,""))
189189- {
190190- var desc = Sam.AssembleAsync(Source.FromFile(Path.Combine(_basePath,path),Encoding.UTF8), CancellationToken.None).Result;
191191- Assert.That(desc, Is.Not.Null);
192192- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
193193- }
194194- }
195195-196196- [Test]
197197- public void ExtractModuleNameInMemory()
198198- {
199199- var desc = Sam.AssembleAsync(Source.FromString("name the_module/5.4.3.2;"), CancellationToken.None).Result;
200200- Assert.That(desc, Is.Not.Null);
201201- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
202202- Assert.That(desc.Name,Is.EqualTo(new ModuleName("the_module",new Version(5,4,3,2))));
203203- }
204204-205205- [Test]
206206- public void ExtractModuleName()
207207- {
208208- const string path = "unrelated_name.pxs";
209209- using (MockFile(path,"name the_module/5.4.3.2;"))
210210- {
211211- var desc = Sam.AssembleAsync(Source.FromFile(Path.Combine(_basePath,path), Encoding.UTF8), CancellationToken.None).Result;
212212- Assert.That(desc, Is.Not.Null);
213213- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
214214- Assert.That(desc.Name, Is.EqualTo(new ModuleName("the_module", new Version(5, 4, 3, 2))));
215215- }
216216- }
217217-218218- [Test]
219219- public void SinglePathDependency()
220220- {
221221- const string path = "find_me.pxs";
222222- using (MockFile(path, "name the_module/5.4.3.2;"))
223223- {
224224- var desc = Sam.AssembleAsync(Source.FromString(@"
225225-name finder;
226226-references {
227227- ""./find_me.pxs""
228228-};
229229-"), CancellationToken.None).Result;
230230- Assert.That(desc, Is.Not.Null);
231231- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
232232- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0,0))));
233233- var theModuleName = new ModuleName("the_module", new Version(5, 4, 3, 2));
234234- Assert.That(desc.Dependencies.Count,Is.GreaterThanOrEqualTo(1),"Primary should have at least one dependency.");
235235- Assert.That(desc.Dependencies,Contains.Item(theModuleName),string.Format("Primary is expected to depend on {0}.", theModuleName));
236236- var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
237237- Assert.That(firstOrDefault,Is.Not.Null,string.Format("Expected a target description of {0} in SAM.", theModuleName));
238238- }
239239- }
240240-241241- [Test]
242242- public void SingleModuleNameDependency()
243243- {
244244- const string path = "found.pxs";
245245- using (MockFile(path, "name found;"))
246246- {
247247- var desc = Sam.AssembleAsync(Source.FromString(@"
248248-name finder;
249249-references {
250250- found
251251-};
252252-"), CancellationToken.None).Result;
253253- Assert.That(desc, Is.Not.Null);
254254- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
255255- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
256256- var theModuleName = new ModuleName("found", new Version(0,0));
257257- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
258258- Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
259259- var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
260260- Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
261261- }
262262- }
263263-264264- [Test]
265265- public void SingleModuleDottedNameDependency()
266266- {
267267- const string path = "hay/stack.pxs";
268268- using (MockFile(path, "name hay::stack;"))
269269- {
270270- var desc = Sam.AssembleAsync(Source.FromString(@"
271271-name finder;
272272-references {
273273- hay::stack
274274-};
275275-"), CancellationToken.None).Result;
276276- Assert.That(desc, Is.Not.Null);
277277- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
278278- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
279279- var theModuleName = new ModuleName("hay.stack", new Version(0, 0));
280280- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
281281- Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
282282- var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
283283- Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
284284- }
285285- }
286286-287287- [Test]
288288- public void DeeplyDottedModuleNameDependency()
289289- {
290290- const string path = "hay/stack/lazy/impl.pxs";
291291- using (MockFile(path, "name hay::stack::lazy::impl;"))
292292- {
293293- var desc = Sam.AssembleAsync(Source.FromString(@"
294294-name finder;
295295-references {
296296- hay::stack::lazy::impl
297297-};
298298-"), CancellationToken.None).Result;
299299- Assert.That(desc, Is.Not.Null);
300300- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
301301- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
302302- var theModuleName = new ModuleName("hay.stack.lazy.impl", new Version(0, 0));
303303- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
304304- Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
305305- var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
306306- Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
307307- }
308308- }
309309-310310-311311- [Test]
312312- public void CommonPrefixDottedModuleNameDependency()
313313- {
314314- const string path = "hay.stack/lazy/impl.pxs";
315315- using (MockFile(path, "name hay::stack::lazy::impl;"))
316316- {
317317- var desc = Sam.AssembleAsync(Source.FromString(@"
318318-name finder;
319319-references {
320320- hay::stack::lazy::impl
321321-};
322322-"), CancellationToken.None).Result;
323323- Assert.That(desc, Is.Not.Null);
324324- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
325325- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
326326- var theModuleName = new ModuleName("hay.stack.lazy.impl", new Version(0, 0));
327327- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
328328- Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
329329- var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
330330- Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
331331- }
332332- }
333333-334334- [Test]
335335- public void FlatDottedModuleNameDependency()
336336- {
337337- const string path = "hay.stack.lazy.impl.pxs";
338338- using (MockFile(path, "name hay::stack::lazy::impl;"))
339339- {
340340- var desc = Sam.AssembleAsync(Source.FromString(@"
341341-name finder;
342342-references {
343343- hay::stack::lazy::impl
344344-};
345345-"), CancellationToken.None).Result;
346346- Assert.That(desc, Is.Not.Null);
347347- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
348348- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
349349- var theModuleName = new ModuleName("hay.stack.lazy.impl", new Version(0, 0));
350350- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
351351- Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
352352- var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
353353- Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
354354- }
355355- }
356356-357357- [Test]
358358- public void DoubleModuleNameDependency()
359359- {
360360- const string pathFound = "found.pxs";
361361- const string pathLost = "lost.pxs";
362362- using (MockFile(pathFound, "name found;"))
363363- using (MockFile(pathLost,"name lost;"))
364364- {
365365- var desc =
366366- Sam.AssembleAsync(
367367- Source.FromString(@"name finder;references{found,lost};"), CancellationToken.None).Result;
368368- Assert.That(desc, Is.Not.Null);
369369- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
370370- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
371371-372372- // Does the primary module depend on lost and found?
373373- var foundModuleName = new ModuleName("found", new Version(0, 0));
374374- var lostModuleName = new ModuleName("lost", new Version(0, 0));
375375- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(2), "Primary should have at least two dependencies.");
376376- Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
377377- Assert.That(desc.Dependencies, Contains.Item(lostModuleName), string.Format("Primary is expected to depend on {0}.", lostModuleName));
378378-379379- // Does SAM contain the found module
380380- var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
381381- Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
382382-// ReSharper disable PossibleNullReferenceException
383383- Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
384384-// ReSharper restore PossibleNullReferenceException
385385-386386- // does SAM contain the lost module?
387387- var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
388388- Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
389389-// ReSharper disable PossibleNullReferenceException
390390- Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
391391-// ReSharper restore PossibleNullReferenceException
392392- }
393393- }
394394-395395- [Test]
396396- public void TransitiveDependency()
397397- {
398398- const string pathFound = "found.pxs";
399399- const string pathLost = "lost.pxs";
400400- using (MockFile(pathFound, "name found;references{lost}"))
401401- using (MockFile(pathLost, "name lost;"))
402402- {
403403- var desc =
404404- Sam.AssembleAsync(
405405- Source.FromString(@"name finder;references{found};"), CancellationToken.None).Result;
406406- Assert.That(desc, Is.Not.Null);
407407- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
408408- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
409409-410410- // Does the primary module depend on lost?
411411- var foundModuleName = new ModuleName("found", new Version(0, 0));
412412- var lostModuleName = new ModuleName("lost", new Version(0, 0));
413413- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
414414- Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
415415-416416- // Does SAM contain the found module?
417417- var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
418418- Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
419419- Debug.Assert(foundTarget != null);
420420-421421- // Does found depend on lost?
422422- // ReSharper disable PossibleNullReferenceException
423423- Assert.That(foundTarget.Dependencies, Contains.Item(lostModuleName), string.Format("{1} is expected to depend on {0}.", lostModuleName, foundModuleName));
424424- Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
425425-426426- // does SAM contain the lost module?
427427- var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
428428- Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
429429- Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
430430- // ReSharper restore PossibleNullReferenceException
431431- }
432432- }
433433-434434- [Test]
435435- public void RelativeDependency()
436436- {
437437- const string pathFound = "stack/found.pxs";
438438- const string pathLost = "stack/lost.pxs";
439439- using (MockFile(pathFound, "name found;references{lost}"))
440440- using (MockFile(pathLost, "name lost;"))
441441- {
442442- var emptyCount = Sam.TargetDescriptions.Count;
443443- var desc =
444444- Sam.AssembleAsync(
445445- Source.FromString(@"name finder;references{""./stack/found.pxs""};"), CancellationToken.None).Result;
446446- Assert.That(desc, Is.Not.Null);
447447- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
448448- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
449449-450450- // Does the primary module depend on lost and found?
451451- var foundModuleName = new ModuleName("found", new Version(0, 0));
452452- var lostModuleName = new ModuleName("lost", new Version(0, 0));
453453- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
454454- Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
455455-456456- // Does SAM contain the found module
457457- var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
458458- Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
459459- // ReSharper disable PossibleNullReferenceException
460460- Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
461461- // ReSharper restore PossibleNullReferenceException
462462- Assert.That(foundTarget.Dependencies, Contains.Item(lostModuleName), string.Format("found module expected to depend on {0}.", lostModuleName));
463463-464464- // does SAM contain the lost module?
465465- var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
466466- Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
467467- // ReSharper disable PossibleNullReferenceException
468468- Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
469469- // ReSharper restore PossibleNullReferenceException
470470-471471- Assert.That(Sam.TargetDescriptions.Count,Is.EqualTo(emptyCount+3), "There should be exactly three new modules: finder, lost and found.");
472472- }
473473- }
474474-475475- [Test]
476476- public void FindProvided()
477477- {
478478- const string pathFound = "found.pxs";
479479- const string pathLost = "lost.pxs";
480480-481481- // Provide the module lost to the SAM ahead of time, fully resolved
482482- var lostModuleName = new ModuleName("lost", new Version(0, 0));
483483- Sam.TargetDescriptions.Add(new ManualTargetDescription(lostModuleName, Source.FromString("name: lost;"),
484484- pathLost, Enumerable.Empty<ModuleName>()));
485485-486486- // Have module found short-circuit when resolving lost
487487- using (MockFile(pathFound, "name found;references{lost}"))
488488- {
489489- var desc =
490490- Sam.AssembleAsync(
491491- Source.FromString(@"name finder;references{found};"), CancellationToken.None).Result;
492492- Assert.That(desc, Is.Not.Null);
493493- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
494494- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
495495-496496- // Does the primary module depend on lost?
497497- var foundModuleName = new ModuleName("found", new Version(0, 0));
498498-499499- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
500500- Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
501501-502502- // Does SAM contain the found module?
503503- var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
504504- Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
505505- Debug.Assert(foundTarget != null);
506506-507507- // Does found depend on lost?
508508- // ReSharper disable PossibleNullReferenceException
509509- Assert.That(foundTarget.Dependencies, Contains.Item(lostModuleName), string.Format("{1} is expected to depend on {0}.", lostModuleName, foundModuleName));
510510- Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
511511-512512- // does SAM contain the lost module?
513513- var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
514514- Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
515515- Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
516516- // ReSharper restore PossibleNullReferenceException
517517- }
518518- }
519519-520520- [Test]
521521- public void DiamondDependency()
522522- {
523523- const string pathFound = "found.pxs";
524524- const string pathLost = "lost.pxs";
525525- const string pathBase = "base.pxs";
526526- using (MockFile(pathFound, "name found;references{base}"))
527527- using (MockFile(pathLost, "name lost;references{base}"))
528528- using(MockFile(pathBase,"name base;"))
529529- {
530530- var desc =
531531- Sam.AssembleAsync(
532532- Source.FromString(@"name finder;references{lost,found};"), CancellationToken.None).Result;
533533- Assert.That(desc, Is.Not.Null);
534534- Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
535535- Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
536536-537537- // Does the primary module depend on lost and found?
538538- var foundModuleName = new ModuleName("found", new Version(0, 0));
539539- var lostModuleName = new ModuleName("lost", new Version(0, 0));
540540- var baseModuelName = new ModuleName("base", new Version(0, 0));
541541- Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
542542- Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
543543- Assert.That(desc.Dependencies, Contains.Item(lostModuleName), string.Format("Primary is expected to depend on {0}.", lostModuleName));
544544-545545- // Does SAM contain the found module?
546546- var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
547547- Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
548548- Debug.Assert(foundTarget != null);
549549-550550- // Does found depend on base?
551551- // ReSharper disable PossibleNullReferenceException
552552- Assert.That(foundTarget.Dependencies, Contains.Item(baseModuelName), string.Format("{1} is expected to depend on {0}.", baseModuelName, foundModuleName));
553553- Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
554554-555555- // does SAM contain the lost module?
556556- var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
557557- Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
558558- Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
559559- // ReSharper restore PossibleNullReferenceException
560560-561561- Assert.That(lostTarget.Dependencies, Contains.Item(baseModuelName), string.Format("{1} is expected to depend on {0}.", baseModuelName, lostTarget));
562562- Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostTarget));
563563- }
564564- }
565565- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using System.Diagnostics;
2828+using System.IO;
2929+using System.Linq;
3030+using System.Text;
3131+using System.Threading;
3232+using JetBrains.Annotations;
3333+using NUnit.Framework;
3434+using Prexonite.Compiler.Build;
3535+using Prexonite.Compiler.Build.Internal;
3636+using Prexonite.Modular;
3737+3838+namespace PrexoniteTests.Tests
3939+{
4040+ [TestFixture]
4141+ public class SelfAssemblingPlanTests
4242+ {
4343+ protected static readonly TraceSource Trace = new TraceSource("PrexoniteTests.Tests.SelfAssemblingPlan");
4444+4545+ private String _basePath;
4646+4747+ protected ISelfAssemblingPlan Sam;
4848+4949+ protected IDisposable MockFile(String path, String content)
5050+ {
5151+ var handle = new MockFileHandle(new FileInfo(Path.Combine(_basePath, path)), this);
5252+ DirectoryInfo fileDir = handle.File.Directory;
5353+ Debug.Assert(fileDir != null, "handle.File.Directory != null");
5454+ fileDir.Create();
5555+ using (var sw = new StreamWriter(handle.File.ToString(),false,Encoding.UTF8))
5656+ {
5757+ sw.Write(content);
5858+ sw.Flush();
5959+ sw.Close();
6060+ }
6161+ return handle;
6262+ }
6363+6464+ private class MockFileHandle : IDisposable
6565+ {
6666+ [NotNull]
6767+ private readonly FileInfo _file;
6868+ [NotNull]
6969+ private readonly SelfAssemblingPlanTests _instance;
7070+7171+ [NotNull]
7272+ public FileInfo File
7373+ {
7474+ get { return _file; }
7575+ }
7676+7777+ [NotNull]
7878+ public SelfAssemblingPlanTests Instance
7979+ {
8080+ get { return _instance; }
8181+ }
8282+8383+ public MockFileHandle([NotNull]FileInfo file, [NotNull]SelfAssemblingPlanTests instance)
8484+ {
8585+ _file = file;
8686+ _instance = instance;
8787+ }
8888+8989+ public void Dispose()
9090+ {
9191+ GC.SuppressFinalize(this);
9292+ Dispose(true);
9393+ }
9494+9595+ protected void Dispose(bool disposing)
9696+ {
9797+ if (disposing)
9898+ {
9999+100100+ }
101101+ _tryDelete();
102102+ }
103103+104104+ private void _tryDelete()
105105+ {
106106+ try
107107+ {
108108+ _file.Delete();
109109+ }
110110+ catch (IOException e)
111111+ {
112112+ Trace.TraceEvent(TraceEventType.Error, 0, string.Format("Cannot delete file {0} because of {1}", _file, e));
113113+ }
114114+ }
115115+116116+ ~MockFileHandle()
117117+ {
118118+ Dispose(false);
119119+ }
120120+ }
121121+122122+ private String _prototypePath;
123123+124124+ [OneTimeSetUp]
125125+ public void Init()
126126+ {
127127+ _prototypePath = Path.Combine(Path.GetTempPath(), "PrexoniteTests.SelfAssemblingPlanTests");
128128+ }
129129+130130+ [SetUp]
131131+ public void Prepare()
132132+ {
133133+ _basePath = Path.Combine(_prototypePath, Guid.NewGuid().ToString("N"));
134134+ if (Directory.Exists(_basePath))
135135+ {
136136+ Trace.TraceEvent(TraceEventType.Warning, 0,
137137+ "Expected temporary directory at {0} not to exist. Using it anyway.", _basePath);
138138+ }
139139+ Sam = Plan.CreateSelfAssembling();
140140+ Sam.SearchPaths.Add(_basePath);
141141+ }
142142+143143+ private void _tryTearDown()
144144+ {
145145+ try
146146+ {
147147+ Directory.Delete(_basePath, recursive: true);
148148+ }
149149+ catch (Exception e)
150150+ {
151151+ Trace.TraceEvent(TraceEventType.Error, 0, "Exception during tear down (deletion of temp dir): {0}", e);
152152+ Console.WriteLine(e);
153153+ }
154154+ }
155155+156156+ [TearDown]
157157+ public void TearDown()
158158+ {
159159+ _tryTearDown();
160160+ }
161161+162162+ [OneTimeTearDown]
163163+ public void LastDitchEffort()
164164+ {
165165+ try
166166+ {
167167+ Directory.Delete(_prototypePath,recursive:true);
168168+ }
169169+ catch (Exception e)
170170+ {
171171+ Trace.TraceEvent(TraceEventType.Error, 0, "Exception during fixture tear down (last ditch effort, deletion of temp dir): {0}", e);
172172+ Console.WriteLine(e);
173173+ }
174174+ }
175175+176176+ [Test]
177177+ public void EmptyInMemory()
178178+ {
179179+ var desc = Sam.AssembleAsync(Source.FromString(""), CancellationToken.None).Result;
180180+ Assert.That(desc,Is.Not.Null);
181181+ Assert.That(desc.BuildMessages,Is.Empty,"Should not have build (error) messages");
182182+ }
183183+184184+ [Test]
185185+ public void Empty()
186186+ {
187187+ const string path = "empty.pxs";
188188+ using (MockFile(path,""))
189189+ {
190190+ var desc = Sam.AssembleAsync(Source.FromFile(Path.Combine(_basePath,path),Encoding.UTF8), CancellationToken.None).Result;
191191+ Assert.That(desc, Is.Not.Null);
192192+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
193193+ }
194194+ }
195195+196196+ [Test]
197197+ public void ExtractModuleNameInMemory()
198198+ {
199199+ var desc = Sam.AssembleAsync(Source.FromString("name the_module/5.4.3.2;"), CancellationToken.None).Result;
200200+ Assert.That(desc, Is.Not.Null);
201201+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
202202+ Assert.That(desc.Name,Is.EqualTo(new ModuleName("the_module",new Version(5,4,3,2))));
203203+ }
204204+205205+ [Test]
206206+ public void ExtractModuleName()
207207+ {
208208+ const string path = "unrelated_name.pxs";
209209+ using (MockFile(path,"name the_module/5.4.3.2;"))
210210+ {
211211+ var desc = Sam.AssembleAsync(Source.FromFile(Path.Combine(_basePath,path), Encoding.UTF8), CancellationToken.None).Result;
212212+ Assert.That(desc, Is.Not.Null);
213213+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
214214+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("the_module", new Version(5, 4, 3, 2))));
215215+ }
216216+ }
217217+218218+ [Test]
219219+ public void SinglePathDependency()
220220+ {
221221+ const string path = "find_me.pxs";
222222+ using (MockFile(path, "name the_module/5.4.3.2;"))
223223+ {
224224+ var desc = Sam.AssembleAsync(Source.FromString(@"
225225+name finder;
226226+references {
227227+ ""./find_me.pxs""
228228+};
229229+"), CancellationToken.None).Result;
230230+ Assert.That(desc, Is.Not.Null);
231231+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
232232+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0,0))));
233233+ var theModuleName = new ModuleName("the_module", new Version(5, 4, 3, 2));
234234+ Assert.That(desc.Dependencies.Count,Is.GreaterThanOrEqualTo(1),"Primary should have at least one dependency.");
235235+ Assert.That(desc.Dependencies,Contains.Item(theModuleName),string.Format("Primary is expected to depend on {0}.", theModuleName));
236236+ var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
237237+ Assert.That(firstOrDefault,Is.Not.Null,string.Format("Expected a target description of {0} in SAM.", theModuleName));
238238+ }
239239+ }
240240+241241+ [Test]
242242+ public void SingleModuleNameDependency()
243243+ {
244244+ const string path = "found.pxs";
245245+ using (MockFile(path, "name found;"))
246246+ {
247247+ var desc = Sam.AssembleAsync(Source.FromString(@"
248248+name finder;
249249+references {
250250+ found
251251+};
252252+"), CancellationToken.None).Result;
253253+ Assert.That(desc, Is.Not.Null);
254254+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
255255+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
256256+ var theModuleName = new ModuleName("found", new Version(0,0));
257257+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
258258+ Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
259259+ var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
260260+ Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
261261+ }
262262+ }
263263+264264+ [Test]
265265+ public void SingleModuleDottedNameDependency()
266266+ {
267267+ const string path = "hay/stack.pxs";
268268+ using (MockFile(path, "name hay::stack;"))
269269+ {
270270+ var desc = Sam.AssembleAsync(Source.FromString(@"
271271+name finder;
272272+references {
273273+ hay::stack
274274+};
275275+"), CancellationToken.None).Result;
276276+ Assert.That(desc, Is.Not.Null);
277277+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
278278+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
279279+ var theModuleName = new ModuleName("hay.stack", new Version(0, 0));
280280+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
281281+ Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
282282+ var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
283283+ Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
284284+ }
285285+ }
286286+287287+ [Test]
288288+ public void DeeplyDottedModuleNameDependency()
289289+ {
290290+ const string path = "hay/stack/lazy/impl.pxs";
291291+ using (MockFile(path, "name hay::stack::lazy::impl;"))
292292+ {
293293+ var desc = Sam.AssembleAsync(Source.FromString(@"
294294+name finder;
295295+references {
296296+ hay::stack::lazy::impl
297297+};
298298+"), CancellationToken.None).Result;
299299+ Assert.That(desc, Is.Not.Null);
300300+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
301301+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
302302+ var theModuleName = new ModuleName("hay.stack.lazy.impl", new Version(0, 0));
303303+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
304304+ Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
305305+ var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
306306+ Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
307307+ }
308308+ }
309309+310310+311311+ [Test]
312312+ public void CommonPrefixDottedModuleNameDependency()
313313+ {
314314+ const string path = "hay.stack/lazy/impl.pxs";
315315+ using (MockFile(path, "name hay::stack::lazy::impl;"))
316316+ {
317317+ var desc = Sam.AssembleAsync(Source.FromString(@"
318318+name finder;
319319+references {
320320+ hay::stack::lazy::impl
321321+};
322322+"), CancellationToken.None).Result;
323323+ Assert.That(desc, Is.Not.Null);
324324+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
325325+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
326326+ var theModuleName = new ModuleName("hay.stack.lazy.impl", new Version(0, 0));
327327+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
328328+ Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
329329+ var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
330330+ Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
331331+ }
332332+ }
333333+334334+ [Test]
335335+ public void FlatDottedModuleNameDependency()
336336+ {
337337+ const string path = "hay.stack.lazy.impl.pxs";
338338+ using (MockFile(path, "name hay::stack::lazy::impl;"))
339339+ {
340340+ var desc = Sam.AssembleAsync(Source.FromString(@"
341341+name finder;
342342+references {
343343+ hay::stack::lazy::impl
344344+};
345345+"), CancellationToken.None).Result;
346346+ Assert.That(desc, Is.Not.Null);
347347+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
348348+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
349349+ var theModuleName = new ModuleName("hay.stack.lazy.impl", new Version(0, 0));
350350+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
351351+ Assert.That(desc.Dependencies, Contains.Item(theModuleName), string.Format("Primary is expected to depend on {0}.", theModuleName));
352352+ var firstOrDefault = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(theModuleName));
353353+ Assert.That(firstOrDefault, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", theModuleName));
354354+ }
355355+ }
356356+357357+ [Test]
358358+ public void DoubleModuleNameDependency()
359359+ {
360360+ const string pathFound = "found.pxs";
361361+ const string pathLost = "lost.pxs";
362362+ using (MockFile(pathFound, "name found;"))
363363+ using (MockFile(pathLost,"name lost;"))
364364+ {
365365+ var desc =
366366+ Sam.AssembleAsync(
367367+ Source.FromString(@"name finder;references{found,lost};"), CancellationToken.None).Result;
368368+ Assert.That(desc, Is.Not.Null);
369369+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
370370+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
371371+372372+ // Does the primary module depend on lost and found?
373373+ var foundModuleName = new ModuleName("found", new Version(0, 0));
374374+ var lostModuleName = new ModuleName("lost", new Version(0, 0));
375375+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(2), "Primary should have at least two dependencies.");
376376+ Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
377377+ Assert.That(desc.Dependencies, Contains.Item(lostModuleName), string.Format("Primary is expected to depend on {0}.", lostModuleName));
378378+379379+ // Does SAM contain the found module
380380+ var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
381381+ Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
382382+// ReSharper disable PossibleNullReferenceException
383383+ Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
384384+// ReSharper restore PossibleNullReferenceException
385385+386386+ // does SAM contain the lost module?
387387+ var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
388388+ Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
389389+// ReSharper disable PossibleNullReferenceException
390390+ Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
391391+// ReSharper restore PossibleNullReferenceException
392392+ }
393393+ }
394394+395395+ [Test]
396396+ public void TransitiveDependency()
397397+ {
398398+ const string pathFound = "found.pxs";
399399+ const string pathLost = "lost.pxs";
400400+ using (MockFile(pathFound, "name found;references{lost}"))
401401+ using (MockFile(pathLost, "name lost;"))
402402+ {
403403+ var desc =
404404+ Sam.AssembleAsync(
405405+ Source.FromString(@"name finder;references{found};"), CancellationToken.None).Result;
406406+ Assert.That(desc, Is.Not.Null);
407407+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
408408+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
409409+410410+ // Does the primary module depend on lost?
411411+ var foundModuleName = new ModuleName("found", new Version(0, 0));
412412+ var lostModuleName = new ModuleName("lost", new Version(0, 0));
413413+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
414414+ Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
415415+416416+ // Does SAM contain the found module?
417417+ var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
418418+ Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
419419+ Debug.Assert(foundTarget != null);
420420+421421+ // Does found depend on lost?
422422+ // ReSharper disable PossibleNullReferenceException
423423+ Assert.That(foundTarget.Dependencies, Contains.Item(lostModuleName), string.Format("{1} is expected to depend on {0}.", lostModuleName, foundModuleName));
424424+ Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
425425+426426+ // does SAM contain the lost module?
427427+ var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
428428+ Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
429429+ Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
430430+ // ReSharper restore PossibleNullReferenceException
431431+ }
432432+ }
433433+434434+ [Test]
435435+ public void RelativeDependency()
436436+ {
437437+ const string pathFound = "stack/found.pxs";
438438+ const string pathLost = "stack/lost.pxs";
439439+ using (MockFile(pathFound, "name found;references{lost}"))
440440+ using (MockFile(pathLost, "name lost;"))
441441+ {
442442+ var emptyCount = Sam.TargetDescriptions.Count;
443443+ var desc =
444444+ Sam.AssembleAsync(
445445+ Source.FromString(@"name finder;references{""./stack/found.pxs""};"), CancellationToken.None).Result;
446446+ Assert.That(desc, Is.Not.Null);
447447+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
448448+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
449449+450450+ // Does the primary module depend on lost and found?
451451+ var foundModuleName = new ModuleName("found", new Version(0, 0));
452452+ var lostModuleName = new ModuleName("lost", new Version(0, 0));
453453+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
454454+ Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
455455+456456+ // Does SAM contain the found module
457457+ var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
458458+ Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
459459+ // ReSharper disable PossibleNullReferenceException
460460+ Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
461461+ // ReSharper restore PossibleNullReferenceException
462462+ Assert.That(foundTarget.Dependencies, Contains.Item(lostModuleName), string.Format("found module expected to depend on {0}.", lostModuleName));
463463+464464+ // does SAM contain the lost module?
465465+ var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
466466+ Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
467467+ // ReSharper disable PossibleNullReferenceException
468468+ Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
469469+ // ReSharper restore PossibleNullReferenceException
470470+471471+ Assert.That(Sam.TargetDescriptions.Count,Is.EqualTo(emptyCount+3), "There should be exactly three new modules: finder, lost and found.");
472472+ }
473473+ }
474474+475475+ [Test]
476476+ public void FindProvided()
477477+ {
478478+ const string pathFound = "found.pxs";
479479+ const string pathLost = "lost.pxs";
480480+481481+ // Provide the module lost to the SAM ahead of time, fully resolved
482482+ var lostModuleName = new ModuleName("lost", new Version(0, 0));
483483+ Sam.TargetDescriptions.Add(new ManualTargetDescription(lostModuleName, Source.FromString("name: lost;"),
484484+ pathLost, Enumerable.Empty<ModuleName>()));
485485+486486+ // Have module found short-circuit when resolving lost
487487+ using (MockFile(pathFound, "name found;references{lost}"))
488488+ {
489489+ var desc =
490490+ Sam.AssembleAsync(
491491+ Source.FromString(@"name finder;references{found};"), CancellationToken.None).Result;
492492+ Assert.That(desc, Is.Not.Null);
493493+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
494494+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
495495+496496+ // Does the primary module depend on lost?
497497+ var foundModuleName = new ModuleName("found", new Version(0, 0));
498498+499499+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
500500+ Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
501501+502502+ // Does SAM contain the found module?
503503+ var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
504504+ Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
505505+ Debug.Assert(foundTarget != null);
506506+507507+ // Does found depend on lost?
508508+ // ReSharper disable PossibleNullReferenceException
509509+ Assert.That(foundTarget.Dependencies, Contains.Item(lostModuleName), string.Format("{1} is expected to depend on {0}.", lostModuleName, foundModuleName));
510510+ Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
511511+512512+ // does SAM contain the lost module?
513513+ var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
514514+ Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
515515+ Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
516516+ // ReSharper restore PossibleNullReferenceException
517517+ }
518518+ }
519519+520520+ [Test]
521521+ public void DiamondDependency()
522522+ {
523523+ const string pathFound = "found.pxs";
524524+ const string pathLost = "lost.pxs";
525525+ const string pathBase = "base.pxs";
526526+ using (MockFile(pathFound, "name found;references{base}"))
527527+ using (MockFile(pathLost, "name lost;references{base}"))
528528+ using(MockFile(pathBase,"name base;"))
529529+ {
530530+ var desc =
531531+ Sam.AssembleAsync(
532532+ Source.FromString(@"name finder;references{lost,found};"), CancellationToken.None).Result;
533533+ Assert.That(desc, Is.Not.Null);
534534+ Assert.That(desc.BuildMessages, Is.Empty, "Should not have build (error) messages");
535535+ Assert.That(desc.Name, Is.EqualTo(new ModuleName("finder", new Version(0, 0))));
536536+537537+ // Does the primary module depend on lost and found?
538538+ var foundModuleName = new ModuleName("found", new Version(0, 0));
539539+ var lostModuleName = new ModuleName("lost", new Version(0, 0));
540540+ var baseModuelName = new ModuleName("base", new Version(0, 0));
541541+ Assert.That(desc.Dependencies.Count, Is.GreaterThanOrEqualTo(1), "Primary should have at least one dependency.");
542542+ Assert.That(desc.Dependencies, Contains.Item(foundModuleName), string.Format("Primary is expected to depend on {0}.", foundModuleName));
543543+ Assert.That(desc.Dependencies, Contains.Item(lostModuleName), string.Format("Primary is expected to depend on {0}.", lostModuleName));
544544+545545+ // Does SAM contain the found module?
546546+ var foundTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(foundModuleName));
547547+ Assert.That(foundTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", foundModuleName));
548548+ Debug.Assert(foundTarget != null);
549549+550550+ // Does found depend on base?
551551+ // ReSharper disable PossibleNullReferenceException
552552+ Assert.That(foundTarget.Dependencies, Contains.Item(baseModuelName), string.Format("{1} is expected to depend on {0}.", baseModuelName, foundModuleName));
553553+ Assert.That(foundTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", foundModuleName));
554554+555555+ // does SAM contain the lost module?
556556+ var lostTarget = Sam.TargetDescriptions.FirstOrDefault(td => td.Name.Equals(lostModuleName));
557557+ Assert.That(lostTarget, Is.Not.Null, string.Format("Expected a target description of {0} in SAM.", lostModuleName));
558558+ Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostModuleName));
559559+ // ReSharper restore PossibleNullReferenceException
560560+561561+ Assert.That(lostTarget.Dependencies, Contains.Item(baseModuelName), string.Format("{1} is expected to depend on {0}.", baseModuelName, lostTarget));
562562+ Assert.That(lostTarget.BuildMessages, Is.Empty, string.Format("{0} should not have build (error) messages", lostTarget));
563563+ }
564564+ }
565565+ }
566566}
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using System.Collections.Generic;
2828-using System.IO;
2929-using System.Linq;
3030-using JetBrains.Annotations;
3131-using Moq;
3232-using NUnit.Framework;
3333-using Prexonite;
3434-using Prexonite.Commands;
3535-using Prexonite.Compiler;
3636-using Prexonite.Compiler.Ast;
3737-using Prexonite.Compiler.Build;
3838-using Prexonite.Compiler.Symbolic;
3939-using Prexonite.Modular;
4040-using Prexonite.Types;
4141-4242-namespace PrexoniteTests.Tests
4343-{
4444- public class Translation : VMTestsBase
4545- {
4646- [Test]
4747- public void SimpleSwitchMetaEntry()
4848- {
4949- Compile(
5050- @"
5151-globalSwitch;
5252-is gloS;
5353-is not gloS2;
5454-not glos3;
5555-5656-function main()[loc]
5757-{
5858-5959-}
6060-6161-function main2 [loc2;
6262-loc3;
6363-not loc4]
6464-{
6565-}
6666-6767-");
6868-6969- var main = target.Functions["main"];
7070- var main2 = target.Functions["main2"];
7171-7272- //Global entries
7373- Assert.That(target, Meta.ContainsExact("globalSwitch", true));
7474- Assert.That(target, Meta.ContainsExact("gloS", true));
7575- Assert.That(target, Meta.ContainsExact("gloS2", false));
7676- Assert.That(target, Meta.ContainsExact("glos3", false));
7777-7878- //First function
7979- Assert.That(main, Is.Not.Null);
8080- Assert.That(main, Meta.ContainsExact("loc", true));
8181-8282- //Second function
8383- Assert.That(main2, Is.Not.Null);
8484- Assert.That(main2, Meta.ContainsExact("loc2", true));
8585- Assert.That(main2, Meta.ContainsExact("loc3", true));
8686- Assert.That(main2, Meta.ContainsExact("loc4", false));
8787- }
8888-8989- [Test]
9090- public void TrailingCommaMetaList()
9191- {
9292- Compile(@"
9393-glob {1,2,3,};
9494-9595-function main [loc {1,2,3,}]
9696-{}
9797-9898-");
9999-100100- var entry = new MetaEntry(new MetaEntry[] {"1", "2", "3"});
101101-102102- Assert.That(target, Meta.Contains("glob", entry));
103103- var main = target.Functions["main"];
104104-105105- Assert.That(main, Is.Not.Null);
106106- Assert.That(main, Meta.Contains("loc", entry));
107107- }
108108-109109- [Test]
110110- public void TrailingCommaListLiteral()
111111- {
112112- Compile(@"
113113-function main = [1,2,3,];
114114-");
115115-116116- Expect(new List<PValue> {1, 2, 3});
117117- }
118118-119119- [Test]
120120- public void TrailingCommaHashLiteral()
121121- {
122122- Compile(
123123- @"
124124-function main(ks,vs)
125125-{
126126- var h = {1: ""a"", 2: ""b"", 3: ""c"",};
127127- var r = """";
128128- for(var i = 0; i < ks.Count; i++)
129129- if(h.ContainsKey(ks[i]) and h[ks[i]] == vs[i])
130130- r += ""1"";
131131- else
132132- r += ""0"";
133133- return r;
134134-}
135135-");
136136-137137- Expect("110101", (PValue) new List<PValue> {1, 2, 4, 3, 2, 1},
138138- (PValue) new List<PValue> {"a", "b", "d", "c", "a", "a"});
139139- }
140140-141141- [Test]
142142- public void TrailingArgumentList()
143143- {
144144- Compile(
145145- @"
146146-function f(a,b,) = a + 2*b;
147147-function main(x,y)
148148-{
149149- return f(x,y,);
150150-}
151151-");
152152-153153- Expect(2 + 6, 2, 3);
154154- }
155155-156156- [Test]
157157- public void SuppressSymbols()
158158- {
159159- var ldr =
160160- Compile(
161161- @"
162162-function g = 5;
163163-var f = 7;
164164-165165-var g[\sps] = 3;
166166-167167-function f as p(x) [\sps]
168168-{
169169- declare var g;
170170- return g*x;
171171-}
172172-173173-// At this point, we should have
174174-// g -> function g
175175-// f -> variable f
176176-// p -> function f
177177-178178-function main(x)
179179-{
180180- var f' = f;
181181-182182- declare function f;
183183- return g + f' + f(x);
184184-}
185185-");
186186-187187- Expect(3*2 + 5 + 7, 2);
188188- Expect(3*11 + 5 + 7, 11);
189189-190190- var mn = ldr.ParentApplication.Module.Name;
191191-192192- {
193193- Assert.That(ldr.TopLevelSymbols.Contains("f"), Is.True,
194194- "Symbol table must contain an entry for 'f'.");
195195- var entry = LookupSymbolEntry(ldr.TopLevelSymbols,"f");
196196- Assert.That(entry,Is.InstanceOf<DereferenceSymbol>());
197197- var deref = (DereferenceSymbol) entry;
198198- Assert.That(deref.InnerSymbol,Is.InstanceOf<ReferenceSymbol>());
199199- var refSym = (ReferenceSymbol) deref.InnerSymbol;
200200- Assert.That(refSym.Entity,Is.InstanceOf<EntityRef.Variable.Global>());
201201- EntityRef.Variable.Global globVar;
202202- refSym.Entity.TryGetGlobalVariable(out globVar);
203203- Assert.That(globVar,Is.EqualTo(EntityRef.Variable.Global.Create("f",mn)));
204204- }
205205-206206- {
207207- Assert.That(ldr.TopLevelSymbols.Contains("g"), Is.True,
208208- "Symbol table must contain an entry for 'g'.");
209209- var entry = LookupSymbolEntry(ldr.TopLevelSymbols, "g");
210210- Assert.That(entry, Is.InstanceOf<DereferenceSymbol>());
211211- var deref = (DereferenceSymbol)entry;
212212- Assert.That(deref.InnerSymbol, Is.InstanceOf<ReferenceSymbol>());
213213- var refSym = (ReferenceSymbol)deref.InnerSymbol;
214214- Assert.That(refSym.Entity, Is.InstanceOf<EntityRef.Function>());
215215- EntityRef.Function func;
216216- refSym.Entity.TryGetFunction(out func);
217217- Assert.That(func, Is.EqualTo(EntityRef.Function.Create("g",mn)));
218218- }
219219-220220- {
221221- Assert.That(ldr.TopLevelSymbols.Contains("p"), Is.True,
222222- "Symbol table must contain an entry for 'p'.");
223223- var entry = LookupSymbolEntry(ldr.TopLevelSymbols, "p");
224224- Assert.That(entry, Is.InstanceOf<DereferenceSymbol>());
225225- var deref = (DereferenceSymbol)entry;
226226- Assert.That(deref.InnerSymbol, Is.InstanceOf<ReferenceSymbol>());
227227- var refSym = (ReferenceSymbol)deref.InnerSymbol;
228228- Assert.That(refSym.Entity, Is.InstanceOf<EntityRef.Function>());
229229- EntityRef.Function func;
230230- refSym.Entity.TryGetFunction(out func);
231231- Assert.That(func, Is.EqualTo(EntityRef.Function.Create("f",mn)));
232232- }
233233- }
234234-235235- [Test]
236236- public void AppendRightLocalFunc()
237237- {
238238- Compile(@"
239239-function main()
240240-{
241241- var ys = [];
242242- coroutine trace(t,xs)
243243- {
244244- foreach(var x in xs)
245245- {
246246- ys[] = t:x;
247247- yield x;
248248- }
249249- }
250250- ([1,2]) >> trace(33) >> all >> println;
251251- return (var args >> trace(77) >> map(?~String) >> foldl((l,r) => l + "" "" + r, """")) + ys;
252252-}
253253-");
254254- Expect(" 1 2 3 4 5 6 7[ 33: 1, 33: 2, 77: 1, 77: 2, 77: 3, 77: 4, 77: 5, 77: 6, 77: 7 ]",1,2,3,4,5,6,7);
255255- }
256256-257257- [Test]
258258- public void TestPsrTestRunSingleTest()
259259- {
260260- Compile(@"function test\run_single_test as run_single_test(testFunc)
261261-{
262262- var t = new Structure;
263263- t.\(""test"") = testFunc;
264264- try
265265- {
266266- testFunc.();
267267- return true: t;
268268- }
269269- catch(var e)
270270- {
271271- t.\(""e"") = e;
272272- return false: t;
273273- }
274274-}
275275-276276-function main()
277277-{
278278- var tp = run_single_test(() => 15);
279279- return ""$(tp.Key):$(tp.Value.test.Id)"";
280280-}");
281281-282282- Expect("True:main\\0");
283283- }
284284-285285- [Test]
286286- public void TestPsrAst3WithPos()
287287- {
288288- Compile(@"
289289-function ast3\withPos(factory,type) [compiler]
290290-{
291291- var args;
292292- var targs = args >> skip(2);
293293-294294- if(factory is null)
295295- throw ""AST factory cannot be null."";
296296-297297- return call\member(factory,type, targs);
298298-}");
299299- var factory = new Mock<IAstFactory>(MockBehavior.Strict);
300300- var astPlaceholder = new AstPlaceholder(NoSourcePosition.MissingFileName, NoSourcePosition.Instance.Line, NoSourcePosition.Instance.Column);
301301- factory.Setup(f => f.Placeholder(It.IsAny<ISourcePosition>(), 5))
302302- .Returns(astPlaceholder);
303303- ExpectNamed("ast3\\withPos", astPlaceholder, sctx.CreateNativePValue(factory.Object), "Placeholder", sctx.CreateNativePValue(NoSourcePosition.Instance), 5);
304304- }
305305-306306- [Test]
307307- public void TestSysDeclaresMacroCommand()
308308- {
309309- Compile(@"//PRX
310310-311311-Name sys;
312312-313313-declare(
314314- print = ref command ""print"",
315315- println = ref command ""println"",
316316- meta = ref command ""meta"",
317317- boxed = ref command ""boxed"",
318318- concat = ref command ""concat"",
319319- map = ref command ""map"",
320320- select = ref command ""select"",
321321- foldl = ref command ""foldl"",
322322- foldr = ref command ""foldr"",
323323- dispose = ref command ""dispose"",
324324- call = expand macro command ""call"",
325325- call\perform = ref command ""call\\perform"",
326326- thunk = ref command ""thunk"",
327327- asthunk = ref command ""asthunk"",
328328- force = ref command ""force"",
329329- toseq = ref command ""toseq"",
330330- call\member = expand macro command ""call\\member"",
331331- call\member\perform = ref command ""call\\member\\perform"",
332332- caller = ref command ""caller"",
333333- pair = ref command ""pair"",
334334- unbind = ref command ""unbind"",
335335- sort = ref command ""sort"",
336336- orderby = ref command ""orderby"",
337337- LoadAssembly = ref command ""LoadAssembly"",
338338- debug = ref command ""debug"",
339339- setcenter = ref command ""setcenter"",
340340- setleft = ref command ""setleft"",
341341- setright = ref command ""setright"",
342342- all = ref command ""all"",
343343- where = ref command ""where"",
344344- skip = ref command ""skip"",
345345- limit = ref command ""limit"",
346346- take = ref command ""take"",
347347- abs = ref command ""abs"",
348348- ceiling = ref command ""ceiling"",
349349- exp = ref command ""exp"",
350350- floor = ref command ""floor"",
351351- log = ref command ""log"",
352352- max = ref command ""max"",
353353- min = ref command ""min"",
354354- pi = ref command ""pi"",
355355- round = ref command ""round"",
356356- sin = ref command ""sin"",
357357- cos = ref command ""cos"",
358358- sqrt = ref command ""sqrt"",
359359- tan = ref command ""tan"",
360360- char = ref command ""char"",
361361- count = ref command ""count"",
362362- distinct = ref command ""distinct"",
363363- union = ref command ""union"",
364364- unique = ref command ""unique"",
365365- frequency = ref command ""frequency"",
366366- groupby = ref command ""groupby"",
367367- intersect = ref command ""intersect"",
368368- call\tail = expand macro command ""call\\tail"",
369369- call\tail\perform = ref command ""call\\tail\\perform"",
370370- list = ref command ""list"",
371371- each = ref command ""each"",
372372- exists = ref command ""exists"",
373373- forall = ref command ""forall"",
374374- CompileToCil = ref command ""CompileToCil"",
375375- takewhile = ref command ""takewhile"",
376376- except = ref command ""except"",
377377- range = ref command ""range"",
378378- reverse = ref command ""reverse"",
379379- headtail = ref command ""headtail"",
380380- append = ref command ""append"",
381381- sum = ref command ""sum"",
382382- contains = ref command ""contains"",
383383- chan = ref command ""chan"",
384384- call\async = expand macro command ""call\\async"",
385385- call\async\perform = ref command ""call\\async\\perform"",
386386- async_seq = ref command ""async_seq"",
387387- call\sub\perform = ref command ""call\\sub\\perform"",
388388- pa\ind = ref command ""pa\\ind"",
389389- pa\mem = ref command ""pa\\mem"",
390390- pa\ctor = ref command ""pa\\ctor"",
391391- pa\check = ref command ""pa\\check"",
392392- pa\cast = ref command ""pa\\cast"",
393393- pa\smem = ref command ""pa\\smem"",
394394- pa\fun\call = ref command ""pa\\fun\\call"",
395395- pa\flip\call = ref command ""pa\\flip\\call"",
396396- pa\call\star = ref command ""pa\\call\\star"",
397397- then = ref command ""then"",
398398- id = ref command ""id"",
399399- const = ref command ""const"",
400400- (+) = ref command ""plus"",
401401- (-) = ref command ""minus"",
402402- (*) = ref command ""times"",
403403- (/) = ref command ""dividedBy"",
404404- $mod = ref command ""mod"",
405405- (^) = ref command ""raisedTo"",
406406- (&) = ref command ""bitwiseAnd"",
407407- (|) = ref command ""bitwiseOr"",
408408- $xor = ref command ""xor"",
409409- (==) = ref command ""isEqualTo"",
410410- (!=) = ref command ""isInequalTo"",
411411- (>) = ref command ""isGreaterThan"",
412412- (>=) = ref command ""isGreaterThanOrEqual"",
413413- (<) = ref command ""isLessThan"",
414414- (<=) = ref command ""isLessThanOrEqual"",
415415- (-.) = ref command ""negation"",
416416- $complement = ref command ""complement"",
417417- $not = ref command ""not"",
418418- create_enumerator = ref command ""create_enumerator"",
419419- create_module_name = ref command ""create_module_name"",
420420- seqconcat = ref command ""seqconcat"",
421421- call\sub = expand macro command ""call\\sub"",
422422- call\sub\interpret = expand macro command ""call\\sub\\interpret"",
423423- macro\pack = expand macro command ""macro\\pack"",
424424- macro\unpack = expand macro command ""macro\\unpack"",
425425- macro\reference = expand macro command ""macro\\reference"",
426426- call\star = expand macro command ""call\\star"",
427427- call\macro = expand macro command ""call\\macro"",
428428- call\macro\impl = expand macro command ""call\\macro\\impl"",
429429- main = ref function(""main"",""testApplication"",0.0),
430430-);
431431-432432-function main(x,y)
433433-{
434434- return call\member(x,y);
435435-}
436436-");
437437-438438- var x = new Mock<ISourcePosition>(MockBehavior.Strict);
439439- x.SetupGet(s => s.Line).Returns(15);
440440- Expect(15,sctx.CreateNativePValue(x.Object),"Line");
441441- }
442442-443443- [Test]
444444- public void BlockDeclarationOfMacroCommand()
445445- {
446446- Compile(@"
447447-declare macro command call\member;
448448-449449-function main(x,y)
450450-{
451451- return call\member(x,y);
452452-}
453453-");
454454- var x = new Mock<ISourcePosition>(MockBehavior.Strict);
455455- x.SetupGet(s => s.Line).Returns(15);
456456- Expect(15, sctx.CreateNativePValue(x.Object), "Line");
457457- }
458458-459459- [Test]
460460- public void ReferenceToSymbolWithMessage()
461461- {
462462- var ldr = Compile(@"
463463-function t1 = 7;
464464-ref t2 = ->t1;
465465-declare(
466466- t3 = warn(pos(""Translation.cs.pxs"",434,5),""T.tt"",""Hooder"", sym ""t2"")
467467-);
468468-469469-function main()
470470-{
471471- return ->t1 == ->t3;
472472-}
473473-");
474474-475475- Expect(true);
476476- Assert.That(ldr.Warnings.Count,Is.EqualTo(1));
477477- Assert.That(ldr.Warnings[0].MessageClass,Is.EqualTo("T.tt"));
478478- }
479479-480480- [Test]
481481- public void EntityRefToCommand()
482482- {
483483- var ldr = Compile(@"
484484-function f{}
485485-var v;
486486-ref r;
487487-macro m{}
488488-489489-function main()
490490-{
491491- var loc;
492492- ref rloc;
493493- var sep = ""|"";
494494- return """" + entityref_to(f) + sep
495495- + entityref_to(v) + sep
496496- + entityref_to(->r) + sep
497497- + entityref_to(m) + sep
498498- + entityref_to(loc) + sep
499499- + entityref_to(->rloc) + sep
500500- + entityref_to(entityref_to) + sep
501501- + entityref_to(print);
502502-}
503503-");
504504- var nm = ldr.ParentApplication.Module.Name;
505505-506506- Expect(rv =>
507507- {
508508- var r = rv.CallToString(sctx).Split('|');
509509- Console.WriteLine(rv);
510510- Assert.That(r.Length,Is.EqualTo(8),"Expected return value to consist of 8 elements. Returned {0}",rv);
511511-512512- Assert.That(r[0],Is.EqualTo(EntityRef.Function.Create("f",nm).ToString()));
513513- Assert.That(r[1], Is.EqualTo(EntityRef.Variable.Global.Create("v", nm).ToString()));
514514- Assert.That(r[2], Is.EqualTo(EntityRef.Variable.Global.Create("r", nm).ToString()));
515515- Assert.That(r[3], Is.EqualTo(EntityRef.Function.Create("m", nm).ToString()));
516516- Assert.That(r[4], Is.EqualTo(EntityRef.Variable.Local.Create("loc").ToString()));
517517- Assert.That(r[5], Is.EqualTo(EntityRef.Variable.Local.Create("rloc").ToString()));
518518- Assert.That(r[6], Is.EqualTo(EntityRef.MacroCommand.Create("entityref_to").ToString()));
519519- Assert.That(r[7], Is.EqualTo(EntityRef.Command.Create("print").ToString()));
520520- });
521521- }
522522-523523- [Test]
524524- public void NamespaceLookup()
525525- {
526526- var ldr = new Loader(options);
527527- Compile(ldr, @"
528528-function f = 17;
529529-");
530530- Symbol f;
531531- if(!ldr.TopLevelSymbols.TryGet("f",out f))
532532- Assert.Fail("Expected module level symbol f to exist.");
533533-534534- var scopea = SymbolStore.Create();
535535- scopea.Declare("g",f);
536536- var nsa = new MergedNamespace(scopea);
537537- var a = Symbol.CreateNamespace(nsa, NoSourcePosition.Instance);
538538- ldr.TopLevelSymbols.Declare("a",a);
539539-540540- Compile(ldr, @"
541541-function main()
542542-{
543543- return a.g;
544544-}
545545-");
546546-547547- Expect(17);
548548- }
549549-550550- [Test]
551551- public void NestedNamespaceLookup()
552552- {
553553-554554- var ldr = new Loader(options);
555555- Compile(ldr, @"
556556-function f = 17;
557557-");
558558- Symbol f;
559559- if (!ldr.TopLevelSymbols.TryGet("f", out f))
560560- Assert.Fail("Expected module level symbol f to exist.");
561561-562562- var scopea = SymbolStore.Create();
563563- scopea.Declare("g", f);
564564- var nsa = new MergedNamespace(scopea);
565565- var a = Symbol.CreateNamespace(nsa, NoSourcePosition.Instance);
566566-567567- var scopeb = SymbolStore.Create();
568568- scopeb.Declare("a",a);
569569- var nsb = new MergedNamespace(scopeb);
570570- var b = Symbol.CreateNamespace(nsb, NoSourcePosition.Instance);
571571-572572- ldr.TopLevelSymbols.Declare("b",b);
573573-574574- Compile(ldr, @"
575575-function main()
576576-{
577577- return b.a.g;
578578-}
579579-");
580580-581581- Expect(17);
582582- }
583583-584584- [Test]
585585- public void AliasedNamespaceLookup()
586586- {
587587-588588- var ldr = new Loader(options);
589589- Compile(ldr, @"
590590-function f = 17;
591591-");
592592- Symbol f;
593593- if (!ldr.TopLevelSymbols.TryGet("f", out f))
594594- Assert.Fail("Expected module level symbol f to exist.");
595595-596596- var scopea = SymbolStore.Create();
597597- scopea.Declare("g", f);
598598- var nsa = new MergedNamespace(scopea);
599599- var a = Symbol.CreateNamespace(nsa, NoSourcePosition.Instance);
600600-601601- var scopeb = SymbolStore.Create();
602602- scopeb.Declare("a", a);
603603- var nsb = new MergedNamespace(scopeb);
604604- var b = Symbol.CreateNamespace(nsb, NoSourcePosition.Instance);
605605-606606- ldr.TopLevelSymbols.Declare("b", b);
607607-608608- Compile(ldr, @"
609609-declare(z = sym(""b"",""a""));
610610-function main()
611611-{
612612- return z.g;
613613-}
614614-");
615615-616616- Expect(17);
617617- }
618618-619619- [Test]
620620- public void NamespaceDeclaration()
621621- {
622622- var ldr = Compile(@"
623623-namespace a
624624-{
625625- function f = 17;
626626-}
627627-628628-function main = a.f;
629629-");
630630- Expect(17);
631631- Symbol dummy;
632632- Assert.That(ldr.TopLevelSymbols.TryGet("f",out dummy),Is.False,"Existence of symbol f in the global scope");
633633- }
634634-635635- [Test]
636636- public void SugaredNestedNamespaceDeclaration()
637637- {
638638-639639- Compile(@"
640640-namespace a.b
641641-{
642642- function f = 17;
643643-}
644644-645645-function main = a.b.f;
646646-");
647647- Expect(17);
648648- }
649649-650650- [Test]
651651- public void NestedNamespaceDeclaration()
652652- {
653653-654654- Compile(@"
655655-namespace a
656656-{
657657- namespace b
658658- {
659659- function f = 17;
660660- }
661661-}
662662-663663-function main = a.b.f;
664664-");
665665- Expect(17);
666666- }
667667-668668- [Test]
669669- public void TopLevelAccessFromNamespace()
670670- {
671671-672672- Compile(@"
673673-function f = 17;
674674-675675-namespace a
676676-{
677677- function g = f;
678678-}
679679-680680-function main = a.g;
681681-");
682682- Expect(17);
683683- }
684684-685685- [Test]
686686- public void SurroundingAccessFromNamespace()
687687- {
688688-689689- Compile(@"
690690-namespace a
691691-{
692692- function f = 17;
693693- namespace b
694694- {
695695- function g = f;
696696- }
697697-}
698698-699699-function main = a.b.g;
700700-");
701701- Expect(17);
702702- }
703703-704704- [Test]
705705- public void Surrounding2AccessFromNamespace()
706706- {
707707-708708- Compile(@"
709709-namespace a
710710-{
711711- function f = 17;
712712- namespace b
713713- {
714714- namespace c
715715- {
716716- function g = f;
717717- }
718718- }
719719-}
720720-721721-function main = a.b.c.g;
722722-");
723723- Expect(17);
724724- }
725725-726726- [Test]
727727- public void SugarComposeNamespaces()
728728- {
729729- Compile(@"
730730-namespace a.b
731731-{
732732- function f = 17;
733733-}
734734-735735-namespace a.c
736736-{
737737- function g = 3;
738738-}
739739-740740-function main = a.b.f + a.c.g;
741741-");
742742- Expect(20);
743743- }
744744-745745- [Test]
746746- public void SugarNsOverride()
747747- {
748748- CompileInvalid(@"
749749-namespace a
750750-{
751751- function b = 13;
752752-}
753753-754754-namespace a.b
755755-{
756756- function f = 17;
757757-}
758758-759759-function main = a.b.f;
760760-","Expected","namespace","func");
761761- }
762762-763763- [Test]
764764- public void DontReExportSurrounding()
765765- {
766766- CompileInvalid(@"
767767-function f = 13;
768768-namespace a
769769-{
770770- function g = 15;
771771-}
772772-773773-function main = a.f;
774774-","symbol","resolve","f");
775775-776776- }
777777-778778- [Test]
779779- public void RestoreExportedOnExtend()
780780- {
781781- Compile(@"
782782-namespace a {
783783- function f = 13;
784784-}
785785-786786-namespace a {
787787- function g = f+2;
788788-}
789789-790790-function main = a.g;
791791-");
792792-793793- Expect(13+2);
794794- }
795795-796796- [Test]
797797- public void SuppressRestoreExportedOnExtend()
798798- {
799799- CompileInvalid(@"
800800-namespace a {
801801- function zz_f = 13;
802802-}
803803-804804-namespace a
805805- import()
806806-{
807807- function g = zz_f+2;
808808-}
809809-810810-function main = a.g;
811811-","symbol","resolve","zz_f");
812812- }
813813-814814- [Test]
815815- public void SimpleNsSugarExtend()
816816- {
817817- Compile(@"
818818-namespace a.c
819819-{
820820- function f = 17;
821821-}
822822-823823-namespace a
824824-{
825825- namespace c
826826- {
827827- function g = 2;
828828- }
829829-}
830830-831831-function main = a.c.f + a.c.g;
832832-");
833833- Expect(17+2);
834834- }
835835-836836- [Test]
837837- public void SugarNsExtend()
838838- {
839839- Compile(@"
840840-namespace a
841841-{
842842- function b = 13;
843843-}
844844-845845-namespace a.c
846846-{
847847- function f = 17;
848848-}
849849-850850-namespace a
851851-{
852852- function d = 10;
853853-}
854854-855855-namespace a
856856-{
857857- namespace c
858858- {
859859- function g = 2;
860860- }
861861-}
862862-863863-function main = a.b + a.c.f + a.d + a.c.g;
864864-");
865865-866866- Expect(13 + 17 + 10 + 2);
867867- }
868868-869869- [Test]
870870- public void NsPhysical()
871871- {
872872- SkipStore = true;
873873-874874- Compile(@"
875875-namespace a
876876-{
877877- function f = 3;
878878-}
879879-880880-namespace b
881881-{
882882- function f = 14;
883883-}
884884-885885-function main = a.f + b.f;
886886-");
887887-888888- Expect(17);
889889- }
890890-891891- [Test]
892892- public void ImportBackgroundConflict()
893893- {
894894- Compile(@"
895895-namespace a {
896896- function f = 13;
897897- function g = 12;
898898- function x = 3;
899899-}
900900-901901-namespace b {
902902- var g = 19;
903903- declare(f = absolute sym(""a"",""f""));
904904- function y = 4;
905905-}
906906-907907-namespace c
908908- import a.*, b.*
909909-{
910910- function s = f + x + y;
911911-}
912912-913913-function main = c.s;
914914-");
915915-916916- Expect(4+3+13);
917917- }
918918-919919- [Test]
920920- public void ImportConflict()
921921- {
922922- CompileInvalid(@"
923923-namespace a
924924-{
925925- function f = 13;
926926-}
927927-928928-namespace b
929929-{
930930- var f = 14;
931931-}
932932-933933-namespace c
934934- import a.*, b.*
935935-{
936936- function s = f;
937937-}
938938-939939-function main = c.s;
940940-","incompatible","namespace a","namespace b","symbol f");
941941- }
942942-943943- [Test]
944944- public void RenameOneAvoidsConflict()
945945- {
946946- Compile(@"
947947-namespace a
948948-{
949949- function f = 13;
950950-}
951951-952952-namespace b
953953-{
954954- var f = 14;
955955-}
956956-957957-namespace c
958958- import a.*, b(f => z)
959959-{
960960- function s = f + z;
961961-}
962962-963963-function main = c.s;
964964-");
965965- Expect(13+14);
966966- }
967967-968968- [Test]
969969- public void UseMultiplicationAsNamespaceName()
970970- {
971971- Compile(@"
972972-namespace a.(*).c {
973973- function f = 3;
974974-}
975975-976976-namespace b
977977- import a.(*).c.f
978978-{
979979- function g = f;
980980-}
981981-982982-function main = b.g;
983983-");
984984- Expect(3);
985985- }
986986-987987- [Test]
988988- public void UseMultiplicationInExplicitTransfer()
989989- {
990990- Compile(@"
991991-namespace a {
992992- function (*) = 3;
993993- var gobb = 4;
994994-}
995995-996996-namespace z {
997997- function gobb = 5;
998998-}
999999-10001000-namespace b
10011001- import a((*)), z(*) // should import only (*) from a, everything from z
10021002-{
10031003- function g = (*) + gobb;
10041004-}
10051005-10061006-function main = b.g;
10071007-");
10081008- }
10091009-10101010- [Test]
10111011- public void ExplicitWildcardTransfer()
10121012- {
10131013- Compile(@"
10141014-namespace a { function f = 13; }
10151015-namespace b import a(*)
10161016-{ function g = f; }
10171017-function main = b.g;
10181018-");
10191019-10201020- Expect(13);
10211021- }
10221022-10231023- [Test]
10241024- public void DropAvoidsConflict()
10251025- {
10261026- Compile(@"
10271027-namespace a
10281028-{
10291029- function f = 13;
10301030-}
10311031-10321032-namespace b
10331033-{
10341034- var f = 14;
10351035- function g = 12;
10361036-}
10371037-10381038-namespace c
10391039- import
10401040- a.*,
10411041- b(*, not f)
10421042-{
10431043- function s = f + g;
10441044-}
10451045-10461046-function main = c.s;
10471047-");
10481048- Expect(13 + 12);
10491049- }
10501050-10511051- [Test]
10521052- public void FunctionScopeImport()
10531053- {
10541054- Compile(@"
10551055-namespace a
10561056-{
10571057- function f = 13;
10581058-}
10591059-10601060-function main namespace import a.f = f;
10611061-");
10621062- Expect(13);
10631063- }
10641064-10651065- [Test]
10661066- public void ForwardDeclarationAncientSyntax()
10671067- {
10681068- Compile(@"
10691069-namespace a
10701070-{
10711071- declare function f;
10721072- function g(x) = f(x);
10731073- function f(x) = 2*x;
10741074-}
10751075-10761076-function main(x) = a.g(x);
10771077-");
10781078-10791079- Expect(16,8);
10801080- }
10811081-10821082- [Test]
10831083- public void ForwardDeclarationOldSyntax()
10841084- {
10851085- Compile(@"
10861086-namespace a
10871087-{
10881088- declare { function: f };
10891089- function g(x) = f(x);
10901090- function f(x) = 2*x;
10911091-}
10921092-10931093-function main(x) = a.g(x);
10941094-");
10951095-10961096- Expect(16,8);
10971097- }
10981098-10991099- [Test]
11001100- public void ForwardDeclarationMachineSyntax()
11011101- {
11021102- Compile(@"
11031103-namespace a
11041104-{
11051105- // This forward declaration is not taken as relative to the namesapce.
11061106- // It is intended for machine consumption.
11071107- declare( f = ref function(""f"",""testApplication"",0.0));
11081108- function g(x) = f(x);
11091109-}
11101110-11111111-function f(x) = 2*x;
11121112-11131113-function main(x) = a.g(x);
11141114-");
11151115-11161116- Expect(16, 8);
11171117- }
11181118-11191119- [Test]
11201120- public void ExportInterferenceWithTimesLiteral()
11211121- {
11221122- Compile(@"
11231123-namespace a{var g;}
11241124-namespace b{}export(*),a(g);
11251125-");
11261126- }
11271127-11281128- [Test]
11291129- public void AlternateExportAllSyntax()
11301130- {
11311131- Compile(@"
11321132-namespace a{var g;}
11331133-namespace b{}export.*,a(g);
11341134-");
11351135- }
11361136-11371137- [Test]
11381138- public void SelfReferenceInVarInit()
11391139- {
11401140- Compile(@"
11411141-namespace a
11421142-{
11431143- var h = 4;
11441144-}
11451145-namespace a{
11461146- var g = g ?? 15;
11471147- var h = h ?? 3;
11481148-}
11491149-11501150-function main = a.g+a.h;
11511151-");
11521152- Expect(15+4);
11531153- }
11541154-11551155- [Test]
11561156- public void NamespaceExtensionCrossModule()
11571157- {
11581158- var plan = Plan.CreateSelfAssembling(StandardLibraryPreference.None);
11591159-11601160- plan.Assemble(Source.FromString(@"
11611161-name one;
11621162-namespace a {
11631163- function b = 15;
11641164-}
11651165-"));
11661166-11671167- var moduleTwoDesc = plan.Assemble(Source.FromString(@"
11681168-name two;
11691169-references {one};
11701170-namespace a {
11711171- function c =7;
11721172-}
11731173-"));
11741174-11751175- var moduleTwo = plan.Build(moduleTwoDesc.Name);
11761176- Assert.That(moduleTwo.Messages.Where(m => m.Severity == MessageSeverity.Error),Is.Empty,"Modules should compile without any error messages.");
11771177- foreach (var message in moduleTwo.Messages)
11781178- Console.WriteLine(message);
11791179- Assert.That(moduleTwo.Exception,Is.Null);
11801180-11811181- var symbols = moduleTwo.Symbols;
11821182- Symbol symbol;
11831183- Assert.That(symbols.TryGet("a",out symbol),Is.True,"Expect module two to have a symbol called 'a'");
11841184- Assert.That(symbol,Is.InstanceOf<NamespaceSymbol>());
11851185- var nsSym = (NamespaceSymbol) symbol;
11861186- _assumeNotNull(nsSym);
11871187- Assert.That(nsSym.Namespace.TryGet("b",out symbol),"Expect namespace a to contain a symbol b.");
11881188- Assert.That(nsSym.Namespace.TryGet("c",out symbol),"Expect namespace a to contain a symbol c.");
11891189-11901190- }
11911191-11921192- [Test]
11931193- public void CommentAtEnd()
11941194- {
11951195- var ldr = new Loader(options);
11961196- var add = new InternalLoadCommand(ldr);
11971197- ldr.ParentEngine.Commands.AddHostCommand("add_internal", add);
11981198- add.VirtualFiles.Add("f1",@"
11991199-function f1() {
12001200- println(""f1 called"");
12011201- // something
12021202- return 15;
12031203-}
12041204-12051205-//s");
12061206- Compile(ldr, @"
12071207-declare command add_internal;
12081208-12091209-function f0() {
12101210- println(""f0 called"");
12111211- /* something else */
12121212- return 16;
12131213-}
12141214-12151215-build does add_internal(""f1"");
12161216-12171217-function main() {
12181218- return f0 + f1;
12191219-}
12201220-");
12211221-12221222- Expect(15+16);
12231223- }
12241224-12251225- [ContractAnnotation("value:null=>halt")]
12261226- private static void _assumeNotNull(object value)
12271227- {
12281228- Assert.That(value,Is.Not.Null);
12291229- }
12301230-12311231- /// <summary>
12321232- /// A command that works in a fashion very similar to the add and requires commands
12331233- /// that a loader exposes in build blocks.
12341234- /// Needs to be initialized first.
12351235- /// </summary>
12361236- private class InternalLoadCommand : PCommand
12371237- {
12381238- [NotNull]
12391239- private readonly Dictionary<string, string> _virtualFiles = new Dictionary<string, string>();
12401240- [NotNull]
12411241- private readonly Loader _loaderReference;
12421242-12431243- public InternalLoadCommand([NotNull] Loader loaderReference)
12441244- {
12451245- _loaderReference = loaderReference;
12461246- }
12471247-12481248- public Dictionary<string, string> VirtualFiles
12491249- {
12501250- get { return _virtualFiles; }
12511251- }
12521252-12531253- public override PValue Run(StackContext sctx, PValue[] args)
12541254- {
12551255- var n = args[0].CallToString(sctx);
12561256- var virtualFile = _virtualFiles[n];
12571257- using(var cr = new StringReader(virtualFile))
12581258- _loaderReference.LoadFromReader(cr,n);
12591259- return PType.Null;
12601260- }
12611261- }
12621262- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using System.Collections.Generic;
2828+using System.IO;
2929+using System.Linq;
3030+using JetBrains.Annotations;
3131+using Moq;
3232+using NUnit.Framework;
3333+using Prexonite;
3434+using Prexonite.Commands;
3535+using Prexonite.Compiler;
3636+using Prexonite.Compiler.Ast;
3737+using Prexonite.Compiler.Build;
3838+using Prexonite.Compiler.Symbolic;
3939+using Prexonite.Modular;
4040+using Prexonite.Types;
4141+4242+namespace PrexoniteTests.Tests
4343+{
4444+ public class Translation : VMTestsBase
4545+ {
4646+ [Test]
4747+ public void SimpleSwitchMetaEntry()
4848+ {
4949+ Compile(
5050+ @"
5151+globalSwitch;
5252+is gloS;
5353+is not gloS2;
5454+not glos3;
5555+5656+function main()[loc]
5757+{
5858+5959+}
6060+6161+function main2 [loc2;
6262+loc3;
6363+not loc4]
6464+{
6565+}
6666+6767+");
6868+6969+ var main = target.Functions["main"];
7070+ var main2 = target.Functions["main2"];
7171+7272+ //Global entries
7373+ Assert.That(target, Meta.ContainsExact("globalSwitch", true));
7474+ Assert.That(target, Meta.ContainsExact("gloS", true));
7575+ Assert.That(target, Meta.ContainsExact("gloS2", false));
7676+ Assert.That(target, Meta.ContainsExact("glos3", false));
7777+7878+ //First function
7979+ Assert.That(main, Is.Not.Null);
8080+ Assert.That(main, Meta.ContainsExact("loc", true));
8181+8282+ //Second function
8383+ Assert.That(main2, Is.Not.Null);
8484+ Assert.That(main2, Meta.ContainsExact("loc2", true));
8585+ Assert.That(main2, Meta.ContainsExact("loc3", true));
8686+ Assert.That(main2, Meta.ContainsExact("loc4", false));
8787+ }
8888+8989+ [Test]
9090+ public void TrailingCommaMetaList()
9191+ {
9292+ Compile(@"
9393+glob {1,2,3,};
9494+9595+function main [loc {1,2,3,}]
9696+{}
9797+9898+");
9999+100100+ var entry = new MetaEntry(new MetaEntry[] {"1", "2", "3"});
101101+102102+ Assert.That(target, Meta.Contains("glob", entry));
103103+ var main = target.Functions["main"];
104104+105105+ Assert.That(main, Is.Not.Null);
106106+ Assert.That(main, Meta.Contains("loc", entry));
107107+ }
108108+109109+ [Test]
110110+ public void TrailingCommaListLiteral()
111111+ {
112112+ Compile(@"
113113+function main = [1,2,3,];
114114+");
115115+116116+ Expect(new List<PValue> {1, 2, 3});
117117+ }
118118+119119+ [Test]
120120+ public void TrailingCommaHashLiteral()
121121+ {
122122+ Compile(
123123+ @"
124124+function main(ks,vs)
125125+{
126126+ var h = {1: ""a"", 2: ""b"", 3: ""c"",};
127127+ var r = """";
128128+ for(var i = 0; i < ks.Count; i++)
129129+ if(h.ContainsKey(ks[i]) and h[ks[i]] == vs[i])
130130+ r += ""1"";
131131+ else
132132+ r += ""0"";
133133+ return r;
134134+}
135135+");
136136+137137+ Expect("110101", (PValue) new List<PValue> {1, 2, 4, 3, 2, 1},
138138+ (PValue) new List<PValue> {"a", "b", "d", "c", "a", "a"});
139139+ }
140140+141141+ [Test]
142142+ public void TrailingArgumentList()
143143+ {
144144+ Compile(
145145+ @"
146146+function f(a,b,) = a + 2*b;
147147+function main(x,y)
148148+{
149149+ return f(x,y,);
150150+}
151151+");
152152+153153+ Expect(2 + 6, 2, 3);
154154+ }
155155+156156+ [Test]
157157+ public void SuppressSymbols()
158158+ {
159159+ var ldr =
160160+ Compile(
161161+ @"
162162+function g = 5;
163163+var f = 7;
164164+165165+var g[\sps] = 3;
166166+167167+function f as p(x) [\sps]
168168+{
169169+ declare var g;
170170+ return g*x;
171171+}
172172+173173+// At this point, we should have
174174+// g -> function g
175175+// f -> variable f
176176+// p -> function f
177177+178178+function main(x)
179179+{
180180+ var f' = f;
181181+182182+ declare function f;
183183+ return g + f' + f(x);
184184+}
185185+");
186186+187187+ Expect(3*2 + 5 + 7, 2);
188188+ Expect(3*11 + 5 + 7, 11);
189189+190190+ var mn = ldr.ParentApplication.Module.Name;
191191+192192+ {
193193+ Assert.That(ldr.TopLevelSymbols.Contains("f"), Is.True,
194194+ "Symbol table must contain an entry for 'f'.");
195195+ var entry = LookupSymbolEntry(ldr.TopLevelSymbols,"f");
196196+ Assert.That(entry,Is.InstanceOf<DereferenceSymbol>());
197197+ var deref = (DereferenceSymbol) entry;
198198+ Assert.That(deref.InnerSymbol,Is.InstanceOf<ReferenceSymbol>());
199199+ var refSym = (ReferenceSymbol) deref.InnerSymbol;
200200+ Assert.That(refSym.Entity,Is.InstanceOf<EntityRef.Variable.Global>());
201201+ EntityRef.Variable.Global globVar;
202202+ refSym.Entity.TryGetGlobalVariable(out globVar);
203203+ Assert.That(globVar,Is.EqualTo(EntityRef.Variable.Global.Create("f",mn)));
204204+ }
205205+206206+ {
207207+ Assert.That(ldr.TopLevelSymbols.Contains("g"), Is.True,
208208+ "Symbol table must contain an entry for 'g'.");
209209+ var entry = LookupSymbolEntry(ldr.TopLevelSymbols, "g");
210210+ Assert.That(entry, Is.InstanceOf<DereferenceSymbol>());
211211+ var deref = (DereferenceSymbol)entry;
212212+ Assert.That(deref.InnerSymbol, Is.InstanceOf<ReferenceSymbol>());
213213+ var refSym = (ReferenceSymbol)deref.InnerSymbol;
214214+ Assert.That(refSym.Entity, Is.InstanceOf<EntityRef.Function>());
215215+ refSym.Entity.TryGetFunction(out var func);
216216+ Assert.That(func, Is.EqualTo(EntityRef.Function.Create("g",mn)));
217217+ }
218218+219219+ {
220220+ Assert.That(ldr.TopLevelSymbols.Contains("p"), Is.True,
221221+ "Symbol table must contain an entry for 'p'.");
222222+ var entry = LookupSymbolEntry(ldr.TopLevelSymbols, "p");
223223+ Assert.That(entry, Is.InstanceOf<DereferenceSymbol>());
224224+ var deref = (DereferenceSymbol)entry;
225225+ Assert.That(deref.InnerSymbol, Is.InstanceOf<ReferenceSymbol>());
226226+ var refSym = (ReferenceSymbol)deref.InnerSymbol;
227227+ Assert.That(refSym.Entity, Is.InstanceOf<EntityRef.Function>());
228228+ refSym.Entity.TryGetFunction(out var func);
229229+ Assert.That(func, Is.EqualTo(EntityRef.Function.Create("f",mn)));
230230+ }
231231+ }
232232+233233+ [Test]
234234+ public void AppendRightLocalFunc()
235235+ {
236236+ Compile(@"
237237+function main()
238238+{
239239+ var ys = [];
240240+ coroutine trace(t,xs)
241241+ {
242242+ foreach(var x in xs)
243243+ {
244244+ ys[] = t:x;
245245+ yield x;
246246+ }
247247+ }
248248+ ([1,2]) >> trace(33) >> all >> println;
249249+ return (var args >> trace(77) >> map(?~String) >> foldl((l,r) => l + "" "" + r, """")) + ys;
250250+}
251251+");
252252+ Expect(" 1 2 3 4 5 6 7[ 33: 1, 33: 2, 77: 1, 77: 2, 77: 3, 77: 4, 77: 5, 77: 6, 77: 7 ]",1,2,3,4,5,6,7);
253253+ }
254254+255255+ [Test]
256256+ public void TestPsrTestRunSingleTest()
257257+ {
258258+ Compile(@"function test\run_single_test as run_single_test(testFunc)
259259+{
260260+ var t = new Structure;
261261+ t.\(""test"") = testFunc;
262262+ try
263263+ {
264264+ testFunc.();
265265+ return true: t;
266266+ }
267267+ catch(var e)
268268+ {
269269+ t.\(""e"") = e;
270270+ return false: t;
271271+ }
272272+}
273273+274274+function main()
275275+{
276276+ var tp = run_single_test(() => 15);
277277+ return ""$(tp.Key):$(tp.Value.test.Id)"";
278278+}");
279279+280280+ Expect("True:main\\0");
281281+ }
282282+283283+ [Test]
284284+ public void TestPsrAst3WithPos()
285285+ {
286286+ Compile(@"
287287+function ast3\withPos(factory,type) [compiler]
288288+{
289289+ var args;
290290+ var targs = args >> skip(2);
291291+292292+ if(factory is null)
293293+ throw ""AST factory cannot be null."";
294294+295295+ return call\member(factory,type, targs);
296296+}");
297297+ var factory = new Mock<IAstFactory>(MockBehavior.Strict);
298298+ var astPlaceholder = new AstPlaceholder(NoSourcePosition.MissingFileName, NoSourcePosition.Instance.Line, NoSourcePosition.Instance.Column);
299299+ factory.Setup(f => f.Placeholder(It.IsAny<ISourcePosition>(), 5))
300300+ .Returns(astPlaceholder);
301301+ ExpectNamed("ast3\\withPos", astPlaceholder, sctx.CreateNativePValue(factory.Object), "Placeholder", sctx.CreateNativePValue(NoSourcePosition.Instance), 5);
302302+ }
303303+304304+ [Test]
305305+ public void TestSysDeclaresMacroCommand()
306306+ {
307307+ Compile(@"//PRX
308308+309309+Name sys;
310310+311311+declare(
312312+ print = ref command ""print"",
313313+ println = ref command ""println"",
314314+ meta = ref command ""meta"",
315315+ boxed = ref command ""boxed"",
316316+ concat = ref command ""concat"",
317317+ map = ref command ""map"",
318318+ select = ref command ""select"",
319319+ foldl = ref command ""foldl"",
320320+ foldr = ref command ""foldr"",
321321+ dispose = ref command ""dispose"",
322322+ call = expand macro command ""call"",
323323+ call\perform = ref command ""call\\perform"",
324324+ thunk = ref command ""thunk"",
325325+ asthunk = ref command ""asthunk"",
326326+ force = ref command ""force"",
327327+ toseq = ref command ""toseq"",
328328+ call\member = expand macro command ""call\\member"",
329329+ call\member\perform = ref command ""call\\member\\perform"",
330330+ caller = ref command ""caller"",
331331+ pair = ref command ""pair"",
332332+ unbind = ref command ""unbind"",
333333+ sort = ref command ""sort"",
334334+ orderby = ref command ""orderby"",
335335+ LoadAssembly = ref command ""LoadAssembly"",
336336+ debug = ref command ""debug"",
337337+ setcenter = ref command ""setcenter"",
338338+ setleft = ref command ""setleft"",
339339+ setright = ref command ""setright"",
340340+ all = ref command ""all"",
341341+ where = ref command ""where"",
342342+ skip = ref command ""skip"",
343343+ limit = ref command ""limit"",
344344+ take = ref command ""take"",
345345+ abs = ref command ""abs"",
346346+ ceiling = ref command ""ceiling"",
347347+ exp = ref command ""exp"",
348348+ floor = ref command ""floor"",
349349+ log = ref command ""log"",
350350+ max = ref command ""max"",
351351+ min = ref command ""min"",
352352+ pi = ref command ""pi"",
353353+ round = ref command ""round"",
354354+ sin = ref command ""sin"",
355355+ cos = ref command ""cos"",
356356+ sqrt = ref command ""sqrt"",
357357+ tan = ref command ""tan"",
358358+ char = ref command ""char"",
359359+ count = ref command ""count"",
360360+ distinct = ref command ""distinct"",
361361+ union = ref command ""union"",
362362+ unique = ref command ""unique"",
363363+ frequency = ref command ""frequency"",
364364+ groupby = ref command ""groupby"",
365365+ intersect = ref command ""intersect"",
366366+ call\tail = expand macro command ""call\\tail"",
367367+ call\tail\perform = ref command ""call\\tail\\perform"",
368368+ list = ref command ""list"",
369369+ each = ref command ""each"",
370370+ exists = ref command ""exists"",
371371+ forall = ref command ""forall"",
372372+ CompileToCil = ref command ""CompileToCil"",
373373+ takewhile = ref command ""takewhile"",
374374+ except = ref command ""except"",
375375+ range = ref command ""range"",
376376+ reverse = ref command ""reverse"",
377377+ headtail = ref command ""headtail"",
378378+ append = ref command ""append"",
379379+ sum = ref command ""sum"",
380380+ contains = ref command ""contains"",
381381+ chan = ref command ""chan"",
382382+ call\async = expand macro command ""call\\async"",
383383+ call\async\perform = ref command ""call\\async\\perform"",
384384+ async_seq = ref command ""async_seq"",
385385+ call\sub\perform = ref command ""call\\sub\\perform"",
386386+ pa\ind = ref command ""pa\\ind"",
387387+ pa\mem = ref command ""pa\\mem"",
388388+ pa\ctor = ref command ""pa\\ctor"",
389389+ pa\check = ref command ""pa\\check"",
390390+ pa\cast = ref command ""pa\\cast"",
391391+ pa\smem = ref command ""pa\\smem"",
392392+ pa\fun\call = ref command ""pa\\fun\\call"",
393393+ pa\flip\call = ref command ""pa\\flip\\call"",
394394+ pa\call\star = ref command ""pa\\call\\star"",
395395+ then = ref command ""then"",
396396+ id = ref command ""id"",
397397+ const = ref command ""const"",
398398+ (+) = ref command ""plus"",
399399+ (-) = ref command ""minus"",
400400+ (*) = ref command ""times"",
401401+ (/) = ref command ""dividedBy"",
402402+ $mod = ref command ""mod"",
403403+ (^) = ref command ""raisedTo"",
404404+ (&) = ref command ""bitwiseAnd"",
405405+ (|) = ref command ""bitwiseOr"",
406406+ $xor = ref command ""xor"",
407407+ (==) = ref command ""isEqualTo"",
408408+ (!=) = ref command ""isInequalTo"",
409409+ (>) = ref command ""isGreaterThan"",
410410+ (>=) = ref command ""isGreaterThanOrEqual"",
411411+ (<) = ref command ""isLessThan"",
412412+ (<=) = ref command ""isLessThanOrEqual"",
413413+ (-.) = ref command ""negation"",
414414+ $complement = ref command ""complement"",
415415+ $not = ref command ""not"",
416416+ create_enumerator = ref command ""create_enumerator"",
417417+ create_module_name = ref command ""create_module_name"",
418418+ seqconcat = ref command ""seqconcat"",
419419+ call\sub = expand macro command ""call\\sub"",
420420+ call\sub\interpret = expand macro command ""call\\sub\\interpret"",
421421+ macro\pack = expand macro command ""macro\\pack"",
422422+ macro\unpack = expand macro command ""macro\\unpack"",
423423+ macro\reference = expand macro command ""macro\\reference"",
424424+ call\star = expand macro command ""call\\star"",
425425+ call\macro = expand macro command ""call\\macro"",
426426+ call\macro\impl = expand macro command ""call\\macro\\impl"",
427427+ main = ref function(""main"",""testApplication"",0.0),
428428+);
429429+430430+function main(x,y)
431431+{
432432+ return call\member(x,y);
433433+}
434434+");
435435+436436+ var x = new Mock<ISourcePosition>(MockBehavior.Strict);
437437+ x.SetupGet(s => s.Line).Returns(15);
438438+ Expect(15,sctx.CreateNativePValue(x.Object),"Line");
439439+ }
440440+441441+ [Test]
442442+ public void BlockDeclarationOfMacroCommand()
443443+ {
444444+ Compile(@"
445445+declare macro command call\member;
446446+447447+function main(x,y)
448448+{
449449+ return call\member(x,y);
450450+}
451451+");
452452+ var x = new Mock<ISourcePosition>(MockBehavior.Strict);
453453+ x.SetupGet(s => s.Line).Returns(15);
454454+ Expect(15, sctx.CreateNativePValue(x.Object), "Line");
455455+ }
456456+457457+ [Test]
458458+ public void ReferenceToSymbolWithMessage()
459459+ {
460460+ var ldr = Compile(@"
461461+function t1 = 7;
462462+ref t2 = ->t1;
463463+declare(
464464+ t3 = warn(pos(""Translation.cs.pxs"",434,5),""T.tt"",""Hooder"", sym ""t2"")
465465+);
466466+467467+function main()
468468+{
469469+ return ->t1 == ->t3;
470470+}
471471+");
472472+473473+ Expect(true);
474474+ Assert.That(ldr.Warnings.Count,Is.EqualTo(1));
475475+ Assert.That(ldr.Warnings[0].MessageClass,Is.EqualTo("T.tt"));
476476+ }
477477+478478+ [Test]
479479+ public void EntityRefToCommand()
480480+ {
481481+ var ldr = Compile(@"
482482+function f{}
483483+var v;
484484+ref r;
485485+macro m{}
486486+487487+function main()
488488+{
489489+ var loc;
490490+ ref rloc;
491491+ var sep = ""|"";
492492+ return """" + entityref_to(f) + sep
493493+ + entityref_to(v) + sep
494494+ + entityref_to(->r) + sep
495495+ + entityref_to(m) + sep
496496+ + entityref_to(loc) + sep
497497+ + entityref_to(->rloc) + sep
498498+ + entityref_to(entityref_to) + sep
499499+ + entityref_to(print);
500500+}
501501+");
502502+ var nm = ldr.ParentApplication.Module.Name;
503503+504504+ Expect(rv =>
505505+ {
506506+ var r = rv.CallToString(sctx).Split('|');
507507+ Console.WriteLine(rv);
508508+ Assert.That((object) r.Length,Is.EqualTo(8),"Expected return value to consist of 8 elements. Returned {0}",rv);
509509+510510+ Assert.That(r[0], Is.EqualTo(EntityRef.Function.Create("f",nm).ToString()));
511511+ Assert.That(r[1], Is.EqualTo(EntityRef.Variable.Global.Create("v", nm).ToString()));
512512+ Assert.That(r[2], Is.EqualTo(EntityRef.Variable.Global.Create("r", nm).ToString()));
513513+ Assert.That(r[3], Is.EqualTo(EntityRef.Function.Create("m", nm).ToString()));
514514+ Assert.That(r[4], Is.EqualTo(EntityRef.Variable.Local.Create("loc").ToString()));
515515+ Assert.That(r[5], Is.EqualTo(EntityRef.Variable.Local.Create("rloc").ToString()));
516516+ Assert.That(r[6], Is.EqualTo(EntityRef.MacroCommand.Create("entityref_to").ToString()));
517517+ Assert.That(r[7], Is.EqualTo(EntityRef.Command.Create("print").ToString()));
518518+ });
519519+ }
520520+521521+ [Test]
522522+ public void NamespaceLookup()
523523+ {
524524+ var ldr = new Loader(options);
525525+ Compile(ldr, @"
526526+function f = 17;
527527+");
528528+ Symbol f;
529529+ if(!ldr.TopLevelSymbols.TryGet("f",out f))
530530+ Assert.Fail("Expected module level symbol f to exist.");
531531+532532+ var scopea = SymbolStore.Create();
533533+ scopea.Declare("g",f);
534534+ var nsa = new MergedNamespace(scopea);
535535+ var a = Symbol.CreateNamespace(nsa, NoSourcePosition.Instance);
536536+ ldr.TopLevelSymbols.Declare("a",a);
537537+538538+ Compile(ldr, @"
539539+function main()
540540+{
541541+ return a.g;
542542+}
543543+");
544544+545545+ Expect(17);
546546+ }
547547+548548+ [Test]
549549+ public void NestedNamespaceLookup()
550550+ {
551551+552552+ var ldr = new Loader(options);
553553+ Compile(ldr, @"
554554+function f = 17;
555555+");
556556+ Symbol f;
557557+ if (!ldr.TopLevelSymbols.TryGet("f", out f))
558558+ Assert.Fail("Expected module level symbol f to exist.");
559559+560560+ var scopea = SymbolStore.Create();
561561+ scopea.Declare("g", f);
562562+ var nsa = new MergedNamespace(scopea);
563563+ var a = Symbol.CreateNamespace(nsa, NoSourcePosition.Instance);
564564+565565+ var scopeb = SymbolStore.Create();
566566+ scopeb.Declare("a",a);
567567+ var nsb = new MergedNamespace(scopeb);
568568+ var b = Symbol.CreateNamespace(nsb, NoSourcePosition.Instance);
569569+570570+ ldr.TopLevelSymbols.Declare("b",b);
571571+572572+ Compile(ldr, @"
573573+function main()
574574+{
575575+ return b.a.g;
576576+}
577577+");
578578+579579+ Expect(17);
580580+ }
581581+582582+ [Test]
583583+ public void AliasedNamespaceLookup()
584584+ {
585585+586586+ var ldr = new Loader(options);
587587+ Compile(ldr, @"
588588+function f = 17;
589589+");
590590+ Symbol f;
591591+ if (!ldr.TopLevelSymbols.TryGet("f", out f))
592592+ Assert.Fail("Expected module level symbol f to exist.");
593593+594594+ var scopea = SymbolStore.Create();
595595+ scopea.Declare("g", f);
596596+ var nsa = new MergedNamespace(scopea);
597597+ var a = Symbol.CreateNamespace(nsa, NoSourcePosition.Instance);
598598+599599+ var scopeb = SymbolStore.Create();
600600+ scopeb.Declare("a", a);
601601+ var nsb = new MergedNamespace(scopeb);
602602+ var b = Symbol.CreateNamespace(nsb, NoSourcePosition.Instance);
603603+604604+ ldr.TopLevelSymbols.Declare("b", b);
605605+606606+ Compile(ldr, @"
607607+declare(z = sym(""b"",""a""));
608608+function main()
609609+{
610610+ return z.g;
611611+}
612612+");
613613+614614+ Expect(17);
615615+ }
616616+617617+ [Test]
618618+ public void NamespaceDeclaration()
619619+ {
620620+ var ldr = Compile(@"
621621+namespace a
622622+{
623623+ function f = 17;
624624+}
625625+626626+function main = a.f;
627627+");
628628+ Expect(17);
629629+ Symbol dummy;
630630+ Assert.That(ldr.TopLevelSymbols.TryGet("f",out dummy),Is.False,"Existence of symbol f in the global scope");
631631+ }
632632+633633+ [Test]
634634+ public void SugaredNestedNamespaceDeclaration()
635635+ {
636636+637637+ Compile(@"
638638+namespace a.b
639639+{
640640+ function f = 17;
641641+}
642642+643643+function main = a.b.f;
644644+");
645645+ Expect(17);
646646+ }
647647+648648+ [Test]
649649+ public void NestedNamespaceDeclaration()
650650+ {
651651+652652+ Compile(@"
653653+namespace a
654654+{
655655+ namespace b
656656+ {
657657+ function f = 17;
658658+ }
659659+}
660660+661661+function main = a.b.f;
662662+");
663663+ Expect(17);
664664+ }
665665+666666+ [Test]
667667+ public void TopLevelAccessFromNamespace()
668668+ {
669669+670670+ Compile(@"
671671+function f = 17;
672672+673673+namespace a
674674+{
675675+ function g = f;
676676+}
677677+678678+function main = a.g;
679679+");
680680+ Expect(17);
681681+ }
682682+683683+ [Test]
684684+ public void SurroundingAccessFromNamespace()
685685+ {
686686+687687+ Compile(@"
688688+namespace a
689689+{
690690+ function f = 17;
691691+ namespace b
692692+ {
693693+ function g = f;
694694+ }
695695+}
696696+697697+function main = a.b.g;
698698+");
699699+ Expect(17);
700700+ }
701701+702702+ [Test]
703703+ public void Surrounding2AccessFromNamespace()
704704+ {
705705+706706+ Compile(@"
707707+namespace a
708708+{
709709+ function f = 17;
710710+ namespace b
711711+ {
712712+ namespace c
713713+ {
714714+ function g = f;
715715+ }
716716+ }
717717+}
718718+719719+function main = a.b.c.g;
720720+");
721721+ Expect(17);
722722+ }
723723+724724+ [Test]
725725+ public void SugarComposeNamespaces()
726726+ {
727727+ Compile(@"
728728+namespace a.b
729729+{
730730+ function f = 17;
731731+}
732732+733733+namespace a.c
734734+{
735735+ function g = 3;
736736+}
737737+738738+function main = a.b.f + a.c.g;
739739+");
740740+ Expect(20);
741741+ }
742742+743743+ [Test]
744744+ public void SugarNsOverride()
745745+ {
746746+ CompileInvalid(@"
747747+namespace a
748748+{
749749+ function b = 13;
750750+}
751751+752752+namespace a.b
753753+{
754754+ function f = 17;
755755+}
756756+757757+function main = a.b.f;
758758+","Expected","namespace","func");
759759+ }
760760+761761+ [Test]
762762+ public void DontReExportSurrounding()
763763+ {
764764+ CompileInvalid(@"
765765+function f = 13;
766766+namespace a
767767+{
768768+ function g = 15;
769769+}
770770+771771+function main = a.f;
772772+","symbol","resolve","f");
773773+774774+ }
775775+776776+ [Test]
777777+ public void RestoreExportedOnExtend()
778778+ {
779779+ Compile(@"
780780+namespace a {
781781+ function f = 13;
782782+}
783783+784784+namespace a {
785785+ function g = f+2;
786786+}
787787+788788+function main = a.g;
789789+");
790790+791791+ Expect(13+2);
792792+ }
793793+794794+ [Test]
795795+ public void SuppressRestoreExportedOnExtend()
796796+ {
797797+ CompileInvalid(@"
798798+namespace a {
799799+ function zz_f = 13;
800800+}
801801+802802+namespace a
803803+ import()
804804+{
805805+ function g = zz_f+2;
806806+}
807807+808808+function main = a.g;
809809+","symbol","resolve","zz_f");
810810+ }
811811+812812+ [Test]
813813+ public void SimpleNsSugarExtend()
814814+ {
815815+ Compile(@"
816816+namespace a.c
817817+{
818818+ function f = 17;
819819+}
820820+821821+namespace a
822822+{
823823+ namespace c
824824+ {
825825+ function g = 2;
826826+ }
827827+}
828828+829829+function main = a.c.f + a.c.g;
830830+");
831831+ Expect(17+2);
832832+ }
833833+834834+ [Test]
835835+ public void SugarNsExtend()
836836+ {
837837+ Compile(@"
838838+namespace a
839839+{
840840+ function b = 13;
841841+}
842842+843843+namespace a.c
844844+{
845845+ function f = 17;
846846+}
847847+848848+namespace a
849849+{
850850+ function d = 10;
851851+}
852852+853853+namespace a
854854+{
855855+ namespace c
856856+ {
857857+ function g = 2;
858858+ }
859859+}
860860+861861+function main = a.b + a.c.f + a.d + a.c.g;
862862+");
863863+864864+ Expect(13 + 17 + 10 + 2);
865865+ }
866866+867867+ [Test]
868868+ public void NsPhysical()
869869+ {
870870+ SkipStore = true;
871871+872872+ Compile(@"
873873+namespace a
874874+{
875875+ function f = 3;
876876+}
877877+878878+namespace b
879879+{
880880+ function f = 14;
881881+}
882882+883883+function main = a.f + b.f;
884884+");
885885+886886+ Expect(17);
887887+ }
888888+889889+ [Test]
890890+ public void ImportBackgroundConflict()
891891+ {
892892+ Compile(@"
893893+namespace a {
894894+ function f = 13;
895895+ function g = 12;
896896+ function x = 3;
897897+}
898898+899899+namespace b {
900900+ var g = 19;
901901+ declare(f = absolute sym(""a"",""f""));
902902+ function y = 4;
903903+}
904904+905905+namespace c
906906+ import a.*, b.*
907907+{
908908+ function s = f + x + y;
909909+}
910910+911911+function main = c.s;
912912+");
913913+914914+ Expect(4+3+13);
915915+ }
916916+917917+ [Test]
918918+ public void ImportConflict()
919919+ {
920920+ CompileInvalid(@"
921921+namespace a
922922+{
923923+ function f = 13;
924924+}
925925+926926+namespace b
927927+{
928928+ var f = 14;
929929+}
930930+931931+namespace c
932932+ import a.*, b.*
933933+{
934934+ function s = f;
935935+}
936936+937937+function main = c.s;
938938+","incompatible","namespace a","namespace b","symbol f");
939939+ }
940940+941941+ [Test]
942942+ public void RenameOneAvoidsConflict()
943943+ {
944944+ Compile(@"
945945+namespace a
946946+{
947947+ function f = 13;
948948+}
949949+950950+namespace b
951951+{
952952+ var f = 14;
953953+}
954954+955955+namespace c
956956+ import a.*, b(f => z)
957957+{
958958+ function s = f + z;
959959+}
960960+961961+function main = c.s;
962962+");
963963+ Expect(13+14);
964964+ }
965965+966966+ [Test]
967967+ public void UseMultiplicationAsNamespaceName()
968968+ {
969969+ Compile(@"
970970+namespace a.(*).c {
971971+ function f = 3;
972972+}
973973+974974+namespace b
975975+ import a.(*).c.f
976976+{
977977+ function g = f;
978978+}
979979+980980+function main = b.g;
981981+");
982982+ Expect(3);
983983+ }
984984+985985+ [Test]
986986+ public void UseMultiplicationInExplicitTransfer()
987987+ {
988988+ Compile(@"
989989+namespace a {
990990+ function (*) = 3;
991991+ var gobb = 4;
992992+}
993993+994994+namespace z {
995995+ function gobb = 5;
996996+}
997997+998998+namespace b
999999+ import a((*)), z(*) // should import only (*) from a, everything from z
10001000+{
10011001+ function g = (*) + gobb;
10021002+}
10031003+10041004+function main = b.g;
10051005+");
10061006+ }
10071007+10081008+ [Test]
10091009+ public void ExplicitWildcardTransfer()
10101010+ {
10111011+ Compile(@"
10121012+namespace a { function f = 13; }
10131013+namespace b import a(*)
10141014+{ function g = f; }
10151015+function main = b.g;
10161016+");
10171017+10181018+ Expect(13);
10191019+ }
10201020+10211021+ [Test]
10221022+ public void DropAvoidsConflict()
10231023+ {
10241024+ Compile(@"
10251025+namespace a
10261026+{
10271027+ function f = 13;
10281028+}
10291029+10301030+namespace b
10311031+{
10321032+ var f = 14;
10331033+ function g = 12;
10341034+}
10351035+10361036+namespace c
10371037+ import
10381038+ a.*,
10391039+ b(*, not f)
10401040+{
10411041+ function s = f + g;
10421042+}
10431043+10441044+function main = c.s;
10451045+");
10461046+ Expect(13 + 12);
10471047+ }
10481048+10491049+ [Test]
10501050+ public void FunctionScopeImport()
10511051+ {
10521052+ Compile(@"
10531053+namespace a
10541054+{
10551055+ function f = 13;
10561056+}
10571057+10581058+function main namespace import a.f = f;
10591059+");
10601060+ Expect(13);
10611061+ }
10621062+10631063+ [Test]
10641064+ public void ForwardDeclarationAncientSyntax()
10651065+ {
10661066+ Compile(@"
10671067+namespace a
10681068+{
10691069+ declare function f;
10701070+ function g(x) = f(x);
10711071+ function f(x) = 2*x;
10721072+}
10731073+10741074+function main(x) = a.g(x);
10751075+");
10761076+10771077+ Expect(16,8);
10781078+ }
10791079+10801080+ [Test]
10811081+ public void ForwardDeclarationOldSyntax()
10821082+ {
10831083+ Compile(@"
10841084+namespace a
10851085+{
10861086+ declare { function: f };
10871087+ function g(x) = f(x);
10881088+ function f(x) = 2*x;
10891089+}
10901090+10911091+function main(x) = a.g(x);
10921092+");
10931093+10941094+ Expect(16,8);
10951095+ }
10961096+10971097+ [Test]
10981098+ public void ForwardDeclarationMachineSyntax()
10991099+ {
11001100+ Compile(@"
11011101+namespace a
11021102+{
11031103+ // This forward declaration is not taken as relative to the namesapce.
11041104+ // It is intended for machine consumption.
11051105+ declare( f = ref function(""f"",""testApplication"",0.0));
11061106+ function g(x) = f(x);
11071107+}
11081108+11091109+function f(x) = 2*x;
11101110+11111111+function main(x) = a.g(x);
11121112+");
11131113+11141114+ Expect(16, 8);
11151115+ }
11161116+11171117+ [Test]
11181118+ public void ExportInterferenceWithTimesLiteral()
11191119+ {
11201120+ Compile(@"
11211121+namespace a{var g;}
11221122+namespace b{}export(*),a(g);
11231123+");
11241124+ }
11251125+11261126+ [Test]
11271127+ public void AlternateExportAllSyntax()
11281128+ {
11291129+ Compile(@"
11301130+namespace a{var g;}
11311131+namespace b{}export.*,a(g);
11321132+");
11331133+ }
11341134+11351135+ [Test]
11361136+ public void SelfReferenceInVarInit()
11371137+ {
11381138+ Compile(@"
11391139+namespace a
11401140+{
11411141+ var h = 4;
11421142+}
11431143+namespace a{
11441144+ var g = g ?? 15;
11451145+ var h = h ?? 3;
11461146+}
11471147+11481148+function main = a.g+a.h;
11491149+");
11501150+ Expect(15+4);
11511151+ }
11521152+11531153+ [Test]
11541154+ public void NamespaceExtensionCrossModule()
11551155+ {
11561156+ var plan = Plan.CreateSelfAssembling(StandardLibraryPreference.None);
11571157+11581158+ plan.Assemble(Source.FromString(@"
11591159+name one;
11601160+namespace a {
11611161+ function b = 15;
11621162+}
11631163+"));
11641164+11651165+ var moduleTwoDesc = plan.Assemble(Source.FromString(@"
11661166+name two;
11671167+references {one};
11681168+namespace a {
11691169+ function c =7;
11701170+}
11711171+"));
11721172+11731173+ var moduleTwo = plan.Build(moduleTwoDesc.Name);
11741174+ Assert.That(moduleTwo.Messages.Where(m => m.Severity == MessageSeverity.Error),Is.Empty,"Modules should compile without any error messages.");
11751175+ foreach (var message in moduleTwo.Messages)
11761176+ Console.WriteLine(message);
11771177+ Assert.That(moduleTwo.Exception,Is.Null);
11781178+11791179+ var symbols = moduleTwo.Symbols;
11801180+ Assert.That(symbols.TryGet("a",out var symbol),Is.True,"Expect module two to have a symbol called 'a'");
11811181+ Assert.That(symbol,Is.InstanceOf<NamespaceSymbol>());
11821182+ var nsSym = (NamespaceSymbol) symbol;
11831183+ _assumeNotNull(nsSym);
11841184+ Assert.That(nsSym.Namespace.TryGet("b",out symbol),"Expect namespace a to contain a symbol b.");
11851185+ Assert.That(nsSym.Namespace.TryGet("c",out symbol),"Expect namespace a to contain a symbol c.");
11861186+11871187+ }
11881188+11891189+ [Test]
11901190+ public void CommentAtEnd()
11911191+ {
11921192+ var ldr = new Loader(options);
11931193+ var add = new InternalLoadCommand(ldr);
11941194+ ldr.ParentEngine.Commands.AddHostCommand("add_internal", add);
11951195+ add.VirtualFiles.Add("f1",@"
11961196+function f1() {
11971197+ println(""f1 called"");
11981198+ // something
11991199+ return 15;
12001200+}
12011201+12021202+//s");
12031203+ Compile(ldr, @"
12041204+declare command add_internal;
12051205+12061206+function f0() {
12071207+ println(""f0 called"");
12081208+ /* something else */
12091209+ return 16;
12101210+}
12111211+12121212+build does add_internal(""f1"");
12131213+12141214+function main() {
12151215+ return f0 + f1;
12161216+}
12171217+");
12181218+12191219+ Expect(15+16);
12201220+ }
12211221+12221222+ [ContractAnnotation("value:null=>halt")]
12231223+ private static void _assumeNotNull(object value)
12241224+ {
12251225+ Assert.That(value,Is.Not.Null);
12261226+ }
12271227+12281228+ /// <summary>
12291229+ /// A command that works in a fashion very similar to the add and requires commands
12301230+ /// that a loader exposes in build blocks.
12311231+ /// Needs to be initialized first.
12321232+ /// </summary>
12331233+ private class InternalLoadCommand : PCommand
12341234+ {
12351235+ [NotNull]
12361236+ private readonly Dictionary<string, string> _virtualFiles = new Dictionary<string, string>();
12371237+ [NotNull]
12381238+ private readonly Loader _loaderReference;
12391239+12401240+ public InternalLoadCommand([NotNull] Loader loaderReference)
12411241+ {
12421242+ _loaderReference = loaderReference;
12431243+ }
12441244+12451245+ public Dictionary<string, string> VirtualFiles => _virtualFiles;
12461246+12471247+ public override PValue Run(StackContext sctx, PValue[] args)
12481248+ {
12491249+ var n = args[0].CallToString(sctx);
12501250+ var virtualFile = _virtualFiles[n];
12511251+ using(var cr = new StringReader(virtualFile))
12521252+ _loaderReference.LoadFromReader(cr,n);
12531253+ return PType.Null;
12541254+ }
12551255+ }
12561256+ }
12631257}
+186-186
PrexoniteTests/Tests/TypeSystem.cs
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-using System;
2727-using System.Threading;
2828-using NUnit.Framework;
2929-using Prexonite;
3030-using Prexonite.Types;
3131-using Prx.Tests;
3232-3333-namespace PrexoniteTests.Tests
3434-{
3535- [TestFixture(Description = "General type system checks")]
3636- public class TypeSystem
3737- {
3838- private Engine engine;
3939- private StackContext sctx;
4040-4141- [TestFixtureSetUp]
4242- public void SetupTypeSystemEngine()
4343- {
4444- engine = new Engine();
4545- sctx = new TestStackContext(engine, new Application());
4646- }
4747-4848- [TestFixtureTearDown]
4949- public void TeardownTypeSystemEngine()
5050- {
5151- engine = null;
5252- sctx = null;
5353- }
5454-5555- [Test(Description = "Does a number of set and get calls on a mock object")]
5656- public void TestFieldAccess()
5757- {
5858- //obj.Subject = 55;
5959- //obj.Count = obj.Subject;
6060- var test = new TestObject();
6161- var obj = engine.CreateNativePValue(test);
6262- Assert.AreEqual(obj.Type, PType.Object[typeof (TestObject)]);
6363- Assert.AreSame(test, obj.Value);
6464-6565- //Set obj.Subject = 55
6666- obj.DynamicCall(
6767- sctx,
6868- new PValue[] {55},
6969- PCall.Set,
7070- "Subject");
7171- Assert.AreSame(test, obj.Value);
7272- Assert.AreEqual(test.Subject, ((TestObject) obj.Value).Subject);
7373-7474- //Get res = obj.Subject
7575- var res = obj.DynamicCall(
7676- sctx,
7777- new PValue[] {},
7878- PCall.Get,
7979- "Subject");
8080- Assert.AreEqual(test.Subject, res.Value);
8181-8282- //Set obj.Count = res
8383- obj.DynamicCall(
8484- sctx,
8585- new[] {res},
8686- PCall.Set,
8787- "Count");
8888- Assert.AreEqual(55, test.Count);
8989-9090- //Get res = obj.Count
9191- res = obj.DynamicCall(
9292- sctx,
9393- new PValue[] {},
9494- PCall.Get,
9595- "Count");
9696- Assert.AreEqual(55, test.Count);
9797- Assert.AreEqual(55, (int) res.Value);
9898- }
9999-100100- [Test(Description = "Test the implicit [basic] to [PValue] conversion operators")]
101101- public void TestImplicitPValueConversion()
102102- {
103103- PValue obj;
104104-105105- obj = 55;
106106- Assert.AreSame(PType.Int, obj.Type);
107107-108108- obj = 5.5;
109109- Assert.AreSame(PType.Real, obj.Type);
110110-111111- obj = true;
112112- Assert.AreSame(PType.Bool, obj.Type);
113113-114114- obj = "Hello World";
115115- Assert.AreSame(PType.String, obj.Type);
116116- }
117117-118118- [Test(Description = "PType creation from type name.")]
119119- public void TestPTypeCreationUsingClrObjects_name()
120120- {
121121- var res =
122122- sctx.ConstructPType(
123123- "Object", new[] {PType.Object.CreatePValue(typeof (Int32))});
124124- Assert.AreEqual(PType.Object[typeof (Int32)], res);
125125- }
126126-127127- [Test(Description = "PType creation from type")]
128128- public void TestPTypeCreationUsingClrObjects_type()
129129- {
130130- var res =
131131- sctx.ConstructPType(
132132- typeof (ObjectPType), new[] {PType.Object.CreatePValue(typeof (DateTime))});
133133- Assert.AreEqual(PType.Object[typeof (DateTime)], res);
134134- }
135135-136136- [Test(Description = "PType creation from type as ClrPType")]
137137- public void TestPTypeCreationUsingClrObjects_clrtype()
138138- {
139139- var res =
140140- sctx.ConstructPType(
141141- PType.Object[typeof (ObjectPType)],
142142- new[] {PType.Object.CreatePValue(typeof (Thread))});
143143- Assert.AreEqual(PType.Object[typeof (Thread)], res);
144144- }
145145-146146- [Test(Description = "Creation of a ClrPType from a fqTypeName")]
147147- public void TestTypeResolving()
148148- {
149149- var res = new ObjectPType(sctx, "System.Threading.Thread");
150150- Assert.AreEqual(PType.Object[typeof (Thread)], res);
151151- }
152152-153153- [Test(Description = "PType creation from type simple expression")]
154154- public void TestPTypeCreationUsingExpression_simple()
155155- {
156156- var res = sctx.ConstructPType("Object(\"System.Threading.Thread\")");
157157- Assert.AreEqual(PType.Object[typeof (Thread)], res);
158158- }
159159-160160- [Test]
161161- public void NativePValue()
162162- {
163163- var str = "Hello ";
164164- var nStr = engine.CreateNativePValue(str);
165165- Assert.IsInstanceOf(typeof (StringPType), nStr.Type);
166166- Assert.AreSame(str, nStr.Value);
167167- }
168168-169169- [Test]
170170- public void TestStringEscape()
171171- {
172172- var sEscaped = @"This is a \n followed by a \ttab and an umlaut: \x" +
173173- ((int) '�').ToString("X") +
174174- " escape sequence.";
175175- var sUnescaped = "This is a \n followed by a \ttab and an umlaut: � escape sequence.";
176176-177177- var escaped = PType.String.CreatePValue(sEscaped);
178178- PValue unescaped;
179179- Assert.IsTrue(
180180- escaped.TryDynamicCall(sctx, new PValue[] {}, PCall.Get, "unescape", out unescaped));
181181- Assert.AreEqual(sUnescaped, unescaped.Value as string);
182182- Assert.IsTrue(
183183- unescaped.TryDynamicCall(sctx, new PValue[] {}, PCall.Get, "escape", out escaped));
184184- Assert.AreEqual(sEscaped, escaped.Value as string);
185185- }
186186- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+using System;
2727+using System.Threading;
2828+using NUnit.Framework;
2929+using Prexonite;
3030+using Prexonite.Types;
3131+using Prx.Tests;
3232+3333+namespace PrexoniteTests.Tests
3434+{
3535+ [TestFixture(Description = "General type system checks")]
3636+ public class TypeSystem
3737+ {
3838+ private Engine engine;
3939+ private StackContext sctx;
4040+4141+ [OneTimeSetUp]
4242+ public void SetupTypeSystemEngine()
4343+ {
4444+ engine = new Engine();
4545+ sctx = new TestStackContext(engine, new Application());
4646+ }
4747+4848+ [OneTimeTearDown]
4949+ public void TeardownTypeSystemEngine()
5050+ {
5151+ engine = null;
5252+ sctx = null;
5353+ }
5454+5555+ [Test(Description = "Does a number of set and get calls on a mock object")]
5656+ public void TestFieldAccess()
5757+ {
5858+ //obj.Subject = 55;
5959+ //obj.Count = obj.Subject;
6060+ var test = new TestObject();
6161+ var obj = engine.CreateNativePValue(test);
6262+ Assert.AreEqual(obj.Type, PType.Object[typeof (TestObject)]);
6363+ Assert.AreSame(test, obj.Value);
6464+6565+ //Set obj.Subject = 55
6666+ obj.DynamicCall(
6767+ sctx,
6868+ new PValue[] {55},
6969+ PCall.Set,
7070+ "Subject");
7171+ Assert.AreSame(test, obj.Value);
7272+ Assert.AreEqual(test.Subject, ((TestObject) obj.Value).Subject);
7373+7474+ //Get res = obj.Subject
7575+ var res = obj.DynamicCall(
7676+ sctx,
7777+ new PValue[] {},
7878+ PCall.Get,
7979+ "Subject");
8080+ Assert.AreEqual(test.Subject, res.Value);
8181+8282+ //Set obj.Count = res
8383+ obj.DynamicCall(
8484+ sctx,
8585+ new[] {res},
8686+ PCall.Set,
8787+ "Count");
8888+ Assert.AreEqual(55, test.Count);
8989+9090+ //Get res = obj.Count
9191+ res = obj.DynamicCall(
9292+ sctx,
9393+ new PValue[] {},
9494+ PCall.Get,
9595+ "Count");
9696+ Assert.AreEqual(55, test.Count);
9797+ Assert.AreEqual(55, (int) res.Value);
9898+ }
9999+100100+ [Test(Description = "Test the implicit [basic] to [PValue] conversion operators")]
101101+ public void TestImplicitPValueConversion()
102102+ {
103103+ PValue obj;
104104+105105+ obj = 55;
106106+ Assert.AreSame(PType.Int, obj.Type);
107107+108108+ obj = 5.5;
109109+ Assert.AreSame(PType.Real, obj.Type);
110110+111111+ obj = true;
112112+ Assert.AreSame(PType.Bool, obj.Type);
113113+114114+ obj = "Hello World";
115115+ Assert.AreSame(PType.String, obj.Type);
116116+ }
117117+118118+ [Test(Description = "PType creation from type name.")]
119119+ public void TestPTypeCreationUsingClrObjects_name()
120120+ {
121121+ var res =
122122+ sctx.ConstructPType(
123123+ "Object", new[] {PType.Object.CreatePValue(typeof (Int32))});
124124+ Assert.AreEqual(PType.Object[typeof (Int32)], res);
125125+ }
126126+127127+ [Test(Description = "PType creation from type")]
128128+ public void TestPTypeCreationUsingClrObjects_type()
129129+ {
130130+ var res =
131131+ sctx.ConstructPType(
132132+ typeof (ObjectPType), new[] {PType.Object.CreatePValue(typeof (DateTime))});
133133+ Assert.AreEqual(PType.Object[typeof (DateTime)], res);
134134+ }
135135+136136+ [Test(Description = "PType creation from type as ClrPType")]
137137+ public void TestPTypeCreationUsingClrObjects_clrtype()
138138+ {
139139+ var res =
140140+ sctx.ConstructPType(
141141+ PType.Object[typeof (ObjectPType)],
142142+ new[] {PType.Object.CreatePValue(typeof (Thread))});
143143+ Assert.AreEqual(PType.Object[typeof (Thread)], res);
144144+ }
145145+146146+ [Test(Description = "Creation of a ClrPType from a fqTypeName")]
147147+ public void TestTypeResolving()
148148+ {
149149+ var res = new ObjectPType(sctx, "System.Threading.Thread");
150150+ Assert.AreEqual(PType.Object[typeof (Thread)], res);
151151+ }
152152+153153+ [Test(Description = "PType creation from type simple expression")]
154154+ public void TestPTypeCreationUsingExpression_simple()
155155+ {
156156+ var res = sctx.ConstructPType("Object(\"System.Threading.Thread\")");
157157+ Assert.AreEqual(PType.Object[typeof (Thread)], res);
158158+ }
159159+160160+ [Test]
161161+ public void NativePValue()
162162+ {
163163+ var str = "Hello ";
164164+ var nStr = engine.CreateNativePValue(str);
165165+ Assert.IsInstanceOf(typeof (StringPType), nStr.Type);
166166+ Assert.AreSame(str, nStr.Value);
167167+ }
168168+169169+ [Test]
170170+ public void TestStringEscape()
171171+ {
172172+ var sEscaped = @"This is a \n followed by a \ttab and an umlaut: \x" +
173173+ ((int) '�').ToString("X") +
174174+ " escape sequence.";
175175+ var sUnescaped = "This is a \n followed by a \ttab and an umlaut: � escape sequence.";
176176+177177+ var escaped = PType.String.CreatePValue(sEscaped);
178178+ PValue unescaped;
179179+ Assert.IsTrue(
180180+ escaped.TryDynamicCall(sctx, new PValue[] {}, PCall.Get, "unescape", out unescaped));
181181+ Assert.AreEqual(sUnescaped, unescaped.Value as string);
182182+ Assert.IsTrue(
183183+ unescaped.TryDynamicCall(sctx, new PValue[] {}, PCall.Get, "escape", out escaped));
184184+ Assert.AreEqual(sEscaped, escaped.Value as string);
185185+ }
186186+ }
187187}
+488-488
PrexoniteTests/Tests/VMTests.Macro.cs
···11-// Prexonite
22-//
33-// Copyright (c) 2014, Christian Klauser
44-// All rights reserved.
55-//
66-// Redistribution and use in source and binary forms, with or without modification,
77-// are permitted provided that the following conditions are met:
88-//
99-// Redistributions of source code must retain the above copyright notice,
1010-// this list of conditions and the following disclaimer.
1111-// Redistributions in binary form must reproduce the above copyright notice,
1212-// this list of conditions and the following disclaimer in the
1313-// documentation and/or other materials provided with the distribution.
1414-// The names of the contributors may be used to endorse or
1515-// promote products derived from this software without specific prior written permission.
1616-//
1717-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020-// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626-#if ((!(DEBUG || Verbose)) || forceIndex) && allowIndex
2727-#define useIndex
2828-#endif
2929-3030-#define UseCil
3131-//need to change this in VMTestsBase.cs too!
3232-3333-using System;
3434-using System.Collections.Generic;
3535-using NUnit.Framework;
3636-using Prexonite;
3737-using Prexonite.Compiler;
3838-using Prexonite.Compiler.Ast;
3939-using Prexonite.Compiler.Macro.Commands;
4040-using Prexonite.Modular;
4141-using Prexonite.Types;
4242-using PrexoniteTests.Tests;
4343-4444-namespace Prx.Tests
4545-{
4646- public abstract partial class VMTests : VMTestsBase
4747- {
4848- [Test]
4949- public void CallSubMacroCommandNested()
5050- {
5151- CompileInvalid(
5252- @"
5353-function main(xs)
5454-{
5555- var zs = [];
5656- function f(x)
5757- {
5858- if(x mod 2 == 0)
5959- continue;
6060- if(x > 6)
6161- break;
6262- return x*3+1;
6363- }
6464- foreach(var x in xs)
6565- {
6666- zs[] = call\sub(f(?),[x]);
6767- }
6868-6969- return zs.ToString();
7070-}
7171-",
7272- CallSub.Alias, "expression");
7373-7474- //var xs = new List<PValue> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
7575- //Expect("[ 4, 10, 16 ]", (PValue)xs);
7676- }
7777-7878- [Test]
7979- public void CallSubMacroCommandTopLevel()
8080- {
8181- Compile(
8282- @"
8383-var zs = [];
8484-function main(x1,x2,x3)
8585-{
8686- function f(x)
8787- {
8888- if(x mod 2 == 0)
8989- continue;
9090- if(x > 6)
9191- break;
9292- return x*3+1;
9393- }
9494-9595- zs[] = call\sub(f(?),[x1]);
9696- zs[] = call\sub(f(?),[x2]);
9797- call\sub(f(?),[x3]);
9898-9999- return zs.ToString();
100100-}
101101-");
102102- Func<List<PValue>> getZs = () =>
103103- {
104104- var pv = target.Variables["zs"].Value.Value as List<PValue>;
105105- return pv ?? new List<PValue>(0);
106106- };
107107- Action resetZs = () => getZs().Clear();
108108-109109- Expect("[ 4, 10 ]", 1, 3);
110110- resetZs();
111111-112112- ExpectNull(2, 4, 8);
113113- Assert.AreEqual(0, getZs().Count);
114114- resetZs();
115115-116116- ExpectNull(1, 8, 8);
117117- var zs = getZs();
118118- Assert.AreEqual(1, zs.Count);
119119- AssertPValuesAreEqual(4, zs[0]);
120120- resetZs();
121121-122122- ExpectNull(1, 3, 8);
123123- zs = getZs();
124124- Assert.AreEqual(2, zs.Count);
125125- AssertPValuesAreEqual(4, zs[0]);
126126- AssertPValuesAreEqual(10, zs[1]);
127127- resetZs();
128128- }
129129-130130- [Test]
131131- public void CallSubMinimal()
132132- {
133133- Compile(
134134- @"
135135-function f(x)
136136-{
137137- return x;
138138-}
139139-140140-function main()
141141-{
142142- call\sub(f(?),[2]);
143143- return 2;
144144-}
145145-");
146146-147147- Expect(2);
148148- }
149149-150150- [Test]
151151- public void CallSubMinimalReturn()
152152- {
153153- Compile(
154154- @"
155155-function f()
156156-{
157157- return 1;
158158-}
159159-160160-function main()
161161-{
162162- var zs = [];
163163- asm{nop nop nop}
164164- zs[] = call\sub(f(?));
165165- asm{nop nop nop}
166166- return zs[0];
167167-}
168168-");
169169-170170- Expect(1);
171171- }
172172-173173- [Test]
174174- public void CallSubOfPartial()
175175- {
176176- CompileInvalid(
177177- @"
178178-function main(xs,y)
179179-{
180180- var zs = [];
181181- function f(x,y)
182182- {
183183- if(x mod 2 == 0)
184184- continue;
185185- if(x > y)
186186- break;
187187- return x*3+1;
188188- }
189189- foreach(var x in xs)
190190- {
191191- zs[] = call\sub(f(?,y),[x]);
192192- }
193193-194194- return zs.ToString();
195195-}
196196-",
197197- CallSub.Alias, "expression");
198198-199199- //var xs = new List<PValue> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
200200- //Expect("[ 4, 10, 16 ]", (PValue)xs, 6);
201201- //Expect("[ 4, 10 ]", (PValue)xs, 4);
202202- }
203203-204204- [Test]
205205- public void CaptureUnmentionedMacroVariable()
206206- {
207207- Compile(
208208- @"
209209- macro echo()
210210- {
211211- var f = (x) =>
212212- if(context is null)
213213- ""context is null""
214214- else if(context.LocalSymbols.TryGet(x, ref r))
215215- var r
216216- else
217217- ""cannot resolve $x"";
218218- println(f.(""x""));
219219- }
220220-221221- function main()
222222- {
223223- var x = 15;
224224- echo;
225225- return x;
226226- }
227227-");
228228- var clo = target.Functions["echo\\0"];
229229- Assert.IsNotNull(clo, "Closure must exist.");
230230- Assert.IsTrue(clo.Meta.ContainsKey(PFunction.SharedNamesKey));
231231- Assert.AreEqual(clo.Meta[PFunction.SharedNamesKey].List.Length, 1);
232232- Assert.AreEqual(clo.Meta[PFunction.SharedNamesKey].List[0].Text,
233233- MacroAliases.ContextAlias);
234234-235235- Expect(15, new PValue[0]);
236236- }
237237-238238- [Test]
239239- public void MacroTransport()
240240- {
241241- Compile(
242242- @"
243243-macro echo(lst)
244244-{
245245- lst = macro\unpack(lst);
246246- return new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
247247- context.Invocation.Line,context.Invocation.Column,sum(lst) + lst.Count);
248248-}
249249-250250-macro gen(n)
251251-{
252252- n = n.Constant~Int;
253253- var id = macro\pack(1.to(n) >> all);
254254- var idConst = new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
255255- context.Invocation.Line,context.Invocation.Column, id);
256256- return call\macro([echo(idConst)]);
257257-}
258258-259259-function main()
260260-{
261261- return gen(4);
262262-}
263263-264264-function main2()
265265-{
266266- return gen(5);
267267-}
268268-");
269269-270270- Expect(1 + 2 + 3 + 4 + 4);
271271- ExpectNamed("main2", 1 + 2 + 3 + 4 + 5 + 5);
272272- }
273273-274274- [Test]
275275- public void CallMacroOnFunction()
276276- {
277277- Compile(
278278- @"
279279-macro __append(con)
280280-{
281281- var c = con.Constant + ""__"";
282282-283283- if(context.IsJustEffect)
284284- c += ""je"";
285285-286286- if(context.Call~Int == Prexonite::Types::PCall.Set~Int)
287287- c += ""="";
288288-289289- var con = new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
290290- context.Invocation.Line,context.Invocation.Column,c);
291291- return con;
292292-}
293293-294294-macro __surround(con, idx)
295295-{
296296- var idx = idx.Constant~Int;
297297- con.Constant = ""__"" + con.Constant;
298298- return [ call\macro([__append],[con])
299299- , call\macro([__append(con)])
300300- , call\macro([__append = con])
301301- , call\macro([__append,true],[con])
302302- , call\macro([__append,false],[con])
303303- , call\macro([__append(con),true])
304304- , call\macro([__append(con),false])
305305- , call\macro([__append = con, true])
306306- , call\macro([__append = con, false]) ][idx];
307307-}
308308-309309-function main(x,y)
310310-{
311311- return [ x + __surround(""xXx"", 0) + y
312312- , x + __surround(""xXx"", 1) + y
313313- , x + __surround(""xXx"", 2) + y
314314- , x + __surround(""xXx"", 3) + y
315315- , x + __surround(""xXx"", 4) + y
316316- , x + __surround(""xXx"", 5) + y
317317- , x + __surround(""xXx"", 6) + y
318318- , x + __surround(""xXx"", 7) + y
319319- , x + __surround(""xXx"", 8) + y];
320320-}
321321-");
322322-323323- Expect(new List<PValue>
324324- {
325325- "a__xXx__b",
326326- "a__xXx__b",
327327- "a__xXx__=b",
328328- "a__xXx__jeb",
329329- "a__xXx__b",
330330- "a__xXx__jeb",
331331- "a__xXx__b",
332332- "a__xXx__je=b",
333333- "a__xXx__=b"
334334- }, "a", "b");
335335-336336- if (CompileToCil)
337337- {
338338- var surround = target.Functions["__surround"];
339339- Assert.That(surround, Is.Not.Null, "Function __surround does not exist.");
340340- Assert.That(surround.Meta[PFunction.VolatileKey].Switch,
341341- Is.False,
342342- string.Format("Function {0} is volatile. Reason: {1}", surround.Id,
343343- surround.Meta[PFunction.DeficiencyKey].Text));
344344- }
345345- }
346346-347347-348348- [Test,Ignore]
349349- public void PartialCallMacroOnFunction()
350350- {
351351- Compile(
352352- @"
353353-macro __append(con)
354354-{
355355- var c = con.Constant + ""__"";
356356-357357- if(context.IsJustEffect)
358358- c += ""je"";
359359-360360- if(context.Call~Int == Prexonite::Types::PCall.Set~Int)
361361- c += ""="";
362362-363363- var con = new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
364364- context.Invocation.Line,context.Invocation.Column,c);
365365- return con;
366366-}
367367-368368-macro __surround\create_pa(con, idx)
369369-{
370370- var idx = idx.Constant~Int;
371371- con.Constant = ""__"" + con.Constant;
372372- var f = [ call\macro([?],[?]) // 20
373373- , call\macro([__append(?0)])
374374- , call\macro([__append = ?0]) // 22
375375- , call\macro([__append,?],[con])
376376- , call\macro([?,?],[?])
377377- , call\macro([__append(con),?]) // 25
378378- , call\macro([__append(?0),?])
379379- , call\macro([__append = ?0, ?]) // 27
380380- , call\macro([__append = con, ?]) ][idx];
381381-382382- var fc = macro\pack(f);
383383- return new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
384384- context.Invocation.Line,context.Invocation.Column,fc);
385385-}
386386-387387-macro __surround(con, idx)
388388-{
389389- var i = idx.Constant~Int; //37
390390- var fc = call\macro([__surround\create_pa(con, idx)]).Expression;
391391- var f = macro\unpack(fc.Constant~Int);
392392- if(i == 0)
393393- return f.(macro\reference(__append),con);
394394- else if(i == 1)
395395- return f.(con);
396396- else if(i == 2)
397397- return f.(con);
398398- else if(i == 3)
399399- return f.(true);
400400- else if(i == 4)
401401- return f.(macro\reference(__append),false,con);
402402- else if(i == 5) // 50
403403- return f.(true);
404404- else if(i == 6)
405405- return f.(con, false);
406406- else if(i == 7)
407407- return f.(con,true);
408408- else if(i == 8)
409409- return f.(false);
410410- else
411411- throw ""ZOMG! (invalid index to macro __surround)"";
412412-} // 60
413413-414414-function main(x,y)
415415-{
416416- return [ x + __surround(""xXx"", 0) + y
417417- , x + __surround(""xXx"", 1) + y
418418- , x + __surround(""xXx"", 2) + y
419419- , x + __surround(""xXx"", 3) + y
420420- , x + __surround(""xXx"", 4) + y
421421- , x + __surround(""xXx"", 5) + y
422422- , x + __surround(""xXx"", 6) + y // 70
423423- , x + __surround(""xXx"", 7) + y // 71
424424- , x + __surround(""xXx"", 8) + y]; // 72
425425-}
426426-");
427427-428428- Expect(new List<PValue>
429429- {
430430- "a__xXx__b",
431431- "a__xXx__b",
432432- "a__xXx__=b",
433433- "a__xXx__jeb",
434434- "a__xXx__b",
435435- "a__xXx__jeb",
436436- "a__xXx__b",
437437- "a__xXx__je=b",
438438- "a__xXx__=b"
439439- }, "a", "b");
440440- }
441441-442442- [Test]
443443- public void AstIsExpand()
444444- {
445445- Compile(@"
446446-var uniq\\node_t6;
447447-448448-function ast_is_Expand(node_arg)
449449-{asm{
450450-var tmpp0
451451-/* 00 */ ldloc node_arg
452452-/* 01 */ cmd.1 boxed
453453-/* 02 */ get.0 Type
454454-/* 03 */ dup 1
455455-/* 04 */ stloc tmpp0
456456-/* 05 */ check.const ""Object(\""Prexonite.Types.ObjectPType\"")""
457457-/* 06 */ jump.t 9
458458-/* 07 */ ldc.bool false
459459-/* 08 */ ret.value
460460-/* 09 */ ldglob uniq\\node_t6
461461-/* 10 */ check.null
462462-/* 11 */ jump.f 15
463463-/* 12 */ ldc.string ""Prexonite.Compiler.Ast.AstExpand""
464464-/* 13 */ sget.1 ""Object(\""System.Type\"")::GetType""
465465-/* 14 */ stglob uniq\\node_t6
466466-/* 15 */ ldglob uniq\\node_t6
467467-/* 16 */ ldloc tmpp0
468468-/* 17 */ get.0 ClrType
469469-/* 18 */ get.1 IsAssignableFrom
470470-/* 19 */ jump.f 26
471471-/* 20 */ ldloc node_arg
472472-/* 21 */ get.0 CheckForPlaceholders
473473-/* 22 */ cmd.1 $not
474474-/* 23 */ jump.f 26
475475-/* 24 */ ldc.bool true
476476-/* 25 */ jump 27
477477-/* 26 */ ldc.bool false
478478-/* 27 */ ret.value
479479-/* 28 */ }}
480480-481481-function main(n) = ast_is_Expand(n);");
482482-483483- Expect(true,
484484- sctx.CreateNativePValue(new AstExpand(NoSourcePosition.Instance,
485485- EntityRef.MacroCommand.Create("call\\macro"), PCall.Get)));
486486-487487- }
488488- }
11+// Prexonite
22+//
33+// Copyright (c) 2014, Christian Klauser
44+// All rights reserved.
55+//
66+// Redistribution and use in source and binary forms, with or without modification,
77+// are permitted provided that the following conditions are met:
88+//
99+// Redistributions of source code must retain the above copyright notice,
1010+// this list of conditions and the following disclaimer.
1111+// Redistributions in binary form must reproduce the above copyright notice,
1212+// this list of conditions and the following disclaimer in the
1313+// documentation and/or other materials provided with the distribution.
1414+// The names of the contributors may be used to endorse or
1515+// promote products derived from this software without specific prior written permission.
1616+//
1717+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1818+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1919+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2020+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2121+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2222+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2323+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2424+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626+#if ((!(DEBUG || Verbose)) || forceIndex) && allowIndex
2727+#define useIndex
2828+#endif
2929+3030+#define UseCil
3131+//need to change this in VMTestsBase.cs too!
3232+3333+using System;
3434+using System.Collections.Generic;
3535+using NUnit.Framework;
3636+using Prexonite;
3737+using Prexonite.Compiler;
3838+using Prexonite.Compiler.Ast;
3939+using Prexonite.Compiler.Macro.Commands;
4040+using Prexonite.Modular;
4141+using Prexonite.Types;
4242+using PrexoniteTests.Tests;
4343+4444+namespace Prx.Tests
4545+{
4646+ public abstract partial class VMTests : VMTestsBase
4747+ {
4848+ [Test]
4949+ public void CallSubMacroCommandNested()
5050+ {
5151+ CompileInvalid(
5252+ @"
5353+function main(xs)
5454+{
5555+ var zs = [];
5656+ function f(x)
5757+ {
5858+ if(x mod 2 == 0)
5959+ continue;
6060+ if(x > 6)
6161+ break;
6262+ return x*3+1;
6363+ }
6464+ foreach(var x in xs)
6565+ {
6666+ zs[] = call\sub(f(?),[x]);
6767+ }
6868+6969+ return zs.ToString();
7070+}
7171+",
7272+ CallSub.Alias, "expression");
7373+7474+ //var xs = new List<PValue> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
7575+ //Expect("[ 4, 10, 16 ]", (PValue)xs);
7676+ }
7777+7878+ [Test]
7979+ public void CallSubMacroCommandTopLevel()
8080+ {
8181+ Compile(
8282+ @"
8383+var zs = [];
8484+function main(x1,x2,x3)
8585+{
8686+ function f(x)
8787+ {
8888+ if(x mod 2 == 0)
8989+ continue;
9090+ if(x > 6)
9191+ break;
9292+ return x*3+1;
9393+ }
9494+9595+ zs[] = call\sub(f(?),[x1]);
9696+ zs[] = call\sub(f(?),[x2]);
9797+ call\sub(f(?),[x3]);
9898+9999+ return zs.ToString();
100100+}
101101+");
102102+ Func<List<PValue>> getZs = () =>
103103+ {
104104+ var pv = target.Variables["zs"].Value.Value as List<PValue>;
105105+ return pv ?? new List<PValue>(0);
106106+ };
107107+ Action resetZs = () => getZs().Clear();
108108+109109+ Expect("[ 4, 10 ]", 1, 3);
110110+ resetZs();
111111+112112+ ExpectNull(2, 4, 8);
113113+ Assert.AreEqual(0, getZs().Count);
114114+ resetZs();
115115+116116+ ExpectNull(1, 8, 8);
117117+ var zs = getZs();
118118+ Assert.AreEqual(1, zs.Count);
119119+ AssertPValuesAreEqual(4, zs[0]);
120120+ resetZs();
121121+122122+ ExpectNull(1, 3, 8);
123123+ zs = getZs();
124124+ Assert.AreEqual(2, zs.Count);
125125+ AssertPValuesAreEqual(4, zs[0]);
126126+ AssertPValuesAreEqual(10, zs[1]);
127127+ resetZs();
128128+ }
129129+130130+ [Test]
131131+ public void CallSubMinimal()
132132+ {
133133+ Compile(
134134+ @"
135135+function f(x)
136136+{
137137+ return x;
138138+}
139139+140140+function main()
141141+{
142142+ call\sub(f(?),[2]);
143143+ return 2;
144144+}
145145+");
146146+147147+ Expect(2);
148148+ }
149149+150150+ [Test]
151151+ public void CallSubMinimalReturn()
152152+ {
153153+ Compile(
154154+ @"
155155+function f()
156156+{
157157+ return 1;
158158+}
159159+160160+function main()
161161+{
162162+ var zs = [];
163163+ asm{nop nop nop}
164164+ zs[] = call\sub(f(?));
165165+ asm{nop nop nop}
166166+ return zs[0];
167167+}
168168+");
169169+170170+ Expect(1);
171171+ }
172172+173173+ [Test]
174174+ public void CallSubOfPartial()
175175+ {
176176+ CompileInvalid(
177177+ @"
178178+function main(xs,y)
179179+{
180180+ var zs = [];
181181+ function f(x,y)
182182+ {
183183+ if(x mod 2 == 0)
184184+ continue;
185185+ if(x > y)
186186+ break;
187187+ return x*3+1;
188188+ }
189189+ foreach(var x in xs)
190190+ {
191191+ zs[] = call\sub(f(?,y),[x]);
192192+ }
193193+194194+ return zs.ToString();
195195+}
196196+",
197197+ CallSub.Alias, "expression");
198198+199199+ //var xs = new List<PValue> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
200200+ //Expect("[ 4, 10, 16 ]", (PValue)xs, 6);
201201+ //Expect("[ 4, 10 ]", (PValue)xs, 4);
202202+ }
203203+204204+ [Test]
205205+ public void CaptureUnmentionedMacroVariable()
206206+ {
207207+ Compile(
208208+ @"
209209+ macro echo()
210210+ {
211211+ var f = (x) =>
212212+ if(context is null)
213213+ ""context is null""
214214+ else if(context.LocalSymbols.TryGet(x, ref r))
215215+ var r
216216+ else
217217+ ""cannot resolve $x"";
218218+ println(f.(""x""));
219219+ }
220220+221221+ function main()
222222+ {
223223+ var x = 15;
224224+ echo;
225225+ return x;
226226+ }
227227+");
228228+ var clo = target.Functions["echo\\0"];
229229+ Assert.IsNotNull(clo, "Closure must exist.");
230230+ Assert.IsTrue(clo.Meta.ContainsKey(PFunction.SharedNamesKey));
231231+ Assert.AreEqual(clo.Meta[PFunction.SharedNamesKey].List.Length, 1);
232232+ Assert.AreEqual(clo.Meta[PFunction.SharedNamesKey].List[0].Text,
233233+ MacroAliases.ContextAlias);
234234+235235+ Expect(15, new PValue[0]);
236236+ }
237237+238238+ [Test]
239239+ public void MacroTransport()
240240+ {
241241+ Compile(
242242+ @"
243243+macro echo(lst)
244244+{
245245+ lst = macro\unpack(lst);
246246+ return new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
247247+ context.Invocation.Line,context.Invocation.Column,sum(lst) + lst.Count);
248248+}
249249+250250+macro gen(n)
251251+{
252252+ n = n.Constant~Int;
253253+ var id = macro\pack(1.to(n) >> all);
254254+ var idConst = new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
255255+ context.Invocation.Line,context.Invocation.Column, id);
256256+ return call\macro([echo(idConst)]);
257257+}
258258+259259+function main()
260260+{
261261+ return gen(4);
262262+}
263263+264264+function main2()
265265+{
266266+ return gen(5);
267267+}
268268+");
269269+270270+ Expect(1 + 2 + 3 + 4 + 4);
271271+ ExpectNamed("main2", 1 + 2 + 3 + 4 + 5 + 5);
272272+ }
273273+274274+ [Test]
275275+ public void CallMacroOnFunction()
276276+ {
277277+ Compile(
278278+ @"
279279+macro __append(con)
280280+{
281281+ var c = con.Constant + ""__"";
282282+283283+ if(context.IsJustEffect)
284284+ c += ""je"";
285285+286286+ if(context.Call~Int == Prexonite::Types::PCall.Set~Int)
287287+ c += ""="";
288288+289289+ var con = new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
290290+ context.Invocation.Line,context.Invocation.Column,c);
291291+ return con;
292292+}
293293+294294+macro __surround(con, idx)
295295+{
296296+ var idx = idx.Constant~Int;
297297+ con.Constant = ""__"" + con.Constant;
298298+ return [ call\macro([__append],[con])
299299+ , call\macro([__append(con)])
300300+ , call\macro([__append = con])
301301+ , call\macro([__append,true],[con])
302302+ , call\macro([__append,false],[con])
303303+ , call\macro([__append(con),true])
304304+ , call\macro([__append(con),false])
305305+ , call\macro([__append = con, true])
306306+ , call\macro([__append = con, false]) ][idx];
307307+}
308308+309309+function main(x,y)
310310+{
311311+ return [ x + __surround(""xXx"", 0) + y
312312+ , x + __surround(""xXx"", 1) + y
313313+ , x + __surround(""xXx"", 2) + y
314314+ , x + __surround(""xXx"", 3) + y
315315+ , x + __surround(""xXx"", 4) + y
316316+ , x + __surround(""xXx"", 5) + y
317317+ , x + __surround(""xXx"", 6) + y
318318+ , x + __surround(""xXx"", 7) + y
319319+ , x + __surround(""xXx"", 8) + y];
320320+}
321321+");
322322+323323+ Expect(new List<PValue>
324324+ {
325325+ "a__xXx__b",
326326+ "a__xXx__b",
327327+ "a__xXx__=b",
328328+ "a__xXx__jeb",
329329+ "a__xXx__b",
330330+ "a__xXx__jeb",
331331+ "a__xXx__b",
332332+ "a__xXx__je=b",
333333+ "a__xXx__=b"
334334+ }, "a", "b");
335335+336336+ if (CompileToCil)
337337+ {
338338+ var surround = target.Functions["__surround"];
339339+ Assert.That(surround, Is.Not.Null, "Function __surround does not exist.");
340340+ Assert.That(surround.Meta[PFunction.VolatileKey].Switch,
341341+ Is.False,
342342+ string.Format("Function {0} is volatile. Reason: {1}", surround.Id,
343343+ surround.Meta[PFunction.DeficiencyKey].Text));
344344+ }
345345+ }
346346+347347+348348+ [Test,Ignore("TODO: figure out why this is ignored")]
349349+ public void PartialCallMacroOnFunction()
350350+ {
351351+ Compile(
352352+ @"
353353+macro __append(con)
354354+{
355355+ var c = con.Constant + ""__"";
356356+357357+ if(context.IsJustEffect)
358358+ c += ""je"";
359359+360360+ if(context.Call~Int == Prexonite::Types::PCall.Set~Int)
361361+ c += ""="";
362362+363363+ var con = new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
364364+ context.Invocation.Line,context.Invocation.Column,c);
365365+ return con;
366366+}
367367+368368+macro __surround\create_pa(con, idx)
369369+{
370370+ var idx = idx.Constant~Int;
371371+ con.Constant = ""__"" + con.Constant;
372372+ var f = [ call\macro([?],[?]) // 20
373373+ , call\macro([__append(?0)])
374374+ , call\macro([__append = ?0]) // 22
375375+ , call\macro([__append,?],[con])
376376+ , call\macro([?,?],[?])
377377+ , call\macro([__append(con),?]) // 25
378378+ , call\macro([__append(?0),?])
379379+ , call\macro([__append = ?0, ?]) // 27
380380+ , call\macro([__append = con, ?]) ][idx];
381381+382382+ var fc = macro\pack(f);
383383+ return new Prexonite::Compiler::Ast::AstConstant(context.Invocation.File,
384384+ context.Invocation.Line,context.Invocation.Column,fc);
385385+}
386386+387387+macro __surround(con, idx)
388388+{
389389+ var i = idx.Constant~Int; //37
390390+ var fc = call\macro([__surround\create_pa(con, idx)]).Expression;
391391+ var f = macro\unpack(fc.Constant~Int);
392392+ if(i == 0)
393393+ return f.(macro\reference(__append),con);
394394+ else if(i == 1)
395395+ return f.(con);
396396+ else if(i == 2)
397397+ return f.(con);
398398+ else if(i == 3)
399399+ return f.(true);
400400+ else if(i == 4)
401401+ return f.(macro\reference(__append),false,con);
402402+ else if(i == 5) // 50
403403+ return f.(true);
404404+ else if(i == 6)
405405+ return f.(con, false);
406406+ else if(i == 7)
407407+ return f.(con,true);
408408+ else if(i == 8)
409409+ return f.(false);
410410+ else
411411+ throw ""ZOMG! (invalid index to macro __surround)"";
412412+} // 60
413413+414414+function main(x,y)
415415+{
416416+ return [ x + __surround(""xXx"", 0) + y
417417+ , x + __surround(""xXx"", 1) + y
418418+ , x + __surround(""xXx"", 2) + y
419419+ , x + __surround(""xXx"", 3) + y
420420+ , x + __surround(""xXx"", 4) + y
421421+ , x + __surround(""xXx"", 5) + y
422422+ , x + __surround(""xXx"", 6) + y // 70
423423+ , x + __surround(""xXx"", 7) + y // 71
424424+ , x + __surround(""xXx"", 8) + y]; // 72
425425+}
426426+");
427427+428428+ Expect(new List<PValue>
429429+ {
430430+ "a__xXx__b",
431431+ "a__xXx__b",
432432+ "a__xXx__=b",
433433+ "a__xXx__jeb",
434434+ "a__xXx__b",
435435+ "a__xXx__jeb",
436436+ "a__xXx__b",
437437+ "a__xXx__je=b",
438438+ "a__xXx__=b"
439439+ }, "a", "b");
440440+ }
441441+442442+ [Test]
443443+ public void AstIsExpand()
444444+ {
445445+ Compile(@"
446446+var uniq\\node_t6;
447447+448448+function ast_is_Expand(node_arg)
449449+{asm{
450450+var tmpp0
451451+/* 00 */ ldloc node_arg
452452+/* 01 */ cmd.1 boxed
453453+/* 02 */ get.0 Type
454454+/* 03 */ dup 1
455455+/* 04 */ stloc tmpp0
456456+/* 05 */ check.const ""Object(\""Prexonite.Types.ObjectPType\"")""
457457+/* 06 */ jump.t 9
458458+/* 07 */ ldc.bool false
459459+/* 08 */ ret.value
460460+/* 09 */ ldglob uniq\\node_t6
461461+/* 10 */ check.null
462462+/* 11 */ jump.f 15
463463+/* 12 */ ldc.string ""Prexonite.Compiler.Ast.AstExpand""
464464+/* 13 */ sget.1 ""Object(\""System.Type\"")::GetType""
465465+/* 14 */ stglob uniq\\node_t6
466466+/* 15 */ ldglob uniq\\node_t6
467467+/* 16 */ ldloc tmpp0
468468+/* 17 */ get.0 ClrType
469469+/* 18 */ get.1 IsAssignableFrom
470470+/* 19 */ jump.f 26
471471+/* 20 */ ldloc node_arg
472472+/* 21 */ get.0 CheckForPlaceholders
473473+/* 22 */ cmd.1 $not
474474+/* 23 */ jump.f 26
475475+/* 24 */ ldc.bool true
476476+/* 25 */ jump 27
477477+/* 26 */ ldc.bool false
478478+/* 27 */ ret.value
479479+/* 28 */ }}
480480+481481+function main(n) = ast_is_Expand(n);");
482482+483483+ Expect(true,
484484+ sctx.CreateNativePValue(new AstExpand(NoSourcePosition.Instance,
485485+ EntityRef.MacroCommand.Create("call\\macro"), PCall.Get)));
486486+487487+ }
488488+ }
489489}