Created
December 8, 2012 10:43
-
-
Save caisui/4239753 to your computer and use it in GitHub Desktop.
if コマンド
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" 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