Skip to content

Instantly share code, notes, and snippets.

@susisu
Last active December 21, 2015 15:29
Show Gist options
  • Save susisu/6327237 to your computer and use it in GitHub Desktop.
Save susisu/6327237 to your computer and use it in GitHub Desktop.
お察し下さい
/*
Copyright(c) 2013 Susisu
for Node.js
*/
var fs = require("fs");
function main()
{
async(
mseq(
async(
_set("hoge")(readFile(_("hoge.txt"))),
_set("fuga")(readFile(_("fuga.txt")))
),
_if(_do(function(){return this.hoge && this.fuga;}),
print(_do(function()
{
return this.hoge.toString().toUpperCase() + ", "
+ this.fuga.toString().toUpperCase();
})
),
print(_("failed to open file(s)"))
)
),
mbind(
_("piyo.txt"),
readFile(_return()),
_do(function(arg){return arg.toString();}),
print(_return())
)
).play({});
}
/*
Action, the unit of process
*/
function Action(func)
{
this.func = func;
this.value = undefined;
this.onComplete = undefined;
}
Object.defineProperty(Action.prototype, "play", {
value: function(env, arg)
{
this.func.call(env, arg);
}
});
Object.defineProperty(Action.prototype, "complete", {
value: function()
{
if(this.onComplete)
{
this.onComplete();
this.onComplete = null;
}
}
});
/*
do nothing, return void
*/
function _void()
{
var action = new Action(function(arg)
{
action.complete();
});
return action;
}
/*
do something
*/
function _do(func)
{
var action = new Action(function(arg)
{
action.value = func.call(this, arg);
action.complete();
});
return action;
}
/*
assign
*/
function assign(name)
{
var action = new Action(function(arg)
{
this[name] = arg;
action.complete();
});
return action;
}
/*
set variable (syntax sugar of 'assign')
*/
function _set(name)
{
return function(value)
{
return bind(value, assign(name))
};
}
/*
get variable
*/
function _get(name)
{
var action = new Action(function(arg)
{
action.value = this[name];
action.complete();
});
return action;
}
/*
convert non-action value to action
*/
function _(value)
{
var action = new Action(function(arg)
{
action.value = value;
action.complete();
});
return action;
}
/*
do nothing
*/
function _return()
{
var action = new Action(function(arg)
{
action.value = arg;
action.complete();
});
return action;
}
/*
a >>= b
*/
function bind(a, b)
{
var action = new Action(function(arg)
{
var env = this;
a.onComplete = function()
{
b.onComplete = function()
{
action.value = b.value;
action.complete();
};
b.play(env, a.value);
};
a.play(env, arg);
});
return action;
}
/*
a >> b
*/
function seq(a, b)
{
var action = new Action(function(arg)
{
var env = this;
a.onComplete = function()
{
b.onComplete = function()
{
action.value = b.value;
action.complete();
};
b.play(env);
};
a.play(env, arg);
});
return action;
}
/*
(((a >>= b) >>= c) >>= ...)
*/
function mbind()
{
if(arguments.length > 0)
{
var t = arguments[0];
for(var i = 1; i < arguments.length; i++)
{
t = bind(t, arguments[i])
}
return t;
}
else
{
return _void();
}
}
/*
(((a >> b) >> c) >> ...)
*/
function mseq()
{
if(arguments.length > 0)
{
var t = arguments[0];
for(var i = 1; i < arguments.length; i++)
{
t = seq(t, arguments[i])
}
return t;
}
else
{
return _void();
}
}
/*
do the actions asynchronously
*/
function async()
{
if(arguments.length > 0)
{
var actions = arguments;
var action = new Action(function(arg)
{
var n = 0;
function handler()
{
n++;
if(n == actions.length)
{
action.complete();
}
}
for(var i = 0; i < actions.length; i++)
{
actions[i].onComplete = handler;
actions[i].play(this, arg);
}
});
return action;
}
else
{
return _void();
}
}
/*
if condition then a else b
*/
function _if(condition, a, b)
{
var action = new Action(function(arg)
{
var env = this;
condition.onComplete = function()
{
if(condition.value)
{
a.onComplete = function()
{
action.value = a.value;
action.complete();
}
a.play(env);
}
else
{
b.onComplete = function()
{
action.value = b.value;
action.complete();
}
b.play(env);
}
};
condition.play(env);
});
return action;
}
/*
read and return a file content
*/
function readFile(path, stopOnError)
{
var action = new Action(function(arg)
{
fs.readFile(arg, function(err, file)
{
if(err && stopOnError)
{
console.log(err);
}
action.value = file;
action.complete();
});
});
return bind(path, action);
}
/*
output to console.log
*/
function print(content)
{
var action = new Action(function(arg)
{
console.log(arg);
action.complete();
});
return bind(content, action);
}
/*
call the main function
*/
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment