Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

add object + array literal syntax (and treat commas in a all lists as…

… whitespace)
  • Loading branch information...
commit 2017d837adf866edde1badf2543246caeac0bdde 1 parent 2d04df3
Scott Taylor authored February 09, 2013
5  README.md
Source Rendered
@@ -34,7 +34,8 @@ Proposed syntax:
34 34
     7                           => 7
35 35
     "foo"                       => "foo"
36 36
     'foo'                       => 'foo'
37  
-    [1,2,3]                     => ([] 1 2 3) (in the future: [1 2 3] ?)
  37
+    [1,2,3]                     => ([] 1 2 3) (syntactic sugar: [1 2 3] or [1,2,3] or [1,2,3,])
  38
+    { a: 'b', c: 'd' }          => ({} a 'b' c 'd') (syntactic sugar: { a 'b' c 'd' } or { a 'b', c 'd'} or { a 'b', c 'd',})
38 39
     foo                         => foo
39 40
     foo()                       => (foo)
40 41
     function() { x + x }        => (function () (+ x x))
@@ -55,7 +56,7 @@ Proposed syntax:
55 56
 
56 57
     foo.bar()                   => (foo.bar)
57 58
     foo = {}                    => (= foo {})
58  
-    { a: 'b', c: 'd' }          => ({} a 'b' c 'd') (in the future: { a 'b' c 'd' } ?)
  59
+
59 60
     [1,2,3,4]                   => [ 1 2 3 4 ]
60 61
     x[2]                        => ([] x 2)
61 62
 
32  lib/loop/grammar.jison
@@ -11,6 +11,11 @@
11 11
 "."                                                     return "DOT";
12 12
 "("                                                     return "OPEN_PAREN";
13 13
 ")"                                                     return "CLOSE_PAREN";
  14
+"{"                                                     return "OPEN_BRACE";
  15
+"}"                                                     return "CLOSE_BRACE";
  16
+"["                                                     return "OPEN_BRACKET";
  17
+"]"                                                     return "CLOSE_BRACKET";
  18
+","                                                     return "COMMA";
14 19
 [0-9]+                                                  return "INT";
15 20
 ([^\(\)\s\n\r])+                                        return "SYMBOL";
16 21
 
@@ -30,6 +35,8 @@ prog
30 35
 
31 36
 s-expression
32 37
   : list            { $$ = $1; }
  38
+  | object-literal  { $$ = $1; }
  39
+  | array-literal   { $$ = $1; }
33 40
   | property-access { $$ = $1; }
34 41
   | atom            { $$ = $1; }
35 42
   | comment         { $$ = $1; }
@@ -44,9 +51,30 @@ list
44 51
   }
45 52
 ;
46 53
 
  54
+object-literal
  55
+  : OPEN_BRACE list-members CLOSE_BRACE {
  56
+    $$ = require("./grammar/token-builders").makeObjectLiteral($2, @2);
  57
+  }
  58
+  | OPEN_BRACE CLOSE_BRACE {
  59
+    $$ = require("./grammar/token-builders").makeObjectLiteral(null, @1);
  60
+  }
  61
+;
  62
+
  63
+array-literal
  64
+  : OPEN_BRACKET list-members CLOSE_BRACKET {
  65
+    $$ = require("./grammar/token-builders").makeArrayLiteral($2, @2);
  66
+  }
  67
+  | OPEN_BRACKET CLOSE_BRACKET {
  68
+    $$ = require("./grammar/token-builders").makeArrayLiteral(null, @1);
  69
+  }
  70
+;
  71
+
  72
+
47 73
 list-members
48  
-  : list-members s-expression { $$ = $1.concat($2); }
49  
-  | s-expression { $$ = [$1]; }
  74
+  : list-members s-expression COMMA  { $$ = $1.concat($2); }
  75
+  | list-members COMMA s-expression  { $$ = $1.concat($3); }
  76
+  | list-members s-expression        { $$ = $1.concat($2) }
  77
+  | s-expression                     { $$ = [$1]; }
50 78
 ;
51 79
 
52 80
 property-access
30  lib/loop/grammar/token-builders.js
@@ -47,6 +47,36 @@ tokenBuilders.makeString = function(str, sourceInfo) {
47 47
   };
48 48
 };
49 49
 
  50
+tokenBuilders.makeObjectLiteral = function(listMembers, sourceInfo) {
  51
+  if (listMembers) {
  52
+    var list = [];
  53
+    list.push(this.makeSymbol("{}", sourceInfo));
  54
+    var i;
  55
+    for (i = 0; i < listMembers.length; i++) {
  56
+      var listMember = listMembers[i];
  57
+      list.push(listMember);
  58
+    }
  59
+    return this.makeList(list, sourceInfo);
  60
+  } else {
  61
+    return this.makeSymbol("{}", sourceInfo);
  62
+  }
  63
+};
  64
+
  65
+tokenBuilders.makeArrayLiteral = function(listMembers, sourceInfo) {
  66
+  if (listMembers) {
  67
+    var list = [];
  68
+    list.push(this.makeSymbol("[]", sourceInfo));
  69
+    var i;
  70
+    for (i = 0; i < listMembers.length; i++) {
  71
+      var listMember = listMembers[i];
  72
+      list.push(listMember);
  73
+    }
  74
+    return this.makeList(list, sourceInfo);
  75
+  } else {
  76
+    return this.makeSymbol("[]", sourceInfo);
  77
+  }
  78
+};
  79
+
50 80
 tokenBuilders.makePropertyAccess = function(key, value, sourceInfo) {
51 81
   return {
52 82
     type: 'prop-access',
55  spec/compile-integration-spec.js
@@ -395,5 +395,60 @@ vows.describe("integration spec").addBatch({
395 395
     var expected = '1+2+3+4+5';
396 396
 
397 397
     assert.equal(loop.compile(source), expected);
  398
+  },
  399
+
  400
+  'it should use { } as an object literal syntax': function() {
  401
+    var source = '(define x { y "foo" })';
  402
+    var expected = 'var x={y:"foo"}';
  403
+    assert.equal(loop.compile(source), expected);
  404
+  },
  405
+
  406
+  'it should allow multiple in an object literal values': function() {
  407
+    var source = '(define x { y "foo" z 100 })';
  408
+    var expected = 'var x={y:"foo",z:100}';
  409
+    assert.equal(loop.compile(source), expected);
  410
+  },
  411
+
  412
+  'it should allow no values in an object literal': function() {
  413
+    var source = '(define x {})';
  414
+    var expected = 'var x={}';
  415
+    assert.equal(loop.compile(source), expected);
  416
+  },
  417
+
  418
+  'it should allow an object literal off on its own': function() {
  419
+    var source = '{}';
  420
+    var expected = '{}';
  421
+    assert.equal(loop.compile(source), expected);
  422
+  },
  423
+
  424
+  'it should allow commas in the object literal': function() {
  425
+    var source = '(define x { one 1, two 2})';
  426
+    var expected = 'var x={one:1,two:2}';
  427
+    assert.equal(loop.compile(source), expected);
  428
+
  429
+    source = '(define x { one 1, two 2,})';
  430
+    assert.equal(loop.compile(source), expected);
  431
+  },
  432
+
  433
+  'it should allow optional commas in a list': function() {
  434
+    var source = "(define x ([] 1 2 3 4))";
  435
+    var expected = 'var x=[1,2,3,4]';
  436
+    assert.equal(loop.compile(source), expected);
  437
+
  438
+    source = "(define x ([] 1, 2, 3, 4))";
  439
+    assert.equal(loop.compile(source), expected);
  440
+  },
  441
+  'it should allow an object literal with []': function() {
  442
+    var source = "(define x [1 2 3 4])";
  443
+    var expected = 'var x=[1,2,3,4]';
  444
+    assert.equal(loop.compile(source), expected);
  445
+
  446
+    source = "(define x [1, 2, 3, 4])";
  447
+    assert.equal(loop.compile(source), expected);
  448
+  },
  449
+  'it should allow an object literal with no values': function() {
  450
+    var source = "(define x [])";
  451
+    var expected = 'var x=[]';
  452
+    assert.equal(loop.compile(source), expected);
398 453
   }
399 454
 }).export(module);

0 notes on commit 2017d83

Please sign in to comment.
Something went wrong with that request. Please try again.