浏览代码

feat: 字面量支持尾调递归优化

SongZihuan 3 年之前
父节点
当前提交
d975787654
共有 4 个文件被更改,包括 71 次插入22 次删除
  1. 16 4
      src/core/__env.h
  2. 49 15
      src/core/env.c
  3. 5 2
      src/core/run.c
  4. 1 1
      src/main.c

+ 16 - 4
src/core/__env.h

@@ -8,6 +8,7 @@ typedef struct af_Activity af_Activity;
 typedef struct af_EnvVarSpace af_EnvVarSpace;
 typedef struct af_EnvVar af_EnvVar;
 typedef struct af_TopMsgProcess af_TopMsgProcess;
+typedef struct af_LiteralDataList af_LiteralDataList;
 
 #include "env.h"
 #include "__object.h"
@@ -47,6 +48,11 @@ struct af_Message {
     struct af_Message *next;
 };
 
+struct af_LiteralDataList {
+    char *literal_data;
+    struct af_LiteralDataList *next;
+};
+
 struct af_Activity {  // 活动记录器
     struct af_Activity *prev;  // 上一个活动记录器
 
@@ -89,7 +95,7 @@ struct af_Activity {  // 活动记录器
 
     /* 字面量专项 */
     bool is_literal;  // 处于字面量运算 意味着函数调用结束后会调用指定API
-    char *literal_data;  // bt->literal.literal_data
+    struct af_LiteralDataList *ld;
 };
 
 struct af_TopMsgProcess {  // 顶层msg处理器
@@ -118,10 +124,10 @@ struct af_Environment {  // 运行环境
     bool process_msg_first;  // 优先处理msg而不是运行代码
 };
 
-/* Core管理寒素 */
+/* Core 管理函数 */
 af_Object *getBaseObjectFromCore(char *name, af_Core *core);
 
-/* Activity运行初始化函数 */
+/* Activity 运行初始化函数 */
 bool addTopActivity(af_Code *code, af_Environment *env);
 
 /* 运行时Activity设置函数 (新增Activity) */
@@ -135,6 +141,12 @@ bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env);
 bool pushMacroFuncActivity(af_Object *func, af_Environment *env);
 bool setFuncActivityToArg(af_Object *func, af_Environment *env);
 bool setFuncActivityAddVar(bool new_vsl, bool is_protect, af_Environment *env);
-
 int setFuncActivityToNormal(af_Environment *env);
+
+/* LiteralData 释放函数 */
+void freeAllLiteralData(af_LiteralDataList *ld);
+
+/* LiteralData 操作函数 */
+void pushLiteralData(char *data, af_Environment *env);
+
 #endif //AFUN__ENV_H

+ 49 - 15
src/core/env.c

@@ -1,32 +1,32 @@
 #include "__env.h"
 
-/* 核心创建和释放 */
+/* Core 创建和释放 */
 static af_Core *makeCore(void);
 static void freeCore(af_Core *core);
 
-/* 核心初始化 */
+/* Core 初始化 */
 static bool enableCore(af_Core *core);
 static void checkInherit(af_Inherit **ih, af_Object *obj);
 
-/* 活动记录器创建和释放 */
+/* Activity 创建和释放 */
 static af_Activity *makeActivity(af_Code *bt_top, af_Code *bt_start, bool return_first, af_Message *msg_up,
                                  af_VarSpaceListNode *vsl, af_Object *belong, af_Object *func);
 static af_Activity *freeActivity(af_Activity *activity);
 static void freeAllActivity(af_Activity *activity);
 static void clearActivity(af_Activity *activity);
 
-/* 活动记录器相关处理函数 */
+/* Activity 相关处理函数 */
 static void freeMark(af_Environment *env);
-static void newActivity(af_Code *bt, const af_Code *next, bool return_first, bool tail, af_Environment *env);
+static void newActivity(af_Code *bt, const af_Code *next, bool return_first, af_Environment *env);
 static void freeMarkByActivity(af_Activity *activity);
 
-/* 环境变量创建与释放 */
+/* 环境变量 创建与释放 */
 static af_EnvVar *makeEnvVar(char *name, char *data);
 static af_EnvVar *freeEnvVar(af_EnvVar *var);
 static void freeAllEnvVar(af_EnvVar *var);
 static void freeEnvVarSpace(af_EnvVarSpace *evs);
 
-/* 顶层消息处理器创建与释放 */
+/* 顶层消息处理器 创建与释放 */
 static af_TopMsgProcess *makeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func);
 static af_TopMsgProcess *freeTopMsgProcess(af_TopMsgProcess *mp);
 static void freeAllTopMsgProcess(af_TopMsgProcess *mp);
@@ -35,6 +35,10 @@ static void freeAllTopMsgProcess(af_TopMsgProcess *mp);
 static void *findTopMsgProcessFunc(char *type, af_Environment *env);
 static void runTopMessageProcess(af_Environment *env);
 
+/* LiteralData 创建与释放 */
+static af_LiteralDataList *makeLiteralDataList(char *data);
+static af_LiteralDataList *freeLiteralData_Pri(af_LiteralDataList *ld);
+
 static af_Core *makeCore(void) {
     af_Core *core = calloc(sizeof(af_Core), 1);
     core->in_init = true;
@@ -190,7 +194,7 @@ static af_Activity *freeActivity(af_Activity *activity) {
     freeAllArgCodeList(activity->acl_start);
     if (activity->fi != NULL)
         freeFuncInfo(activity->fi);
-    free(activity->literal_data);
+    freeAllLiteralData(activity->ld);
     free(activity);
     return prev;
 }
@@ -222,6 +226,36 @@ static void clearActivity(af_Activity *activity) {
     activity->body_next = NULL;
 }
 
+/*
+ * 函数名: makeLiteralDataList
+ * 目标: 生成一个 af_LiteralDataList
+ * 注意: char *data 要求传入一个已经被复制的data值
+ * makeLiteralDataList是内部函数, 属于可控函数, 因此data在函数内部不再复制
+ */
+static af_LiteralDataList *makeLiteralDataList(char *data) {
+    af_LiteralDataList *ld = calloc(sizeof(af_LiteralDataList), 1);
+    ld->literal_data = data;
+    return ld;
+}
+
+static af_LiteralDataList *freeLiteralData_Pri(af_LiteralDataList *ld) {
+    af_LiteralDataList *next = ld->next;
+    free(ld->literal_data);
+    free(ld);
+    return next;
+}
+
+void freeAllLiteralData(af_LiteralDataList *ld) {
+    while (ld != NULL)
+        ld = freeLiteralData_Pri(ld);
+}
+
+void pushLiteralData(char *data, af_Environment *env) {
+    af_LiteralDataList *ld = makeLiteralDataList(data);
+    ld->next = env->activity->ld;
+    env->activity->ld = ld;
+}
+
 af_Message *makeMessage(char *type, size_t size) {
     af_Message *msg = calloc(sizeof(af_Message), 1);
     msg->type = strCopy(type);
@@ -467,8 +501,8 @@ bool changeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
     return true;
 }
 
-static void newActivity(af_Code *bt, const af_Code *next, bool return_first, bool tail, af_Environment *env){
-    if (tail && next == NULL && env->activity->body_next == NULL) {
+static void newActivity(af_Code *bt, const af_Code *next, bool return_first, af_Environment *env){
+    if (next == NULL && env->activity->body_next == NULL) {
         printf("Tail tone recursive optimization\n");
         clearActivity(env->activity);
         env->activity->bt_top = bt;
@@ -492,7 +526,7 @@ bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env)
 
     env->activity->bt_next = next;
 
-    newActivity(bt, next, return_first, true, env);
+    newActivity(bt, next, return_first, env);
     env->activity->bt_start = bt->next;
     env->activity->bt_next = bt->next;
 
@@ -528,7 +562,7 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
 
     env->activity->bt_next = next;
 
-    newActivity(bt, next, false, true, env);
+    newActivity(bt, next, false, env);
     env->activity->bt_start = func;
     env->activity->bt_next = func;
 
@@ -544,9 +578,9 @@ bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env) {
     env->activity->bt_next = bt->next;
 
     /* 隐式调用不设置 bt_top */
-    newActivity(NULL, bt->next, false, !env->activity->is_literal, env);  // 如果原activity也是字面量, 则不进行尾调递归优化
+    newActivity(NULL, bt->next, false, env);  // 如果原activity也是字面量, 则不进行尾调递归优化
     env->activity->is_literal = true;
-    env->activity->literal_data = literal_data;
+    pushLiteralData(literal_data, env);
     return setFuncActivityToArg(func, env);
 }
 
@@ -554,7 +588,7 @@ bool pushVariableActivity(af_Code *bt, af_Object *func, af_Environment *env) {
     env->activity->bt_next = bt->next;
 
     /* 隐式调用不设置 bt_top */
-    newActivity(bt, bt->next, false, true, env);
+    newActivity(bt, bt->next, false, env);
     return setFuncActivityToArg(func, env);
 }
 

+ 5 - 2
src/core/run.c

@@ -110,8 +110,11 @@ static bool checkLiteral(af_Message **msg, af_Environment *env) {
         return false;
     }
 
-    func(env->activity->literal_data, obj->data->data, obj, env);
-    free(env->activity->literal_data);
+    for (af_LiteralDataList *ld = env->activity->ld; ld != NULL; ld = ld->next)
+        func(ld->literal_data, obj->data->data, obj, env);
+
+    freeAllLiteralData(env->activity->ld);
+    env->activity->ld = NULL;
     env->activity->is_literal = false;
     return true;
 }

+ 1 - 1
src/main.c

@@ -523,7 +523,7 @@ int main() {
         printf("\n");
     }
 
-    {  // 对象函数的调用 (尾调递归有啊)
+    {  // 对象函数的调用 (尾调递归优化)
         printf("TAG P:\n");
         af_Code *bt1 = makeVariableCode("func4", 0, 1, NULL);