Skip to content

Commit

Permalink
efficient template compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrsh committed Apr 2, 2017
1 parent 159eee8 commit 9d577b8
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 45 deletions.
95 changes: 73 additions & 22 deletions dist/moon.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,28 +187,6 @@
return path[0];
};

/**
* Compiles a Template
* @param {String} template
* @param {Boolean} isString
* @return {String} compiled template
*/
var compileTemplate = function (template, isString) {
var TEMPLATE_RE = /{{([A-Za-z0-9_$@]+)([A-Za-z0-9_.()'"+\-*/\s\[\]]+)?}}/gi;
var compiled = template;
template.replace(TEMPLATE_RE, function (match, key, modifiers) {
if (!modifiers) {
modifiers = '';
}
if (isString) {
compiled = compiled.replace(match, '" + instance.get("' + key + '")' + modifiers + ' + "');
} else {
compiled = compiled.replace(match, 'instance.get("' + key + '")' + modifiers);
}
});
return compiled;
};

/**
* Extracts the Slots From Component Children
* @param {Array} children
Expand Down Expand Up @@ -819,6 +797,79 @@
};

/* ======= Compiler ======= */
var openRE = /\{\{/;
var closeRE = /\}\}/;
var modifierRE = /\[|\./;

var compileTemplate = function (template, isString) {
var state = {
current: 0,
template: template,
output: ""
};

compileTemplateState(state, isString);

return state.output;
};

var compileTemplateState = function (state, isString) {
var template = state.template;
var length = template.length;
while (state.current < length) {
var value = scanTemplateStateUntil(state, openRE);

if (value) {
state.output += value;
}

state.current += 2;

var name = scanTemplateStateUntil(state, closeRE);

if (name) {
var modifiers = "";
var modifierIndex = null;
if ((modifierIndex = name.search(modifierRE)) !== -1) {
modifiers = name.substring(modifierIndex);
name = name.substring(0, modifierIndex);
}

if (isString) {
state.output += '" + instance.get("' + name + '")' + modifiers + ' + "';
} else {
state.output += 'instance.get("' + name + '")' + modifiers;
}
}

state.current += 2;
}
};

var scanTemplateStateUntil = function (state, re) {
var template = state.template;
var tail = template.substring(state.current);
var length = tail.length;
var idx = tail.search(re);

var match = "";

switch (idx) {
case -1:
match = tail;
break;
case 0:
match = '';
break;
default:
match = tail.substring(0, idx);
}

state.current += match.length;

return match;
};

var lex = function (input) {
var state = {
input: input,
Expand Down
2 changes: 1 addition & 1 deletion dist/moon.min.js

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions src/compiler/template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const openRE = /\{\{/;
const closeRE = /\}\}/;
const modifierRE = /\[|\./;

const compileTemplate = function(template, isString) {
let state = {
current: 0,
template: template,
output: ""
};

compileTemplateState(state, isString);

return state.output;
}

const compileTemplateState = function(state, isString) {
const template = state.template;
const length = template.length;
while(state.current < length) {
const value = scanTemplateStateUntil(state, openRE);

if(value) {
state.output += value;
}

state.current += 2;

let name = scanTemplateStateUntil(state, closeRE);

if(name) {
let modifiers = "";
let modifierIndex = null;
if((modifierIndex = (name.search(modifierRE))) !== -1) {
modifiers = name.substring(modifierIndex);
name = name.substring(0, modifierIndex);
}

if(isString) {
state.output += `" + instance.get("${name}")${modifiers} + "`;
} else {
state.output += `instance.get("${name}")${modifiers}`;
}
}

state.current += 2;
}
}

const scanTemplateStateUntil = function(state, re) {
const template = state.template;
const tail = template.substring(state.current);
const length = tail.length;
const idx = tail.search(re);

let match = "";

switch (idx) {
case -1:
match = tail;
break;
case 0:
match = '';
break;
default:
match = tail.substring(0, idx);
}

state.current += match.length;

return match;
}
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ let id = 0;
//=require util/vdom.js

/* ======= Compiler ======= */
//=require compiler/template.js
//=require compiler/lexer.js
//=require compiler/parser.js
//=require compiler/generator.js
Expand Down
22 changes: 0 additions & 22 deletions src/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,28 +75,6 @@ const resolveKeyPath = function(instance, obj, keypath, val) {
return path[0];
}

/**
* Compiles a Template
* @param {String} template
* @param {Boolean} isString
* @return {String} compiled template
*/
const compileTemplate = function(template, isString) {
const TEMPLATE_RE = /{{([A-Za-z0-9_$@]+)([A-Za-z0-9_.()'"+\-*/\s\[\]]+)?}}/gi;
let compiled = template;
template.replace(TEMPLATE_RE, function(match, key, modifiers) {
if(!modifiers) {
modifiers = '';
}
if(isString) {
compiled = compiled.replace(match, `" + instance.get("${key}")${modifiers} + "`);
} else {
compiled = compiled.replace(match, `instance.get("${key}")${modifiers}`);
}
});
return compiled;
}

/**
* Extracts the Slots From Component Children
* @param {Array} children
Expand Down

0 comments on commit 9d577b8

Please sign in to comment.