Skip to content

Commit e6a7080

Browse files
committed
Merge branch 'master' of github.com:vddCore/EVIL
2 parents 809e218 + 5bffe24 commit e6a7080

11 files changed

Lines changed: 143 additions & 79 deletions

File tree

VirtualMachine/EVIL.Ceres/EVIL.Ceres.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
99
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
1010

11-
<Version>9.2.0</Version>
11+
<Version>9.2.1</Version>
1212

1313
<IsPackable>false</IsPackable>
1414
</PropertyGroup>

VirtualMachine/EVIL.Ceres/ExecutionEngine/Diagnostics/Chunk.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,16 @@ public static Chunk Deserialize(Stream stream, out byte version, out long timest
355355

356356
public Chunk Clone()
357357
{
358+
var contexts = new Dictionary<string, ClosureContext>();
359+
foreach (var kvp in _closureContexts)
360+
{
361+
contexts[kvp.Key] = new ClosureContext(kvp.Value.EnclosedFunctionName);
362+
foreach (var kvp2 in kvp.Value.Values)
363+
{
364+
contexts[kvp.Key].Values[kvp2.Key] = kvp2.Value;
365+
}
366+
}
367+
358368
var clone = new Chunk(
359369
Name,
360370
_code.ToArray(),
@@ -369,7 +379,7 @@ public Chunk Clone()
369379
IsSelfAware = IsSelfAware,
370380
_subChunks = new(_subChunks),
371381
_closures = new(_closures),
372-
_closureContexts = new(_closureContexts),
382+
_closureContexts = contexts,
373383
_labels = new(_labels),
374384
_attributes = new(_attributes),
375385
_parameterInitializers = new(_parameterInitializers),

VirtualMachine/EVIL.Ceres/ExecutionEngine/ExecutionUnit.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace EVIL.Ceres.ExecutionEngine;
77
using EVIL.Ceres.ExecutionEngine.Collections;
88
using EVIL.Ceres.ExecutionEngine.Concurrency;
99
using EVIL.Ceres.ExecutionEngine.Diagnostics;
10+
using EVIL.Ceres.ExecutionEngine.Marshaling;
1011
using EVIL.Ceres.ExecutionEngine.TypeSystem;
1112
using EVIL.CommonTypes.TypeSystem;
1213

@@ -1087,7 +1088,18 @@ public void Step()
10871088
}
10881089
else
10891090
{
1090-
PushValue(targetFrame.Locals![closureInfo.EnclosedId]);
1091+
if (frame.Chunk.ClosureContexts.ContainsKey(closureInfo.EnclosedFunctionName))
1092+
{
1093+
PushValue(
1094+
frame.Chunk.ClosureContexts[
1095+
closureInfo.EnclosedFunctionName
1096+
].Values[closureInfo.EnclosedId]
1097+
);
1098+
}
1099+
else
1100+
{
1101+
PushValue(targetFrame.Locals![closureInfo.EnclosedId]);
1102+
}
10911103
}
10921104
}
10931105
else
@@ -1190,7 +1202,16 @@ public void Step()
11901202
}
11911203
else
11921204
{
1193-
PushValue(a.NativeObject!.GetType().FullName!);
1205+
var obj = a.NativeObject!;
1206+
1207+
if (obj is INativeTypeProvider nativeTypeProvider)
1208+
{
1209+
PushValue(nativeTypeProvider.ProvideType());
1210+
}
1211+
else
1212+
{
1213+
PushValue(a.NativeObject!.GetType().FullName!);
1214+
}
11941215
}
11951216

11961217
break;
@@ -1449,7 +1470,7 @@ public void Step()
14491470

14501471
if (value == DynamicValue.Nil)
14511472
{
1452-
value = new Table();
1473+
value = new Table();
14531474
c.SetEntry(a, value);
14541475
}
14551476

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace EVIL.Ceres.ExecutionEngine.Marshaling;
2+
3+
public interface INativeTypeProvider
4+
{
5+
string ProvideType();
6+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace EVIL.Ceres.LanguageTests;
2+
3+
using EVIL.Ceres.ExecutionEngine.Marshaling;
4+
5+
public class NativeTypeProviderObject : INativeTypeProvider
6+
{
7+
public string ProvideType()
8+
=> "SomeNativeTypeLol";
9+
}

VirtualMachine/Tests/EVIL.Ceres.LanguageTests/TestRunner.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ private async Task<int> Execute(TestSet testSet)
144144
VM.Global.Set("__new_dummy_object_2", new(
145145
(_, _) => DynamicValue.FromObject(new DummyNativeClass()))
146146
);
147+
VM.Global.Set("__new_native_type_provider_object", new (
148+
(_, _) => DynamicValue.FromObject(new NativeTypeProviderObject())));
147149

148150
VM.Global.Set("__throw_test", new(
149151
(fiber, args) => fiber.ThrowFromNative(args[0]))

VirtualMachine/Tests/EVIL.Ceres.LanguageTests/tests/000_regression.vil

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,43 @@
1-
fn delay(ms) {
2-
val end = time.stamp.ms + ms;
3-
while(time.stamp.ms < end){}
1+
#[test]
2+
fn for_loop_table_fill {
3+
val t = {};
44

5-
ret 2.137;
5+
for (rw val i = 0; i < 4; i++) {
6+
t[i] = i;
7+
}
8+
9+
assert.equal(t[0], 0);
10+
assert.equal(t[1], 1);
11+
assert.equal(t[2], 2);
12+
assert.equal(t[3], 3);
613
}
714

15+
816
#[test]
9-
fn yield_zombie {
10-
rw val outer_arg = nil;
11-
rw val zombified = false;
17+
fn for_loop_closure_capture {
18+
val funcs = {};
1219

13-
loc fn dies_and_rises(rw arg) {
14-
rw val zombified_2 = false;
15-
16-
loc fn dies_and_rises_2 {
17-
if (!zombified_2) {
18-
arg = 12;
19-
zombified_2 = true;
20-
yield<delay>(10);
21-
yield<dies_and_rises_2>();
22-
23-
throw arg;
24-
}
25-
}
20+
for (rw val i = 0; i < 3; i++) {
21+
funcs[i] = fn -> i;
22+
}
2623

27-
if (!zombified) {
28-
zombified = true;
29-
yield<delay>(10);
30-
yield<dies_and_rises>();
31-
32-
try {
33-
yield<dies_and_rises_2>();
34-
} catch (e) {
35-
outer_arg = e;
36-
}
37-
}
24+
assert.equal(funcs[0](), 0);
25+
assert.equal(funcs[1](), 1);
26+
assert.equal(funcs[2](), 2);
27+
}
3828

39-
ret "undead";
40-
}
29+
fn delay(ms) {
30+
val end = time.stamp.ms + ms;
31+
while(time.stamp.ms < end){}
4132

42-
zombified = false;
43-
val result = yield<dies_and_rises>();
44-
assert.equal(outer_arg, 12);
45-
assert.equal(result, "undead");
33+
ret 2.137;
4634
}
4735

4836
#[test]
4937
fn tonum_indexing {
5038
val data = { a: { b: { c: "1", d: "2", e: "3", f: "4" } } };
5139
val x = $data.a.b.c * $data.a.b.d;
52-
40+
5341
assert.equal(x, 2);
5442
}
5543

VirtualMachine/Tests/EVIL.Ceres.LanguageTests/tests/008_for_loop.vil

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,49 @@ fn for_multiple_statements {
7575

7676
assert.equal(i, 10);
7777
assert.equal(j, 20);
78+
}
79+
80+
#[test]
81+
fn for_loop_mutates_limit {
82+
rw val i, limit = 5;
83+
84+
for (i = 0; i < limit; i++) {
85+
if (i == 2) limit = 10;
86+
}
87+
88+
assert.equal(i, 10);
89+
}
90+
91+
#[test]
92+
fn for_loop_nested_skip_break {
93+
rw val count = 0;
94+
95+
for (rw val i = 0; i < 5; i++) {
96+
for (rw val j = 0; j < 5; j++) {
97+
if (j == 2) skip;
98+
if (j == 4) break;
99+
count += 1;
100+
}
101+
}
102+
103+
/* j=0,1,3; i=0..4 → 3 * 5 = 15 */
104+
assert.equal(count, 15);
105+
}
106+
107+
#[test]
108+
fn for_skip_increment {
109+
rw val i = 0, count = 0;
110+
111+
for (i; i < 10; i) {
112+
if (i % 2 == 0) {
113+
i++;
114+
skip;
115+
}
116+
117+
count++;
118+
i++;
119+
}
120+
121+
assert.equal(count, 5);
122+
assert.equal(i, 10);
78123
}

VirtualMachine/Tests/EVIL.Ceres.LanguageTests/tests/012_type.vil

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,30 @@ fn value_is_native_type_via_interpolated_string {
127127
}
128128

129129
#[test]
130-
fn value_native_type_get_when_native_object() {
130+
fn value_native_type_get_when_native_object {
131131
val testval = __new_dummy_object();
132132
val type = typeof!(testval);
133133

134134
assert.equal(type, "EVIL.Ceres.LanguageTests.DummyNativeClass");
135135
}
136136

137137
#[test]
138-
fn value_native_type_get_when_not_native_object() {
138+
fn value_native_type_get_when_not_native_object {
139139
val type = typeof!(21.37);
140140
assert.equal(type, nil);
141+
}
142+
143+
#[test]
144+
fn value_native_type_get_when_type_provider {
145+
val testval = __new_native_type_provider_object();
146+
val type = typeof!(testval);
147+
148+
assert.equal(type, "SomeNativeTypeLol");
149+
}
150+
151+
#[test]
152+
fn value_is_native_type_with_provider {
153+
val testval = __new_native_type_provider_object();
154+
155+
assert(testval is NativeObject "SomeNativeTypeLol");
141156
}

VirtualMachine/Tests/EVIL.Ceres.LanguageTests/tests/019_closures.vil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ fn many_subchunks_capture_same_local_no_change {
177177
}
178178

179179
#[test]
180-
fn many_subchunks_capture_same_local_after_change {
180+
fn many_subchunks_capture_local_value_after_change {
181181
rw val local_a = 11;
182182
val f1 = fn(x) -> local_a + x;
183183

@@ -192,7 +192,7 @@ fn many_subchunks_capture_same_local_after_change {
192192

193193
val result = f1(2) + f2(4) + f3(5) + f4(4);
194194

195-
assert.equal(result, 47);
195+
assert.equal(result, 59);
196196
}
197197

198198
fn invoke_func_out_of_scope(f) -> f();

0 commit comments

Comments
 (0)