txlyre 1 miesiąc temu
rodzic
commit
5bc1284799
1 zmienionych plików z 144 dodań i 6 usunięć
  1. 144 6
      qic.c

+ 144 - 6
qic.c

@@ -309,6 +309,11 @@ typedef struct {
     T_EQUALS,
     T_NOTEQUALS,
     T_PLUSASSIGN,
+    T_MINUSASSIGN,
+    T_SLASHASSIGN,
+    T_STARASSIGN,
+    T_SLASHSLASHASSIGN,
+    T_PERCENTASSIGN,
     T_BARBAR,
     T_ANDAND,
     T_STARSTAR,
@@ -322,17 +327,20 @@ typedef struct {
     T_COLON,
     T_BAR,
     T_AND,
-    T_RAISE,
     T_LT,
     T_LTLT,
     T_GT,
     T_GTGT,
+    T_LE,
+    T_GE,
     T_STAR,
     T_SLASH,
     T_PERCENT,
     T_COMMA,
     T_DOT,
     T_BANG,
+    T_RAISE,
+    T_TILDE,
 
     T_INLINE,
 
@@ -577,6 +585,16 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(NOTEQUALS);
   else if (strncmp(&source[*pos], "+=", 2) == 0 && ++(*pos) && ++(*pos))
     return TK(PLUSASSIGN);
+  else if (strncmp(&source[*pos], "-=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(MINUSASSIGN);
+  else if (strncmp(&source[*pos], "*=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(STARASSIGN);
+  else if (strncmp(&source[*pos], "/=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(SLASHASSIGN);
+  else if (strncmp(&source[*pos], "//=", 3) == 0 && ++(*pos) && ++(*pos) && ++(*pos))
+    return TK(SLASHSLASHASSIGN);
+  else if (strncmp(&source[*pos], "%=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(PERCENTASSIGN);
   else if (strncmp(&source[*pos], "||", 2) == 0 && ++(*pos) && ++(*pos))
     return TK(BARBAR);
   else if (strncmp(&source[*pos], "&&", 2) == 0 && ++(*pos) && ++(*pos))
@@ -593,6 +611,10 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(LTLT);
   else if (strncmp(&source[*pos], ">>", 2) == 0 && ++(*pos) && ++(*pos))
     return TK(GTGT);
+  else if (strncmp(&source[*pos], "<=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(LE);
+  else if (strncmp(&source[*pos], ">=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(GE);
   else if (source[*pos] == '(' && ++(*pos))
     return TK(LPAR);
   else if (source[*pos] == ')' && ++(*pos))
@@ -633,6 +655,14 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(GT);
   else if (source[*pos] == '!' && ++(*pos))
     return TK(BANG);
+  else if (source[*pos] == '|' && ++(*pos))
+    return TK(BAR);
+  else if (source[*pos] == '&' && ++(*pos))
+    return TK(AND);
+  else if (source[*pos] == '^' && ++(*pos))
+    return TK(RAISE);
+  else if (source[*pos] == '~' && ++(*pos))
+    return TK(TILDE);
 
   LEX_ERROR("unexpected input")
 }
@@ -668,6 +698,7 @@ struct _node_t {
 
     N_NOT,
     N_NEGATE,
+    N_BNOT,
 
     N_LITERAL,
     N_LIST,
@@ -688,9 +719,18 @@ struct _node_t {
     N_POW,
     N_SHL,
     N_SHR,
+    N_XOR,
+    N_BOR,
+    N_BAND,
 
     N_ASSIGN,
     N_ASSIGN_ADD,
+    N_ASSIGN_SUB,
+    N_ASSIGN_MUL,
+    N_ASSIGN_DIV,
+    N_ASSIGN_IDIV,
+    N_ASSIGN_MOD,
+    N_ASSIGN_POW,
 
     N_EQUALS,
     N_NOTEQUALS,
@@ -701,6 +741,8 @@ struct _node_t {
 
     N_LT,
     N_GT,
+    N_LE,
+    N_GE,
 
     N_INC,
     N_DEC,
@@ -1054,6 +1096,10 @@ node_t *parse_unary(list_t *tokens, size_t *pos) {
     node_t *a = parse_unary(tokens, pos);
 
     return NODE1(NOT, a);
+  } else if (MATCH(TILDE)) {
+    node_t *a = parse_unary(tokens, pos);
+
+    return NODE1(BNOT, a);
   }
 
   return parse_postfix(tokens, pos);
@@ -1175,6 +1221,18 @@ node_t *parse_relation(list_t *tokens, size_t *pos) {
 
       a = NODE2(GT, a, b);
 
+      continue;
+    } else if (MATCH(LE)) {
+      node_t *b = parse_shift(tokens, pos);
+
+      a = NODE2(LE, a, b);
+
+      continue;
+    } else if (MATCH(GE)) {
+      node_t *b = parse_shift(tokens, pos);
+
+      a = NODE2(GE, a, b);
+
       continue;
     }
 
@@ -1241,18 +1299,36 @@ node_t *parse_equality(list_t *tokens, size_t *pos) {
 node_t *parse_bitand(list_t *tokens, size_t *pos) {
   node_t *a = parse_equality(tokens, pos);
 
+  while (MATCH(AND)) {
+    node_t *b = parse_equality(tokens, pos);
+
+    a = NODE2(BAND, a, b);
+  }
+
   return a;
 }
 
 node_t *parse_bitxor(list_t *tokens, size_t *pos) {
   node_t *a = parse_bitand(tokens, pos);
 
+  while (MATCH(RAISE)) {
+    node_t *b = parse_bitand(tokens, pos);
+
+    a = NODE2(XOR, a, b);
+  }
+
   return a;
 }
 
 node_t *parse_bitor(list_t *tokens, size_t *pos) {
   node_t *a = parse_bitxor(tokens, pos);
 
+  while (MATCH(BAR)) {
+    node_t *b = parse_bitxor(tokens, pos);
+
+    a = NODE2(BOR, a, b);
+  }
+
   return a;
 }
 
@@ -1309,6 +1385,26 @@ node_t *parse_assignment(list_t *tokens, size_t *pos) {
     node_t *b = parse_assignment(tokens, pos);
 
     return NODE2(ASSIGN_ADD, a, b);
+  } else if (MATCH(MINUSASSIGN)) {
+    node_t *b = parse_assignment(tokens, pos);
+
+    return NODE2(ASSIGN_SUB, a, b);
+  } else if (MATCH(STARASSIGN)) {
+    node_t *b = parse_assignment(tokens, pos);
+
+    return NODE2(ASSIGN_MUL, a, b);
+  } else if (MATCH(SLASHASSIGN)) {
+    node_t *b = parse_assignment(tokens, pos);
+
+    return NODE2(ASSIGN_DIV, a, b);
+  } else if (MATCH(SLASHSLASHASSIGN)) {
+    node_t *b = parse_assignment(tokens, pos);
+
+    return NODE2(ASSIGN_IDIV, a, b);
+  } else if (MATCH(PERCENTASSIGN)) {
+    node_t *b = parse_assignment(tokens, pos);
+
+    return NODE2(ASSIGN_MOD, a, b);
   }
 
   return a;
@@ -1332,7 +1428,7 @@ node_t *parse_block(list_t *tokens, size_t *pos) {
   return NODEL(PROGRAM, stmts);
 }
 
-#define BLOCK() (MATCH(COLON)?parse_stmt(tokens, pos):parse_block(tokens, pos))
+#define BLOCK() (CLIFF||MATCH(COLON)?parse_stmt(tokens, pos):parse_block(tokens, pos))
 
 node_t *parse_if(list_t *tokens, size_t *pos) {
   node_t *a = parse_expr(tokens, pos);
@@ -1479,7 +1575,7 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
     node_t *b = NULL;
     node_t *c = NULL;
 
-    if (!AT(LCB) && !AT(COLON)) {
+    if (!AT(LCB) && !AT(COLON) && !CLIFF) {
       if (MATCH(VAR)) {
         if (AT(NAME) && ATP(OF, 1)) {
           token_t *t = tokens->data[(*pos)++];
@@ -1517,7 +1613,7 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
   } else if (MATCH(DEFER)) {
     node_t *a;
 
-    if (AT(LCB) || AT(COLON))
+    if (AT(LCB))
       a = BLOCK();
     else a = parse_stmt(tokens, pos);
 
@@ -1529,7 +1625,7 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
 
     EXPECT(CATCH, "catch");
 
-    if (!AT(COLON) && !AT(LCB)) {
+    if (!AT(COLON) && !AT(LCB) && !CLIFF) {
       if (!AT(NAME))
         PARSE_ERROR("expected identifier");
 
@@ -1862,7 +1958,18 @@ const char *STD[][2] = {
     "func die(msg, c=1) {\n"
     "  println(msg)\n"
     "  exit(c)\n"
-    "}"
+    "}\n"
+    "let SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2\n"
+    "func frewind(file)\n"
+    "  fseek(file, 0, SEEK_SET)\n"
+    "func file_read(filename) {\n"
+    "  var file = fopen(filename, \"r\")\n"
+    "  defer fclose(file)\n"
+    "  fseek(file, 0, SEEK_END)\n"
+    "  let size = ftell(file)\n"
+    "  frewind(file)\n"
+    "  return str(fread(file, size))\n"
+    "}\n"
   },
 
   {NULL, NULL}
@@ -1988,6 +2095,12 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
     case N_ASSIGN: ASSIGN(node->a, compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
 
     case N_ASSIGN_ADD: COMPASSIGN(node->a, "add", compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
+    case N_ASSIGN_SUB: COMPASSIGN(node->a, "sub", compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
+    case N_ASSIGN_MUL: COMPASSIGN(node->a, "mul", compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
+    case N_ASSIGN_DIV: COMPASSIGN(node->a, "div", compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
+    case N_ASSIGN_IDIV: COMPASSIGN(node->a, "idiv", compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
+    case N_ASSIGN_MOD: COMPASSIGN(node->a, "mod", compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
+    case N_ASSIGN_POW: COMPASSIGN(node->a, "pow", compile_node(gbuf, buf, ctx, lstk, lbl, node->b)); break;
 
     case N_INC: 
       COMPASSIGN(node->a, "add", EMIT("state->one"));
@@ -1998,6 +2111,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       break;
 
     case N_VAR: break;
+    case N_LET: break;
 
     case N_IF:
       EMIT("if (_qi_truthy(state, ");
@@ -2300,6 +2414,14 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       BINOP("gt");
       break;
 
+    case N_LE:
+      BINOP("le");
+      break;
+
+    case N_GE:
+      BINOP("ge");
+      break;
+
     case N_ADD:
       BINOP("add");
       break;
@@ -2336,6 +2458,18 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       BINOP("shr");
       break;
 
+    case N_XOR:
+      BINOP("xor");
+      break;
+
+    case N_BOR:
+      BINOP("bor");
+      break;
+
+    case N_BAND:
+      BINOP("band");
+      break;
+
     case N_NEGATE:
       UNOP("negate");
       break;
@@ -2344,6 +2478,10 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       UNOP("not");
       break;
 
+    case N_BNOT:
+      UNOP("bnot");
+      break;
+
     case N_INLINE: EMIT("%s;", unescape(node->t->text)); break;
 
     default: