Browse Source

Combine rules and children

master
Dylan Baker 5 years ago
parent
commit
c7208daaee
4 changed files with 50 additions and 20 deletions
  1. 14
    9
      src/ast.ts
  2. 5
    4
      src/moss.ts
  3. 3
    4
      src/parser.ts
  4. 28
    3
      src/tests/parser.test.ts

+ 14
- 9
src/ast.ts View File

257
 
257
 
258
   export class RuleSet extends Node {
258
   export class RuleSet extends Node {
259
     public selectors: Selector[];
259
     public selectors: Selector[];
260
-    public rules: Rule[];
261
-    public children: RuleSet[];
260
+    public children: (RuleSet | Rule)[];
262
 
261
 
263
     public constructor(
262
     public constructor(
264
       selectors: Selector[],
263
       selectors: Selector[],
265
-      rules: Rule[],
266
-      children: RuleSet[] = []
264
+      children: (RuleSet | Rule)[] = []
267
     ) {
265
     ) {
268
       super();
266
       super();
269
       this.selectors = selectors;
267
       this.selectors = selectors;
270
-      this.rules = rules;
271
       this.children = children;
268
       this.children = children;
272
     }
269
     }
273
 
270
 
280
       const lineages = ([] as string[]).concat(
277
       const lineages = ([] as string[]).concat(
281
         ...this.selectors.map((sel) => sel.getLineages())
278
         ...this.selectors.map((sel) => sel.getLineages())
282
       );
279
       );
283
-      const rules = this.rules.map((rule: Rule) => rule.compile(env, opts));
284
-      const rulesError = rules.find((rule) => rule instanceof EnvError);
280
+
281
+      const rules: Array<string | EnvError> = this.children
282
+        .filter((child) => child instanceof Rule)
283
+        .map(
284
+        (child): string | EnvError => {
285
+          return child.compile(env, opts);
286
+        }
287
+      );
288
+      const rulesError = rules.find((child) => child instanceof EnvError);
285
       if (rulesError !== undefined) return rulesError;
289
       if (rulesError !== undefined) return rulesError;
286
 
290
 
287
       const compiledRules = rules.join(lineSpacer);
291
       const compiledRules = rules.join(lineSpacer);
288
 
292
 
289
-      const children: Array<string | EnvError> = this.children.map(
290
-        (child: RuleSet): string | EnvError => {
293
+      const children: Array<string | EnvError> = this.children
294
+      .filter((child) => child instanceof RuleSet).map(
295
+        (child): string | EnvError => {
291
           return child.compile(env, opts);
296
           return child.compile(env, opts);
292
         }
297
         }
293
       );
298
       );

+ 5
- 4
src/moss.ts View File

9
 import Lexer, { LexerError } from './lexer';
9
 import Lexer, { LexerError } from './lexer';
10
 import Parser, { ParserError } from './parser';
10
 import Parser, { ParserError } from './parser';
11
 
11
 
12
-// import { inspect } from 'util';
13
-// const print = (obj: any) => {
14
-//   console.log(inspect(obj, { depth: null }));
15
-// };
12
+import { inspect } from 'util';
13
+const print = (obj: any) => {
14
+  console.log(inspect(obj, { depth: null }));
15
+};
16
 
16
 
17
 const rawArgs = minimist(process.argv.slice(2));
17
 const rawArgs = minimist(process.argv.slice(2));
18
 
18
 
42
   } else {
42
   } else {
43
     const parser = new Parser(tokens);
43
     const parser = new Parser(tokens);
44
     const tree = parser.parse();
44
     const tree = parser.parse();
45
+    print(tree);
45
     if (tree instanceof ParserError) {
46
     if (tree instanceof ParserError) {
46
       return tree;
47
       return tree;
47
     } else {
48
     } else {

+ 3
- 4
src/parser.ts View File

244
       selectors.push(selector);
244
       selectors.push(selector);
245
     }
245
     }
246
 
246
 
247
-    const rules: AST.Rule[] = [];
248
-    const children: AST.RuleSet[] = [];
247
+    const children: (AST.Rule | AST.RuleSet)[] = [];
249
 
248
 
250
     while (
249
     while (
251
       [TokenTypes.PROPERTY, TokenTypes.LPAREN].includes(
250
       [TokenTypes.PROPERTY, TokenTypes.LPAREN].includes(
261
         const value = this.value();
260
         const value = this.value();
262
         if (value instanceof ParserError) return value;
261
         if (value instanceof ParserError) return value;
263
 
262
 
264
-        rules.push(new AST.Rule(property, value));
263
+        children.push(new AST.Rule(property, value));
265
       } else if (this.currentToken().type === TokenTypes.LPAREN) {
264
       } else if (this.currentToken().type === TokenTypes.LPAREN) {
266
         const ruleSet = this.ruleSet(selectors);
265
         const ruleSet = this.ruleSet(selectors);
267
         if (ruleSet instanceof ParserError) return ruleSet;
266
         if (ruleSet instanceof ParserError) return ruleSet;
272
     const rParen = this.eat(TokenTypes.RPAREN);
271
     const rParen = this.eat(TokenTypes.RPAREN);
273
     if (rParen instanceof ParserError) return rParen;
272
     if (rParen instanceof ParserError) return rParen;
274
 
273
 
275
-    return new AST.RuleSet(selectors, rules, children);
274
+    return new AST.RuleSet(selectors, children);
276
   }
275
   }
277
 
276
 
278
   private value():
277
   private value():

+ 28
- 3
src/tests/parser.test.ts View File

104
     t.deepEqual(result.tree, [
104
     t.deepEqual(result.tree, [
105
       new AST.RuleSet(
105
       new AST.RuleSet(
106
         [new AST.Selector(literalToken('body'))],
106
         [new AST.Selector(literalToken('body'))],
107
-        [new AST.Rule(property('color'), literalNode('black'))],
108
         [
107
         [
108
+          new AST.Rule(property('color'), literalNode('black')),
109
           new AST.RuleSet(
109
           new AST.RuleSet(
110
             [
110
             [
111
               new AST.Selector(literalToken('div'), [
111
               new AST.Selector(literalToken('div'), [
112
                 new AST.Selector(literalToken('body')),
112
                 new AST.Selector(literalToken('body')),
113
               ]),
113
               ]),
114
             ],
114
             ],
115
-            [new AST.Rule(property('color'), literalNode('blue'))],
116
             [
115
             [
116
+              new AST.Rule(property('color'), literalNode('blue')),
117
               new AST.RuleSet(
117
               new AST.RuleSet(
118
                 [
118
                 [
119
                   new AST.Selector(literalToken('span'), [
119
                   new AST.Selector(literalToken('span'), [
297
       result.tree[0],
297
       result.tree[0],
298
       new AST.RuleSet(
298
       new AST.RuleSet(
299
         [new AST.Selector(literalToken('div'))],
299
         [new AST.Selector(literalToken('div'))],
300
-        [new AST.Rule(property('color'), literalNode('green'))],
301
         [
300
         [
302
           new AST.RuleSet(
301
           new AST.RuleSet(
303
             [
302
             [
307
             ],
306
             ],
308
             [new AST.Rule(property('color'), literalNode('blue'))]
307
             [new AST.Rule(property('color'), literalNode('blue'))]
309
           ),
308
           ),
309
+          new AST.Rule(property('color'), literalNode('green')),
310
+        ]
311
+      )
312
+    );
313
+  }
314
+});
315
+
316
+test('combine rules and children', (t) => {
317
+  t.plan(2);
318
+  const result = parse('(div :color green (span :color blue))');
319
+  t.false(result instanceof ParserError);
320
+  if (!(result instanceof LexerError) && !(result instanceof ParserError)) {
321
+    t.deepEqual(
322
+      result.tree[0],
323
+      new AST.RuleSet(
324
+        [new AST.Selector(literalToken('div'))],
325
+        [
326
+          new AST.Rule(property('color'), literalNode('green')),
327
+          new AST.RuleSet(
328
+            [
329
+              new AST.Selector(literalToken('span'), [
330
+                new AST.Selector(literalToken('div')),
331
+              ]),
332
+            ],
333
+            [new AST.Rule(property('color'), literalNode('blue'))]
334
+          ),
310
         ]
335
         ]
311
       )
336
       )
312
     );
337
     );

Loading…
Cancel
Save