Browse Source

Combine rules and children

master
Dylan Baker 3 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,17 +257,14 @@ export namespace AST {
257 257
 
258 258
   export class RuleSet extends Node {
259 259
     public selectors: Selector[];
260
-    public rules: Rule[];
261
-    public children: RuleSet[];
260
+    public children: (RuleSet | Rule)[];
262 261
 
263 262
     public constructor(
264 263
       selectors: Selector[],
265
-      rules: Rule[],
266
-      children: RuleSet[] = []
264
+      children: (RuleSet | Rule)[] = []
267 265
     ) {
268 266
       super();
269 267
       this.selectors = selectors;
270
-      this.rules = rules;
271 268
       this.children = children;
272 269
     }
273 270
 
@@ -280,14 +277,22 @@ export namespace AST {
280 277
       const lineages = ([] as string[]).concat(
281 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 289
       if (rulesError !== undefined) return rulesError;
286 290
 
287 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 296
           return child.compile(env, opts);
292 297
         }
293 298
       );

+ 5
- 4
src/moss.ts View File

@@ -9,10 +9,10 @@ import { EnvError } from './env';
9 9
 import Lexer, { LexerError } from './lexer';
10 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 17
 const rawArgs = minimist(process.argv.slice(2));
18 18
 
@@ -42,6 +42,7 @@ const moss = (
42 42
   } else {
43 43
     const parser = new Parser(tokens);
44 44
     const tree = parser.parse();
45
+    print(tree);
45 46
     if (tree instanceof ParserError) {
46 47
       return tree;
47 48
     } else {

+ 3
- 4
src/parser.ts View File

@@ -244,8 +244,7 @@ export default class Parser {
244 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 249
     while (
251 250
       [TokenTypes.PROPERTY, TokenTypes.LPAREN].includes(
@@ -261,7 +260,7 @@ export default class Parser {
261 260
         const value = this.value();
262 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 264
       } else if (this.currentToken().type === TokenTypes.LPAREN) {
266 265
         const ruleSet = this.ruleSet(selectors);
267 266
         if (ruleSet instanceof ParserError) return ruleSet;
@@ -272,7 +271,7 @@ export default class Parser {
272 271
     const rParen = this.eat(TokenTypes.RPAREN);
273 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 277
   private value():

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

@@ -104,16 +104,16 @@ test('parses an expression with children', (t) => {
104 104
     t.deepEqual(result.tree, [
105 105
       new AST.RuleSet(
106 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 109
           new AST.RuleSet(
110 110
             [
111 111
               new AST.Selector(literalToken('div'), [
112 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 117
               new AST.RuleSet(
118 118
                 [
119 119
                   new AST.Selector(literalToken('span'), [
@@ -297,7 +297,6 @@ test('allow rules and children in any order', (t) => {
297 297
       result.tree[0],
298 298
       new AST.RuleSet(
299 299
         [new AST.Selector(literalToken('div'))],
300
-        [new AST.Rule(property('color'), literalNode('green'))],
301 300
         [
302 301
           new AST.RuleSet(
303 302
             [
@@ -307,6 +306,32 @@ test('allow rules and children in any order', (t) => {
307 306
             ],
308 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