середу, 28 липня 2010 р.

Лексический анализатор

function lexer(config){
var stack=[""];
var data=(function(config){
var data={};
for(var state in config){
data[state]=(function(src){
for(var a=[],i=0;i<src.length;i++){
var re=src[i][0];
var fn=src[i][1];
if(re instanceof RegExp)
re=new RegExp("^("+re.source+").*",'m');
else re=new RegExp("^("+re+").*",'m');
if(!(fn instanceof Function))
fn=new Function("",fn);
a.push([re,fn]);
}
return a;})(config[state]);
}
return data;})(config);
var control={
begin:function(state){
if(state in config)
stack[0]=state;
else throw "wrong state";
},
push:function(){
if(state in config)
stack.unshift(state);
else throw "wrong state";
},
pop:function(){return stack.shift();},
top:function(){return stack[0];},
}
function lex(text){
while(text.length>0){
var token=step.apply(this,[text]);
puts(token);
if(token)
text=text.substring(token.length);
}
}
function step(text){
var current=data[stack[0]];
var token;
for(var ci in current)if(token=(function(re,fn){
var match=re(text);
var token=match&&match[1];
if(token){
control.text=token;
fn.apply(this,[control]);
return token;
}
})(current[ci][0],current[ci][1]))return token;
throw "not found";
}
return lex;}


четвер, 1 липня 2010 р.

Понадобилось мне привязать функции к разным конструкторам, а чтобы избежать можификации обектов понадобились словари. Вот мой вариант словарей:

function Dict(def){
var data=[];
var default_val=def;
var dict;
function find(key){
for(var i=0;i<data.length;i++)
if(data[i].key===key)
return i;
return -1;
}
function add(key,value){
data.push({key:key,value:value});
dict.length=data.length;
}
dict=function(key,value){
var i=find(key);
if(typeof value=='undefined')
return (i==-1)?default_val:data[i].value;
if(i==-1)add(key,value);
else data[i].value=value;
return dict;
}
dict.del=function(key){
var i=find(key);
if(i!=-1)data.splice(i,1);
dict.length=data.length;
return dict;
};
dict.forEach=function(callback){
for(var i=0;i<data.length;i++)
callback(data[i].key,data[i].value);
return dict;
};
dict.filter=function(callback){
var res=Dict();
dict.forEach(function(k,v)if(callback(k,v))res(k,v));
return res;
};
dict.copy=function()dict.filter(function()true);
dict.clear=function(){data=[];dict.length=0;};
dict.size=function(){return data.length};
dict.get=function(key,def){
var i=find(key);
return (i==-1)?def:data[i].value;
}
return dict;
};

понеділок, 1 березня 2010 р.

Сигналы на JavaScript

Этот код я создал под впечетлением QScriptEngine. В дальнейшем заметил что начал его слишком часто использовать. Собственно вот:



function signalize(val){
var events={};
val.connect=function(name,func){
if(func.constructor!=Function)return;
if(!events[name])events[name]=[];
events[name].push(func);
}
val.disconnect=function(name,func){
var list=[];
for(var i in events[name])
if(events[name][i]!=func)
list.push(events[name][i]);
events[name]=list;
}
val.emit=function(){
var name=arguments[0];
var rest=Array.prototype.slice.call(arguments, 1);
for(var i in events[name])
events[name][i].apply(val,rest);
}
return val;
}


Жду замечаний и предложений.

неділю, 20 грудня 2009 р.

Решил таки завести блог

Всвязи с предстоящим закрытием бесплатного хостинга на ho.ua решил начать вести блог с последующим переносом моих наработок сюда.