/
ScopeTests.cs
137 lines (117 loc) · 5.84 KB
/
ScopeTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System;
using Rook.Compiling.Syntax;
using Rook.Compiling.Types;
using Should;
using Xunit;
namespace Rook.Compiling
{
public class ScopeTests
{
private static readonly NamedType Integer = NamedType.Integer;
private static readonly NamedType Boolean = NamedType.Boolean;
private readonly Scope global, ab, cd;
public ScopeTests()
{
var typeChecker = new TypeChecker();
global = new GlobalScope(typeChecker);
ab = new LocalScope(global);
ab.Bind("a", Integer);
ab.Bind("b", Integer);
cd = new LocalScope(ab);
cd.Bind("c", Boolean);
cd.Bind("d", Boolean);
}
[Fact]
public void StoresLocals()
{
AssertType(Integer, ab, "a");
AssertType(Integer, ab, "b");
AssertType(Boolean, cd, "c");
AssertType(Boolean, cd, "d");
}
[Fact]
public void DefersToSurroundingScopeAfterSearchingLocals()
{
AssertType(Integer, cd, "a");
AssertType(Integer, cd, "b");
}
[Fact]
public void ProvidesContainmentPredicate()
{
ab.Contains("a").ShouldBeTrue();
ab.Contains("b").ShouldBeTrue();
ab.Contains("c").ShouldBeFalse();
ab.Contains("d").ShouldBeFalse();
ab.Contains("z").ShouldBeFalse();
cd.Contains("a").ShouldBeTrue();
cd.Contains("b").ShouldBeTrue();
cd.Contains("c").ShouldBeTrue();
cd.Contains("d").ShouldBeTrue();
cd.Contains("z").ShouldBeFalse();
}
[Fact]
public void ProvidesBuiltinSignaturesInTheGlobalScope()
{
AssertType("System.Func<int, int, bool>", global, "<");
AssertType("System.Func<int, int, bool>", global, "<=");
AssertType("System.Func<int, int, bool>", global, ">");
AssertType("System.Func<int, int, bool>", global, ">=");
AssertType("System.Func<int, int, bool>", global, "==");
AssertType("System.Func<int, int, bool>", global, "!=");
AssertType("System.Func<int, int, int>", global, "+");
AssertType("System.Func<int, int, int>", global, "-");
AssertType("System.Func<int, int, int>", global, "*");
AssertType("System.Func<int, int, int>", global, "/");
AssertType("System.Func<bool, bool, bool>", global, "||");
AssertType("System.Func<bool, bool, bool>", global, "&&");
AssertType("System.Func<bool, bool>", global, "!");
AssertType("System.Func<Rook.Core.Nullable<0>, 0, 0>", global, "??");
AssertType("System.Func<0, Rook.Core.Void>", global, "Print");
AssertType("System.Func<0, Rook.Core.Nullable<0>>", global, "Nullable");
AssertType("System.Func<System.Collections.Generic.IEnumerable<0>, 0>", global, "First");
AssertType("System.Func<System.Collections.Generic.IEnumerable<0>, int, System.Collections.Generic.IEnumerable<0>>", global, "Take");
AssertType("System.Func<System.Collections.Generic.IEnumerable<0>, int, System.Collections.Generic.IEnumerable<0>>", global, "Skip");
AssertType("System.Func<System.Collections.Generic.IEnumerable<0>, bool>", global, "Any");
AssertType("System.Func<System.Collections.Generic.IEnumerable<0>, int>", global, "Count");
AssertType("System.Func<System.Collections.Generic.IEnumerable<0>, System.Func<0, 1>, System.Collections.Generic.IEnumerable<1>>", global, "Select");
AssertType("System.Func<System.Collections.Generic.IEnumerable<0>, System.Func<0, bool>, System.Collections.Generic.IEnumerable<0>>", global, "Where");
AssertType("System.Func<Rook.Core.Collections.Vector<0>, System.Collections.Generic.IEnumerable<0>>", global, "Each");
AssertType("System.Func<Rook.Core.Collections.Vector<0>, int, 0>", global, "Index");
AssertType("System.Func<Rook.Core.Collections.Vector<0>, int, int, Rook.Core.Collections.Vector<0>>", global, "Slice");
AssertType("System.Func<Rook.Core.Collections.Vector<0>, 0, Rook.Core.Collections.Vector<0>>", global, "Append");
AssertType("System.Func<Rook.Core.Collections.Vector<0>, int, 0, Rook.Core.Collections.Vector<0>>", global, "With");
}
[Fact]
public void CanBePopulatedWithAUniqueBinding()
{
global.TryIncludeUniqueBinding(new Parameter(null, Integer, "a")).ShouldBeTrue();
global.TryIncludeUniqueBinding(new Parameter(null, Boolean, "b")).ShouldBeTrue();
AssertType(Integer, global, "a");
AssertType(Boolean, global, "b");
}
[Fact]
public void DemandsUniqueBindingsWhenIncludingUniqueBindings()
{
global.TryIncludeUniqueBinding(new Parameter(null, Integer, "a")).ShouldBeTrue();
global.TryIncludeUniqueBinding(new Parameter(null, Integer, "a")).ShouldBeFalse();
global.TryIncludeUniqueBinding(new Parameter(null, Boolean, "a")).ShouldBeFalse();
AssertType(Integer, global, "a");
}
private static void AssertType(DataType expectedType, Scope scope, string key)
{
DataType value;
if (scope.TryGet(key, out value))
value.ShouldEqual(expectedType);
else
throw new Exception("Failed to look up the type of '" + key + "' in the Scope");
}
private static void AssertType(string expectedType, Scope scope, string key)
{
DataType value;
if (scope.TryGet(key, out value))
expectedType.ShouldEqual(value.ToString());
else
throw new Exception("Failed to look up the type of '" + key + "' in the Scope");
}
}
}