Skip to content

Commit 1681128

Browse files
author
Rick Button
committed
Reimplemented interpreter as a parser->compiler->vm
1 parent cd60b85 commit 1681128

55 files changed

Lines changed: 1706 additions & 529 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
##
44
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
55

6-
src/Scheme.NET/Parser/*
6+
src/Scheme.NET/Parser/Scheme*.cs
7+
src/Scheme.NET/Parser/*.tokens
78

89
# User-specific files
910
*.suo

Scheme.NET.sln

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scheme.NET", "src\Scheme.NE
88
EndProject
99
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scheme.NET.Repl", "src\Scheme.NET.Repl\Scheme.NET.Repl.csproj", "{7B11B275-176B-4EC7-9E2A-B5898AAB643B}"
1010
EndProject
11-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scheme.NET.Tests", "src\Scheme.NET.Tests\Scheme.NET.Tests.csproj", "{BC7B7181-E2C2-489C-9793-4E27E7DD4085}"
11+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scheme.NET.Tests", "src\Scheme.NET.Tests\Scheme.NET.Tests.csproj", "{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}"
1212
EndProject
1313
Global
1414
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -44,25 +44,25 @@ Global
4444
{7B11B275-176B-4EC7-9E2A-B5898AAB643B}.Release|x64.Build.0 = Release|Any CPU
4545
{7B11B275-176B-4EC7-9E2A-B5898AAB643B}.Release|x86.ActiveCfg = Release|Any CPU
4646
{7B11B275-176B-4EC7-9E2A-B5898AAB643B}.Release|x86.Build.0 = Release|Any CPU
47-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
48-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Debug|Any CPU.Build.0 = Debug|Any CPU
49-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Debug|x64.ActiveCfg = Debug|Any CPU
50-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Debug|x64.Build.0 = Debug|Any CPU
51-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Debug|x86.ActiveCfg = Debug|Any CPU
52-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Debug|x86.Build.0 = Debug|Any CPU
53-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Release|Any CPU.ActiveCfg = Release|Any CPU
54-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Release|Any CPU.Build.0 = Release|Any CPU
55-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Release|x64.ActiveCfg = Release|Any CPU
56-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Release|x64.Build.0 = Release|Any CPU
57-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Release|x86.ActiveCfg = Release|Any CPU
58-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085}.Release|x86.Build.0 = Release|Any CPU
47+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
48+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Debug|Any CPU.Build.0 = Debug|Any CPU
49+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Debug|x64.ActiveCfg = Debug|Any CPU
50+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Debug|x64.Build.0 = Debug|Any CPU
51+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Debug|x86.ActiveCfg = Debug|Any CPU
52+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Debug|x86.Build.0 = Debug|Any CPU
53+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Release|Any CPU.ActiveCfg = Release|Any CPU
54+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Release|Any CPU.Build.0 = Release|Any CPU
55+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Release|x64.ActiveCfg = Release|Any CPU
56+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Release|x64.Build.0 = Release|Any CPU
57+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Release|x86.ActiveCfg = Release|Any CPU
58+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A}.Release|x86.Build.0 = Release|Any CPU
5959
EndGlobalSection
6060
GlobalSection(SolutionProperties) = preSolution
6161
HideSolutionNode = FALSE
6262
EndGlobalSection
6363
GlobalSection(NestedProjects) = preSolution
6464
{5D57952D-981E-4C49-BC98-3A20E07DC216} = {5CB99A27-2E63-4C9E-9866-AE1B3FBC6D5C}
6565
{7B11B275-176B-4EC7-9E2A-B5898AAB643B} = {5CB99A27-2E63-4C9E-9866-AE1B3FBC6D5C}
66-
{BC7B7181-E2C2-489C-9793-4E27E7DD4085} = {5CB99A27-2E63-4C9E-9866-AE1B3FBC6D5C}
66+
{9153593C-2CD3-4FF5-93A0-3A6DB52AB28A} = {5CB99A27-2E63-4C9E-9866-AE1B3FBC6D5C}
6767
EndGlobalSection
6868
EndGlobal

src/Scheme.NET.Repl/Program.cs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,70 @@
33
using System.Linq;
44
using System.Text;
55
using System.Threading.Tasks;
6-
using Scheme.NET.Eval;
7-
using Scheme.NET.Lib;
86
using Antlr4.Runtime;
9-
using Scheme.NET.Visitors;
107
using Scheme.NET.Scheme;
8+
using Scheme.NET.VirtualMachine.Compiler;
9+
using Scheme.NET.VirtualMachine;
10+
using Scheme.NET.VirtualMachine.Natives;
11+
using Scheme.NET.Parser;
1112

1213
namespace Scheme.NET.Repl
1314
{
1415
class Program
1516
{
17+
18+
19+
1620
public static void Main(string[] args)
1721
{
18-
var env = Environment.Create();
22+
Console.WriteLine("Scheme.NET REPL v0.1");
23+
Console.WriteLine("\n\n");
24+
25+
var lib = Library.CreateBase();
26+
var vm = new SchemeVM(lib);
1927

2028
var input = "";
2129
while (true)
2230
{
23-
input += Console.ReadLine();
24-
if (IsBalanced(input))
31+
if (string.IsNullOrWhiteSpace(input))
32+
Console.Write("> ");
33+
34+
input += Console.ReadLine() + "\n";
35+
try
2536
{
26-
try
37+
if (IsBalanced(input))
2738
{
28-
var arr = env.Eval(input);
39+
var arr = ParserHelpers.Parse(input);
40+
var carr = arr.Select(a => SchemeCompiler.Compile(a));
2941

30-
foreach (var a in arr)
42+
foreach (var c in carr)
3143
{
32-
if (a != null)
33-
Console.WriteLine(a.String());
44+
var s = vm.Execute(c);
45+
if (s != null)
46+
Console.WriteLine(s.String());
3447
}
35-
} catch (Exception e)
36-
{
37-
Console.WriteLine("[ERROR] " + e.Message);
48+
input = "";
3849
}
50+
}
51+
catch (Exception e)
52+
{
53+
Console.WriteLine("ERROR: " + e.Message);
3954
input = "";
40-
4155
}
4256
}
4357
}
4458

59+
public static int CountOpen(string input) { return input.Count(c => c == '('); }
60+
public static int CountClose(string input) { return input.Count(c => c == ')'); }
61+
4562
public static bool IsBalanced(string input)
4663
{
4764
int count = 0;
4865
for (int i = 0; i < input.Length; i++)
4966
{
5067
if (input[i] == '(') count++;
5168
if (input[i] == ')') count--;
52-
if (count < 0) return false;
69+
if (count < 0) throw new Exception("invalid syntax");
5370
}
5471
if (count == 0) return true;
5572
return false;

src/Scheme.NET.Tests/ProcedureTests/EqTest.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using NUnit.Framework;
2-
using Scheme.NET.Eval;
3-
using Scheme.NET.Lib;
42
using Scheme.NET.Scheme;
53
using System;
64
using System.Collections.Generic;
@@ -66,9 +64,9 @@ public void TestNil()
6664
[Test]
6765
public void TestLocs()
6866
{
69-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("a"), Eval("(1 . 2)"));
70-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("b"), Eval("\"test\""));
71-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("c"), Eval("#(1 2)"));
67+
VM.E.DefineHere(AtomHelper.SymbolFromString("a"), Eval("(1 . 2)"));
68+
VM.E.DefineHere(AtomHelper.SymbolFromString("b"), Eval("\"test\""));
69+
VM.E.DefineHere(AtomHelper.SymbolFromString("c"), Eval("#(1 2)"));
7270
Assert.AreEqual(AtomHelper.True, Eval("(eq? a a)"));
7371
Assert.AreEqual(AtomHelper.True, Eval("(eq? b b)"));
7472
Assert.AreEqual(AtomHelper.True, Eval("(eq? c c)"));

src/Scheme.NET.Tests/ProcedureTests/EqualTest.cs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using NUnit.Framework;
2-
using Scheme.NET.Eval;
3-
using Scheme.NET.Lib;
42
using Scheme.NET.Scheme;
53
using System;
64
using System.Collections.Generic;
@@ -66,15 +64,15 @@ public void TestNil()
6664
[Test]
6765
public void TestLocs()
6866
{
69-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("a"), Eval("(1 . 2)"));
70-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("a2"), Eval("(1 . 3)"));
71-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("a3"), Eval("(1 . 2)"));
72-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("b"), Eval("\"test\""));
73-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("b2"), Eval("\"testa\""));
74-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("b3"), Eval("\"test\""));
75-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("c"), Eval("#(1 2)"));
76-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("c2"), Eval("#(1 3)"));
77-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("c3"), Eval("#(1 2)"));
67+
VM.E.DefineHere(AtomHelper.SymbolFromString("a"), Eval("(1 . 2)"));
68+
VM.E.DefineHere(AtomHelper.SymbolFromString("a2"), Eval("(1 . 3)"));
69+
VM.E.DefineHere(AtomHelper.SymbolFromString("a3"), Eval("(1 . 2)"));
70+
VM.E.DefineHere(AtomHelper.SymbolFromString("b"), Eval("\"test\""));
71+
VM.E.DefineHere(AtomHelper.SymbolFromString("b2"), Eval("\"testa\""));
72+
VM.E.DefineHere(AtomHelper.SymbolFromString("b3"), Eval("\"test\""));
73+
VM.E.DefineHere(AtomHelper.SymbolFromString("c"), Eval("#(1 2)"));
74+
VM.E.DefineHere(AtomHelper.SymbolFromString("c2"), Eval("#(1 3)"));
75+
VM.E.DefineHere(AtomHelper.SymbolFromString("c3"), Eval("#(1 2)"));
7876
Assert.AreEqual(AtomHelper.True, Eval("(equal? a a)"));
7977
Assert.AreEqual(AtomHelper.False, Eval("(equal? a a2)"));
8078
Assert.AreEqual(AtomHelper.True, Eval("(equal? a a3)"));

src/Scheme.NET.Tests/ProcedureTests/EqvTest.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using NUnit.Framework;
2-
using Scheme.NET.Eval;
3-
using Scheme.NET.Lib;
42
using Scheme.NET.Scheme;
53
using System;
64
using System.Collections.Generic;
@@ -66,9 +64,9 @@ public void TestNil()
6664
[Test]
6765
public void TestLocs()
6866
{
69-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("a"), Eval("(1 . 2)"));
70-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("b"), Eval("\"test\""));
71-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("c"), Eval("#(1 2)"));
67+
VM.E.DefineHere(AtomHelper.SymbolFromString("a"), Eval("(1 . 2)"));
68+
VM.E.DefineHere(AtomHelper.SymbolFromString("b"), Eval("\"test\""));
69+
VM.E.DefineHere(AtomHelper.SymbolFromString("c"), Eval("#(1 2)"));
7270
Assert.AreEqual(AtomHelper.True, Eval("(eqv? a a)"));
7371
Assert.AreEqual(AtomHelper.True, Eval("(eqv? b b)"));
7472
Assert.AreEqual(AtomHelper.True, Eval("(eqv? c c)"));
Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using NUnit.Framework;
2-
using Scheme.NET.Eval;
3-
using Scheme.NET.Lib;
2+
using Scheme.NET.Parser;
43
using Scheme.NET.Scheme;
4+
using Scheme.NET.VirtualMachine;
5+
using Scheme.NET.VirtualMachine.Compiler;
6+
using Scheme.NET.VirtualMachine.Natives;
57
using System;
68
using System.Collections.Generic;
79
using System.Linq;
@@ -12,18 +14,27 @@ namespace Scheme.NET.Tests.ProcedureTests
1214
{
1315
public abstract class TestBase
1416
{
15-
protected SchemeLexer Lexer;
16-
protected Environment Env;
17+
protected ISchemeVM VM { get; private set; }
1718

1819
[SetUp]
1920
public void SetUp()
2021
{
21-
Env = Environment.Create();
22+
var lib = Library.CreateBase();
23+
VM = new SchemeVM(lib);
24+
}
25+
26+
protected ISExpression Eval(ISExpression e)
27+
{
28+
var a = SchemeCompiler.Compile(e);
29+
return VM.Execute(a);
2230
}
2331

2432
protected ISExpression Eval(string input)
2533
{
26-
var s = Env.Eval(input);
34+
var arr = ParserHelpers.Parse(input);
35+
var carr = arr.Select(a => SchemeCompiler.Compile(a));
36+
var s = carr.Select(c => VM.Execute(c));
37+
2738
if (s.Count() > 0)
2839
return s.First();
2940
else
@@ -32,7 +43,10 @@ protected ISExpression Eval(string input)
3243

3344
protected IEnumerable<ISExpression> EvalAll(string input)
3445
{
35-
return Env.Eval(input);
46+
var arr = ParserHelpers.Parse(input);
47+
var carr = arr.Select(a => SchemeCompiler.Compile(a));
48+
var s = carr.Select(c => VM.Execute(c));
49+
return s;
3650
}
3751
}
3852
}

src/Scheme.NET.Tests/ScriptTests.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using NUnit.Framework;
2-
using Scheme.NET.Eval;
32
using Scheme.NET.Scheme;
43
using Scheme.NET.Tests.ProcedureTests;
54
using System;
@@ -23,8 +22,12 @@ public void TestScripts()
2322
var path = Path.GetDirectoryName(typeof(ScriptTests).GetTypeInfo().Assembly.Location);
2423
var tests = File.ReadAllText(Path.Combine(path, "tests.scm"));
2524

26-
Env.GlobalScope.Define(AtomHelper.SymbolFromString("test"),
27-
AtomHelper.CreateProcedure("test", Test, true));
25+
var def = AtomHelper.CreateList(
26+
AtomHelper.SymbolFromString("define"),
27+
AtomHelper.SymbolFromString("test"),
28+
AtomHelper.CreateList(AtomHelper.SymbolFromString("lambda"), AtomHelper.Nil, AtomHelper.CreateProcedure("test", Test, false))
29+
);
30+
Eval(def);
2831

2932
var errors = "";
3033
var exprs = EvalAll(tests).ToArray();
@@ -52,15 +55,11 @@ private ISExpression Test(Scope scope, IEnumerable<ISExpression> args)
5255

5356
try
5457
{
55-
56-
var actualResult = Evaluator.Eval(scope, actual);
57-
var expectedResult = Evaluator.Eval(scope, expected);
58-
59-
if (actualResult.Equals(expectedResult))
58+
if (actual.Equals(expected))
6059
return AtomHelper.True;
6160

6261
return AtomHelper.StringFromString(
63-
$"[FAIL] expected [ {expected.String()} ], but result of [ {actual.String()} ] was [ {actualResult.String()} ]");
62+
$"[FAIL] expected [ {expected.String()} ], but result of [ {actual.String()} ] was [ {actual.String()} ]");
6463
} catch (Exception e)
6564
{
6665
return AtomHelper.StringFromString(

src/Scheme.NET/Lib/Eval.cs

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)