浏览代码

feat: 实现grammar解析Statement

grammar可以把token解析为Statement
Statement可以实现运行
目前支持: 数字字面量、加法、减法、字符串字面量
SongZihuan 4 年之前
父节点
当前提交
ea55579615
共有 23 个文件被更改,包括 1070 次插入157 次删除
  1. 2 1
      CMakeLists.txt
  2. 18 0
      include/__macro.h
  3. 8 7
      include/__virtualmath.h
  4. 40 0
      include/function.h
  5. 21 0
      include/grammar.h
  6. 2 1
      include/lexical.h
  7. 7 1
      include/mem.h
  8. 14 0
      include/run.h
  9. 87 0
      include/statement.h
  10. 2 0
      include/syntax.h
  11. 12 10
      include/token.h
  12. 15 102
      main.c
  13. 49 6
      memory/mem.c
  14. 264 0
      parser/grammar.c
  15. 1 1
      parser/lexical.c
  16. 10 19
      parser/syntax.c
  17. 12 9
      parser/token.c
  18. 27 0
      src/inter.c
  19. 121 0
      src/operation.c
  20. 74 0
      src/run.c
  21. 40 0
      src/statement.c
  22. 100 0
      src/value.c
  23. 144 0
      src/var.c

+ 2 - 1
CMakeLists.txt

@@ -5,6 +5,7 @@ SET(CMAKE_C_STANDARD 11)
 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/memory MEM_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/parser PASER_LIST)
+AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src SRC_LIST)
 
 message("project dir is ${PROJECT_SOURCE_DIR}")
-ADD_EXECUTABLE(VirtualMath main.c ${PASER_LIST} ${MEM_LIST})
+ADD_EXECUTABLE(VirtualMath main.c ${SRC_LIST} ${PASER_LIST} ${MEM_LIST})

+ 18 - 0
include/__macro.h

@@ -0,0 +1,18 @@
+#ifndef VIRTUALMATH___MACRO_H
+#define VIRTUALMATH___MACRO_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define bool int
+#define true 1
+#define false 0
+
+#define pass ;
+
+#define number_type long int
+#define baseFunctionSig Statement *st, Inter *inter, VarList *var_list
+#define callFunctionSig(st, var_list) st, inter, var_list
+
+#endif //VIRTUALMATH___MACRO_H

+ 8 - 7
include/__virtualmath.h

@@ -1,13 +1,14 @@
 #ifndef VIRTUALMATH___VIRTUALMATH_H
 #define VIRTUALMATH___VIRTUALMATH_H
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
+#include "__macro.h"
 #include "mem.h"
-
-#define bool int
-#define true 1
-#define false 0
+#include "function.h"
+#include "statement.h"
+#include "run.h"
+#include "syntax.h"
+#include "lexical.h"
+#include "token.h"
+#include "grammar.h"
 
 #endif //VIRTUALMATH___VIRTUALMATH_H

+ 40 - 0
include/function.h

@@ -0,0 +1,40 @@
+#ifndef VIRTUALMATH_FUNCTION_H
+#define VIRTUALMATH_FUNCTION_H
+#include "__macro.h"
+#include "statement.h"
+#include "run.h"
+
+// 所有statement相关的function都在此处声明
+
+// value的处理
+Value *makeValue(Inter *inter);
+void freeValue(Value *value, Inter *inter);
+LinkValue *makeLinkValue(Value *value, LinkValue *linkValue,Inter *inter);
+void freeLinkValue(LinkValue *value, Inter *inter);
+Value *makeNumberValue(long num, Inter *inter);
+Value *makeStringValue(char *str, Inter *inter);
+
+void setResult(Result *ru, bool link, Inter *inter);
+
+// Inter的处理
+Inter *makeInter();
+void freeInter(Inter *inter, bool self);
+
+// statement的处理
+Statement *makeStatement();
+void connectStatement(Statement *base, Statement *new);
+void freeStatement(Statement *st);
+
+// run的处理
+Result iterStatement(baseFunctionSig);
+Result operationStatement(baseFunctionSig);
+Result globalIterStatement(Inter *inter);
+
+// var的处理
+VarList *makeVarList(Inter *inter);
+VarList *freeVarList(VarList *vl, bool self);
+LinkValue *findFromVarList(char *name, VarList *var_list, number_type times);
+void addFromVarList(char *name, VarList *var_list, number_type times, LinkValue *value);
+void freeHashTable(HashTable *ht, Inter *inter);
+
+#endif //VIRTUALMATH_FUNCTION_H

+ 21 - 0
include/grammar.h

@@ -0,0 +1,21 @@
+#ifndef VIRTUALMATH_GRAMMAR_H
+#define VIRTUALMATH_GRAMMAR_H
+#include "run.h"
+
+#define PASERSSIGNATURE parserMessage *pm, Inter *inter /*pasers函数的统一签名*/
+#define CALLPASERSSIGNATURE pm, inter /*pasers函数调用的统一实参*/
+
+typedef struct parserMessage{
+    struct tokenMessage *tm;
+    enum parserMessageStatus{
+        success = 1,
+        syntax_error,
+        command_list_error,
+    } status;
+    char *status_message;
+} parserMessage;
+
+parserMessage *makeParserMessage(char *file_dir);
+void freePasersMessage(parserMessage *pm, bool self);
+void commandList(parserMessage *pm, Inter *inter, bool global, Statement *st);
+#endif //VIRTUALMATH_GRAMMAR_H

+ 2 - 1
include/lexical.h

@@ -1,6 +1,7 @@
 #ifndef VIRTUALMATH_LEXICAL_H
 #define VIRTUALMATH_LEXICAL_H
-#include "__virtualmath.h"
+#include "__macro.h"
+#include "stdio.h"
 
 typedef struct lexFile{
     FILE *file;

+ 7 - 1
include/mem.h

@@ -1,13 +1,19 @@
 #ifndef VIRTUALMATH_MEM_H
 #define VIRTUALMATH_MEM_H
 #include <string.h>
+#include <__macro.h>
 
 void *memFreeCore(void *p);
 void *memCalloc(size_t num, size_t size);
 void *memRealloc(void *old, size_t size);
-char *memStrcpy(size_t nsize, int free_old, char *str, int write, ...);
+char *memStrcpy(char *str, size_t nsize, int free_old, int write, ...);
 char *memString(size_t size);
 size_t memStrlen(char *p);
+char *memStrcat(char *first, char *second);
+char *memStrcpySelf(char *str, number_type times);
+char *memStrrev(char *str);
+
 #define memFree(p) p=memFreeCore(p)
+#define eqString(str1, str2) (!strcmp(str1, str2))
 
 #endif //VIRTUALMATH_MEM_H

+ 14 - 0
include/run.h

@@ -0,0 +1,14 @@
+#ifndef VIRTUALMATH_RUN_H
+#define VIRTUALMATH_RUN_H
+#include "statement.h"
+
+typedef struct globalInterpreter{
+    struct VirtualMathValue *base;
+    struct VirtualMathLinkValue *link_base;
+    struct VirtualMathHashTable *hash_base;
+    Statement *statement;
+    VarList *var_list;
+} Inter;
+
+
+#endif //VIRTUALMATH_RUN_H

+ 87 - 0
include/statement.h

@@ -0,0 +1,87 @@
+#ifndef VIRTUALMATH_STATEMENT_H
+#define VIRTUALMATH_STATEMENT_H
+#include "__macro.h"
+#define MAX_SIZE (1024)
+
+struct Statement;
+
+typedef struct VirtualMathValue{
+    enum ValueType{
+        number=1,
+        string,
+    } type;
+    union data{
+        struct Number{
+            number_type num;
+        } num;
+        struct String{
+            char *str;
+        } str;
+    }data;
+    struct VirtualMathValue *next;
+    struct VirtualMathValue *last;
+} Value;
+
+typedef struct VirtualMathLinkValue{
+    struct VirtualMathValue *value;
+    struct VirtualMathLinkValue *father;
+    struct VirtualMathLinkValue *next;
+    struct VirtualMathLinkValue *last;
+} LinkValue;
+
+typedef struct VirtualMathResult{
+    enum ResultType{
+        statement_end = 1,
+    } type;
+    struct VirtualMathLinkValue *value;
+} Result;
+
+typedef struct VirtualMathVar{
+    char *name;
+    struct VirtualMathLinkValue *value;
+    struct VirtualMathVar *next;
+} Var;
+
+typedef struct VirtualMathHashTable{
+    struct VirtualMathVar **hashtable;
+    int count;
+    struct VirtualMathHashTable *next;
+    struct VirtualMathHashTable *last;
+} HashTable;
+
+typedef struct VirtualMathVarList{
+    struct VirtualMathHashTable *hashtable;
+    struct VirtualMathVarList *next;
+} VarList;
+
+typedef struct Statement{
+    enum StatementType{
+        start = 1,
+        base_value,
+        base_var,
+        operation,
+    } type;
+    union StatementU{
+        struct base_value{
+            struct VirtualMathValue *value;
+        } base_value;
+        struct base_var{
+            char *name;
+            struct Statement *times;
+        } base_var;
+        struct operation{
+            enum OperationType{
+                ADD = 1,
+                SUB,
+                MUL,
+                DIV,
+                ASS,
+            } OperationType;
+            struct Statement *left;
+            struct Statement *right;
+        } operation;
+    }u;
+    struct Statement *next;
+} Statement;
+
+#endif //VIRTUALMATH_STATEMENT_H

+ 2 - 0
include/syntax.h

@@ -1,5 +1,6 @@
 #ifndef VIRTUALMATH_SYNTAX_H
 #define VIRTUALMATH_SYNTAX_H
+
 #include "lexical.h"
 #include "token.h"
 
@@ -11,4 +12,5 @@ void charMather(char p, lexMather *mather, char dest_p);
 
 #define strMatherMacro(n, word) strMather(p, mathers->mathers[n], word) /*这个宏只能用于getMatherStatus*/
 #define charMatherMacro(n, word) charMather(p, mathers->mathers[n], word) /*这个宏只能用于getMatherStatus*/
+
 #endif //VIRTUALMATH_SYNTAX_H

+ 12 - 10
include/token.h

@@ -1,6 +1,5 @@
 #ifndef VIRTUALMATH_TOKEN_H
 #define VIRTUALMATH_TOKEN_H
-#include "__virtualmath.h"
 
 #define MATHER_NUMBER 0
 #define MATHER_STRING 1
@@ -86,17 +85,24 @@
 
 #define MATHER_MAX 74
 
+// 从-5开始是为了避开status的特殊值,尽管这并没有什么影响
+#define COMMANDLIST -5
+#define COMMAND -6
+#define OPERATION -7
+#define POLYNOMIAL -8
+#define BASEVALUE -9
+
 // 预定义一部分的内容
-struct statement;
+struct Statement;
 struct lexFile;
 struct lexMathers;
 
 typedef struct token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配
-    struct data{
+    struct{
         char *str;
         char *second_str;  // 针对123.4j这种形式设定的,其中second_str存储j
-        struct statement *st;
+        struct Statement *st;
     } data;
 } token;
 
@@ -115,16 +121,12 @@ typedef struct tokenMessage{
 
 token *makeToken();
 token *makeLexToken(int type, char *str, char *second_str);
-token *makeStatementToken(int type, struct statement *st);
-void freeToken(token *tk, bool self);
+token *makeStatementToken(int type, struct Statement *st);
+void freeToken(token *tk, bool self, bool error);
 
 extern token *getToken(struct lexFile *file, struct lexMathers *mathers);
 
-extern struct lexFile *makeLexFile(char *dir);
-extern void freeLexFile(struct lexFile *file, bool self);
 
-extern struct lexMathers *makeMathers(int size);
-extern void freeMathers(struct lexMathers *mathers, bool self);
 int safeGetToken(tokenMessage *tm);
 token *forwardToken(tokenStream *ts);
 token *backToken(tokenStream *ts);

+ 15 - 102
main.c

@@ -1,118 +1,31 @@
 #include "__virtualmath.h"
-#include "lexical.h"
-#include "token.h"
-
-#define testMain3macro(tm, message) do{ \
-printf("message: %s\n", message); \
-printf("token stream: \n"); \
-printTokenStream(tm->ts->token_list, tm->ts->size); \
-printf("token ahead: \n"); \
-printTokenStream(tm->ts->token_ahead, tm->ts->ahead); \
-printf("end\n"); \
-}while(0)
 
 int testMain(int argc, char *argv[]);
-int testMain2(int argc, char *argv[]);
-int testMain3(int argc, char *argv[]);
-void printToken(token *tk);
-void printTokenStream(token **tk, int max);
 
 int main(int argc, char *argv[]) {
-    testMain3(argc, argv);
-    return 0;
-}
-
-int testMain3(int argc, char *argv[]) {
-    if (argc != 2) {
-        printf("Too many or little argc\n");
-    }
-    tokenMessage *tm = makeTokenMessage(argv[1]);
-    safeGetToken(tm);
-    safeGetToken(tm);
-    safeGetToken(tm);
-    testMain3macro(tm, "3 times safeGetToken test");
-    backToken(tm->ts);
-    backToken(tm->ts);
-    testMain3macro(tm, "2 times backToken test");
-
-    forwardToken(tm->ts);
-    testMain3macro(tm, "1 times forwardToken test");
-
-    token *tmp = popToken(tm->ts);
-    printToken(tmp);
-    testMain3macro(tm, "1 times popToken test");
-
-    addToken(tm->ts, tmp);
-    testMain3macro(tm, "1 times addToken test");
-
-    safeGetToken(tm);
-    testMain3macro(tm, "3 times safeGetToken test");
-    
-    freeTokenMessage(tm, true);
+    testMain(argc, argv);
     return 0;
 }
 
-int testMain2(int argc, char *argv[]) {
+int testMain(int argc, char *argv[]) {
     if (argc != 2) {
         printf("Too many or little argc\n");
     }
-    tokenMessage *tm = makeTokenMessage(argv[1]);
-    int tmp;
-    while (true){
-        tmp = safeGetToken(tm);
-        if (tmp == MATHER_EOF){
-            break;
-        }
-    }
-    printTokenStream(tm->ts->token_list, tm->ts->size);
-    freeTokenMessage(tm, true);
-    return 0;
-}
-/**
- * 用于测试的主函数程序
- * 需要一个命令行参数,指定一个vm文件用于解析
- * @param argc
- * @param argv
- * @return
- */
-int testMain(int argc, char *argv[]){
-    if (argc != 2){
-        printf("Too many or little argc\n");
+    Inter *global_iter = makeInter();
+    parserMessage *pm = makeParserMessage(argv[1]);
+    commandList(pm, global_iter, true, global_iter->statement);
+    if (pm->status != success){
+        printf("Syntax Error: %s\n", pm->status_message);
+        goto error_;
     }
+    globalIterStatement(global_iter);
 
-    lexFile *file = makeLexFile(argv[1]);
-    lexMathers *mathers = makeMathers(MATHER_MAX);
-    token *tmp;
-    while (true){
-       tmp = getToken(file, mathers);
-       if (tmp->token_type == MATHER_EOF){
-           freeToken(tmp, true);
-           break;
-       }
-       printToken(tmp);
-       freeToken(tmp, true);
-    }
-    freeMathers(mathers, true);
-    freeLexFile(file, true);
+    freePasersMessage(pm, true);
+    freeInter(global_iter, true);
     return 0;
-}
-
-void printToken(token *tk){
-    char *tmp = tk->data.str, *second_tmp = tk->data.second_str;
-    if (!strcmp(tmp, "\n")){
-        tmp = "\\n";
-    }
-    if (!strcmp(second_tmp, "\n")){
-        second_tmp = "\\n";
-    }
-    if (tmp[0] == EOF){
-        tmp = "(EOF)";
-    }
-    printf("<token str = ('%s','%s'), type = %d>\n", tmp, second_tmp, tk->token_type);
-}
 
-void printTokenStream(token **tk, int max){
-    for (int i=0; i < max; i ++){
-        printToken(tk[i]);
-    }
+    error_:
+    freePasersMessage(pm, true);
+    freeInter(global_iter, true);
+    return 0;
 }

+ 49 - 6
memory/mem.c

@@ -1,7 +1,4 @@
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "mem.h"
+#include "__virtualmath.h"
 
 void *memFreeCore(void *p){
     if (p != NULL)
@@ -37,16 +34,18 @@ size_t memStrlen(char *p){  // 可以读取NULL的strlen
 }
 
 char *memString(size_t size) {  // 比memCalloc多了一个设置\0的步骤
+    if (size == 0){
+        return NULL;
+    }
     char *tmp = (char *)memCalloc(size + 1, sizeof(char));
     tmp[size] = '\0';
     return tmp;
 }
 
-char *memStrcpy(size_t nsize, int free_old, char *str, int write, ...) {  // 复制str到新的空间,nszie是要扩展的大小。该函数支持让str=NULL,则变为单纯的memString
+char *memStrcpy(char *str, size_t nsize, bool free_old, bool write, ...) {  // 复制str到新的空间,nszie是要扩展的大小。该函数支持让str=NULL,则变为单纯的memString
     char *tmp = memString(memStrlen(str) + nsize + 1);
     if (str != NULL){
         strcpy(tmp, str);
-        tmp[memStrlen(str)] = (char)0;  // 去除多余的\0
     }
     if (write){
         va_list argp;
@@ -61,3 +60,47 @@ char *memStrcpy(size_t nsize, int free_old, char *str, int write, ...) {  // 复
     }
     return tmp;
 }
+
+char *memStrcat(char *first, char *second){
+    if (first == NULL && second == NULL){
+        return NULL;
+    }
+    else if (first == NULL){
+        first = second;
+        second = NULL;
+    }
+
+    char *new = memStrcpy(first, memStrlen(second), false, false);
+    if (second != NULL){
+        strcat(new, second);
+    }
+    return new;
+}
+
+char *memStrcpySelf(char *str, number_type times){
+    bool need_free = false;
+    if (times < 0){
+        str = memStrrev(str);
+        times = -times;
+        need_free = true;
+    }
+    char *new_str = memStrcpy(str, 0, false, false), *tmp;
+    for (number_type i=0;i < times - 1;i++){
+        tmp = memStrcat(new_str, str);
+        memFree(new_str);
+        new_str = tmp;
+    }
+    if (need_free){
+        memFree(str);
+    }
+    return new_str;
+}
+
+char *memStrrev(char *str){
+    size_t len_str = memStrlen(str);
+    char *new_str = memString(len_str);
+    for (int i = 0;i < len_str;i++){
+        new_str[i] = str[len_str - i - 1];
+    }
+    return new_str;
+}

+ 264 - 0
parser/grammar.c

@@ -0,0 +1,264 @@
+#include "__virtualmath.h"
+
+#define readBackToken(status, pm) do{ \
+status = safeGetToken(pm->tm); \
+backToken(pm->tm->ts); \
+} while(0) /*预读token*/
+
+#define popAheadToken(token_var, pm) do{ \
+safeGetToken(pm->tm); \
+token_var = popToken(pm->tm->ts); \
+} while(0)
+
+#define addStatementToken(type, st, pm) do{\
+token *tmp_new_token; \
+tmp_new_token = makeStatementToken(type, st); \
+addToken(pm->tm->ts, tmp_new_token); \
+backToken(pm->tm->ts); \
+} while(0)
+
+#define backToken_(pm, token) do{ \
+addToken(pm->tm->ts, token); \
+backToken(pm->tm->ts); \
+}while(0)
+
+#define call_success(pm) (pm->status == success)
+
+void command(PASERSSIGNATURE);
+void parserOperation(PASERSSIGNATURE);
+void polynomial(PASERSSIGNATURE);
+void baseValue(PASERSSIGNATURE);
+
+void syntaxError(parserMessage *pm, char *message, enum parserMessageStatus status);
+
+parserMessage *makeParserMessage(char *file_dir){
+    parserMessage *tmp = memCalloc(1, sizeof(parserMessage));
+    tmp->tm = makeTokenMessage(file_dir);
+    tmp->status = success;
+    tmp->status_message = NULL;
+    return tmp;
+}
+
+void freePasersMessage(parserMessage *pm, bool self) {
+    freeTokenMessage(pm->tm, true);
+    memFree(pm->status_message);
+    if (self){
+        memFree(pm);
+    }
+}
+
+// TODO-szh 代码重构, 匹配器函数加前缀pasers或者grammar
+void commandList(parserMessage *pm, Inter *inter, bool global, Statement *st) {
+    int token_type, command_int, stop;
+    struct Statement *base_st = st;
+    while (true){
+        readBackToken(token_type, pm);
+        if (token_type == MATHER_EOF){
+            // printf("get EOF\n");
+            goto return_;
+        }
+        else{
+            token *command_token,*stop_token;
+            command(CALLPASERSSIGNATURE);
+            if (!call_success(pm)){
+                goto return_;
+            }
+            readBackToken(command_int, pm);
+            if (COMMAND != command_int){
+                if (global){
+                    syntaxError(pm, "ERROR from command list(get command)", command_list_error);
+                }
+                goto return_;
+            }
+            popAheadToken(command_token, pm);
+
+            readBackToken(stop, pm);
+            if (stop == MATHER_ENTER){
+                popAheadToken(stop_token, pm);
+                freeToken(stop_token, true, false);
+            }
+            else if(stop == MATHER_EOF){
+                popAheadToken(stop_token, pm);
+                backToken_(pm, stop_token);
+            }
+            else{
+                syntaxError(pm, "ERROR from command list(get stop)", command_list_error);
+                freeToken(command_token, true, true);
+                goto return_;
+            }
+            /*...do something for commandList...*/
+            // printf("do something for commandList\n");
+            connectStatement(base_st, command_token->data.st);
+            freeToken(command_token, true, false);
+        }
+    }
+    return_:
+    addStatementToken(COMMANDLIST, base_st, pm);
+}
+
+void command(PASERSSIGNATURE){
+    int token_type;
+    Statement *st = NULL;
+    readBackToken(token_type, pm);
+    if (false){
+        pass
+    }
+    else{
+        int command_int;
+        token *command_token;
+        parserOperation(CALLPASERSSIGNATURE);
+        if (!call_success(pm)){
+            goto return_;
+        }
+        readBackToken(command_int, pm);
+        if (command_int != OPERATION){
+            goto return_;
+        }
+        popAheadToken(command_token, pm);
+        /*...do something for command...*/
+        // printf("do something for command\n");
+        st = command_token->data.st;
+        freeToken(command_token, true, false);
+    }
+    addStatementToken(COMMAND, st, pm);
+
+    return_:
+    return;
+}
+
+void parserOperation(PASERSSIGNATURE){
+    int operation_int;
+    polynomial(CALLPASERSSIGNATURE);
+    if (!call_success(pm)){
+        goto return_;
+    }
+    readBackToken(operation_int, pm);
+    if (operation_int != POLYNOMIAL){
+        goto return_;
+    }
+    token *operation_token;
+    popAheadToken(operation_token, pm);
+    /*...do something for operation...*/
+    // printf("do something for operation\n");
+
+    addStatementToken(OPERATION, operation_token->data.st, pm);
+    freeToken(operation_token, true, false);
+
+    return_:
+    return;
+}
+
+void polynomial(PASERSSIGNATURE){
+    while(true){
+        int left, symbol, right;
+        token *left_token, *symbol_token, *right_token;
+        struct Statement *st = NULL;
+        readBackToken(left, pm);
+        if (left != POLYNOMIAL){
+            baseValue(CALLPASERSSIGNATURE);  // 获得左值
+            if (!call_success(pm)){
+                goto return_;
+            }
+            readBackToken(left, pm);
+            if (left != BASEVALUE){  // 若非正确数值
+                goto return_;
+            }
+            // printf("polynomial: get base value\n");
+        }
+        popAheadToken(left_token, pm);
+        readBackToken(symbol, pm);
+        switch (symbol) {
+            case MATHER_ADD:
+                // printf("polynomial: get a add symbol\n");
+                popAheadToken(symbol_token, pm);
+                freeToken(symbol_token, true, false);
+                symbol_token = NULL;
+
+                st = makeStatement();
+                st->type = operation;
+                st->u.operation.OperationType = ADD;
+                break;
+            case MATHER_SUB:
+                // printf("polynomial: get a sub symbol\n");
+                popAheadToken(symbol_token, pm);
+                freeToken(symbol_token, true, false);
+                symbol_token = NULL;
+
+                st = makeStatement();
+                st->type = operation;
+                st->u.operation.OperationType = SUB;
+                break;
+            default:
+                // printf("polynomial: get another symbol\n");
+                backToken_(pm, left_token);
+                goto return_;
+        }
+
+        baseValue(CALLPASERSSIGNATURE);  // 获得左值
+        if (!call_success(pm)){
+            freeToken(left_token, true, false);
+            freeStatement(st);
+            goto return_;
+        }
+        readBackToken(right, pm);
+        if (right != BASEVALUE){  // 若非正确数值
+            syntaxError(pm, "ERROR from polynomial(get right)", syntax_error);
+            freeToken(left_token, true, true);
+            freeStatement(st);
+            goto return_;
+        }
+        popAheadToken(right_token, pm);
+
+        st->u.operation.left = left_token->data.st;
+        st->u.operation.right = right_token->data.st;
+
+        freeToken(left_token, true, false);
+        freeToken(right_token, true, false);
+        addStatementToken(POLYNOMIAL, st, pm);
+        // printf("polynomial: push token\n");
+    }
+    return_:
+    return;
+}
+
+/**
+ * 字面量匹配
+ * baseValue:
+ * | MATHER_NUMBER
+ * | MATHER_STRING
+ * @param pm
+ */
+void baseValue(PASERSSIGNATURE){
+    int token_type;
+    struct Statement *st = NULL;
+    readBackToken(token_type, pm);
+    if(MATHER_NUMBER == token_type){
+        // 匹配到正常字面量
+        token *value_token;
+        char *stop;
+        popAheadToken(value_token, pm);
+        st = makeStatement();
+        st->type = base_value;
+        st->u.base_value.value = makeNumberValue(strtol(value_token->data.str, &stop, 10), inter);
+        freeToken(value_token, true, false);
+    }
+    else if(MATHER_STRING == token_type){
+        token *value_token;
+        popAheadToken(value_token, pm);
+        st = makeStatement();
+        st->type = base_value;
+        st->u.base_value.value = makeStringValue(value_token->data.str, inter);
+        freeToken(value_token, true, false);
+    }
+    else{
+        goto return_;
+    }
+    addStatementToken(BASEVALUE, st, pm);
+    return_:
+    return;
+}
+
+void syntaxError(parserMessage *pm, char *message, enum parserMessageStatus status){
+    pm->status = status;
+    pm->status_message = memStrcpy(message, 0, false, false);
+}

+ 1 - 1
parser/lexical.c

@@ -1,4 +1,4 @@
-#include "lexical.h"
+#include "__virtualmath.h"
 
 /**
  * 从文件中读取一个字节,并处理is_back

+ 10 - 19
parser/syntax.c

@@ -1,4 +1,4 @@
-#include "syntax.h"
+#include "__virtualmath.h"
 
 /**
  * 匹配一个数字字面量
@@ -15,7 +15,7 @@
 void numberMather(char p, lexMather *mather){
     if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING || mather->status == LEXMATHER_INGPOINT){
         if ('0'<= p && '9' >= p || '.' == p && mather->status == LEXMATHER_ING){
-            mather->str = memStrcpy(1, true, mather->str, true, p);
+            mather->str = memStrcpy(mather->str, 1, true, true, p);
             mather->len += 1;
             if ('.' == p)
                 mather->status = LEXMATHER_INGPOINT;
@@ -24,7 +24,7 @@ void numberMather(char p, lexMather *mather){
         }
         else if(mather->status == LEXMATHER_ING || mather->status == LEXMATHER_INGPOINT){
             if ('A'<= p && 'Z' >= p ||'a'<= p && 'z' >= p ||'_' == p){
-                mather->second_str = memStrcpy(1, true, mather->second_str, true, p);
+                mather->second_str = memStrcpy(mather->second_str, 1, true, true, p);
                 mather->status = LEXMATHER_INGSECOND;
             }
             else{
@@ -38,7 +38,7 @@ void numberMather(char p, lexMather *mather){
     else if (mather->status == LEXMATHER_INGSECOND){
         if ('A'<= p && 'Z' >= p ||'a'<= p && 'z' >= p ||'_' == p ||
             '0'<= p && '9' >= p){
-            mather->second_str = memStrcpy(1, true, mather->second_str, true, p);
+            mather->second_str = memStrcpy(mather->second_str, 1, true, true, p);
         }
         else{
             mather->status = LEXMATHER_END;
@@ -61,7 +61,7 @@ void varMather(char p, lexMather *mather){
     if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING){
         if ('A'<= p && 'Z' >= p ||'a'<= p && 'z' >= p ||'_' == p ||
             '0'<= p && '9' >= p && mather->status == LEXMATHER_ING){
-            mather->str = memStrcpy(1, true, mather->str, true, p);
+            mather->str = memStrcpy(mather->str, 1, true, true, p);
             mather->len ++;
             mather->status = LEXMATHER_ING;
         }
@@ -100,7 +100,7 @@ void stringMather(char p, lexMather *mather){
             mather->status = LEXMATHER_PASS;
         }
         else{
-            mather->str = memStrcpy(1, true, mather->str, true, p);
+            mather->str = memStrcpy(mather->str, 1, true, true, p);
             mather->len ++;
             mather->status = LEXMATHER_ING;
         }
@@ -108,7 +108,7 @@ void stringMather(char p, lexMather *mather){
     else if (mather->status == LEXMATHER_INGSECOND){
         if ('A'<= p && 'Z' >= p ||'a'<= p && 'z' >= p ||'_' == p ||
             '0'<= p && '9' >= p){
-            mather->second_str = memStrcpy(1, true, mather->second_str, true, p);
+            mather->second_str = memStrcpy(mather->second_str, 1, true, true, p);
         }
         else{
             mather->status = LEXMATHER_END;
@@ -116,7 +116,7 @@ void stringMather(char p, lexMather *mather){
     }
     else if(mather->status == LEXMATHER_PASS){
         if ('A'<= p && 'Z' >= p ||'a'<= p && 'z' >= p ||'_' == p){
-            mather->second_str = memStrcpy(1, true, mather->second_str, true, p);
+            mather->second_str = memStrcpy(mather->second_str, 1, true, true, p);
             mather->status = LEXMATHER_INGSECOND;
         }
         else{
@@ -137,7 +137,7 @@ void stringMather(char p, lexMather *mather){
 void strMather(char p, lexMather *mather, const char *dest_p){
     if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING){
         if (p == dest_p[mather->len]){
-            mather->str = memStrcpy(1, true, mather->str, true, p);
+            mather->str = memStrcpy(mather->str, 1, true, true, p);
             mather->len ++;
             mather->status = LEXMATHER_ING;
         }
@@ -163,7 +163,7 @@ void strMather(char p, lexMather *mather, const char *dest_p){
 void charMather(char p, lexMather *mather, char dest_p){
     int tmp_p = (int)p, tmp_dest = (int)dest_p;
     if (tmp_p == tmp_dest && mather->status == LEXMATHER_START){
-        mather->str = memStrcpy(1, true, mather->str, true, p);
+        mather->str = memStrcpy(mather->str, 1, true, true, p);
         mather->len ++;
         mather->status = LEXMATHER_ING;
     }
@@ -175,15 +175,6 @@ void charMather(char p, lexMather *mather, char dest_p){
     }
 }
 
-bool isIn(char p, char *list){
-    int max = memStrlen(list);
-    for (int i=0;i < max;i++){
-        if (p == list[i])
-            return true;
-    }
-    return false;
-}
-
 /**
  * 开始匹配,返回的int即checkoutMather返回的值(匹配成功的匹配器的索引)
  * @param file

+ 12 - 9
parser/token.c

@@ -1,4 +1,4 @@
-#include "token.h"
+#include "__virtualmath.h"
 
 token *makeToken(){
     token *tmp = memCalloc(1, sizeof(token));
@@ -12,21 +12,24 @@ token *makeToken(){
 token *makeLexToken(int type, char *str, char *second_str) {
     struct token *tmp = makeToken();
     tmp->token_type = type;
-    tmp->data.str = memStrcpy(0, false, str, false);
-    tmp->data.second_str = memStrcpy(0, false, second_str, false);
+    tmp->data.str = memStrcpy(str, 0, false, false);
+    tmp->data.second_str = memStrcpy(second_str, 0, false, false);
     return tmp;
 }
 
-token *makeStatementToken(int type, struct statement *st){
+token *makeStatementToken(int type, struct Statement *st){
     struct token *tmp = makeToken();
     tmp->token_type = type;
     tmp->data.st = st;
     return tmp;
 }
 
-void freeToken(token *tk, bool self){
+void freeToken(token *tk, bool self, bool error) {
     memFree(tk->data.str);
     memFree(tk->data.second_str);
+    if (error){
+        freeStatement(tk->data.st);
+    }
     if (self){
         memFree(tk);
     }
@@ -41,12 +44,12 @@ tokenStream *makeTokenStream(){
     return tmp;
 }
 
-void freeToekStream(tokenStream *ts, bool self){
+void freeToekStream(tokenStream *ts, bool self) {
     for (int i=0; i < ts->size; i++){
-        freeToken(ts->token_list[i], true);
+        freeToken(ts->token_list[i], true, false);
     }
     for (int i=0; i < ts->ahead; i++){
-        freeToken(ts->token_ahead[i], true);
+        freeToken(ts->token_ahead[i], true, false);
     }
     memFree(ts->token_list);
     memFree(ts->token_ahead);
@@ -63,7 +66,7 @@ tokenMessage *makeTokenMessage(char *file_dir){
     return tm;
 }
 
-void freeTokenMessage(tokenMessage *tm, bool self){
+void freeTokenMessage(tokenMessage *tm, bool self) {
     freeLexFile(tm->file, true);
     freeToekStream(tm->ts, true);
     freeMathers(tm->mathers, true);

+ 27 - 0
src/inter.c

@@ -0,0 +1,27 @@
+#include "__virtualmath.h"
+
+Inter *makeInter(){
+    Inter *tmp = memCalloc(1, sizeof(Inter));
+    tmp->base = NULL;
+    tmp->link_base = NULL;
+    tmp->statement = makeStatement();
+    tmp->var_list = makeVarList(tmp);
+    return tmp;
+}
+
+void freeInter(Inter *inter, bool self){
+    while (inter->base != NULL){
+        freeValue(inter->base, inter);
+    }
+    while (inter->link_base != NULL){
+        freeLinkValue(inter->link_base, inter);
+    }
+    while (inter->hash_base != NULL){
+        freeHashTable(inter->hash_base, inter);
+    }
+    freeStatement(inter->statement);
+    freeVarList(inter->var_list, true);
+    if (self){
+        memFree(inter);
+    }
+}

+ 121 - 0
src/operation.c

@@ -0,0 +1,121 @@
+#include "__virtualmath.h"
+/**
+ * operation.c中是用于数学计算的函数
+ */
+
+#define getresult(base, var, inter) var = iterStatement(callFunctionSig(st->u.operation. base, var_list))
+#define viewtype_core(a, b, valuetype_a, valuetype_a_b) a .value->value->type == valuetype_a && b.value->value->type == valuetype_a_b
+#define viewtype(a, b, valuetype) viewtype_core(a, b, valuetype, valuetype)
+#define operationValue(a, b, type, symbol) a.value->value->data.type symbol b.value->value->data.type
+#define valueToResult(result, result_value, type, inter) result.value->value = make##type##Value(result_value, inter)
+
+Result addOperation(baseFunctionSig);
+Result subOperation(baseFunctionSig);
+Result mulOperation(baseFunctionSig);
+Result divOperation(baseFunctionSig);
+Result assOperation(baseFunctionSig);
+
+Result operationStatement(baseFunctionSig) {
+    Result result;
+    setResult(&result, true, inter);
+    switch (st->u.operation.OperationType) {
+        case ADD:
+            result = addOperation(callFunctionSig(st, var_list));
+            break;
+        case SUB:
+            result = subOperation(callFunctionSig(st, var_list));
+            break;
+        case MUL:
+            result = mulOperation(callFunctionSig(st, var_list));
+            break;
+        case DIV:
+            result = divOperation(callFunctionSig(st, var_list));
+            break;
+        case ASS:
+            result = assOperation(callFunctionSig(st, var_list));
+            break;
+        default:
+            break;
+    }
+    return result;
+}
+
+Result addOperation(baseFunctionSig) {
+    Result left, right, result;
+    setResult(&result, true, inter);
+    getresult(left, left, inter);
+    getresult(right, right, inter);
+    if (viewtype(left, right, number)){
+        valueToResult(result, (operationValue(left, right, num.num, +)), Number, inter);
+    }
+    else if(viewtype(left, right, string)){
+        char *new_string = memStrcat(left.value->value->data.str.str, right.value->value->data.str.str);
+        valueToResult(result, new_string, String, inter);
+        memFree(new_string);
+    }
+    return result;
+}
+
+Result subOperation(baseFunctionSig) {
+    Result left, right, result;
+    setResult(&result, true, inter);
+    getresult(left, left, inter);
+    getresult(right, right, inter);
+    if (viewtype(left, right, number)){
+        valueToResult(result, (operationValue(left, right, num.num, -)), Number, inter);
+    }
+    return result;
+}
+
+Result mulOperation(baseFunctionSig) {
+    Result left, right, result;
+    setResult(&result, true, inter);
+    getresult(left, left, inter);
+    getresult(right, right, inter);
+    if (viewtype(left, right, number)){
+        valueToResult(result, (operationValue(left, right, num.num, *)), Number, inter);
+    }
+    else if(viewtype_core(left, right, number, string)){
+        Result tmp = left;
+        left = right;
+        right = tmp;
+        goto mul_str;
+    }
+    else if(viewtype_core(left, right, string, number)){
+        mul_str:
+        {
+            char *new_string = memStrcpySelf(left.value->value->data.str.str, right.value->value->data.num.num);
+            valueToResult(result, new_string, String, inter);
+            memFree(new_string);
+        }
+    }
+    return result;
+}
+
+Result divOperation(baseFunctionSig) {
+    Result left, right, result;
+    setResult(&result, true, inter);
+    getresult(left, left, inter);
+    getresult(right, right, inter);
+    if (viewtype(left, right, number)){
+        valueToResult(result, (operationValue(left, right, num.num, /)), Number, inter);
+    }
+    return result;
+}
+
+Result assOperation(baseFunctionSig) {
+    Result times, right;
+    int int_times;
+    getresult(right, right, inter);
+    if (st->u.operation.left->type == base_var){
+        if (st->u.operation.left->u.base_var.times == NULL){
+            int_times = 0;
+            goto not_times;
+        }
+        times = iterStatement(callFunctionSig(st->u.operation.left->u.base_var.times, var_list));
+        int_times = (int)times.value->value->data.num.num;
+        not_times:
+        addFromVarList(st->u.operation.left->u.base_var.name, var_list, int_times, right.value);
+    }
+    return right;
+}

+ 74 - 0
src/run.c

@@ -0,0 +1,74 @@
+#include "__virtualmath.h"
+#define printResult(result, first, last) do{ \
+switch (result.value->value->type){ \
+    case number: \
+        printf("%s %ld %s \n", first, result.value->value->data.num.num, last); \
+        break; \
+    case string: \
+        printf("%s %s %s \n", first, result.value->value->data.str.str, last); \
+        break; \
+    default: \
+        printf("%s default %s \n", first, last); \
+        break; \
+} \
+} while(0) \
+
+Result getBaseVar(baseFunctionSig) {
+    Result times, result;
+    int int_times;
+    if (st->u.base_var.times == NULL){
+        int_times = 0;
+        goto not_times;
+    }
+    times = iterStatement(callFunctionSig(st->u.base_var.times, var_list));
+    int_times = (int)times.value->value->data.num.num;
+
+    not_times:
+    result.value = findFromVarList(st->u.base_var.name, var_list, int_times);
+    if (result.value == NULL){
+        printf("not found[%s]\n", st->u.base_var.name);
+    }
+    return result;
+}
+
+Result runStatement(baseFunctionSig) {
+    Result result;
+    setResult(&result, true, inter);
+    switch (st->type) {
+        case base_value:
+            result.value->value = st->u.base_value.value;
+            break;
+        case base_var:
+            result = getBaseVar(callFunctionSig(st, var_list));
+            break;
+        case operation:
+            result = operationStatement(callFunctionSig(st, var_list));
+            printResult(result, "operation result = ", "");
+            break;
+        default:
+            break;
+    }
+    return result;
+}
+
+Result iterStatement(baseFunctionSig) {
+    Result result;
+    Statement *base_st = st;
+    VarList *new_var_list = var_list;
+    while(base_st != NULL){
+        result = runStatement(callFunctionSig(base_st, new_var_list));
+        base_st = base_st->next;
+    }
+    return result;
+}
+
+Result globalIterStatement(Inter *inter) {
+    Result result;
+    Statement *base_st = inter->statement;
+    VarList *new_var_list = inter->var_list;
+    while(base_st != NULL){
+        result = runStatement(callFunctionSig(base_st, new_var_list));
+        base_st = base_st->next;
+    }
+    return result;
+}

+ 40 - 0
src/statement.c

@@ -0,0 +1,40 @@
+#include "__virtualmath.h"
+
+Statement *makeStatement(){
+    Statement *tmp;
+    tmp = memCalloc(1, sizeof(Statement));
+    tmp->type = start;
+    tmp->next = NULL;
+    return tmp;
+}
+
+void connectStatement(Statement *base, Statement *new){
+    while (base->next != NULL){
+        base = base->next;
+    }
+    base->next = new;
+}
+
+void freeStatement(Statement *st){
+    if (st == NULL){
+        return;
+    }
+    Statement *next_tmp;
+    while (st != NULL){
+        switch (st->type) {
+            case operation:
+                freeStatement(st->u.operation.right);
+                freeStatement(st->u.operation.left);
+                break;
+            case base_var:
+                memFree(st->u.base_var.name);
+                freeStatement(st->u.base_var.times);
+                break;
+            default:
+                break;
+        }
+        next_tmp = st->next;
+        memFree(st);
+        st = next_tmp;
+    }
+}

+ 100 - 0
src/value.c

@@ -0,0 +1,100 @@
+#include "__virtualmath.h"
+
+Value *makeValue(Inter *inter) {
+    Value *tmp, *list_tmp = inter->base;
+    tmp = memCalloc(1, sizeof(Value));
+    tmp->type = number;
+    tmp->data.num.num = 0;
+    tmp->next = NULL;
+    if (list_tmp == NULL){
+        inter->base = tmp;
+        tmp->last = NULL;
+        goto return_;
+    }
+
+    while (list_tmp->next !=  NULL){
+        list_tmp = list_tmp->next;
+    }
+    list_tmp->next = tmp;
+    tmp->last = list_tmp->next;
+
+    return_:
+    return tmp;
+}
+
+Value *makeNumberValue(number_type num, Inter *inter) {
+    Value *tmp;
+    tmp = makeValue(inter);
+    tmp->type = number;
+    tmp->data.num.num = num;
+    return tmp;
+}
+
+Value *makeStringValue(char *str, Inter *inter) {
+    Value *tmp;
+    tmp = makeValue(inter);
+    tmp->type = string;
+    tmp->data.str.str = memStrcpy(str, 0, false, false);
+    return tmp;
+}
+
+void freeValue(Value *value, Inter *inter){
+    if (value->last == NULL){
+        inter->base = value->next;
+    }
+    else{
+        value->last->next = value->next;
+    }
+    if (value->next != NULL){
+        value->next->last = value->last;
+    }
+    switch (value->type) {
+        case string:
+            memFree(value->data.str.str);
+            break;
+        default:
+            break;
+    }
+    memFree(value);
+}
+
+LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
+    LinkValue *tmp, *list_tmp = inter->link_base;
+    tmp = memCalloc(1, sizeof(Value));
+    tmp->father = linkValue;
+    tmp->value = value;
+    if (list_tmp == NULL){
+        inter->link_base = tmp;
+        tmp->last = NULL;
+        goto return_;
+    }
+
+    while (list_tmp->next !=  NULL){
+        list_tmp = list_tmp->next;
+    }
+    list_tmp->next = tmp;
+    tmp->last = list_tmp->next;
+
+    return_:
+    return tmp;
+}
+
+void freeLinkValue(LinkValue *value, Inter *inter){
+    if (value->last == NULL){
+        inter->link_base = value->next;
+    }
+    else{
+        value->last->next = value->next;
+    }
+    if (value->next != NULL){
+        value->next->last = value->last;
+    }
+    memFree(value);
+}
+
+void setResult(Result *ru, bool link, Inter *inter) {
+    ru->type = statement_end;
+    if (link){
+        ru->value = makeLinkValue(NULL, NULL, inter);
+    }
+}

+ 144 - 0
src/var.c

@@ -0,0 +1,144 @@
+#include "__virtualmath.h"
+
+Var *makeVar(char *name, LinkValue *value){
+    Var *tmp;
+    tmp = memCalloc(1, sizeof(Var));
+    tmp->name = memStrcpy(name, 0, false, false);
+    tmp->value = value;
+    tmp->next = NULL;
+    return tmp;
+}
+
+Var *freeVar(Var *var, bool self){
+    memFree(var->name);
+    if (self){
+        Var *next_var = var->next;
+        memFree(var);
+        return next_var;
+    }
+    return var;
+}
+
+HashTable *makeHashTable(Inter *inter) {
+    HashTable *tmp, *list_tmp = inter->hash_base;
+    tmp = memCalloc(1, sizeof(Value));
+    tmp->hashtable = (Var **)calloc(MAX_SIZE, sizeof(Var *));
+    tmp->next = NULL;
+    if (list_tmp == NULL){
+        inter->hash_base = tmp;
+        tmp->last = NULL;
+        goto return_;
+    }
+
+    while (list_tmp->next !=  NULL){
+        list_tmp = list_tmp->next;
+    }
+    list_tmp->next = tmp;
+    tmp->last = list_tmp->next;
+
+    return_:
+    return tmp;
+}
+
+void freeHashTable(HashTable *ht, Inter *inter){
+    if (ht->last == NULL){
+        inter->hash_base = ht->next;
+    }
+    else{
+        ht->last->next = ht->next;
+    }
+    if (ht->next != NULL){
+        ht->next->last = ht->last;
+    }
+
+    for (int i=0; i < MAX_SIZE; i++){
+        Var *tmp = ht->hashtable[i];
+        while (tmp != NULL){
+            tmp = freeVar(tmp, true);
+        }
+    }
+    memFree(ht->hashtable);
+    memFree(ht);
+}
+
+VarList *makeVarList(Inter *inter) {
+    VarList *tmp = calloc(1, sizeof(VarList));
+    tmp->next = NULL;
+    tmp->hashtable = makeHashTable(inter);
+    return tmp;
+}
+
+VarList *freeVarList(VarList *vl, bool self){
+    if (self){
+        VarList *next_var = vl->next;
+        memFree(vl);
+        return next_var;
+    }
+    return vl;
+
+}
+
+unsigned int time33(char *key){ // hash function
+    unsigned int hash = 5381;
+    while(*key){
+        hash += (hash << (unsigned int)5) + (*key++);
+    }
+    return (hash & (unsigned int)0x7FFFFFFF) % MAX_SIZE;
+}
+
+
+void addVar(char *name, LinkValue *value, VarList *var_list){
+    unsigned int index = time33(name);
+    Var *base = var_list->hashtable->hashtable[index];
+    if (base == NULL){
+        var_list->hashtable->hashtable[index] = makeVar(name, value);
+        goto return_;
+    }
+    while (base->next != NULL){
+        base = base->next;
+    }
+    base->next = makeVar(name, value);
+    return_:
+    return;
+}
+
+LinkValue *findVar(char *name, VarList *var_list){
+    LinkValue *tmp = NULL;
+    unsigned int index = time33(name);
+    Var *base = var_list->hashtable->hashtable[index];
+    if (base == NULL){
+        goto return_;
+    }
+    while (base != NULL){
+        if (eqString(base->name, name)){
+            tmp = base->value;
+            goto return_;
+        }
+        base = base->next;
+    }
+    return_:
+    return tmp;
+}
+
+LinkValue *findFromVarList(char *name, VarList *var_list, number_type times){
+    LinkValue *tmp = NULL;
+    for (number_type i=0;i<times && var_list->next != NULL;i++){
+        var_list = var_list->next;
+    }
+    while (var_list != NULL){
+        tmp = findVar(name, var_list);
+        if (tmp != NULL){
+            goto return_;
+        }
+        var_list = var_list->next;
+    }
+    return_:
+    return tmp;
+}
+
+void addFromVarList(char *name, VarList *var_list, number_type times, LinkValue *value){
+    for (number_type i=0;i<times && var_list->next != NULL;i++){
+        var_list = var_list->next;
+    }
+    addVar(name, value, var_list);
+}