瀏覽代碼

feat: 添加环境变量模块

SongZihuan 3 年之前
父節點
當前提交
6d2fbe5ee6
共有 3 個文件被更改,包括 84 次插入2 次删除
  1. 5 1
      include/env.h
  2. 14 1
      src/core/__env.h
  3. 65 0
      src/core/env.c

+ 5 - 1
include/env.h

@@ -24,4 +24,8 @@ void pushMessageUp(af_Message *msg, af_Environment *env);
 void pushMessageDown(af_Message *msg, af_Environment *env);
 af_Message *popMessageUp(char *type, af_Environment *env);
 af_Message *popMessageDown(char *type, af_Environment *env);
-#endif //AFUN__ENV_H_PUBLIV
+
+void setEnvVar(char *name, char *data, af_Environment *env);
+char *findEnvVar(char *name, af_Environment *env);
+
+#endif //AFUN__ENV_H_PUBLIC

+ 14 - 1
src/core/__env.h

@@ -4,6 +4,8 @@
 
 typedef struct af_Core af_Core;
 typedef struct af_Activity af_Activity;
+typedef struct af_EnvVarSpace af_EnvVarSpace;
+typedef struct af_EnvVar af_EnvVar;
 
 #include "env.h"
 #include "__object.h"
@@ -11,7 +13,7 @@ typedef struct af_Activity af_Activity;
 #include "__bytecode.h"
 #include "__gc.h"
 
-
+#define ENV_VAR_HASH_SIZE (8)
 typedef uint16_t ActivityCount;
 
 struct af_Core {  // 解释器核心
@@ -53,9 +55,20 @@ struct af_Activity {  // 活动记录器
     bool is_top;  // 最顶层
 };
 
+struct af_EnvVar {  // 环境变量
+    char *name;
+    char *data;
+    struct af_EnvVar *next;
+};
+
+struct af_EnvVarSpace {  // 环境变量
+    struct af_EnvVar *(var[ENV_VAR_HASH_SIZE]);
+};
+
 struct af_Environment {  // 运行环境
     struct af_Core *core;
     struct af_Activity *activity;
+    struct af_EnvVarSpace *esv;
 };
 
 af_Object *getBaseObjectFromCore(char *name, af_Core *core);

+ 65 - 0
src/core/env.c

@@ -10,6 +10,11 @@ static af_Activity *makeActivity(af_ByteCode *bt,bool new_vs, af_VarSpaceListNod
 static af_Activity *freeActivity(af_Activity *activity);
 static void freeAllActivity(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_Core *makeCore(void) {
     af_Core *core = calloc(sizeof(af_Core), 1);
     core->in_init = true;
@@ -201,9 +206,68 @@ af_Message *popMessageDown(char *type, af_Environment *env) {
     return NULL;
 }
 
+static af_EnvVar *makeEnvVar(char *name, char *data) {
+    af_EnvVar *var = calloc(sizeof(af_EnvVar), 1);
+    var->name = strCopy(name);
+    var->data = strCopy(data);
+    return var;
+}
+
+static af_EnvVar *freeEnvVar(af_EnvVar *var) {
+    af_EnvVar *next = var->next;
+    free(var->data);
+    free(var->name);
+    free(var);
+    return next;
+}
+
+static void freeAllEnvVar(af_EnvVar *var) {
+    while (var != NULL)
+        var = freeEnvVar(var);
+}
+
+static af_EnvVarSpace *makeEnvVarSpace(void) {
+    af_EnvVarSpace *esv = calloc(sizeof(af_EnvVarSpace), 1);
+    return esv;
+}
+
+static void freeEnvVarSpace(af_EnvVarSpace *evs) {
+    for (int i = 0; i < ENV_VAR_HASH_SIZE; i++)
+        freeAllEnvVar(evs->var[i]);
+    free(evs);
+}
+
+void setEnvVar(char *name, char *data, af_Environment *env) {
+    time33_t index = time33(name);
+    af_EnvVar **pvar = &env->esv->var[index];
+
+    for (NULL; *pvar != NULL; pvar = &((*pvar)->next)) {
+        if (EQ_STR((*pvar)->name, name)) {
+            free((*pvar)->data);
+            (*pvar)->data = strCopy(data);
+            return;
+        }
+    }
+
+    *pvar = makeEnvVar(name, data);
+}
+
+char *findEnvVar(char *name, af_Environment *env) {
+    time33_t index = time33(name);
+    af_EnvVar **pvar = &env->esv->var[index];
+
+    for (NULL; *pvar != NULL; pvar = &((*pvar)->next)) {
+        if (EQ_STR((*pvar)->name, name))
+            return (*pvar)->data;
+    }
+
+    return NULL;
+}
+
 af_Environment *makeEnvironment(void) {
     af_Environment *env = calloc(sizeof(af_Environment), 1);
     env->core = makeCore();
+    env->esv = makeEnvVarSpace();
     return env;
 }
 
@@ -222,6 +286,7 @@ bool enableEnvironment(af_ByteCode *bt, af_Environment *env) {
 void freeEnvironment(af_Environment *env) {
     freeCore(env->core);
     freeAllActivity(env->activity);
+    freeEnvVarSpace(env->esv);
     free(env);
 }