|
@@ -3,8 +3,10 @@
|
|
* 目标: 管理ByteCode结构体的函数
|
|
* 目标: 管理ByteCode结构体的函数
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+#include <stdio.h>
|
|
#include "aFun.h"
|
|
#include "aFun.h"
|
|
-#include "bytecode.h"
|
|
|
|
|
|
+#include "__bytecode.h"
|
|
|
|
+#include "tool.h"
|
|
|
|
|
|
static af_ByteCode *makeByteCode(char prefix, FileLine line, FilePath path) {
|
|
static af_ByteCode *makeByteCode(char prefix, FileLine line, FilePath path) {
|
|
af_ByteCode *bt = calloc(1, sizeof(af_ByteCode));
|
|
af_ByteCode *bt = calloc(1, sizeof(af_ByteCode));
|
|
@@ -55,8 +57,12 @@ static bool countElement(af_ByteCode *element, ByteCodeUint *count, af_ByteCode
|
|
|
|
|
|
af_ByteCode *makeBlockByteCode(enum af_BlockType type, af_ByteCode *element, char prefix, FileLine line, FilePath path, af_ByteCode **next) {
|
|
af_ByteCode *makeBlockByteCode(enum af_BlockType type, af_ByteCode *element, char prefix, FileLine line, FilePath path, af_ByteCode **next) {
|
|
af_ByteCode *bt = NULL;
|
|
af_ByteCode *bt = NULL;
|
|
|
|
+ af_ByteCode *tmp = NULL;
|
|
ByteCodeUint count = 0;
|
|
ByteCodeUint count = 0;
|
|
|
|
|
|
|
|
+ if (next == NULL)
|
|
|
|
+ next = &tmp;
|
|
|
|
+
|
|
if (!countElement(element, &count, next))
|
|
if (!countElement(element, &count, next))
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
@@ -68,6 +74,17 @@ af_ByteCode *makeBlockByteCode(enum af_BlockType type, af_ByteCode *element, cha
|
|
return bt;
|
|
return bt;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+af_ByteCode *connectByteCode(af_ByteCode **base, af_ByteCode *next) {
|
|
|
|
+ while ((*base) != NULL)
|
|
|
|
+ base = &((*base)->next);
|
|
|
|
+ *base = next;
|
|
|
|
+
|
|
|
|
+ while (next != NULL && next->next != NULL)
|
|
|
|
+ next = next->next;
|
|
|
|
+
|
|
|
|
+ return next;
|
|
|
|
+}
|
|
|
|
+
|
|
af_ByteCode *CopyByteCode(af_ByteCode *base, FilePath *path) {
|
|
af_ByteCode *CopyByteCode(af_ByteCode *base, FilePath *path) {
|
|
af_ByteCode *dest = NULL;
|
|
af_ByteCode *dest = NULL;
|
|
af_ByteCode **pdest = &dest;
|
|
af_ByteCode **pdest = &dest;
|
|
@@ -108,20 +125,20 @@ af_ByteCode *freeByteCode(af_ByteCode *bt) {
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
af_ByteCode *next = bt->next;
|
|
af_ByteCode *next = bt->next;
|
|
|
|
+ free(bt->path);
|
|
switch (bt->type) {
|
|
switch (bt->type) {
|
|
case literal:
|
|
case literal:
|
|
free(bt->literal.literal_data);
|
|
free(bt->literal.literal_data);
|
|
free(bt->literal.func);
|
|
free(bt->literal.func);
|
|
break;
|
|
break;
|
|
-
|
|
|
|
case variable:
|
|
case variable:
|
|
free(bt->variable.name);
|
|
free(bt->variable.name);
|
|
break;
|
|
break;
|
|
-
|
|
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ free(bt);
|
|
return next;
|
|
return next;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -143,3 +160,135 @@ void freeAllByteCode(af_ByteCode *bt) {
|
|
while (bt != NULL)
|
|
while (bt != NULL)
|
|
bt = freeByteCode(bt);
|
|
bt = freeByteCode(bt);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+#define Done(write) do{if(!(write)){return false;}}while(0)
|
|
|
|
+
|
|
|
|
+static bool writeByteCode(af_ByteCode *bt, FILE *file) {
|
|
|
|
+ Done(byteWriteUint_8(file, bt->type));
|
|
|
|
+ Done(byteWriteUint_8(file, bt->prefix));
|
|
|
|
+ Done(byteWriteUint_32(file, bt->line));
|
|
|
|
+
|
|
|
|
+ if (bt->path != NULL) {
|
|
|
|
+ Done(byteWriteUint_8(file, true)); // 表示有path
|
|
|
|
+ Done(byteWriteStr(file, bt->path));
|
|
|
|
+ } else {
|
|
|
|
+ Done(byteWriteUint_8(file, false)); // 表示无path
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (bt->type) {
|
|
|
|
+ case literal:
|
|
|
|
+ Done(byteWriteStr(file, bt->literal.literal_data));
|
|
|
|
+ Done(byteWriteStr(file, bt->literal.func));
|
|
|
|
+ break;
|
|
|
|
+ case variable:
|
|
|
|
+ Done(byteWriteStr(file, bt->variable.name));
|
|
|
|
+ break;
|
|
|
|
+ case block:
|
|
|
|
+ Done(byteWriteUint_8(file, bt->block.type));
|
|
|
|
+ Done(byteWriteUint_32(file, bt->block.elements));
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * 函数名: writeAllByteCode
|
|
|
|
+ * 目标: 将ByteCode写入字节码文件中
|
|
|
|
+ * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可
|
|
|
|
+ */
|
|
|
|
+bool writeAllByteCode(af_ByteCode *bt, FILE *file) {
|
|
|
|
+ uint32_t count = 0;
|
|
|
|
+
|
|
|
|
+ if (bt == NULL || bt->path == NULL)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ for (af_ByteCode *tmp = bt; tmp != NULL; tmp = tmp->next) // 统计个数
|
|
|
|
+ count++;
|
|
|
|
+
|
|
|
|
+ Done(byteWriteUint_32(file,count));
|
|
|
|
+ for (NULL; bt != NULL; bt = bt->next) {
|
|
|
|
+ if (!writeByteCode(bt, file))
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static bool readByteCode(af_ByteCode **bt, FILE *file) {
|
|
|
|
+ uint8_t type;
|
|
|
|
+ uint8_t prefix;
|
|
|
|
+ uint32_t line;
|
|
|
|
+ uint8_t have_path;
|
|
|
|
+ char *path = NULL;
|
|
|
|
+
|
|
|
|
+ Done(byteReadUint_8(file, &type));
|
|
|
|
+ Done(byteReadUint_8(file, &prefix));
|
|
|
|
+ Done(byteReadUint_32(file,&line));
|
|
|
|
+ Done(byteReadUint_8(file, &(have_path)));
|
|
|
|
+
|
|
|
|
+ if (have_path)
|
|
|
|
+ Done(byteReadStr(file, &path));
|
|
|
|
+
|
|
|
|
+ *bt = makeByteCode((char)prefix, line, path);
|
|
|
|
+ free(path);
|
|
|
|
+ (*bt)->type = type;
|
|
|
|
+
|
|
|
|
+ switch (type) {
|
|
|
|
+ case literal:
|
|
|
|
+ Done(byteReadStr(file, &((*bt)->literal.literal_data)));
|
|
|
|
+ Done(byteReadStr(file, &((*bt)->literal.func)));
|
|
|
|
+ break;
|
|
|
|
+ case variable:
|
|
|
|
+ Done(byteReadStr(file, &((*bt)->variable.name)));
|
|
|
|
+ break;
|
|
|
|
+ case block: {
|
|
|
|
+ uint8_t block_type;
|
|
|
|
+ uint32_t elements;
|
|
|
|
+ Done(byteReadUint_8(file, &block_type));
|
|
|
|
+ Done(byteReadUint_32(file,&elements));
|
|
|
|
+ (*bt)->block.type = block_type;
|
|
|
|
+ (*bt)->block.elements = elements;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * 函数名: writeAllByteCode
|
|
|
|
+ * 目标: 将ByteCode写入字节码文件中
|
|
|
|
+ * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可 【语义检查还未实现】
|
|
|
|
+ */
|
|
|
|
+bool readAllByteCode(af_ByteCode **bt, FILE *file) {
|
|
|
|
+ uint32_t count;
|
|
|
|
+ Done(byteReadUint_32(file,&count));
|
|
|
|
+
|
|
|
|
+ for (NULL; count != 0; count--, bt = &((*bt)->next)) {
|
|
|
|
+ if(!readByteCode(bt, file))
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void printByteCode(af_ByteCode *bt) {
|
|
|
|
+ for (NULL; bt != NULL; bt = bt->next) {
|
|
|
|
+ switch (bt->type) {
|
|
|
|
+ case literal:
|
|
|
|
+ printf("literal: %s %s prefix: %d\n", bt->literal.literal_data, bt->literal.func, bt->prefix);
|
|
|
|
+ break;
|
|
|
|
+ case variable:
|
|
|
|
+ printf("variable: %s prefix: %d\n", bt->variable.name, bt->prefix);
|
|
|
|
+ break;
|
|
|
|
+ case block:
|
|
|
|
+ printf("variable: %d %d prefix: %d\n", bt->block.elements, bt->block.type, bt->prefix);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ printf("Unknow: %d prefix: %d\n", bt->type, bt->prefix);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|