txlyre 1 өдөр өмнө
parent
commit
9c998005e4
1 өөрчлөгдсөн 62 нэмэгдсэн , 4 устгасан
  1. 62 4
      qic.c

+ 62 - 4
qic.c

@@ -1025,6 +1025,7 @@ struct _node_t {
     N_MVAR,
 
     N_MIF,
+    N_MSET,
     N_MSTMT,
     N_MEXPR
   } tag;
@@ -2446,9 +2447,9 @@ node_t *parse_mprimary(list_t *tokens, size_t *pos) {
     }
 
     return NODET(LITERAL, t);
-  } else if (MATCH(NUMBER))
+  } else if (MATCH(NUMBER) || MATCH(STRING))
     return NODET(LITERAL, tokens->data[(*pos)-1]);
-
+  
   PARSE_ERROR("expected m-expression");
 
   return NULL;
@@ -2544,7 +2545,15 @@ node_t *parse_mif(list_t *tokens, size_t *pos, int sub) {
 node_t *parse_mstmt(list_t *tokens, size_t *pos) {
   if (MATCHM("if"))
     return parse_mif(tokens, pos, 0);
-  else if (MATCHM("$")) {
+  else if (MATCHM("set")) {
+    if(!AT(NAME))
+      PARSE_ERROR("expected identifier");
+
+    token_t *t = tokens->data[(*pos)++];
+    node_t *a = parse_mexpr(tokens, pos);
+
+    return NODE1t(MSET, a, t);
+  } else if (MATCHM("$")) {
     node_t *a = parse_stmt(tokens, pos);
 
     if (a->tag == N_EXPRSTMT)
@@ -3487,6 +3496,7 @@ node_t *YES;
 
 #define IS_NUMBER(n) ((n) && (n)->tag == N_LITERAL && (n)->t->tag == T_NUMBER)
 #define TO_DOUBLE(n) (strtod((n)->t->text, NULL))
+#define IS_STRING(n) ((n) && (n)->tag == N_LITERAL && (n)->t->tag == T_STRING)
 
 node_t *make_number(double v) {
   char buf[64];
@@ -3562,6 +3572,47 @@ node_t *mf_newList(list_t *t) {
   return nodel(N_LIST, t);
 }
 
+node_t *mf_newName(list_t *t) {
+  if (t->length != 1)
+    return NULL;
+
+  node_t *a = t->data[0];
+  if (!IS_STRING(a))
+    return NULL;
+
+  char *text = a->t->text;
+  if (*text != '_' && !isalpha(*text))
+    return NULL;
+
+  for (size_t i = 0; i < strlen(text); i++)
+    if (text[i] != '_' && !isdigit(text[i]) && !isalpha(text[i]))
+      return NULL;
+
+  return nodet(N_LITERAL, token(T_NAME, text));
+}
+
+node_t *mf_newVar(list_t *t) {
+  if (t->length != 1 && t->length != 2)
+    return NULL;
+
+  node_t *a = t->data[0];
+  if (!a || a->tag != N_LITERAL || a->t->tag != T_NAME)
+    return NULL;
+
+  node_t *b = NULL;
+  if (t->length == 2) {
+    b = t->data[1];
+
+    if (!(b->tag > N_EXPRS_BEGIN && b->tag < N_EXPRS_END))
+      return NULL;
+  }
+
+  table_t *h = table_new();
+  table_set(h, a->t->text, b);
+
+  return nodeh(N_VAR, h);
+}
+
 node_t *mf_len(list_t *t) {
   if (t->length != 1)
     return NULL;
@@ -3601,7 +3652,9 @@ struct {
   { "isExpr", mf_isExpr },
   { "isList", mf_isList },
 
+  { "newName", mf_newName },
   { "newList", mf_newList },
+  { "newVar", mf_newVar },
 
   { "len", mf_len },
   { "nth", mf_nth },
@@ -3666,7 +3719,7 @@ node_t *run_mexpr(node_t *node) {
         case T_NAME:
           return table_get(list_index(MVARS, -1), node->t->text);
 
-        case T_NUMBER:
+        case T_NUMBER: case T_STRING:
           return node;
 
         default:
@@ -3765,6 +3818,10 @@ node_t *run_mnode(node_t *node) {
         r = run_mnodes(node->l2);
       break;
 
+    case N_MSET:
+      table_set(list_index(MVARS, -1), node->t->text, run_mexpr(node->a));
+      break;
+
     case N_MSTMT:
       r = node->a;
       break;
@@ -3782,6 +3839,7 @@ node_t *run_mnode(node_t *node) {
 
 node_t *run_macro(macro_t *macro, list_t *args) {
   table_t *mvars = list_index(MVARS, -1);
+  table_set(mvars, "nil", NULL);
 
   if (macro->variable)
     table_set(mvars, "*", nodel(N_LIST, args));