Browse Source

feat: 添加了ByteCode结构体及其操作函数

SongZihuan 3 years ago
parent
commit
dde1793437
8 changed files with 219 additions and 4 deletions
  1. 5 0
      include/aFun.h
  2. 5 2
      include/macro.h
  3. 3 2
      include/mem.h
  4. 3 0
      include/tool.h
  5. 2 0
      src/CMakeLists.txt
  6. 9 0
      src/core/CMakeLists.txt
  7. 145 0
      src/core/bytecode.c
  8. 47 0
      src/core/bytecode.h

+ 5 - 0
include/aFun.h

@@ -1,4 +1,9 @@
 #ifndef AFUN__H
 #ifndef AFUN__H
 #define AFUN__H
 #define AFUN__H
+#include "mem.h"
+#include "macro.h"
+#include "tool.h"
+
+typedef struct af_ByteCode af_ByteCode;
 
 
 #endif //AFUN__H
 #endif //AFUN__H

+ 5 - 2
include/macro.h

@@ -6,6 +6,7 @@
 #ifndef MACRO__H
 #ifndef MACRO__H
 #define MACRO__H
 #define MACRO__H
 #include <stdbool.h>
 #include <stdbool.h>
+#include <inttypes.h>
 
 
 #ifndef __bool_true_false_are_defined
 #ifndef __bool_true_false_are_defined
 #define bool int
 #define bool int
@@ -16,7 +17,9 @@
 #define NUL ((char)0)
 #define NUL ((char)0)
 #define W_NUL ((wchar_t)0)
 #define W_NUL ((wchar_t)0)
 
 
-typedef int fline;
-typedef char *fpath;
+typedef int32_t FileLine;  // 文件航海
+typedef int8_t *FilePath;  // 文件路径
+
+typedef uint32_t ByteCodeUint;  // ByteCode int
 
 
 #endif //MACRO__H
 #endif //MACRO__H

+ 3 - 2
include/mem.h

@@ -6,8 +6,10 @@
 #ifndef MEM__H
 #ifndef MEM__H
 #define MEM__H
 #define MEM__H
 
 
-#if BUILD_MEM
 #include <stdlib.h>
 #include <stdlib.h>
+#define free(p) ((((p)!=NULL) ? (free(p), NULL) : NULL), (p)=NULL)  // free不是可选的宏
+
+#if BUILD_MEM
 
 
 static void *safeCalloc(size_t n, size_t size);
 static void *safeCalloc(size_t n, size_t size);
 static void *safeCalloc(size_t n, size_t size) {
 static void *safeCalloc(size_t n, size_t size) {
@@ -18,7 +20,6 @@ static void *safeCalloc(size_t n, size_t size) {
 }
 }
 
 
 #define calloc(n, size) (safeCalloc(n, size))
 #define calloc(n, size) (safeCalloc(n, size))
-#define free(p) ((((p)!=NULL) ? (free(p), NULL) : NULL), (p)=NULL)
 
 
 #endif
 #endif
 #endif  // MEM__H
 #endif  // MEM__H

+ 3 - 0
include/tool.h

@@ -29,6 +29,9 @@ time33_t w_time33(wchar_t *str);
 // string 工具
 // string 工具
 #define EQ_STR(str1, str2) (!strcmp((str1), (str2)))
 #define EQ_STR(str1, str2) (!strcmp((str1), (str2)))
 #define EQ_WSTR(wid1, wid2) (!wcscmp((wid1), (wid2)))
 #define EQ_WSTR(wid1, wid2) (!wcscmp((wid1), (wid2)))
+
+#define pathCopy(path) ((FilePath)strCopy((char *)(path)))
+
 #define NEW_STR(size) (char *)calloc((size) + 1, sizeof(char))
 #define NEW_STR(size) (char *)calloc((size) + 1, sizeof(char))
 #define NEW_WSTR(size) (wchar_t *)calloc((size) + 1, sizeof(wchar_t))
 #define NEW_WSTR(size) (wchar_t *)calloc((size) + 1, sizeof(wchar_t))
 #define STR_LEN(p) (((p) == NULL) ? 0 : strlen((p)))
 #define STR_LEN(p) (((p) == NULL) ? 0 : strlen((p)))

+ 2 - 0
src/CMakeLists.txt

@@ -8,5 +8,7 @@ ADD_SUBDIRECTORY(cjson)
 
 
 SET(libary af_tool af_json)
 SET(libary af_tool af_json)
 
 
+ADD_SUBDIRECTORY(core)
+
 ADD_EXECUTABLE(aFun main.c)
 ADD_EXECUTABLE(aFun main.c)
 TARGET_LINK_LIBRARIES(aFun ${libary})
 TARGET_LINK_LIBRARIES(aFun ${libary})

+ 9 - 0
src/core/CMakeLists.txt

@@ -0,0 +1,9 @@
+PROJECT(af_core LANGUAGES C)
+
+AUX_SOURCE_DIRECTORY(${af_core_SOURCE_DIR} src)  # 寻找源文件
+ADD_LIBRARY(af_core ${src})
+
+SET_TARGET_PROPERTIES(af_core PROPERTIES OUTPUT_NAME "aFunCore")
+TARGET_LINK_LIBRARIES(af_core ${libary})
+
+INSTALL(TARGETS af_core)

+ 145 - 0
src/core/bytecode.c

@@ -0,0 +1,145 @@
+/*
+ * 文件名: bytecode.c
+ * 目标: 管理ByteCode结构体的函数
+ */
+
+#include "aFun.h"
+#include "bytecode.h"
+
+static af_ByteCode *makeByteCode(char prefix, FileLine line, FilePath path) {
+    af_ByteCode *bt = calloc(1, sizeof(af_ByteCode));
+    bt->line = line;
+    bt->prefix = prefix;
+    if (path != NULL)
+        bt->path = pathCopy(path);
+    return bt;
+}
+
+af_ByteCode *makeLiteralByteCode(char *literal_data, char *func, char prefix, FileLine line, FilePath path) {
+    af_ByteCode *bt = makeByteCode(prefix, line, path);
+    bt->type = literal;
+    bt->literal.literal_data = strCopy(literal_data);
+    bt->literal.func = strCopy(func);
+    return bt;
+}
+
+
+af_ByteCode *makeVariableByteCode(char *var, char prefix, FileLine line, FilePath path) {
+    af_ByteCode *bt = makeByteCode(prefix, line, path);
+    bt->type = variable;
+    bt->variable.name = strCopy(var);
+    return bt;
+}
+
+/*
+ * 函数名: countElement
+ * 目标: 统计元素个数(不包括元素的子元素)
+ */
+static bool countElement(af_ByteCode *element, ByteCodeUint *count, af_ByteCode **next) {
+    ByteCodeUint to_next = 0;  // 表示紧接着的元素都不纳入统计(指block的子元素)
+
+    for (*count = 0; element != NULL; *next = element, element = element->next) {
+        if (to_next == 0)
+            (*count)++;
+        else
+            to_next--;
+
+        if (element->type == block)
+            to_next += element->block.elements;
+    }
+
+    if (to_next != 0)
+        return false;
+    return true;
+}
+
+af_ByteCode *makeBlockByteCode(enum af_BlockType type, af_ByteCode *element, char prefix, FileLine line, FilePath path, af_ByteCode **next) {
+    af_ByteCode *bt = NULL;
+    ByteCodeUint count = 0;
+
+    if (!countElement(element, &count, next))
+        return NULL;
+
+    bt = makeByteCode(prefix, line, path);
+    bt->type = block;
+    bt->block.type = type;
+    bt->block.elements = count;
+    bt->next = element;
+    return bt;
+}
+
+af_ByteCode *CopyByteCode(af_ByteCode *base, FilePath *path) {
+    af_ByteCode *dest = NULL;
+    af_ByteCode **pdest = &dest;
+
+    for (NULL; base != NULL; base = base->next) {
+        *pdest = makeByteCode(base->prefix, base->line, base->path);
+        (*pdest)->type = base->type;
+        switch (base->type) {
+            case literal:
+                (*pdest)->literal.literal_data = strCopy(base->literal.literal_data);
+                (*pdest)->literal.func = strCopy(base->literal.func);
+                break;
+
+            case variable:
+                (*pdest)->variable.name = strCopy(base->variable.name);
+                break;
+
+            case block:
+                (*pdest)->block.elements = base->block.elements;
+                (*pdest)->block.type = base->block.type;
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    if (dest != NULL && path != NULL) {
+        free(dest->path);
+        dest->path = pathCopy(path);
+    }
+
+    return dest;
+}
+
+af_ByteCode *freeByteCode(af_ByteCode *bt) {
+    if (bt == NULL)
+        return NULL;
+
+    af_ByteCode *next = bt->next;
+    switch (bt->type) {
+        case literal:
+            free(bt->literal.literal_data);
+            free(bt->literal.func);
+            break;
+
+        case variable:
+            free(bt->variable.name);
+            break;
+
+        default:
+            break;
+    }
+
+    return next;
+}
+
+bool freeByteCodeWithElement(af_ByteCode *bt, af_ByteCode **next) {
+    ByteCodeUint count = 1;  // 要释放的元素个数
+    for (NULL; count != 0; count--) {
+        if (bt == NULL)
+            return false;
+        if (bt->type == block)
+            count += bt->block.elements;
+        bt = freeByteCode(bt);
+    }
+
+    *next = bt;
+    return true;
+}
+
+void freeAllByteCode(af_ByteCode *bt) {
+    while (bt != NULL)
+        bt = freeByteCode(bt);
+}

+ 47 - 0
src/core/bytecode.h

@@ -0,0 +1,47 @@
+/*
+ * 文件名: bytecode.h
+ * 目标: 定义ByteCode结构体
+ */
+
+#ifndef BYTECODE__H
+#define BYTECODE__H
+#include "macro.h"
+
+enum af_ByteCodeType {
+    literal = 0,
+    variable,
+    block,  // 括号
+};
+
+enum af_BlockType {
+    parentheses = 0,  // 小括号
+    brackets,  // 中括号
+    curly,  // 大括号
+};
+
+struct af_ByteCode {  // 一个 ByteCode 的结构体
+    enum af_ByteCodeType type;
+    char prefix;  // 前缀
+    union {
+        struct {
+            char *literal_data;
+            char *func;  // 函数名称
+        } literal;
+
+        struct {
+            char *name;
+        } variable;
+
+        struct {
+            ByteCodeUint elements;  // 元素个数
+            enum af_BlockType type;  // 括号类型
+        } block;
+    };
+
+    FileLine line;
+    FilePath path;  // path == NULL表示沿用上层地址
+
+    struct af_ByteCode *next;
+};
+
+#endif //BYTECODE__H