-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathinterp_in_thread.cs
70 lines (62 loc) · 2.04 KB
/
interp_in_thread.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
// An example of running Lisp in another thread
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using System.Threading;
// csc -o -t:library -r:System.Numerics.dll ../lisp.cs ../arith.cs
// csc -r:lisp.dll interp_in_thread.cs
// mono interp_in_thread.exe
// Expected output:
// => (1 . 2)
// Reiwa
// => Reiwa
public static class ThreadTest {
// A simple substitute for Console.Out
class SendOut: TextWriter {
public BlockingCollection<object> Queue
= new BlockingCollection<object>();
public override Encoding Encoding => Encoding.UTF8;
public override void Write(char value) {
Queue.Add(value);
}
}
static readonly string EndSentinel = ":END";
// A Read-Eval-Send Loop in another thread
static void RESLoop(SendOut so, BlockingCollection<string> receiveIn) {
var interp = NukataLisp.MakeInterp().Result;
interp.COut = so;
for (;;) {
string s = receiveIn.Take();
if (s == EndSentinel)
break;
object x = NukataLisp.Run(interp, new StringReader(s)).Result;
so.Queue.Add(x);
so.Queue.Add(EndSentinel);
}
so.Queue.Add(EndSentinel);
}
// Run Lisp in another thread and send it S-expression strings.
static void Main(string[] args) {
SendOut so = new SendOut();
var queue = new BlockingCollection<string>();
new Thread(() => RESLoop(so, queue)).Start();
foreach (string sExpression in new string[]{
"(cons 1 2)",
"(print 'Reiwa)",
EndSentinel
}) {
queue.Add(sExpression);
for (;;) {
object x = so.Queue.Take();
if (x is string s && s == EndSentinel) {
break;
} else if (x is char ch) {
Console.Write(ch);
} else {
Console.WriteLine("=> {0}", x);
}
}
}
}
}