我正在研究自己设计的函数式编程语言,我偶然发现了一个超出我的解决技能的问题.我想知道是否有人有任何关于如何解决它的建议或者为什么不可能的原因.
下面的代码概述了一个不理想但折衷的解决方案.
这个问题是我目前使用的运行时系统的核心.我没有依赖.Net堆栈,而是使用monad在蹦床上执行操作.这应该有助于逐步调试,并允许用户不必担心堆栈空间.这是我目前正在使用的monad的简化版本.
type 't StackFree =
|Return of 't //Return a value
|StackPush of ('t->'t StackFree)*'t StackFree //Pushes a return handler onto the "Stack"
|Continuation of (unit->'t StackFree) //Perform a simple opperation
type StackFreeMonad() =
member this.Delay(fn) =
Continuation(fn)
member this.Bind(expr,fn) =
StackPush(fn,expr)
member this.Return(value) =
Return(value)
member this.ReturnFrom(x) =x
let stackfree = StackFreeMonad()
Run Code Online (Sandbox Code Playgroud)
这不是最初的设计,但它是我在理想世界中使用F#计算表达式时最好的,上面的计算表达式可以在这种类型上工作.
type 't Running =
|Result of 't
|Step of (unit->'t Running)
Run Code Online (Sandbox Code Playgroud)
因此,为了将StackFree转换为Running类型,我必须使用此转换函数
//this method loops through the StackFree structure finding the next computation and …Run Code Online (Sandbox Code Playgroud) 我正在开发一个宠物项目:Javascript/Scheme 思维方式的编程语言 该项目可以在这里找到
我浏览了现有的 Stackoverflow 问题,例如Making a CLR/.NET Language Debuggable。然而,这些解决方案中的大多数都涉及生成程序集。由于多种原因,我宁愿避免创建新的程序集。
class Program
{
public static void ThrowingFunction()
{
throw new Exception("Test Exception");
}
static void Main(string[] args)
{
Action thw = ThrowingFunction;
ParameterExpression param = Expression.Parameter(typeof(int), "arg");
SymbolDocumentInfo info = Expression.SymbolDocument("example-script", new Guid("83c65910-8376-11e2-9e96-0800200c9a66"));
Expression<Func<int,int>> exp = Expression.Lambda<Func<int,int>>(
Expression.Block(
Expression.DebugInfo(info,1,1,1,20),
Expression.Invoke(Expression.Constant(thw, typeof(Action))),
Expression.Add(param,Expression.Constant(1))
),
new List<ParameterExpression> { param }
);
Console.WriteLine(exp);
Func<int,int> Fn = exp.Compile(DebugInfoGenerator.CreatePdbGenerator());
try {
Fn(1);
}
catch (Exception e) {
Console.WriteLine(e);
Console.WriteLine(e.InnerException);
}
}
} …Run Code Online (Sandbox Code Playgroud)