Sfoglia il codice sorgente

feat: 引入bool类型, pass_value类型和null类型

SongZihuan 4 anni fa
parent
commit
d893f2329d
14 ha cambiato i file con 102 aggiunte e 24 eliminazioni
  1. 2 2
      file/file.c
  2. 2 2
      include/mem.h
  3. 1 1
      include/parameter.h
  4. 5 0
      include/statement.h
  5. 2 1
      include/token.h
  6. 8 1
      include/value.h
  7. 0 4
      main.c
  8. 10 2
      parser/grammar.c
  9. 1 0
      parser/syntax.c
  10. 2 0
      src/run.c
  11. 7 0
      src/runbranch.c
  12. 20 6
      src/runoperation.c
  13. 12 1
      src/statement.c
  14. 30 4
      src/value.c

+ 2 - 2
file/file.c

@@ -7,10 +7,10 @@
  */
 int checkFile(char *dir){
     struct stat my_stat;
-    int status = 0;
+    int status;
     if (dir == NULL)
         return 3;
-    stat(dir, &my_stat);
+    status = stat(dir, &my_stat);
     if (status != 0)
         return 0;
     else if (S_ISREG(my_stat.st_mode))

+ 2 - 2
include/mem.h

@@ -8,11 +8,11 @@ extern bool memVirtualMathUseJmp;
 
 void *memCalloc(size_t num, size_t size);
 void *memRealloc(void *old, size_t size);
-char *memStrcpy(const char *const str);
+char *memStrcpy(const char *str);
 char *memStrCharcpy(char *str, size_t nsize, int free_old, int write, ...);
 char *memStrcat(char *first, char *second, bool free_first, bool free_last);
 char *memStrcpySelf(char *str, NUMBER_TYPE times);
-char *memStrrev(const char *const str);
+char *memStrrev(const char *str);
 
 #define memFree(p) ((p)=((p) != NULL ? (free(p), NULL) : NULL))
 #define eqString(str1, str2) (!strcmp(str1, str2))

+ 1 - 1
include/parameter.h

@@ -66,7 +66,7 @@ Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE);
 ResultType setParameterCore(long int line, char *file, Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST);
 ResultType setParameter(long int line, char *file, Parameter *call_base, Parameter *function_base, VarList *function_var, LinkValue *function_father, INTER_FUNCTIONSIG_NOT_ST);
 ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTER_FUNCTIONSIG_NOT_ST);
-Argument * getArgument(Parameter *call, bool is_dict, INTER_FUNCTIONSIG_NOT_ST);
+Argument *getArgument(Parameter *call, bool is_dict, INTER_FUNCTIONSIG_NOT_ST);
 
 ResultType defaultParameter(Parameter **function_ad, NUMBER_TYPE *num, INTER_FUNCTIONSIG_NOT_ST);
 ResultType argumentToVar(Argument **call_ad, NUMBER_TYPE *num, INTER_FUNCTIONSIG_NOT_ST);

+ 5 - 0
include/statement.h

@@ -43,6 +43,10 @@ struct Statement{
                 link_value = 0,
                 string_str = 1,
                 number_str = 2,
+                bool_true = 3,
+                bool_false = 4,
+                pass_value = 5,
+                null_value = 6,
             } type;
             struct LinkValue *value;
             char *str;
@@ -219,6 +223,7 @@ Statement *makeOperationBaseStatement(enum OperationType type, long int line, ch
 Statement *makeOperationStatement(enum OperationType type, Statement *left, Statement *right);
 Statement *makeBaseLinkValueStatement(LinkValue *value, long int line, char *file);
 Statement *makeBaseStrValueStatement(char *value, enum BaseValueType type, long int line, char *file);
+Statement *makeBaseValueStatement(enum BaseValueType type, long int line, char *file);
 Statement *makeBaseVarStatement(char *name, Statement *times, long int line, char *file);
 Statement *makeBaseSVarStatement(Statement *name, Statement *times);
 Statement *makeBaseDictStatement(Parameter *pt, long int line, char *file);

+ 2 - 1
include/token.h

@@ -93,8 +93,9 @@
 #define MATHER_COMMENT 79
 #define MATHER_GOTO 80
 #define MATHER_LABEL 81
+#define MATHER_PASSVALUE 82
 
-#define MATHER_MAX 82
+#define MATHER_MAX 83
 
 // 从-6开始是为了避开status的特殊值,尽管这并没有什么影响
 #define COMMAND -6

+ 8 - 1
include/value.h

@@ -27,6 +27,8 @@ struct Value{
         dict=5,
         class=6,
         object_=7,
+        bool_=8,
+        pass_=9,
     } type;
     struct {
         struct VarList *var;
@@ -50,12 +52,15 @@ struct Value{
                 value_list,
             } type;
             struct LinkValue **list;
-            long int size;
+            NUMBER_TYPE size;  // TODO-szh typedef NUMBER_TYPE
         } list;
         struct Dict{
             struct HashTable *dict;
             NUMBER_TYPE size;
         } dict;
+        struct Bool{
+            bool bool_;
+        } bool_;
     }data;
     struct Value *gc_next;
     struct Value *gc_last;
@@ -115,6 +120,8 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue,Inter *inter);
 void freeLinkValue(LinkValue **value);
 LinkValue *copyLinkValue(LinkValue *value, Inter *inter);
 Value *makeNoneValue(Inter *inter);
+Value *makeBoolValue(bool bool_num, Inter *inter);
+Value *makePassValue(Inter *inter);
 Value *makeNumberValue(long num, Inter *inter);
 Value *makeStringValue(char *str, Inter *inter);
 Value *makeFunctionValue(struct Statement *st, struct Parameter *pt, struct VarList *var_list, Inter *inter);

+ 0 - 4
main.c

@@ -21,13 +21,9 @@ int main(int argc, char *argv[]) {
 
 
 /** TODO-szh List
- * 检查copy函数不copy next
  * __call__ 设定
  * __var__ 设定
  * 下标和切片
- * ...运算符
- * null符号
- * true和false符号
  * super函数
  * 默认形参
  * 官方函数

+ 10 - 2
parser/grammar.c

@@ -1210,6 +1210,14 @@ void parserBaseValue(PASERSSIGNATURE){
             st = makeCallStatement(sencod_var, makeValueParameter(tmp));
         }
     }
+    else if (MATHER_TRUE == value_token->token_type)
+        st = makeBaseValueStatement(bool_true, value_token->line, pm->file);
+    else if (MATHER_FALSE == value_token->token_type)
+        st = makeBaseValueStatement(bool_false, value_token->line, pm->file);
+    else if (MATHER_NULL == value_token->token_type)
+        st = makeBaseValueStatement(null_value, value_token->line, pm->file);
+    else if (MATHER_PASSVALUE == value_token->token_type)
+        st = makeBaseValueStatement(pass_value, value_token->line, pm->file);
     else if (MATHER_LAMBDA == value_token->token_type){
         Parameter *pt = NULL;
         Statement *lambda_st = NULL;
@@ -1234,8 +1242,8 @@ void parserBaseValue(PASERSSIGNATURE){
     else if (MATHER_SVAR == value_token->token_type){
         Statement *svar_st = NULL;
         if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &svar_st, NULL)){
-            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get super var after $");
+            freeToken(value_token, true);
             goto return_;
         }
         st = makeBaseSVarStatement(svar_st, NULL);
@@ -1254,7 +1262,7 @@ void parserBaseValue(PASERSSIGNATURE){
         else if(tmp == -1){
             freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get ] from list/var");
-            goto return_;
+            goto return_;  // 优化goto return freeToken
         }
         if (MATHER_VAR == readBackToken(pm)){
             Token *var_token;

+ 1 - 0
parser/syntax.c

@@ -327,6 +327,7 @@ int getMatherStatus(LexFile *file, LexMathers *mathers) {
         strMatherMacro(MATHER_LAMBDA, "lambda");
         strMatherMacro(MATHER_GOTO, "goto");
         strMatherMacro(MATHER_LABEL, "label");
+        strMatherMacro(MATHER_PASSVALUE, "...");
 
         status = checkoutMather(mathers, MATHER_MAX);
     }

+ 2 - 0
src/run.c

@@ -195,6 +195,8 @@ bool operationSafeInterStatement(INTER_FUNCTIONSIG){
     type = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
     if (run_continue_type(type))
         return false;
+    else if (type != return_code && type != error_return)
+        setResultErrorSt(result, inter, "ResultException", "Get Not Support Result", st, father, true);
     return true;
 }
 

+ 7 - 0
src/runbranch.c

@@ -22,8 +22,15 @@ bool checkBool(Value *value){
             return value->data.num.num != 0;
         case string:
             return memStrlen(value->data.str.str) > 0;
+        case bool_:
+            return value->data.bool_.bool_;
+        case pass_:
         case none:
             return false;
+        case list:
+            return value->data.list.size > 0;
+        case dict:
+            return value->data.dict.size > 0;
         default:
             return true;
     }

+ 20 - 6
src/runoperation.c

@@ -157,7 +157,9 @@ ResultType divOperation(INTER_FUNCTIONSIG) {
 ResultType blockOperation(INTER_FUNCTIONSIG) {
     ResultType type;
     var_list = pushVarList(var_list, inter);
-    type = operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.left, var_list, result, father));
+    type = functionSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.left, var_list, result, father));
+    if (type == not_return)
+        setResult(result, inter, father);
     if (run_continue_type(type) && st->aut != auto_aut)
         result->value->aut = st->aut;
     popVarList(var_list);
@@ -346,12 +348,24 @@ ResultType getBaseValue(INTER_FUNCTIONSIG) {
     setResultCore(result);
     if (st->u.base_value.type == link_value)
         result->value = st->u.base_value.value;
-    else if (st->u.base_value.type == number_str){
-        char *stop = NULL;
-        result->value = makeLinkValue(makeNumberValue(strtol(st->u.base_value.str, &stop, 10), inter), father, inter);
+    else {
+        Value *value = NULL;
+        if (st->u.base_value.type == number_str) {
+            char *stop = NULL;
+            value = makeNumberValue(strtol(st->u.base_value.str, &stop, 10), inter);
+        }
+        else if (st->u.base_value.type == bool_true)
+            value = makeBoolValue(true, inter);
+        else if (st->u.base_value.type == bool_false)
+            value = makeBoolValue(false, inter);
+        else if (st->u.base_value.type == pass_value)
+            value = makePassValue(inter);
+        else if (st->u.base_value.type == null_value)
+            value = makeNoneValue(inter);
+        else
+            value = makeStringValue(st->u.base_value.str, inter);
+        result->value = makeLinkValue(value, father, inter);
     }
-    else
-        result->value = makeLinkValue(makeStringValue(st->u.base_value.str, inter), father, inter);
 
     result->type = operation_return;
     gc_addTmpLink(&result->value->gc_status);

+ 12 - 1
src/statement.c

@@ -54,6 +54,15 @@ Statement *makeBaseStrValueStatement(char *value, enum BaseValueType type, long
     return tmp;
 }
 
+Statement *makeBaseValueStatement(enum BaseValueType type, long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
+    tmp->type = base_value;
+    tmp->u.base_value.type = type;
+    tmp->u.base_value.value = NULL;
+    tmp->u.base_value.str = NULL;
+    return tmp;
+}
+
 Statement *makeBaseVarStatement(char *name, Statement *times, long int line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_var;
@@ -434,11 +443,13 @@ Statement *copyStatementCore(Statement *st){
     switch (st->type) {
         case base_value:
             new->u.base_value.type = st->u.base_value.type;
+            new->u.base_value.value = NULL;
+            new->u.base_value.str = NULL;
             if (new->u.base_value.type == link_value) {
                 new->u.base_value.value = st->u.base_value.value;
                 gc_addStatementLink(&new->u.base_value.value->gc_status);
             }
-            else
+            else if (new->u.base_value.type == string_str || new->u.base_value.type == number_str)
                 new->u.base_value.str = memStrcpy(st->u.base_value.str);
             break;
         case operation:

+ 30 - 4
src/value.c

@@ -1,6 +1,5 @@
 #include "__virtualmath.h"
 
-
 Value *makeObject(Inter *inter, VarList *object, VarList *out_var, FatherValue *father) {
     Value *tmp, *list_tmp = inter->base;
     tmp = memCalloc(1, sizeof(Value));
@@ -27,9 +26,28 @@ Value *makeObject(Inter *inter, VarList *object, VarList *out_var, FatherValue *
 }
 
 Value *makeNoneValue(Inter *inter) {
+    Value *tmp;
+    if (inter->base == NULL) {
+        tmp = makeObject(inter, NULL, NULL, NULL);
+        tmp->type = none;
+    }
+    else
+        tmp = inter->base;
+    return tmp;
+}
+
+Value *makeBoolValue(bool bool_num, Inter *inter) {
     Value *tmp;
     tmp = makeObject(inter, NULL, NULL, NULL);
-    tmp->type = none;
+    tmp->type = bool_;
+    tmp->data.bool_.bool_ = bool_num;
+    return tmp;
+}
+
+Value *makePassValue(Inter *inter){
+    Value *tmp;
+    tmp = makeObject(inter, NULL, NULL, NULL);
+    tmp->type = pass_;
     return tmp;
 }
 
@@ -194,11 +212,10 @@ void setResult(Result *ru, Inter *inter, LinkValue *father) {
 
 void setResultBase(Result *ru, Inter *inter, LinkValue *father) {
     setResultCore(ru);
-    ru->value = makeLinkValue(inter->base, father, inter);
+    ru->value = makeLinkValue(makeNoneValue(inter), father, inter);
     gc_addTmpLink(&ru->value->gc_status);
 }
 
-// TODO-szh findUseage调整为 setResultError
 void setResultErrorSt(Result *ru, Inter *inter, char *error_type, char *error_message, Statement *st, LinkValue *father, bool new) {
     setResultError(ru, inter, error_type, error_message, st->line, st->code_file, father, new);
 }
@@ -299,6 +316,15 @@ void printValue(Value *value, FILE *debug){
         case object_:
             fprintf(debug, "object on <%p>", value);
             break;
+        case bool_:
+            if (value->data.bool_.bool_)
+                fprintf(debug, "true");
+            else
+                fprintf(debug, "false");
+            break;
+        case pass_:
+            fprintf(debug, "...");
+            break;
         default:
             fprintf(debug, "default on <%p>", value);
             break;