domingo, 17 de julho de 2011

Implementando uma Toy Programming Language

Estou implementando uma linguagem sem nome (ainda usando um nome temporário), e estou pensando em implementar o básico que uma linguagem moderna precisa. Estou implementando para aprimorar meus próprios conhecimentos sobre programação e relembrar coisas que aprendi na época da faculdade. Aqui vai um exemplo da sintaxe da linguagem que estou implementando:

Pessoa = Class({
nome = "";
falar = { texto:
print(texto);
};
});
p = Pessoa("Rafael Caricio");
print( p("nome") );
p("falar")("Hello world!");
view raw pessoa hosted with ❤ by GitHub


Tudo na linguagem é função, expressão, lista e valor. Inclusive o "if". Que nela é uma função que é definida na propria linguagem:

if = { _op, _true, _false:
_op && _true() || _false()
};
view raw if hosted with ❤ by GitHub


E usado desta foma:

k = 0;
if ( x == 2, {
*k = 2
}, {
*k = 3
});
view raw if_sample hosted with ❤ by GitHub


O "*" informa ao interpretador que estou querendo referenciar a variável "k" no escopo dinâmico (escopo onde a função está sendo executada) e não no escopo local interno da função, onde modificações a esta variável não fariam diferença para o escopo onde a função foi chamada (caso exista uma variável com o mesmo nome).
Na linguagem existe também apenas uma estrutura de loop que é o "while". E funciona da seguinte forma:

i = 10;
while { i > 0:
print( i );
*i--
};
view raw while hosted with ❤ by GitHub


Com o "while" eu posso definir como é minha estrutura de "for". Assim:

for = { number, block:
_i = 0;
while { i < number:
_i++;
block(_i - 1)
}
}
view raw for_def hosted with ❤ by GitHub


E usar da seguinte forma:

a = [];
for(10, { i :
*a[i] = i
});
view raw for_use hosted with ❤ by GitHub


Assim o valor de "a" é [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. E outra coisa interessante que posso definir é a função "map", que ficaria da seguinte forma:

map = { _array, func:
_x = len(_array);
while { _x > 0:
_x--;
_func(_array[_x - 1])
}
};
view raw map_def hosted with ❤ by GitHub


Nesta linguagem o comportamento do "map" é o mesmo do "for each" pois uma função SEMPRE retorna um valor nem que ele seja "Null".
Com o essas funções previamente definidas, podemos implementar uma função de "filter" e ficaria assim:

filter = { _array, _func:
map( map(_array, _func), { _item:
if ( _item, {
_item
});
});
};
view raw filter_def hosted with ❤ by GitHub


Os "_" underlines nestas funções servem para não conflitar com nome das variáveis do escopo onde o programador vai usar.

Quem quiser saber mais sobre este projeto pode acompanhar pelo github. Aceito reclamações, xingamentos, elogios e etc.

https://github.com/rafaelcaricio/fny