more helper functions

This commit is contained in:
Christopher Jeffrey 2013-02-22 03:40:58 -06:00
parent 1988c22cab
commit f17634dfa7

View File

@ -330,19 +330,7 @@ Tput.prototype._compile = function(val) {
function clear() { function clear() {
if (buff) { if (buff) {
code += 'out.push(' echo(JSON.stringify(buff).replace(/\\u001b/g, '\\x1b'));
+ JSON.stringify(buff).replace(/\\u001b/g, '\\x1b')
+ '),';
// code += 'out.push("';
// code += buff
// .replace(/"/g, '\\"')
// .replace(/\x1b/g, '\\x1b')
// .replace(/\r/g, '\\r')
// .replace(/\n/g, '\\n')
// .replace(/\x07/g, '\\x07')
// .replace(/\x08/g, '\\x08')
// .replace(/\t/g, '\\t');
// code += '"),';
buff = ''; buff = '';
} }
} }
@ -356,128 +344,142 @@ Tput.prototype._compile = function(val) {
return cap; return cap;
} }
function stmt() { function stmt(c) {
if (code[code.length-1] === ',') code = code.slice(0, -1); if (code[code.length-1] === ',') {
code = code.slice(0, -1);
}
code += c;
// code += ';' + c;
}
function expr(c) {
code += c + ',';
// code += '(' + c + '),';
}
function echo(c) {
expr('out.push(' + c + ')');
}
function print(c) {
echo('"' + c + '"');
} }
while (val) { while (val) {
// '\e' -> ^[ // '\e' -> ^[
if (read(/^\\e/i)) { if (read(/^\\e/i)) {
code += 'out.push("'; print('\\x1b');
code += '\\x1b';
code += '"),';
continue; continue;
} }
// '^A' -> ^A // '^A' -> ^A
// case-insensitive? // case-insensitive?
if (read(/^\^(.)/i)) { if (read(/^\^(.)/i)) {
code += 'out.push("';
switch (ch.toUpperCase()) { switch (ch.toUpperCase()) {
case '@': case '@':
code += '\\x00'; ch = '\\x00';
break; break;
case 'A': case 'A':
code += '\\x01'; ch = '\\x01';
break; break;
case 'B': case 'B':
code += '\\x02'; ch = '\\x02';
break; break;
case 'C': case 'C':
code += '\\x03'; ch = '\\x03';
break; break;
case 'D': case 'D':
code += '\\x04'; ch = '\\x04';
break; break;
case 'E': case 'E':
code += '\\x05'; ch = '\\x05';
break; break;
case 'F': case 'F':
code += '\\x06'; ch = '\\x06';
break; break;
case 'G': case 'G':
code += '\\x07'; ch = '\\x07';
break; break;
case 'H': case 'H':
code += '\\x08'; ch = '\\x08';
break; break;
case 'I': case 'I':
code += '\\x09'; // \t ch = '\\x09'; // \t
break; break;
case 'J': case 'J':
code += '\\x0a'; // \n ch = '\\x0a'; // \n
break; break;
case 'K': case 'K':
code += '\\x0b'; ch = '\\x0b';
break; break;
case 'L': case 'L':
code += '\\x0c'; ch = '\\x0c';
break; break;
case 'M': case 'M':
code += '\\x0d'; ch = '\\x0d';
break; break;
case 'N': case 'N':
code += '\\x0e'; ch = '\\x0e';
break; break;
case 'O': case 'O':
code += '\\x0f'; ch = '\\x0f';
break; break;
case 'P': case 'P':
code += '\\x10'; ch = '\\x10';
break; break;
case 'Q': case 'Q':
code += '\\x11'; ch = '\\x11';
break; break;
case 'R': case 'R':
code += '\\x12'; ch = '\\x12';
break; break;
case 'S': case 'S':
code += '\\x13'; ch = '\\x13';
break; break;
case 'T': case 'T':
code += '\\x14'; ch = '\\x14';
break; break;
case 'U': case 'U':
code += '\\x15'; ch = '\\x15';
break; break;
case 'V': case 'V':
code += '\\x16'; ch = '\\x16';
break; break;
case 'W': case 'W':
code += '\\x17'; ch = '\\x17';
break; break;
case 'X': case 'X':
code += '\\x18'; ch = '\\x18';
break; break;
case 'Y': case 'Y':
code += '\\x19'; ch = '\\x19';
break; break;
case 'Z': case 'Z':
code += '\\x1a'; ch = '\\x1a';
break; break;
case '\\': case '\\':
code += '\\x1c'; ch = '\\x1c';
break; break;
case '^': case '^':
code += '\\x1e'; ch = '\\x1e';
break; break;
case '_': case '_':
code += '\\x1f'; ch = '\\x1f';
break; break;
case '[': case '[':
code += '\\x1b'; ch = '\\x1b';
break; break;
case ']': case ']':
code += '\\x1d'; ch = '\\x1d';
break; break;
case '?': case '?':
code += '\\x7f'; ch = '\\x7f';
break; break;
default: default:
code += '\\' + ch; ch = '\\' + ch;
break; break;
} }
code += '"),'; print(ch);
continue; continue;
} }
@ -485,75 +487,71 @@ Tput.prototype._compile = function(val) {
// '\r' -> \r // '\r' -> \r
// '\0' -> \200 (special case) // '\0' -> \200 (special case)
if (read(/^\\([nlrtbfs\^\\,:0])/)) { if (read(/^\\([nlrtbfs\^\\,:0])/)) {
code += 'out.push("';
switch (ch) { switch (ch) {
case 'n': case 'n':
code += '\\n'; ch = '\\n';
break; break;
case 'l': case 'l':
code += ''; ch = '';
break; break;
case 'r': case 'r':
code += '\\r'; ch = '\\r';
break; break;
case 't': case 't':
code += '\\t'; ch = '\\t';
break; break;
case 'b': case 'b':
code += '\\x08'; ch = '\\x08';
break; break;
case 'f': case 'f':
code += '\\x0c'; ch = '\\x0c';
break; break;
case 's': case 's':
code += ' '; ch = ' ';
break; break;
case '\\': case '\\':
code += '\\\\'; ch = '\\\\';
break; break;
case ',': case ',':
code += ','; ch = ',';
break; break;
case ';': case ';':
code += ';'; ch = ';';
break; break;
case '0': case '0':
//code += '\\0'; //ch = '\\0';
code += '\\200'; ch = '\\200';
break; break;
//case 'v': //case 'v':
// code += '\\x0b'; // ch = '\\x0b';
// break; // break;
//case 'a': //case 'a':
// code += '\\x07': // ch = '\\x07':
// break; // break;
default:
ch = '';
break;
} }
code += '"),'; print(ch);
continue; continue;
} }
// 3 octal digits -> character // 3 octal digits -> character
if (read(/^\\(\d\d\d)/)) { if (read(/^\\(\d\d\d)/)) {
code += 'out.push("'; print('\\' + ch);
code += '\\' + ch;
//code += String.fromCharCode(parseInt(ch, 8));
code += '"),';
continue; continue;
} }
// $<5> -> padding // $<5> -> padding
// e.g. flash_screen: '\u001b[?5h$<100/>\u001b[?5l', // e.g. flash_screen: '\u001b[?5h$<100/>\u001b[?5l',
if (read(/^\$<(\d+)>(\*|\/)/)) { if (read(/^\$<(\d+)>(\*|\/)/)) {
code += 'out.push("'; print('');
code += '"),';
continue; continue;
} }
// %% outputs `%' // %% outputs `%'
if (read(/^%%/)) { if (read(/^%%/)) {
code += 'out.push("'; print('%');
code += '%';
code += '"),';
continue; continue;
} }
@ -562,61 +560,54 @@ Tput.prototype._compile = function(val) {
// next character to be a `-' flag, avoiding interpreting "%-" as an // next character to be a `-' flag, avoiding interpreting "%-" as an
// operator. // operator.
if (read(/^%(:-|[+# ])(?:(\d+)(\.\d+)?)?([doxXs])?/)) { if (read(/^%(:-|[+# ])(?:(\d+)(\.\d+)?)?([doxXs])?/)) {
code += 'out.push("'; print('');
code += '"),';
continue; continue;
} }
// %c print pop() like %c in printf // %c print pop() like %c in printf
if (read(/^%c/)) { if (read(/^%c/)) {
code += 'out.push('; echo('stack.pop()');
code += 'stack.pop()'; // TODO: FORMAT
code += '),';
continue; continue;
} }
// %d print pop() like %d in printf // %d print pop() like %d in printf
// NOT SURE ABOUT %d being print! // NOT SURE ABOUT %d being print!
if (read(/^%d/)) { if (read(/^%d/)) {
code += 'out.push('; echo('stack.pop()');
code += 'stack.pop()'; // TODO: FORMAT
code += '),';
continue; continue;
} }
// %s print pop() like %s in printf // %s print pop() like %s in printf
if (read(/^%s/)) { if (read(/^%s/)) {
code += 'out.push('; echo('stack.pop()');
code += 'stack.pop()'; // TODO: FORMAT
code += '),';
continue; continue;
} }
// %p[1-9] // %p[1-9]
// push i'th parameter // push i'th parameter
if (read(/^%p([1-9])/)) { if (read(/^%p([1-9])/)) {
code += '(stack.push(v = params[' + (i - 1) + ']), v),'; expr('(stack.push(v = params[' + (i - 1) + ']), v)');
continue; continue;
} }
// %P[a-z] // %P[a-z]
// set dynamic variable [a-z] to pop() // set dynamic variable [a-z] to pop()
if (read(/^%P([a-z])/)) { if (read(/^%P([a-z])/)) {
code += 'dyn.' + v + ' = stack.pop(),'; expr('dyn.' + v + ' = stack.pop()');
continue; continue;
} }
// %g[a-z] // %g[a-z]
// get dynamic variable [a-z] and push it // get dynamic variable [a-z] and push it
if (read(/^%g([a-z])/)) { if (read(/^%g([a-z])/)) {
code += '(stack.push(dyn.' + v + '), dyn.' + v + '),'; expr('(stack.push(dyn.' + v + '), dyn.' + v + ')');
continue; continue;
} }
// %P[A-Z] // %P[A-Z]
// set static variable [a-z] to pop() // set static variable [a-z] to pop()
if (read(/^%P([A-Z])/)) { if (read(/^%P([A-Z])/)) {
code += 'stat.' + v + ' = stack.pop(),'; expr('stat.' + v + ' = stack.pop()');
continue; continue;
} }
@ -630,26 +621,26 @@ Tput.prototype._compile = function(val) {
// impact portability to other implementations. // impact portability to other implementations.
if (read(/^%g([A-Z])/)) { if (read(/^%g([A-Z])/)) {
code += '(stack.push(v = stat.' + v + '), v),'; expr('(stack.push(v = stat.' + v + '), v)');
continue; continue;
} }
// %'c' char constant c // %'c' char constant c
if (read(/^%'(\w)'/)) { if (read(/^%'(\w)'/)) {
code += '(stack.push(v = "' + ch + '", v),'; expr('(stack.push(v = "' + ch + '", v)');
continue; continue;
} }
// %{nn} // %{nn}
// integer constant nn // integer constant nn
if (read(/^%\{(\d+)\}/)) { if (read(/^%\{(\d+)\}/)) {
code += '(stack.push(v = ' + ch + '), v),'; expr('(stack.push(v = ' + ch + '), v)');
continue; continue;
} }
// %l push strlen(pop) // %l push strlen(pop)
if (read(/^%l/)) { if (read(/^%l/)) {
code += '(stack.push(v = stack.pop().length), v),'; expr('(stack.push(v = stack.pop().length), v)');
continue; continue;
} }
@ -662,28 +653,27 @@ Tput.prototype._compile = function(val) {
if (read(/^%([+\-*\/m&|\^=><])/)) { if (read(/^%([+\-*\/m&|\^=><])/)) {
if (op === '=') op = '==='; if (op === '=') op = '===';
else if (op === 'm') op = '%'; else if (op === 'm') op = '%';
code += '(stack.push(v = (stack.pop() ' + op + ' stack.pop())), v),'; expr('(stack.push(v = (stack.pop() ' + op + ' stack.pop())), v)');
continue; continue;
} }
// %A, %O // %A, %O
// logical AND and OR operations (for conditionals) // logical AND and OR operations (for conditionals)
if (read(/^%([AO])/)) { if (read(/^%([AO])/)) {
stmt(); stmt(op === ' A ' ? ' && ' : ' || ');
code += op === ' A ' ? ' && ' : ' || ';
continue; continue;
} }
// %! %~ // %! %~
// unary operations (logical and bit complement): push(op pop()) // unary operations (logical and bit complement): push(op pop())
if (read(/^%([!~])/)) { if (read(/^%([!~])/)) {
code += '(stack.push(v = ' + op + 'stack.pop()), v),'; expr('(stack.push(v = ' + op + 'stack.pop()), v)');
continue; continue;
} }
// %i add 1 to first two parameters (for ANSI terminals) // %i add 1 to first two parameters (for ANSI terminals)
if (read(/^%i/)) { if (read(/^%i/)) {
code += '(params[0]++, params[1]++),'; expr('(params[0]++, params[1]++)');
continue; continue;
} }
@ -703,34 +693,30 @@ Tput.prototype._compile = function(val) {
// written on one line. The -f option splits the string into lines with // written on one line. The -f option splits the string into lines with
// the parts indented. // the parts indented.
if (read(/^%\?/)) { if (read(/^%\?/)) {
stmt(); stmt(';if (');
code += ';if (';
continue; continue;
} }
if (read(/^%t/)) { if (read(/^%t/)) {
stmt(); stmt(') {');
code += ') {';
continue; continue;
} }
if (read(/^%e/)) { if (read(/^%e/)) {
stmt();
var end = val.indexOf('%;'); var end = val.indexOf('%;');
var els = val.indexOf('%e'); var els = val.indexOf('%e');
var then = val.indexOf('%t'); var then = val.indexOf('%t');
// does else if's like this: %?[expr]%t...%e[expr]%t...%; // does else if's like this: %?[expr]%t...%e[expr]%t...%;
if (then < end && then < els) { if (then < end && then < els) {
code += '} else if ('; stmt('} else if (');
} else { } else {
code += '} else {'; stmt('} else {');
} }
continue; continue;
} }
if (read(/^%;/)) { if (read(/^%;/)) {
stmt(); stmt('}');
code += '}';
continue; continue;
} }
@ -768,8 +754,7 @@ Tput.prototype._compile = function(val) {
clear(); clear();
stmt(); stmt(';return out.join("");');
code += ';return out.join("");';
// Optimize // Optimize
// ... out.push("foo");return out.join(""); // ... out.push("foo");return out.join("");