From 1ac08934396253535efe0fd78c503d50f0d68d27 Mon Sep 17 00:00:00 2001 From: Syeerzy Date: Mon, 23 Apr 2018 14:33:29 +0800 Subject: [PATCH 1/7] add call/cc --- src/schemy/Builtins.cs | 1 + src/schemy/Continuation.cs | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/schemy/Continuation.cs diff --git a/src/schemy/Builtins.cs b/src/schemy/Builtins.cs index c20d59c..03e3615 100644 --- a/src/schemy/Builtins.cs +++ b/src/schemy/Builtins.cs @@ -49,6 +49,7 @@ public static IDictionary CreateBuiltins(Interpreter interpreter builtins[Symbol.FromString("null?")] = NativeProcedure.Create(x => x is List && ((List)x).Count == 0, "null?"); builtins[Symbol.FromString("assert")] = new NativeProcedure(AssertImpl, "assert"); builtins[Symbol.FromString("load")] = NativeProcedure.Create(filename => LoadImpl(interpreter, filename), "load"); + builtins[Symbol.FromString("call/cc")] = NativeProcedure.Create(Continuation.CallWithCurrentContinuation); return builtins; } diff --git a/src/schemy/Continuation.cs b/src/schemy/Continuation.cs new file mode 100644 index 0000000..6ef0509 --- /dev/null +++ b/src/schemy/Continuation.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +namespace Schemy +{ + class Continuation: Exception + { + object Value { get; set; } + StackTrace Stack { get; set; } + Thread Thread { get; set; } + + public static object CallWithCurrentContinuation(ICallable fc1) + { + var ccc = new Continuation { Stack = new StackTrace(), Thread = Thread.CurrentThread }; + try + { + var exitproc = NativeProcedure.Create(v => + { + var f1 = new StackTrace().GetFrames(); + var c1 = ccc.Stack.GetFrames(); + var offset = f1.Length - c1.Length; + if (ccc.Thread == Thread.CurrentThread) + { + for (int i = c1.Length - 1; i >= 0; i--) + { + if (c1[i].GetMethod() != f1[i+offset].GetMethod()) + { + throw new NotImplementedException("not supported, continuation called outside dynamic extent"); + } + } + } + ccc.Value = v; + throw ccc; + }); + return fc1.Call(new List { exitproc }); + } + catch (Continuation c) + { + if (ccc == c) + { + return c.Value; + } + else + { + throw; + } + } + } + } +} From 6384fceaf195c6f080a0316e25cc5e59941b9dc5 Mon Sep 17 00:00:00 2001 From: Syeerzy Date: Mon, 23 Apr 2018 15:01:34 +0800 Subject: [PATCH 2/7] And add Continuation.cs And add Continuation.cs --- src/schemy/schemy.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/schemy/schemy.csproj b/src/schemy/schemy.csproj index 9149780..bea81e7 100644 --- a/src/schemy/schemy.csproj +++ b/src/schemy/schemy.csproj @@ -56,6 +56,7 @@ init.ss + From bad683dba191b171c2f61e4e948573cb16024473 Mon Sep 17 00:00:00 2001 From: Syeerzy Date: Mon, 23 Apr 2018 15:06:52 +0800 Subject: [PATCH 3/7] Add call/cc --- src/schemy/Builtins.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schemy/Builtins.cs b/src/schemy/Builtins.cs index 03e3615..65c6a89 100644 --- a/src/schemy/Builtins.cs +++ b/src/schemy/Builtins.cs @@ -49,7 +49,7 @@ public static IDictionary CreateBuiltins(Interpreter interpreter builtins[Symbol.FromString("null?")] = NativeProcedure.Create(x => x is List && ((List)x).Count == 0, "null?"); builtins[Symbol.FromString("assert")] = new NativeProcedure(AssertImpl, "assert"); builtins[Symbol.FromString("load")] = NativeProcedure.Create(filename => LoadImpl(interpreter, filename), "load"); - builtins[Symbol.FromString("call/cc")] = NativeProcedure.Create(Continuation.CallWithCurrentContinuation); + builtins[Symbol.FromString("call/cc")] = NativeProcedure.Create(Continuation.CallWithCurrentContinuation, "call/cc"); return builtins; } From c70505a55b195122c874af46a0524910fa37a88f Mon Sep 17 00:00:00 2001 From: Syeerzy Date: Mon, 23 Apr 2018 15:15:32 +0800 Subject: [PATCH 4/7] Update tests.ss Add call/cc test --- src/test/tests.ss | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/test/tests.ss b/src/test/tests.ss index 7821c2d..bf4b36c 100644 --- a/src/test/tests.ss +++ b/src/test/tests.ss @@ -114,6 +114,25 @@ (* a b))) (assert (= 20 x))) +(define (test-call/cc) + ; test call/cc + (assert + (= 20 + (call/cc + (lambda (k) + (* 5 4))))) + (assert + (= 4 + (call/cc + (lambda (k) + (* 5 (k 4)))))) + (assert + (= 6 + (+ 2 (call/cc + (lambda (k) + (* 5 (k 4)))))))) + + ;; ========= ;; RUN TESTS @@ -132,7 +151,7 @@ (test-list) (test-syntax) (test-macro) - +(test-call/cc) ;; ======================= ;; Interpreter integration From d2a4bfe9682d5900c40aadfcee4fb902edd67100 Mon Sep 17 00:00:00 2001 From: Syeerzy Date: Mon, 23 Apr 2018 15:20:07 +0800 Subject: [PATCH 5/7] Update README.md call/cc now supported --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 620010c..f5dfe15 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,6 @@ It has most features that a language would support: Many Scheme features are not (yet) supported. Among those are: -* continuation (`call/cc`) * use square brackets `[...]` in place of parenthesis `(...)` From 6badb3b2a62b3d0a549cd1ecb14b88208e92663e Mon Sep 17 00:00:00 2001 From: Syeerzy Date: Mon, 23 Apr 2018 16:03:48 +0800 Subject: [PATCH 6/7] formatting --- src/schemy/Continuation.cs | 58 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/schemy/Continuation.cs b/src/schemy/Continuation.cs index 6ef0509..2d63498 100644 --- a/src/schemy/Continuation.cs +++ b/src/schemy/Continuation.cs @@ -5,46 +5,46 @@ namespace Schemy { class Continuation: Exception - { - object Value { get; set; } - StackTrace Stack { get; set; } - Thread Thread { get; set; } + { + object Value { get; set; } + StackTrace Stack { get; set; } + Thread Thread { get; set; } - public static object CallWithCurrentContinuation(ICallable fc1) - { - var ccc = new Continuation { Stack = new StackTrace(), Thread = Thread.CurrentThread }; - try + public static object CallWithCurrentContinuation(ICallable fc1) + { + var ccc = new Continuation { Stack = new StackTrace(), Thread = Thread.CurrentThread }; + try { var exitproc = NativeProcedure.Create(v => - { - var f1 = new StackTrace().GetFrames(); - var c1 = ccc.Stack.GetFrames(); + { + var f1 = new StackTrace().GetFrames(); + var c1 = ccc.Stack.GetFrames(); var offset = f1.Length - c1.Length; - if (ccc.Thread == Thread.CurrentThread) - { - for (int i = c1.Length - 1; i >= 0; i--) - { - if (c1[i].GetMethod() != f1[i+offset].GetMethod()) - { - throw new NotImplementedException("not supported, continuation called outside dynamic extent"); - } - } - } - ccc.Value = v; - throw ccc; - }); + if (ccc.Thread == Thread.CurrentThread) + { + for (int i = c1.Length - 1; i >= 0; i--) + { + if (c1[i].GetMethod() != f1[i+offset].GetMethod()) + { + throw new NotImplementedException("not supported, continuation called outside dynamic extent"); + } + } + } + ccc.Value = v; + throw ccc; + }); return fc1.Call(new List { exitproc }); } - catch (Continuation c) - { - if (ccc == c) + catch (Continuation c) + { + if (ccc == c) { - return c.Value; + return c.Value; } else { throw; - } + } } } } From 1eaa7e78025134ec0e549cac41b227ee06ea44b1 Mon Sep 17 00:00:00 2001 From: Syeerzy Date: Mon, 23 Apr 2018 16:46:31 +0800 Subject: [PATCH 7/7] formatting repace space with tab --- src/schemy/Continuation.cs | 70 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/schemy/Continuation.cs b/src/schemy/Continuation.cs index 2d63498..dc54cd5 100644 --- a/src/schemy/Continuation.cs +++ b/src/schemy/Continuation.cs @@ -1,50 +1,50 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; namespace Schemy { - class Continuation: Exception - { - object Value { get; set; } - StackTrace Stack { get; set; } - Thread Thread { get; set; } - - public static object CallWithCurrentContinuation(ICallable fc1) - { - var ccc = new Continuation { Stack = new StackTrace(), Thread = Thread.CurrentThread }; - try + class Continuation : Exception + { + object Value { get; set; } + StackTrace Stack { get; set; } + Thread Thread { get; set; } + + public static object CallWithCurrentContinuation(ICallable fc1) + { + var ccc = new Continuation { Stack = new StackTrace(), Thread = Thread.CurrentThread }; + try { - var exitproc = NativeProcedure.Create(v => - { - var f1 = new StackTrace().GetFrames(); - var c1 = ccc.Stack.GetFrames(); - var offset = f1.Length - c1.Length; - if (ccc.Thread == Thread.CurrentThread) - { - for (int i = c1.Length - 1; i >= 0; i--) - { - if (c1[i].GetMethod() != f1[i+offset].GetMethod()) - { - throw new NotImplementedException("not supported, continuation called outside dynamic extent"); - } - } - } - ccc.Value = v; - throw ccc; - }); + var exitproc = NativeProcedure.Create(v => + { + var f1 = new StackTrace().GetFrames(); + var c1 = ccc.Stack.GetFrames(); + var offset = f1.Length - c1.Length; + if (ccc.Thread == Thread.CurrentThread) + { + for (int i = c1.Length - 1; i >= 0; i--) + { + if (c1[i].GetMethod() != f1[i + offset].GetMethod()) + { + throw new NotImplementedException("not supported, continuation called outside dynamic extent"); + } + } + } + ccc.Value = v; + throw ccc; + }); return fc1.Call(new List { exitproc }); - } - catch (Continuation c) - { - if (ccc == c) + } + catch (Continuation c) + { + if (ccc == c) { - return c.Value; + return c.Value; } else { throw; - } + } } } }