Permalink
Browse files

Attach node types to the parser class; this provides a way for the ge…

…nerated parser to refer to them if we make it into a CommonJS module and remove globals.
  • Loading branch information...
jcoglan committed Apr 28, 2012
1 parent c88a7fa commit de080ed94e0114f4743c5b492ba6823ca1a525b5
View
@@ -32,13 +32,11 @@ packages:
- canopy/compiler/sequence
- canopy/compiler/sequence_part
- canopy/compiler/reference
+ - bindings
meta:
provides:
- Canopy
- Canopy.MetaGrammarParser
- Canopy.Compiler
- Canopy.compile
- requires:
- - JS.Class
- - JS.Module
View
@@ -1,16 +1,15 @@
<%= license %>
var Canopy = {};
-if (typeof module === 'object') module.exports = Canopy;
Canopy.extend = function(destination, source) {
- if (!destination || !source) return destination;
- for (var key in source) {
- if (destination[key] !== source[key])
- destination[key] = source[key];
- }
- return destination;
-};
+ if (!destination || !source) return destination;
+ for (var key in source) {
+ if (destination[key] !== source[key])
+ destination[key] = source[key];
+ }
+ return destination;
+ };
Canopy.extend(Canopy, {
compile: function(grammar) {
@@ -21,6 +20,18 @@ Canopy.extend(Canopy, {
return source;
},
+ find: function(root, objectName) {
+ var parts = objectName.split('.'),
+ part;
+
+ while (part = parts.shift()) {
+ root = root[part];
+ if (root === undefined)
+ throw new Error('Cannot find object named ' + objectName);
+ }
+ return root;
+ },
+
forEach: function(list, block, context) {
for (var i = 0, n = list.length; i < n; i++)
block.call(context, list[i], i);
View
@@ -65,12 +65,13 @@ Canopy.extend(Canopy.Builder.prototype, {
syntaxNode_: function(address, nodeType, expression, bump, elements, labelled) {
elements = ', ' + (elements || '[]');
labelled = labelled ? ', ' + labelled : '';
- var klass, of = ', ' + this.offset_();
+ var klass, type, of = ', ' + this.offset_();
if (nodeType) {
klass = this.tempVar_('klass');
- this.if_(nodeType + ' instanceof Function', function(builder) {
- builder.line_(klass + ' = ' + nodeType);
+ type = this.findType_(nodeType);
+ this.if_(type + ' instanceof Function', function(builder) {
+ builder.line_(klass + ' = ' + type);
});
this.else_(function(builder) {
builder.line_(klass + ' = SyntaxNode');
@@ -80,10 +81,17 @@ Canopy.extend(Canopy.Builder.prototype, {
}
this.line_(address + ' = new ' + klass + '(' + expression + of + elements + labelled + ')');
- this.extendNode_(address, nodeType);
+ this.extendNode_(address, type);
this.line_(this.offset_() + ' += ' + bump);
},
+ findType_: function(nodeType) {
+ if (nodeType)
+ return this.tempVar_('type', 'find(this.constructor, "' + nodeType + '")');
+ else
+ return this.tempVar_('type', 'null');
+ },
+
extendNode_: function(address, nodeType) {
if (!nodeType) return;
this.unless_(nodeType + ' instanceof Function', function(builder) {
@@ -28,7 +28,10 @@ Canopy.Compiler.Choice = {
expressions[index].compile(builder, address);
builder.if_(address, function(builder) {
- builder.extendNode_(address, nodeType);
+ if (nodeType) {
+ var type = builder.findType_(nodeType);
+ builder.extendNode_(address, type);
+ }
});
builder.else_(function(builder) {
builder.line_(builder.offset_() + ' = ' + startOffset);
@@ -13,15 +13,10 @@ Canopy.Compiler.Grammar = {
compile: function(builder) {
builder.closure_(function(builder) {
- builder.function_('var extend', ['destination', 'source'], function(builder) {
- builder.line_('if (!source) return destination');
- builder.for_('var key in source', function(builder) {
- builder.if_('destination[key] !== source[key]', function(builder) {
- builder.line_('destination[key] = source[key]');
- });
- });
- builder.return_('destination');
- });
+ builder.line_('var extend = ' + Canopy.extend.toString());
+ builder.newline_();
+ builder.line_('var find = ' + Canopy.find.toString());
+ builder.newline_();
builder.nameSpace_(this.grammarName());
builder.newline_();
@@ -9,7 +9,10 @@ Canopy.Compiler.Reference = {
compile: function(builder, address, nodeType) {
builder.line_(address + ' = this.__consume__' + this.referenceName() + '()');
- builder.extendNode_(address, nodeType);
+ if (nodeType) {
+ var type = builder.findType_(nodeType);
+ builder.extendNode_(address, type);
+ }
}
};
@@ -51,11 +51,13 @@ Canopy.Compiler.Repeat = {
_compileMaybe: function(builder, address, nodeType) {
var startOffset = builder.tempVar_('index', builder.offset_());
-
this.atomic().compile(builder, address);
builder.if_(address, function(builder) {
- builder.extendNode_(address, nodeType);
+ if (nodeType) {
+ var type = builder.findType_(nodeType);
+ builder.extendNode_(address, type);
+ }
});
builder.else_(function(builder) {
builder.line_(builder.offset_() + ' = ' + startOffset);
Oops, something went wrong.

0 comments on commit de080ed

Please sign in to comment.