123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- /*
- * 文件名: bytecode.c
- * 目标: 管理ByteCode结构体的函数
- */
- #include <stdio.h>
- #include "aFun.h"
- #include "__bytecode.h"
- #include "tool.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;
- af_ByteCode *tmp = NULL;
- ByteCodeUint count = 0;
- if (next == NULL)
- next = &tmp;
- 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 *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 *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;
- free(bt->path);
- switch (bt->type) {
- case literal:
- free(bt->literal.literal_data);
- free(bt->literal.func);
- break;
- case variable:
- free(bt->variable.name);
- break;
- default:
- break;
- }
- free(bt);
- 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);
- }
- #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;
- }
- }
- }
|