# DJLang **Repository Path**: ZerAx/DJLang ## Basic Information - **Project Name**: DJLang - **Description**: 一个简易的Lisp方言。Unity Package版 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2023-03-22 - **Last Updated**: 2023-04-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DJLang ---------------- 我开发自用的一个简易的脚本解释器。 + [语法](Documentation~/Syntax.md) + [标准库](Documentation~/StandardLibrary.md) ## 入门 这是一段让Unity Console输出`Hello, world!`的程序。 ``` csharp var env = new DJEnv(); env.LoadStandard(DJStdLoadFlags.Arithmetics); var hello = new DJReader("(+ \"Hello\" \", world!\")") .EvaluateToEnd(env) .GetManaged(); Debug.Log(hello); ``` `DJEnv` 类用于存储环境中定义的变量。 `DJReader` 构造于一个 `TextReader` ,可以将其中的内容解析成可被求值的 `DJValue` 的对象。 ## 添加自定义函数 可以向 `DJEnv.PutFunction()` 方法传入函数名和 `DJCallableDelegate` 类型的委托来自定义函数。委托定义如下 ``` csharp public delegate IDJValue DJCallableDelegate(DJEnv env, DJSeq args); ``` 下面是一个例子,实现了一个让Unity Console输出第一个参数的函数。 ``` csharp var env = new DJEnv(); env.PutFunction("debug", (env, args) => { Debug.Log(args.Pop()); return new DJNil(); }); new DJReader("(debug 123)").EvaluateToEnd(env); ``` 也可以为类中的**静态方法**添加 `[DJFunc(string name)]` 特性。这样就可以调用 `DJEnv.PutLibrary()` 方法,使用反射的方式批量添加自定义函数。 ``` csharp class Demo { [DJFunc("debug")] public static IDJValue DebugLog(DJEnv env, DJSeq args) { Debug.Log(args.Pop()); return new DJNil(); } } var env = new DJEnv(); env.PutLibrary(typeof(Demo)); // or env.PutLibrary(); new DJReader("(debug 123)").EvaluateToEnd(env); ``` ## 添加自定义宏 类似自定义函数,有两种方法添加宏。([宏是什么?](Documentation~/Syntax.md#宏)) 1. 直接调用 `DJEnv.PutMacro()` 方法。 ``` csharp var env = new DJEnv(); env.PutMacro("println", (env, args) => { Debug.Log(args.Pop()); return new DJNil(); }); new DJReader("(println! 123)").EvaluateToEnd(env); ``` 2. 为类中的静态方法添加 `[DJMacro(string name)]` 属性。 ``` csharp class Demo { [DJMacro("println")] public static IDJValue PrintLn(DJEnv env, DJSeq args) { Debug.Log(args.Pop().Evaluate(env)); return new DJNil(); } } var env = new DJEnv(); env.PutLibrary(typeof(Demo)); // or env.PutLibrary(); new DJReader("(println! 123)").EvaluateToEnd(env); ```