Skip to content

Instantly share code, notes, and snippets.

@caisui
Created December 8, 2012 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caisui/4239753 to your computer and use it in GitHub Desktop.
Save caisui/4239753 to your computer and use it in GitHub Desktop.
if コマンド
// vim: set fdm=marker :
function Reader() {} //{{{
Reader.prototype.END = {};
(function (F) {
var P = F.prototype;
P.open = true;
P.path = "undefined(str)";
P.close = function close() {
this.open = false;
};
})(Reader); //}}}
function StrReader(str) //{{{
{
this.str = str;
this.offset = 0;
this.num = 0;
}
(function (F) {
const re = /(.*)(?:\r\n|[\r\n])/g;
var P = F.prototype = new Reader;
P.readline = function () {
if (this.open) {
re.lastIndex = this.offset;
var m = re.exec(this.str);
if (m) {
this.offset = re.lastIndex;
return [this.num, m[1]];
this.num++;
}
}
return this.END;
};
})(StrReader); //}}}
function CommandLineReader(cmdline) //{{{
{
this.cmdline = cmdline || commandline;
this.num = 0;
}
(function (F) {
var P = F.prototype = new Reader;
P.readline = function () {
var wait = true;
var value;
if (!this.open) return this.END;
//window.setTimeout(function () {
commandline.input(" ", function (v) {
value = v;
wait = false;
}, {
completer: completion.ex,
onCancel: function () { wait = false; },
});
//}, 0);
var thread = services.get("tm").mainThread;
while (wait) {
thread.processNextEvent(true);
}
if (value === undefined) {
this.close();
return this.END;
}
return [this.num++, value];
};
})(CommandLineReader); //}}}
function getCommand(reader) {
var res;
var hereDocEnd = null;
while (1) {
res = reader.readline();
if (res === reader.END) {
break;
}
var i = res[0];
var line = res[1].replace(/\r$/, "");
if (hereDocEnd) {
if (line === hereDocEnd) {
return obj;
hereDocEnd = null;
} else {
obj.args += line + "\n";
continue;
}
}
if (/^\s*(".*)?$/.test(line))
continue;
var res = commands.parseCommand(line);
var obj = {
count: res[0],
cmd: res[1],
special: res[2],
args: res[3],
};
var cmd = obj.cmd;
var command = obj.cmd = commands.get(cmd);
if (!command) {
let lineNumber = i + 1;
liberator.echoerr("Error detected while processing: " + reader.path, commandline.FORCE_MULTILINE);
commandline.echo("line " + lineNumber + ":", commandline.HL_LINENR, commandline.APPEND_TO_MESSAGES);
liberator.echoerr("Not an editor command: " + line);
} else {
if (command.hereDoc) {
var m = obj.args.match(/(.*)<<\s*(\S+)$/);
if (m) {
obj.args = m[1];
hereDocEnd = m[2]
}
}
if (!hereDocEnd)
return obj;
}
}
if (hereDocEnd) {
return obj;
}
}
io.source =
function (filename, silent) {
let wasSourcing = this.sourcing;
try {
if (typeof filename === "string") {
var file = File(filename);
} else if (filename instanceof File) {
filename = file.path;
} else if (filename instanceof Ci.nsIFile) {
var file = File(filename);
filename = file.path;
} else {
}
if (file instanceof File) {
if (!file.exists() || !file.isReadable() || file.isDirectory()) {
if (!silent) {
if (file.exists() && file.isDirectory())
liberator.echomsg("Cannot source a directory: " + filename);
else
liberator.echomsg("Could not source: " + filename);
liberator.echoerr("Cannot open file: " + filename);
}
return;
}
this.sourcing = {
file: file.path,
line: 0
};
var uri = services.get("io").newFileURI(file);
} else if (filename instanceof Reader) {
file = filename;
filename = "<string>"
this.sourcing = {
file: filename,
line: 0
};
} else {
throw Error("do not support");
}
// liberator.echomsg("Sourcing \"" + filename + "\" ...");
// handle pure JavaScript files specially
if (/\.js$/.test(filename)) {
try {
// Workaround for SubscriptLoader caching.
let suffix = '?' + encodeURIComponent(services.get("UUID").generateUUID().toString());
liberator.loadScript(uri.spec + suffix, Script(file));
if (liberator.initialized)
liberator.initHelp();
}
catch (e) {
let err = new Error();
for (let [k, v] in Iterator(e))
err[k] = v;
err.echoerr = file.path + ":" + e.lineNumber + ": " + e;
throw err;
}
}
else if (/\.css$/.test(filename))
storage.styles.registerSheet(uri.spec, false, true);
else {
if (file instanceof File) {
var reader = new StrReader(file.read());
} else {
reader = file;
file = {setFrom: {path: this.sourcing.path}};
}
var kwargs = {setFrom: file, reader: reader};
var obj;
while (obj = getCommand(reader)) {
if (obj.cmd.name === "finish") {
reader.close();
break;
} else {
obj.cmd.execute(obj.args, obj.bang, obj.count, kwargs);
}
}
}
if (this._scriptNames.indexOf(file.path) == -1)
this._scriptNames.push(file.path);
liberator.log("Sourced: " + filename);
}
catch (e) {
liberator.echoerr(e, null, "Sourcing file failed: ");
}
finally {
this.sourcing = wasSourcing;
}
};
var extra = {
argCount: 1,
literal: 0,
hereDoc: true,
completer: completion.javascript,
};
commands.addUserCommand(["if"], "if expression", function ifexpression(args, kwargs) {
try {
var reader = kwargs.reader || new CommandLineReader;
var scope = Object.create(userContext);
var useElse = false;
var obj, cmd;
if (!kwargs.skip) {
var res = liberator.eval(args.string, scope);
if (!res) {
LOOP: while (obj = getCommand(reader)) {
switch (obj.cmd.name) {
case "if":
var extra = Object.create(kwargs);
extra.skip = true;
ifexpression(obj.args, extra);
break;
case "elseif":
res = liberator.eval(obj.args, scope);
if (res) break LOOP;
break;
case "else":
res = true;
useElse = true;
break LOOP;
case "endif":
return;
}
}
}
if (!res) throw Error("E171:");
// execute
LOOP: while (obj = getCommand(reader)) {
switch(obj.cmd.name) {
//case "if":
// cmd.execute(args, Object.create(kwargs));
// break;
case "elseif":
if (useElse) throw Error("E584:");
break LOOP;
case "else":
if (useElse) throw Error("E583:");
useElse = true;
break LOOP;
case "endif":
return;
case "finish":
reader.close();
return;
default:
obj.cmd.execute(obj.args, obj.bang, obj.count, Object.create(kwargs));
break;
}
}
}
while (obj = getCommand(reader)) {
switch (obj.cmd.name) {
case "if":
var ex = Object.create(kwargs);
ex.skip = true;
obj.cmd.execute(obj.args, obj.bang, obj.count, ex);
break;
case "elseif":
if (useElse) throw Error("E583");
break;
case "else":
if (useElse) throw Error("E583");
useElse = true;
break;
case "endif":
return;
}
}
throw Error("E171:");
} catch (ex) {
Cu.reportError(ex);
liberator.echoerr(ex);
}
}, extra, true);
commands.addUserCommand(["elsei[f]"], "elseif expression",function (args) { throw Error("E581"); }, extra, true);
commands.addUserCommand(["el[se]"], "else expression", function (args) { throw Error("E581"); }, {}, true);
commands.addUserCommand(["en[dif]"], "endif expression", function (args) { throw Error("E580"); }, {}, true);
commands.addUserCommand(["exstr", "exs"], "read ex commands from args literal",
function (args) {
var reader = new StrReader(args.string);
io.source(reader);
},{
hereDoc: true,
argCount: 1,
literal: 0,
}, true);
" vim: set ft=vim:
exstr <<TEST
js <<CODE
commands.addUserCommand(["echolog", "ecl"], "",
function (args) {
liberator.log(args.string);
}, {literal:0, argCount: 1}, true);
userContext.$d = function (s) liberator.log(s)
CODE
ecl start
ecl ----------------------------------
if 1
ecl test1:ok
else
ecl test1:ng
endif
if 0
ecl test2:ng
else
ecl test2:ok
endif
if 0
ecl test3:ng
elseif 1
ecl test3:ok
else
ecl test3:ng
endif
if 1
ecl test4:ok
elseif 1
ecl test4:ng
else
ecl test4:ng
endif
if <<END
var s = 32
s !== 32
END
ecl test5:ng
else
ecl test5:ok
endif
if <<END
var s = 99
s !== 99
END
elseif <<END
s === 99
END
ecl test6:ok
endif
if 1
if 1
ecl test7-1:ok
if $d("test7:eval") || 1
ecl test7-2:ok
endif
else
ecl test7-1:ng
if $d("test7:not eval")
ecl test7-2:ng
else
ecl test7-3:ng
endif
endif
ecl test7-3:ok
endif
if 1
if 0
ecl test8-1:ng
if $d("test8:not eval") 11
ecl test7-2:ng
endif
else
ecl test8-1:ok
if $d("test8: eval")
ecl test8-3:ng
else
ecl test8-3:ok
endif
endif
ecl test8-4:ok
endif
if 1
if <<END1
1
// don't indent!
END1
ecl test9:ok
endif
endif
ecl *************************************
TEST
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment