手順
頭がこんがらがってきた・・・みんなみたいに賢くないから・・・ね
1.haskellソースを読み込む
2.テキストをトークンに分割する
3.構文解析(LALR)する
4.順に処理する
0.シンボルのいくつかの機能だけ環境でマッピングしておく
このときの「いくつか」がいまいち,頭の中で整理できてない><
遅延評価の部分も含めて,かつ関数適用のためのcurry化
弾さんのが美しかったのでこちらを引用して
var _ = {} _['Bind'] = function(id, val){ if(typeof val == 'function'){ _[id] = curry(val); }else{ _[id] = function(){ return val; }; } return _[id]; } //遅延評価のための引数実行への置換 var lazy = function(func, args){ var tokens = func.match(/\"(?:[^\"])*\"|\'(?:[^\'])*\'|[a-zA-Z]+|[\+\*\.\\\/;:-><\(\)\[\]\{\}]*/gm).filter(/^[^\s]/); var pat = eval('/(^'+args.join('$)|(^')+'$)/g'); var token; var retokens = new Array(); while(token = tokens.pop()){ if(token.match(pat)) token = token+'()'; retokens.push(token); } return retokens.reverse().join(' '); } //curry化 var curry = function(func){ var fs = func.toString().replace(/\n/g, ''); var args = null; if(fs.match(/^.+?\((.+?)\)/)) args = fs.match(/^.+?\((.+?)\)/)[1].split(/,\s*/); //引数が無ければまま if(!args) return function(){ return fs }; var body = fs.match(/^.+?\{(.+?)\}$/)[1]; //body内で使われている引数の遅延評価のためにlazyで置換 var f = new Function('', lazy(body, args)); var arg; while(arg = args.pop()) f = new Function(arg, 'return '+f.toString()); return f; } _['Compile'] = function(expr){ //この中をいいように埋めないとだめ〜 } _['Bind']('sum3', function(a,b,c){return a+b+c;}) _['Compile']('main = show $ 1 + 3'); _['sum3'](function(){return 1})(function(){return 2})(function(){return 3})()
結局Compileができないとなんにせよダメ・・・orz
追記 2008-02-18
tokenizeとかlazyの正規表現は適当(適当すぎ・・・)です。