Skip to content

Commit

Permalink
Simple handling of try/catch directives.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashb committed Sep 21, 2009
1 parent 421f95f commit fef532c
Showing 1 changed file with 54 additions and 10 deletions.
64 changes: 54 additions & 10 deletions lib/Template.js
Expand Up @@ -64,8 +64,8 @@ Template.Constants = {
};

Template.Exception = function(code, message) {
this.code = code;
this.message = message;
this.type = code;
this.info = message;
}
Template.Exception.prototype.__proto__ = Error.prototype;
Template.Exception.prototype.name = "Template.Exception";
Expand Down Expand Up @@ -276,10 +276,6 @@ Template.Context.prototype = {
return ret;
},

write: function(str) { this.out_arr.push(str); },

get_output: function() { return this.out_arr.join("") },

nullObj: { toString: function() { return ''; } },

dot_op: function Template$Context$dot_op(stash, segments, args) {
Expand Down Expand Up @@ -453,6 +449,19 @@ Template.Context.prototype = {
// Default implementation is no file IO.
load_file: function load_file(file) {
throw new Template.Exception("NOT_FOUND", "File " + uneval(file) + " not found");
},

$catch: function $catch(err) {
var errType = typeof err == "object" &&
err.constructor &&
err.constructor.name
? err.constructor.name
: 'undef';
if (!(err instanceof Template.Exception) ) {
err = new Template.Exception('undef', err);
}
this.dot_op(this.stash, ["error"], { assign: err } );
return err;
}
};

Expand Down Expand Up @@ -2027,6 +2036,7 @@ Template.Parser.prototype = {
switch (this.token.type) {
case ';':
this.consumeToken();
c.signature = false;
break;
case 'DEFAULT':
c.signature = this.consumeToken();
Expand Down Expand Up @@ -2092,12 +2102,12 @@ Template.Interpreter.prototype = {
var out_arr = []; ctx.StopIteration = StopIteration || 'StopIteration'; \
function __perl_truth(val) { return (!!val && val != '0' && val !== ctx.nullObj) ? val : '' };\
function __not_perl_truth(val) { return (!!val && val != '0' && val !== ctx.nullObj) ? '' : 1 };\
function write() { out_arr = out_arr.concat(Array.prototype.slice.apply(arguments)); };\n\
function write() { out_arr = out_arr.concat(Array.slice(arguments)); };\n\
try {\n",

postlude: "\n\
}\n\
catch (e) { if (!(e instanceof Template.Exception && e.code == 'stop')) throw e; } \n\
catch (e) { if (!(e instanceof Template.Exception && e.type == 'stop')) throw e; } \n\
return out_arr.join('');\n\
}",

Expand All @@ -2113,9 +2123,9 @@ Template.Interpreter.prototype = {
// check for things like GET, SET or CALL
// Not everything writes directly.
var write = ['IF', 'FOR', 'CALL', 'setlist', 'DEFAULT', 'UNLESS', 'BLOCK',
'NEXT', 'LAST', 'WHILE', 'SWITCH'
'NEXT', 'LAST', 'WHILE', 'SWITCH', 'TRY', 'THROW', 'CATCH'
].indexOf(chunk.type) == -1;
var add_semicolon = write;// || chunk.type == 'BLOCK';
var add_semicolon = write || ['THROW'].indexOf(chunk.type) != -1;

if (chunk.toSource)
output += '/* ' + chunk.toSource() + ' */\n';
Expand Down Expand Up @@ -2418,6 +2428,40 @@ Template.Interpreter.prototype = {
ret += '}\n';
return ret;

case 'TRY':
var ret = "try {\n";

var body = this.walk(term.tryBlock);
ret += body.replace(/^/gm, ' ');

ret += "}\n";

if (term.catches.length) {
ret += 'catch ($e) { $e = ctx.$catch($e); \n';

for (var i in term.catches) {
var c = term.catches[i];
if (c.signature == 'DEFAULT') {}
else if (c.signature) {}
else {
var body = this.walk(c.block);
ret += body.replace(/^/gm, ' ');
}
}

ret += '}\n';
}
if (term['final'].length) {
}

// TT doesn't require a CATCH or FINAL block. JS does
if (!term.catches.length && !term['final'].length) {
ret += "catch ($e) {}\n"
}

return ret;
case 'THROW':
return "throw " + this.handle_nameargs(term);
default:
throw new Error('Unhandled ' + term.toSource());
}
Expand Down

0 comments on commit fef532c

Please sign in to comment.