|
@@ -1,7 +1,6 @@
|
1
|
1
|
import Env, { EnvError } from './env';
|
2
|
2
|
import Token from './token';
|
3
|
3
|
|
4
|
|
-
|
5
|
4
|
export namespace AST {
|
6
|
5
|
export type Child = Rule | RuleSet | Application;
|
7
|
6
|
|
|
@@ -222,7 +221,11 @@ export namespace AST {
|
222
|
221
|
public parameters: Identifier[];
|
223
|
222
|
public children: Child[];
|
224
|
223
|
|
225
|
|
- public constructor(name: Token, parameters: Identifier[], children: Child[]) {
|
|
224
|
+ public constructor(
|
|
225
|
+ name: Token,
|
|
226
|
+ parameters: Identifier[],
|
|
227
|
+ children: Child[]
|
|
228
|
+ ) {
|
226
|
229
|
super();
|
227
|
230
|
this.name = name;
|
228
|
231
|
this.parameters = parameters;
|
|
@@ -260,12 +263,9 @@ export namespace AST {
|
260
|
263
|
|
261
|
264
|
export class RuleSet extends Node {
|
262
|
265
|
public selectors: Selector[];
|
263
|
|
- public children: (Application | Rule | RuleSet)[];
|
|
266
|
+ public children: Child[];
|
264
|
267
|
|
265
|
|
- public constructor(
|
266
|
|
- selectors: Selector[],
|
267
|
|
- children: (Application | Rule | RuleSet)[] = []
|
268
|
|
- ) {
|
|
268
|
+ public constructor(selectors: Selector[], children: Child[] = []) {
|
269
|
269
|
super();
|
270
|
270
|
this.selectors = selectors;
|
271
|
271
|
this.children = children;
|
|
@@ -284,15 +284,42 @@ export namespace AST {
|
284
|
284
|
const rules: (String | EnvError)[] = [];
|
285
|
285
|
const children: (String | EnvError)[] = [];
|
286
|
286
|
|
287
|
|
- this.children.map((child) => {
|
|
287
|
+ for (const child of this.children) {
|
288
|
288
|
if (child instanceof Rule) {
|
289
|
289
|
rules.push(child.compile(env, opts));
|
290
|
290
|
} else if (child instanceof RuleSet) {
|
291
|
291
|
children.push(child.compile(env, opts));
|
292
|
292
|
} else if (child instanceof Application) {
|
293
|
|
- console.log(child.compile(env, opts));
|
|
293
|
+ const mixin = env.get(child.name.value);
|
|
294
|
+ if (mixin instanceof EnvError) return mixin;
|
|
295
|
+ if (mixin instanceof AST.Mixin) {
|
|
296
|
+ if (mixin.parameters.length !== child.arguments.length) {
|
|
297
|
+ return new EnvError(
|
|
298
|
+ child.name.value.line,
|
|
299
|
+ `Expected ${mixin.parameters.length} arguments but received ${
|
|
300
|
+ child.arguments.length
|
|
301
|
+ }`
|
|
302
|
+ );
|
|
303
|
+ }
|
|
304
|
+ const mixinEnv = new Env(env);
|
|
305
|
+ mixin.parameters.forEach((param, index) => {
|
|
306
|
+ mixinEnv.set(param.name.value, child.arguments[index]);
|
|
307
|
+ });
|
|
308
|
+ mixin.children.forEach((mixinChild) => {
|
|
309
|
+ if (mixinChild instanceof Rule) {
|
|
310
|
+ rules.push(mixinChild.compile(mixinEnv, opts));
|
|
311
|
+ } else if (mixinChild instanceof RuleSet) {
|
|
312
|
+ mixinChild.selectors.map((sel) => {
|
|
313
|
+ sel.parents = this.selectors;
|
|
314
|
+ });
|
|
315
|
+ children.push(mixinChild.compile(mixinEnv, opts));
|
|
316
|
+ } else {
|
|
317
|
+ console.log(mixinChild);
|
|
318
|
+ }
|
|
319
|
+ });
|
|
320
|
+ }
|
294
|
321
|
}
|
295
|
|
- });
|
|
322
|
+ }
|
296
|
323
|
|
297
|
324
|
const rulesError = rules.find((node) => node instanceof EnvError);
|
298
|
325
|
if (rulesError instanceof EnvError) return rulesError;
|