Commits

Mathias Panzenböck committed c8d6851

patterns++, i18n++

Comments (0)

Files changed (2)

 function getstrings (code, options) {
 	if (!options) options = {};
 	var strings = options.strings || {};
+	var callback = options.transform;
 	var troptions = extend({},options);
 	delete troptions.strings;
+	delete troptions.transform;
 	var has = Object.prototype.hasOwnProperty;
-	new Transformer().on(
+	var transformer = new Transformer().on(
 		match.global('_').call(match.string(), match.many()),
 		options.loc ? function (node) {
 			var s = node.arguments[0].value;
 			else {
 				strings[s] = 1;
 			}
-		}).transform(code, troptions);
+		});
+	if (callback) callback(transformer);
+	transformer.transform(code, troptions);
 	return strings;
 }
 
 	if (!options) options = {};
 	var strings = options.strings || {};
 	var nextid = options.nextid || 0;
+	var callback = options.transform;
 	var troptions = extend({},options);
 	delete troptions.strings;
 	delete troptions.nextid;
+	delete troptions.transform;
 	var has = Object.prototype.hasOwnProperty;
-	var node = new Transformer().replace(
+	var transformer = new Transformer().replace(
 		match.global('_').call(match.string(), match.many()),
 		function (node) {
 			var s = node.arguments[0].value;
 				strings[s] = id = '_'+(nextid++);
 			}
 			return make.id('_').get(id);
-		}).transform(code, troptions);
+		});
+	if (callback) callback(transformer);
+	var node = transformer.transform(code, troptions);
 	return {
 		strings: strings,
 		nextid: nextid,
 	return new BlockStatementPattern(body.map(stmtwrap));
 }
 
+function blockwrap (body) {
+	if (body instanceof ExpressionPattern) {
+		return new ExpressionStatementPattern(body);
+	}
+	else if (body instanceof Pattern) {
+		return body;
+	}
+	else if (body === null || body === undefined) {
+		return new BlockStatementPattern([]);
+	}
+	return new BlockStatementPattern(body.map(stmtwrap));
+}
+
 var PatternHelper = {
 	val: wrap,
 	any: function () {
 	},
 	funexp: function (name, args, body) {
 		args = args === null ? [IgnorableElements] : args.map(argwrap);
-		return new FunctionExpressionPattern(wrap(name), args, wrap(body));
+		return new FunctionExpressionPattern(wrap(name), args, blockwrap(body));
 	},
 	fundecl: function (name, args, body) {
 		args = args === null ? [IgnorableElements] : args.map(argwrap);
-		return new FunctionDeclarationPattern(wrap(name), args, wrap(body));
+		return new FunctionDeclarationPattern(wrap(name), args, blockwrap(body));
 	},
 	fun: function (name, args, body) {
 		if (name === null) {
 	block: function (body) {
 		return new BlockStatementPattern(body ? body.map(stmtwrap) : null);
 	},
-	// TODO: label, if, while, do while, for, for in, with, return, break,
-	//       continue, try, throw, catch, switch, case
+	nothing: function () {
+		return new NothingPattern();
+	},
 	label: function (label, stmt) {
 		return stmtwrap(stmt).label(label);
 	},
 	if: function (test, consequent, alternate) {
+		return new IfStatementPattern(
+			wrap(test),
+			stmtwrap(consequent),
+			alternate !== null ? stmtwrap(alternate) : this.nothing());
 	},
 	while: function (test, body) {
+		return new WhilePattern(wrap(test), stmtwrap(body));
 	},
 	do_while: function (body, test) {
+		return new DoWhilePattern(stmtwrap(body), wrap(test));
 	},
 	for: function (init, test, update, body) {
+		return new ForPattern(
+			init !== null ? wrap(init) : this.nothing(),
+			test !== null ? wrap(test) : this.nothing(),
+			update !== null ? wrap(update) : this.nothing(),
+			stmtwrap(body));
 	},
 	for_in: function (iterator, object, body) {
+		return new ForInPattern(wrap(iterator), wrap(object), stmtwrap(body));
 	},
 	with: function (object, body) {
+		return new WithPattern(wrap(object), stmtwrap(body));
 	},
 	return: function (argument) {
+		return new ReturnPattern(argument !== null ? wrap(argument) : this.nothing());
 	},
 	break: function (label) {
+		return new ReturnPattern(label !== null ? wrap(label) : this.nothing());
 	},
 	continue: function (label) {
+		return new ContinuePattern(label !== null ? wrap(label) : this.nothing());
 	},
 	try: function (block, handlers, finalizer) {
+		return new TryPattern(
+			stmtwrap(block),
+			handlers !== null ? (handlers||[]).map(wrap) : null,
+			finalizer !== null ? blockwrap(finalizer) : this.nothing());
 	},
 	throw: function (argument) {
+		return new ThrowPattern(wrap(argument));
 	},
 	catch: function (param, body) {
+		return new CatchPattern(wrap(param), blockwrap(body));
 	},
 	switch: function (discriminant, cases) {
+		return new SwitchPattern(wrap(discriminant),
+			cases !== null ? (cases||[]).map(wrap) : null);
 	},
 	case: function (test, consequent) {
+		return new CasePattern(
+			test !== null ? wrap(test) : this.nothing(),
+			consequent !== null ? (consequent||[]).map(stmtwrap) : null);
 	},
 	default: function (consequent) {
+		return new CasePattern(
+			this.nothing(),
+			consequent !== null ? (consequent||[]).map(stmtwrap) : null);
 	}
 };
 
 		return node instanceof nodes.Statement;
 	},
 	label: function (label) {
-		// TODO
+		return new LabelPattern(wrap(label), this);
 	},
 	if: function (test) {
-		// TODO
+		return new IfStatementPattern(wrap(test), this, new NothingPattern());
 	}
 });
 
 	}
 });
 
+function NothingPattern () {}
+
+NothingPattern.prototype = extend(new Pattern(), {
+	test: function (node) {
+		return !node;
+	}
+});
+
+// TODO:
+// LabelPattern
+// IfStatementPattern
+// WhilePattern
+// DoWhilePattern
+// ForPattern
+// ForInPattern
+// WithPattern
+// ReturnPattern
+// ContinuePattern
+// TryPattern
+// ThrowPattern
+// CatchPattern
+// SwitchPattern
+// CasePattern
+
 exports.PatternHelper = PatternHelper;
 exports.AlternativesPattern = AlternativesPattern;
 exports.ArrayPattern = ArrayPattern;
 exports.ProgramPattern = ProgramPattern;
 exports.BlockStatementPattern = BlockStatementPattern;
 exports.PropertyPattern = PropertyPattern;
+exports.NothingPattern = NothingPattern;