]> granicus.if.org Git - jq/commitdiff
Merge remote-tracking branch 'origin/master'
authorStephen Dolan <mu@netsoc.tcd.ie>
Mon, 26 Nov 2012 22:23:30 +0000 (22:23 +0000)
committerStephen Dolan <mu@netsoc.tcd.ie>
Mon, 26 Nov 2012 22:24:04 +0000 (22:24 +0000)
1  2 
builtin.c
jv.h
lexer.gen.c
lexer.l
parser.gen.c
parser.y
testdata

diff --cc builtin.c
Simple merge
diff --cc jv.h
Simple merge
diff --cc lexer.gen.c
index c78730e3d8e6a08cbb4d52e7278417f7e37bcff3,c1458c6910c1c0c601aef254addb9b58d5440a66..250fc430a20c2bc919472a4932976bab7c213875
@@@ -2285,6 -2298,6 +2298,10 @@@ static int try_exit(int c, int state, y
      match = ')'; 
      ret = QQSTRING_INTERP_END;
      break;
++
++  default:
++    // may not be the best error to give
++    return INVALID_CHARACTER;
    }
    assert(match);
    if (match == c) {
diff --cc lexer.l
Simple merge
diff --cc parser.gen.c
index 4abc81e73e4a77c93feed69db1b245a28f11c0d8,896eb2a35c3716b5f33194a25f0a1699233ef9d4..0fb39b3c02146fdb2ba4153f84b3aa4321b40c3d
@@@ -240,14 -241,14 +241,11 @@@ int yylex(YYSTYPE* yylval, YYLTYPE* yyl
  }
  
  static block gen_dictpair(block k, block v) {
--  block b = gen_subexp(k);
--  block_append(&b, gen_subexp(v));
--  block_append(&b, gen_op_simple(INSERT));
--  return b;
++  return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT));
  }
  
  static block gen_index(block obj, block key) {
--  return block_join(obj, block_join(gen_subexp(key), gen_op_simple(INDEX)));
++  return BLOCK(obj, gen_subexp(key), gen_op_simple(INDEX));
  }
  
  static block gen_binop(block a, block b, int op) {
    }
    assert(funcname);
  
--  block c = gen_noop();
--  block_append(&c, gen_subexp(a));
--  block_append(&c, gen_subexp(b));
--  block_append(&c, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, funcname)));
--  return c;
++  return gen_call(funcname, BLOCK(gen_lambda(a), gen_lambda(b)));
  }
  
  static block gen_format(block a) {
--  return block_join(a, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, "tostring")));
++  return BLOCK(a, gen_call("tostring", gen_noop()));
  }
   
  static block gen_update(block a, block op, int optype) {
--  block assign = a;
--  block_append(&assign, gen_op_simple(DUP));
    if (optype) {
      op = gen_binop(gen_noop(), op, optype);
    }
--  block_append(&assign, op);
--  return gen_assign(assign);
++  return gen_assign(BLOCK(a, gen_op_simple(DUP), op));
  }
  
  
  
  /* Line 343 of yacc.c  */
- #line 294 "parser.gen.c"
 -#line 296 "parser.gen.c"
++#line 286 "parser.gen.c"
  
  #ifdef short
  # undef short
@@@ -612,13 -615,14 +605,14 @@@ static const yytype_int8 yyrhs[] 
  /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
  static const yytype_uint16 yyrline[] =
  {
-        0,   183,   183,   186,   191,   194,   199,   203,   210,   213,
-      218,   227,   231,   235,   239,   243,   247,   251,   255,   259,
-      263,   267,   271,   275,   279,   283,   287,   291,   295,   299,
-      303,   307,   311,   316,   321,   327,   335,   338,   341,   347,
-      350,   355,   359,   365,   368,   371,   375,   378,   381,   384,
-      387,   390,   393,   396,   401,   405,   409,   419,   420,   421,
-      422,   425,   428,   429,   430,   433,   436,   439,   443,   446
 -       0,   185,   185,   188,   193,   196,   201,   205,   212,   215,
 -     220,   229,   233,   237,   241,   245,   249,   253,   257,   261,
 -     265,   269,   273,   277,   281,   285,   289,   293,   297,   301,
 -     305,   309,   313,   317,   322,   327,   333,   341,   344,   347,
 -     353,   356,   361,   365,   371,   374,   377,   381,   384,   387,
 -     390,   393,   396,   399,   402,   407,   411,   415,   425,   426,
 -     427,   428,   431,   434,   435,   436,   439,   442,   445,   449,
 -     452
++       0,   175,   175,   178,   183,   186,   191,   195,   202,   205,
++     210,   214,   218,   222,   226,   230,   234,   238,   242,   246,
++     250,   254,   258,   262,   266,   270,   274,   278,   282,   286,
++     290,   294,   298,   302,   307,   312,   317,   325,   328,   331,
++     337,   340,   345,   349,   355,   358,   361,   365,   368,   371,
++     374,   377,   380,   383,   386,   389,   393,   397,   402,   403,
++     404,   405,   408,   411,   412,   413,   416,   419,   422,   426,
++     429
  };
  #endif
  
@@@ -1523,7 -1537,7 +1527,7 @@@ yydestruct (yymsg, yytype, yyvaluep, yy
        { jv_free((yyvaluep->literal)); };
  
  /* Line 1391 of yacc.c  */
- #line 1527 "parser.gen.c"
 -#line 1541 "parser.gen.c"
++#line 1531 "parser.gen.c"
        break;
        case 5: /* "LITERAL" */
  
        { jv_free((yyvaluep->literal)); };
  
  /* Line 1391 of yacc.c  */
- #line 1536 "parser.gen.c"
 -#line 1550 "parser.gen.c"
++#line 1540 "parser.gen.c"
        break;
-       case 27: /* "QQSTRING_TEXT" */
+       case 28: /* "QQSTRING_TEXT" */
  
  /* Line 1391 of yacc.c  */
  #line 32 "parser.y"
        { jv_free((yyvaluep->literal)); };
  
  /* Line 1391 of yacc.c  */
- #line 1545 "parser.gen.c"
 -#line 1559 "parser.gen.c"
++#line 1549 "parser.gen.c"
        break;
-       case 52: /* "FuncDefs" */
+       case 53: /* "FuncDefs" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1554 "parser.gen.c"
 -#line 1568 "parser.gen.c"
++#line 1558 "parser.gen.c"
        break;
-       case 53: /* "Exp" */
+       case 54: /* "Exp" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1563 "parser.gen.c"
 -#line 1577 "parser.gen.c"
++#line 1567 "parser.gen.c"
        break;
-       case 54: /* "String" */
+       case 55: /* "String" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1572 "parser.gen.c"
 -#line 1586 "parser.gen.c"
++#line 1576 "parser.gen.c"
        break;
-       case 55: /* "FuncDef" */
+       case 56: /* "FuncDef" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1581 "parser.gen.c"
 -#line 1595 "parser.gen.c"
++#line 1585 "parser.gen.c"
        break;
-       case 56: /* "QQString" */
+       case 57: /* "QQString" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1590 "parser.gen.c"
 -#line 1604 "parser.gen.c"
++#line 1594 "parser.gen.c"
        break;
-       case 57: /* "ElseBody" */
+       case 58: /* "ElseBody" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1599 "parser.gen.c"
 -#line 1613 "parser.gen.c"
++#line 1603 "parser.gen.c"
        break;
-       case 58: /* "ExpD" */
+       case 59: /* "ExpD" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1608 "parser.gen.c"
 -#line 1622 "parser.gen.c"
++#line 1612 "parser.gen.c"
        break;
-       case 59: /* "Term" */
+       case 60: /* "Term" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1617 "parser.gen.c"
 -#line 1631 "parser.gen.c"
++#line 1621 "parser.gen.c"
        break;
-       case 60: /* "MkDict" */
+       case 61: /* "MkDict" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1626 "parser.gen.c"
 -#line 1640 "parser.gen.c"
++#line 1630 "parser.gen.c"
        break;
-       case 61: /* "MkDictPair" */
+       case 62: /* "MkDictPair" */
  
  /* Line 1391 of yacc.c  */
  #line 33 "parser.y"
        { block_free((yyvaluep->blk)); };
  
  /* Line 1391 of yacc.c  */
- #line 1635 "parser.gen.c"
 -#line 1649 "parser.gen.c"
++#line 1639 "parser.gen.c"
        break;
  
        default:
@@@ -1963,7 -1977,7 +1967,7 @@@ yyreduce
          case 2:
  
  /* Line 1806 of yacc.c  */
- #line 183 "parser.y"
 -#line 185 "parser.y"
++#line 175 "parser.y"
      {
    *answer = (yyvsp[(1) - (1)].blk);
  }
    case 3:
  
  /* Line 1806 of yacc.c  */
- #line 186 "parser.y"
 -#line 188 "parser.y"
++#line 178 "parser.y"
      {
    *answer = (yyvsp[(1) - (1)].blk);
  }
    case 4:
  
  /* Line 1806 of yacc.c  */
- #line 191 "parser.y"
 -#line 193 "parser.y"
++#line 183 "parser.y"
      {
    (yyval.blk) = gen_noop();
  }
    case 5:
  
  /* Line 1806 of yacc.c  */
- #line 194 "parser.y"
 -#line 196 "parser.y"
++#line 186 "parser.y"
      {
    (yyval.blk) = block_join((yyvsp[(1) - (2)].blk), (yyvsp[(2) - (2)].blk));
  }
    case 6:
  
  /* Line 1806 of yacc.c  */
- #line 199 "parser.y"
 -#line 201 "parser.y"
++#line 191 "parser.y"
      {
    (yyval.blk) = block_bind((yyvsp[(1) - (2)].blk), (yyvsp[(2) - (2)].blk), OP_IS_CALL_PSEUDO);
  }
    case 7:
  
  /* Line 1806 of yacc.c  */
- #line 203 "parser.y"
 -#line 205 "parser.y"
++#line 195 "parser.y"
      {
--  (yyval.blk) = gen_op_simple(DUP);
--  block_append(&(yyval.blk), (yyvsp[(1) - (6)].blk));
--  block_append(&(yyval.blk), block_bind(gen_op_var_unbound(STOREV, jv_string_value((yyvsp[(4) - (6)].literal))), (yyvsp[(6) - (6)].blk), OP_HAS_VARIABLE));
++  (yyval.blk) = BLOCK(gen_op_simple(DUP), (yyvsp[(1) - (6)].blk), 
++             block_bind(gen_op_var_unbound(STOREV, jv_string_value((yyvsp[(4) - (6)].literal))), 
++                        (yyvsp[(6) - (6)].blk), OP_HAS_VARIABLE));
    jv_free((yyvsp[(4) - (6)].literal));
  }
      break;
    case 8:
  
  /* Line 1806 of yacc.c  */
- #line 210 "parser.y"
 -#line 212 "parser.y"
++#line 202 "parser.y"
      {
    (yyval.blk) = gen_cond((yyvsp[(2) - (5)].blk), (yyvsp[(4) - (5)].blk), (yyvsp[(5) - (5)].blk));
  }
    case 9:
  
  /* Line 1806 of yacc.c  */
- #line 213 "parser.y"
 -#line 215 "parser.y"
++#line 205 "parser.y"
      {
    FAIL((yyloc), "Possibly unterminated 'if' statment");
    (yyval.blk) = (yyvsp[(2) - (3)].blk);
    case 10:
  
  /* Line 1806 of yacc.c  */
- #line 218 "parser.y"
 -#line 220 "parser.y"
++#line 210 "parser.y"
      {
--  block assign = gen_op_simple(DUP);
--  block_append(&assign, (yyvsp[(3) - (3)].blk));
--  block_append(&assign, gen_op_simple(SWAP));
--  block_append(&assign, (yyvsp[(1) - (3)].blk));
--  block_append(&assign, gen_op_simple(SWAP));
--  (yyval.blk) = gen_assign(assign);
++  (yyval.blk) = gen_assign(BLOCK(gen_op_simple(DUP), (yyvsp[(3) - (3)].blk), gen_op_simple(SWAP), (yyvsp[(1) - (3)].blk), gen_op_simple(SWAP)));
  }
      break;
  
    case 11:
  
  /* Line 1806 of yacc.c  */
- #line 227 "parser.y"
 -#line 229 "parser.y"
++#line 214 "parser.y"
      {
    (yyval.blk) = gen_or((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk));
  }
    case 12:
  
  /* Line 1806 of yacc.c  */
- #line 231 "parser.y"
 -#line 233 "parser.y"
++#line 218 "parser.y"
      {
    (yyval.blk) = gen_and((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk));
  }
    case 13:
  
  /* Line 1806 of yacc.c  */
- #line 235 "parser.y"
 -#line 237 "parser.y"
++#line 222 "parser.y"
      {
    (yyval.blk) = gen_definedor((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk));
  }
    case 14:
  
  /* Line 1806 of yacc.c  */
- #line 239 "parser.y"
 -#line 241 "parser.y"
++#line 226 "parser.y"
      {
    (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), gen_definedor(gen_noop(), (yyvsp[(3) - (3)].blk)), 0);
  }
    case 15:
  
  /* Line 1806 of yacc.c  */
- #line 243 "parser.y"
 -#line 245 "parser.y"
++#line 230 "parser.y"
      {
    (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), 0);
  }
    case 16:
  
  /* Line 1806 of yacc.c  */
- #line 247 "parser.y"
 -#line 249 "parser.y"
++#line 234 "parser.y"
      { 
    (yyval.blk) = block_join((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); 
  }
    case 17:
  
  /* Line 1806 of yacc.c  */
- #line 251 "parser.y"
 -#line 253 "parser.y"
++#line 238 "parser.y"
      { 
    (yyval.blk) = gen_both((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); 
  }
    case 18:
  
  /* Line 1806 of yacc.c  */
- #line 255 "parser.y"
 -#line 257 "parser.y"
++#line 242 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '+');
  }
    case 19:
  
  /* Line 1806 of yacc.c  */
- #line 259 "parser.y"
 -#line 261 "parser.y"
++#line 246 "parser.y"
      {
    (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '+');
  }
    case 20:
  
  /* Line 1806 of yacc.c  */
- #line 263 "parser.y"
 -#line 265 "parser.y"
++#line 250 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '-');
  }
    case 21:
  
  /* Line 1806 of yacc.c  */
- #line 267 "parser.y"
 -#line 269 "parser.y"
++#line 254 "parser.y"
      {
    (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '-');
  }
    case 22:
  
  /* Line 1806 of yacc.c  */
- #line 271 "parser.y"
 -#line 273 "parser.y"
++#line 258 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '*');
  }
    case 23:
  
  /* Line 1806 of yacc.c  */
- #line 275 "parser.y"
 -#line 277 "parser.y"
++#line 262 "parser.y"
      {
    (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '*');
  }
    case 24:
  
  /* Line 1806 of yacc.c  */
- #line 279 "parser.y"
 -#line 281 "parser.y"
++#line 266 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '/');
  }
    case 25:
  
  /* Line 1806 of yacc.c  */
- #line 283 "parser.y"
 -#line 285 "parser.y"
++#line 270 "parser.y"
      {
    (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '/');
  }
    case 26:
  
  /* Line 1806 of yacc.c  */
- #line 287 "parser.y"
 -#line 289 "parser.y"
++#line 274 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), EQ);
  }
    case 27:
  
  /* Line 1806 of yacc.c  */
- #line 291 "parser.y"
 -#line 293 "parser.y"
++#line 278 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), NEQ);
  }
    case 28:
  
  /* Line 1806 of yacc.c  */
- #line 295 "parser.y"
 -#line 297 "parser.y"
++#line 282 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '<');
  }
    case 29:
  
  /* Line 1806 of yacc.c  */
- #line 299 "parser.y"
 -#line 301 "parser.y"
++#line 286 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '>');
  }
    case 30:
  
  /* Line 1806 of yacc.c  */
- #line 303 "parser.y"
 -#line 305 "parser.y"
++#line 290 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), LESSEQ);
  }
    case 31:
  
  /* Line 1806 of yacc.c  */
- #line 307 "parser.y"
 -#line 309 "parser.y"
++#line 294 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), GREATEREQ);
  }
    case 32:
  
  /* Line 1806 of yacc.c  */
- #line 311 "parser.y"
 -#line 313 "parser.y"
++#line 298 "parser.y"
+     {
+   (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), CONTAINS);
+ }
+     break;
+   case 33:
+ /* Line 1806 of yacc.c  */
 -#line 317 "parser.y"
++#line 302 "parser.y"
      { 
    (yyval.blk) = (yyvsp[(1) - (1)].blk); 
  }
      break;
  
-   case 33:
+   case 34:
  
  /* Line 1806 of yacc.c  */
- #line 316 "parser.y"
 -#line 322 "parser.y"
++#line 307 "parser.y"
      {
    (yyval.blk) = (yyvsp[(2) - (3)].blk);
  }
      break;
  
-   case 34:
+   case 35:
  
  /* Line 1806 of yacc.c  */
- #line 321 "parser.y"
 -#line 327 "parser.y"
++#line 312 "parser.y"
      {
--  block body = block_join((yyvsp[(4) - (5)].blk), gen_op_simple(RET));
--  (yyval.blk) = gen_op_block_defn_rec(CLOSURE_CREATE, jv_string_value((yyvsp[(2) - (5)].literal)), body);
++  (yyval.blk) = gen_function(jv_string_value((yyvsp[(2) - (5)].literal)), (yyvsp[(4) - (5)].blk));
    jv_free((yyvsp[(2) - (5)].literal));
  }
      break;
  
-   case 35:
+   case 36:
  
  /* Line 1806 of yacc.c  */
- #line 327 "parser.y"
 -#line 333 "parser.y"
++#line 317 "parser.y"
      {
--  block body = block_bind(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value((yyvsp[(4) - (8)].literal))), block_join((yyvsp[(7) - (8)].blk), gen_op_simple(RET)), OP_IS_CALL_PSEUDO);
--  (yyval.blk) = gen_op_block_defn_rec(CLOSURE_CREATE, jv_string_value((yyvsp[(2) - (8)].literal)), body);
++  block body = block_bind(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value((yyvsp[(4) - (8)].literal))), (yyvsp[(7) - (8)].blk), OP_IS_CALL_PSEUDO);
++  (yyval.blk) = gen_function(jv_string_value((yyvsp[(2) - (8)].literal)), body);
    jv_free((yyvsp[(2) - (8)].literal));
    jv_free((yyvsp[(4) - (8)].literal));
  }
      break;
  
-   case 36:
+   case 37:
  
  /* Line 1806 of yacc.c  */
- #line 335 "parser.y"
 -#line 341 "parser.y"
++#line 325 "parser.y"
      {
    (yyval.blk) = gen_op_const(LOADK, jv_string(""));
  }
      break;
  
-   case 37:
+   case 38:
  
  /* Line 1806 of yacc.c  */
- #line 338 "parser.y"
 -#line 344 "parser.y"
++#line 328 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (2)].blk), gen_op_const(LOADK, (yyvsp[(2) - (2)].literal)), '+');
  }
      break;
  
-   case 38:
+   case 39:
  
  /* Line 1806 of yacc.c  */
- #line 341 "parser.y"
 -#line 347 "parser.y"
++#line 331 "parser.y"
      {
    (yyval.blk) = gen_binop((yyvsp[(1) - (4)].blk), gen_format((yyvsp[(3) - (4)].blk)), '+');
  }
      break;
  
-   case 39:
+   case 40:
  
  /* Line 1806 of yacc.c  */
- #line 347 "parser.y"
 -#line 353 "parser.y"
++#line 337 "parser.y"
      {
    (yyval.blk) = gen_cond((yyvsp[(2) - (5)].blk), (yyvsp[(4) - (5)].blk), (yyvsp[(5) - (5)].blk));
  }
      break;
  
-   case 40:
+   case 41:
  
  /* Line 1806 of yacc.c  */
- #line 350 "parser.y"
 -#line 356 "parser.y"
++#line 340 "parser.y"
      {
    (yyval.blk) = (yyvsp[(2) - (3)].blk);
  }
      break;
  
-   case 41:
+   case 42:
  
  /* Line 1806 of yacc.c  */
- #line 355 "parser.y"
 -#line 361 "parser.y"
++#line 345 "parser.y"
      { 
    (yyval.blk) = block_join((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk));
  }
      break;
  
-   case 42:
+   case 43:
  
  /* Line 1806 of yacc.c  */
- #line 359 "parser.y"
 -#line 365 "parser.y"
++#line 349 "parser.y"
      {
    (yyval.blk) = (yyvsp[(1) - (1)].blk);
  }
      break;
  
-   case 43:
+   case 44:
  
  /* Line 1806 of yacc.c  */
- #line 365 "parser.y"
 -#line 371 "parser.y"
++#line 355 "parser.y"
      {
    (yyval.blk) = gen_noop(); 
  }
      break;
  
-   case 44:
+   case 45:
  
  /* Line 1806 of yacc.c  */
- #line 368 "parser.y"
 -#line 374 "parser.y"
++#line 358 "parser.y"
      {
    (yyval.blk) = gen_index((yyvsp[(1) - (3)].blk), gen_op_const(LOADK, (yyvsp[(3) - (3)].literal))); 
  }
      break;
  
-   case 45:
+   case 46:
  
  /* Line 1806 of yacc.c  */
- #line 371 "parser.y"
 -#line 377 "parser.y"
++#line 361 "parser.y"
      { 
    (yyval.blk) = gen_index(gen_noop(), gen_op_const(LOADK, (yyvsp[(2) - (2)].literal))); 
  }
      break;
  
-   case 46:
+   case 47:
  
  /* Line 1806 of yacc.c  */
- #line 375 "parser.y"
 -#line 381 "parser.y"
++#line 365 "parser.y"
      {
    (yyval.blk) = gen_index((yyvsp[(1) - (4)].blk), (yyvsp[(3) - (4)].blk)); 
  }
      break;
  
-   case 47:
+   case 48:
  
  /* Line 1806 of yacc.c  */
- #line 378 "parser.y"
 -#line 384 "parser.y"
++#line 368 "parser.y"
      {
    (yyval.blk) = block_join((yyvsp[(1) - (3)].blk), gen_op_simple(EACH)); 
  }
      break;
  
-   case 48:
+   case 49:
  
  /* Line 1806 of yacc.c  */
- #line 381 "parser.y"
 -#line 387 "parser.y"
++#line 371 "parser.y"
      {
    (yyval.blk) = gen_op_const(LOADK, (yyvsp[(1) - (1)].literal)); 
  }
      break;
  
-   case 49:
+   case 50:
  
  /* Line 1806 of yacc.c  */
- #line 384 "parser.y"
 -#line 390 "parser.y"
++#line 374 "parser.y"
      {
    (yyval.blk) = (yyvsp[(1) - (1)].blk);
  }
      break;
  
-   case 50:
+   case 51:
  
  /* Line 1806 of yacc.c  */
- #line 387 "parser.y"
 -#line 393 "parser.y"
++#line 377 "parser.y"
      { 
    (yyval.blk) = (yyvsp[(2) - (3)].blk); 
  }
      break;
  
-   case 51:
+   case 52:
  
  /* Line 1806 of yacc.c  */
- #line 390 "parser.y"
 -#line 396 "parser.y"
++#line 380 "parser.y"
      { 
    (yyval.blk) = gen_collect((yyvsp[(2) - (3)].blk)); 
  }
      break;
  
-   case 52:
+   case 53:
  
  /* Line 1806 of yacc.c  */
- #line 393 "parser.y"
 -#line 399 "parser.y"
++#line 383 "parser.y"
      { 
    (yyval.blk) = gen_op_const(LOADK, jv_array()); 
  }
      break;
  
-   case 53:
+   case 54:
  
  /* Line 1806 of yacc.c  */
- #line 396 "parser.y"
 -#line 402 "parser.y"
++#line 386 "parser.y"
      { 
--  (yyval.blk) = gen_subexp(gen_op_const(LOADK, jv_object()));
--  block_append(&(yyval.blk), (yyvsp[(2) - (3)].blk));
--  block_append(&(yyval.blk), gen_op_simple(POP));
++  (yyval.blk) = BLOCK(gen_subexp(gen_op_const(LOADK, jv_object())), (yyvsp[(2) - (3)].blk), gen_op_simple(POP));
  }
      break;
  
-   case 54:
+   case 55:
  
  /* Line 1806 of yacc.c  */
- #line 401 "parser.y"
 -#line 407 "parser.y"
++#line 389 "parser.y"
      {
    (yyval.blk) = gen_location((yyloc), gen_op_var_unbound(LOADV, jv_string_value((yyvsp[(2) - (2)].literal))));
    jv_free((yyvsp[(2) - (2)].literal));
  }
      break;
  
-   case 55:
+   case 56:
  
  /* Line 1806 of yacc.c  */
- #line 405 "parser.y"
 -#line 411 "parser.y"
++#line 393 "parser.y"
      {
--  (yyval.blk) = gen_location((yyloc), gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, jv_string_value((yyvsp[(1) - (1)].literal)))));
++  (yyval.blk) = gen_location((yyloc), gen_call(jv_string_value((yyvsp[(1) - (1)].literal)), gen_noop()));
    jv_free((yyvsp[(1) - (1)].literal));
  }
      break;
  
-   case 56:
+   case 57:
  
  /* Line 1806 of yacc.c  */
- #line 409 "parser.y"
 -#line 415 "parser.y"
++#line 397 "parser.y"
      {
--  (yyval.blk) = gen_op_call(CALL_1_1, 
--                   block_join(gen_op_block_unbound(CLOSURE_REF, jv_string_value((yyvsp[(1) - (4)].literal))),
--                              block_bind(gen_op_block_defn(CLOSURE_CREATE,
--                                                "lambda",
--                                                           block_join((yyvsp[(3) - (4)].blk), gen_op_simple(RET))),
--                                         gen_noop(), OP_IS_CALL_PSEUDO)));
++  (yyval.blk) = gen_call(jv_string_value((yyvsp[(1) - (4)].literal)), gen_lambda((yyvsp[(3) - (4)].blk)));
    (yyval.blk) = gen_location((yylsp[(1) - (4)]), (yyval.blk));
    jv_free((yyvsp[(1) - (4)].literal));
  }
      break;
  
-   case 57:
+   case 58:
  
  /* Line 1806 of yacc.c  */
- #line 419 "parser.y"
 -#line 425 "parser.y"
++#line 402 "parser.y"
      { (yyval.blk) = gen_noop(); }
      break;
  
-   case 58:
+   case 59:
  
  /* Line 1806 of yacc.c  */
- #line 420 "parser.y"
 -#line 426 "parser.y"
++#line 403 "parser.y"
      { (yyval.blk) = gen_noop(); }
      break;
  
-   case 59:
+   case 60:
  
  /* Line 1806 of yacc.c  */
- #line 421 "parser.y"
 -#line 427 "parser.y"
++#line 404 "parser.y"
      { (yyval.blk) = (yyvsp[(1) - (4)].blk); }
      break;
  
-   case 60:
+   case 61:
  
  /* Line 1806 of yacc.c  */
- #line 422 "parser.y"
 -#line 428 "parser.y"
++#line 405 "parser.y"
      { (yyval.blk) = gen_noop(); }
      break;
  
-   case 61:
+   case 62:
  
  /* Line 1806 of yacc.c  */
- #line 425 "parser.y"
 -#line 431 "parser.y"
++#line 408 "parser.y"
      { 
    (yyval.blk)=gen_noop(); 
  }
      break;
  
-   case 62:
+   case 63:
  
  /* Line 1806 of yacc.c  */
- #line 428 "parser.y"
 -#line 434 "parser.y"
++#line 411 "parser.y"
      { (yyval.blk) = (yyvsp[(1) - (1)].blk); }
      break;
  
-   case 63:
+   case 64:
  
  /* Line 1806 of yacc.c  */
- #line 429 "parser.y"
 -#line 435 "parser.y"
++#line 412 "parser.y"
      { (yyval.blk)=block_join((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); }
      break;
  
-   case 64:
+   case 65:
  
  /* Line 1806 of yacc.c  */
- #line 430 "parser.y"
 -#line 436 "parser.y"
++#line 413 "parser.y"
      { (yyval.blk) = (yyvsp[(3) - (3)].blk); }
      break;
  
-   case 65:
+   case 66:
  
  /* Line 1806 of yacc.c  */
- #line 433 "parser.y"
 -#line 439 "parser.y"
++#line 416 "parser.y"
      { 
    (yyval.blk) = gen_dictpair(gen_op_const(LOADK, (yyvsp[(1) - (3)].literal)), (yyvsp[(3) - (3)].blk));
   }
      break;
  
-   case 66:
+   case 67:
  
  /* Line 1806 of yacc.c  */
- #line 436 "parser.y"
 -#line 442 "parser.y"
++#line 419 "parser.y"
      {
    (yyval.blk) = gen_dictpair((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk));
    }
      break;
  
-   case 67:
+   case 68:
  
  /* Line 1806 of yacc.c  */
- #line 439 "parser.y"
 -#line 445 "parser.y"
++#line 422 "parser.y"
      {
    (yyval.blk) = gen_dictpair(gen_op_const(LOADK, jv_copy((yyvsp[(1) - (1)].literal))),
                      gen_index(gen_noop(), gen_op_const(LOADK, (yyvsp[(1) - (1)].literal))));
    }
      break;
  
-   case 68:
+   case 69:
  
  /* Line 1806 of yacc.c  */
- #line 443 "parser.y"
 -#line 449 "parser.y"
++#line 426 "parser.y"
      {
    (yyval.blk) = gen_dictpair((yyvsp[(2) - (5)].blk), (yyvsp[(5) - (5)].blk));
    }
      break;
  
-   case 69:
+   case 70:
  
  /* Line 1806 of yacc.c  */
- #line 446 "parser.y"
 -#line 452 "parser.y"
++#line 429 "parser.y"
      { (yyval.blk) = (yyvsp[(5) - (5)].blk); }
      break;
  
@@@ -2823,7 -2846,7 +2823,7 @@@ yyreturn
  
  
  /* Line 2067 of yacc.c  */
- #line 447 "parser.y"
 -#line 453 "parser.y"
++#line 430 "parser.y"
  
  
  int jq_parse(struct locfile* locations, block* answer) {
diff --cc parser.y
Simple merge
diff --cc testdata
index 4fff7167f103b0e7889209d34941b5348b1f0e4d,ce330112b65d923ead12a137cbdfde229fdeae53..de224b9651a1aac9a53d96ce582082c379980a08
+++ b/testdata
@@@ -400,3 -395,28 +400,28 @@@ def inc(x): x |= .+1; inc(.[].a
  [{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":18},"world"]},{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":19},"world"]}]
  {}
  [true,false]
 -false
+ # containment operator
+ ["foo" contains "foo", "foobar" contains "foo", "foo" contains "foobar"]
+ {}
+ [true, true, false]
+ [[] contains [], [1,2,3] contains [1,2], [1,2,3] contains [3,1], [1,2,3] contains [4], [1,2,3] contains [1,4]]
+ {}
+ [true, true, true, false, false]
+ [["foobar", "foobaz"] contains ["baz", "bar"], ["foobar", "foobaz"] contains ["foo"], ["foobar", "foobaz"] contains ["blap"]]
+ {}
+ [true, true, false]
+ [{foo: 12, bar:13} contains {foo: 12}, {foo: 12} contains {}, {foo: 12, bar:13} contains {baz:14}]
+ {}
+ [true, true, false]
+ {foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {}}}
+ {}
+ true
+ {foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {bar: 14}}}
+ {}
++false