-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from kassane/new-chapters
Add New chapters: Dub and byExample (translated)
- Loading branch information
Showing
12 changed files
with
395 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# Gerador de código (Parser) | ||
|
||
Neste exemplo, um parser de configuração é gerado em tempo de compilação. | ||
Vamos supor que nosso programa tenha algumas opções de configuração, | ||
resumidas em uma `struct` de configurações: | ||
|
||
```d | ||
struct Config | ||
{ | ||
int runs, port; | ||
string name; | ||
} | ||
``` | ||
|
||
Embora escrever um parser para essa estrutura não seja difícil, teríamos que | ||
atualizar constantemente o parser, sempre que modificarmos o objeto `Config`. | ||
Por isso, estamos interessados em escrever uma função `parse` genérica que possa | ||
ler opções de configuração arbitrárias. Para simplificar, `parse` aceitará | ||
um formato muito simples de opções de configuração `key1=value1,key2=value2`, mas a mesma técnica | ||
pode ser usada para qualquer formato de configuração arbitrário. Para muitos formatos de configuração | ||
formatos de configuração populares, é claro, já existem soluções prontas de outros parsers no [registro do DUB](https://code.dlang.org). | ||
|
||
Configuração de leitura | ||
------------------------- | ||
|
||
Vamos supor que o usuário tenha __"name=dlang,port=8080"__ como uma string de configuração. | ||
Em seguida, dividimos diretamente as opções de configuração por vírgula e chamamos `parse` para cada definição de configuração, individualmente. | ||
Depois que todas as opções de configurações tiverem sido analisadas, todo o objeto de configuração será exibido. | ||
|
||
Análise | ||
----- | ||
|
||
O `parse` é onde a verdadeira mágica acontece, mas primeiro dividimos a opção de configuração fornecida (por exemplo, "name=dlang") por "=" em chave ("name") e valor ("dlang"). | ||
A instrução `switch` é executada com a chave analisada, mas o mais interessante é que | ||
os casos de `switch` foram gerados estaticamente. O `c.tupleof` retorna uma lista de todos os membros no formato `(idx, name)`. O compilador detecta que o `c.tupleof` é conhecido em tempo de compilação e desenrolará o loop foreach em tempo de compilação. | ||
Portanto, `Conf.tupleof[idx].stringof` produzirá os membros individuais do objeto struct | ||
e gerará uma instrução de caso para cada membro. | ||
|
||
Da mesma forma, enquanto estiver no loop estático, os membros individuais podem ser acessados pelo índice: | ||
`c.tupleof[idx]` e, assim, podemos atribuir ao respectivo membro o valor analisado da | ||
string de configuração fornecida. Além disso, `dropOne` é necessário, pois o `range` dividido ainda aponta para a chave e, portanto, `dropOne.front` retornará o segundo elemento. | ||
Além disso, `to!(typeof(field))` fará a análise real da string de entrada | ||
para o respectivo tipo do membro da estrutura de configuração. | ||
Por fim, como o loop `foreach` é executado em tempo de compilação, um `break` interromperia esse loop. | ||
|
||
Entretanto, depois que uma opção de configuração for analisada com sucesso, não queremos pular para o próximo caso na instrução `switch` e, portanto, um `break` é utilizado para interromper a instrução `switch`. | ||
|
||
## {SourceCode} | ||
|
||
```d | ||
import std.algorithm, std.conv, std.range, | ||
std.stdio, std.traits; | ||
struct Config | ||
{ | ||
int runs, port; | ||
string name; | ||
} | ||
void main() | ||
{ | ||
Config conf; | ||
// use o parser gerado a | ||
// cada entrada | ||
"runs=1,port=2,name=hello" | ||
.splitter(",") | ||
.each!(e => conf.parse(e)); | ||
conf.writeln; | ||
} | ||
void parse(Conf)(ref Conf c, string entry) | ||
{ | ||
auto r = entry.splitter("="); | ||
auto key = r.front, value = r.dropOne.front; | ||
`Switch`: `switch` (key) | ||
{ | ||
static foreach(idx, field; Conf.tupleof) | ||
{ | ||
case field.stringof: | ||
c.tupleof[idx] = | ||
value.to!(typeof(field)); | ||
break `Switch`; | ||
} | ||
default: | ||
assert (0, "Unknown member name."); | ||
} | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
title: Exemplos feito em D | ||
ordering: | ||
- code-generation-parser |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# EMSI Containers | ||
|
||
Experimente [emsi_containers](https://github.com/dlang-community/containers) | ||
|
||
## {SourceCode:incomplete} | ||
|
||
```d | ||
/+dub.sdl: | ||
dependency "emsi_containers" version="~>0.7" | ||
+/ | ||
import std.stdio; | ||
void main(string[] args) | ||
{ | ||
import containers; | ||
DynamicArray!int arr; | ||
arr ~= 1; | ||
foreach (e; arr) | ||
e.writeln; | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
title: Pacotes DUB | ||
ordering: | ||
- mir-algorithm | ||
- mir-random | ||
- mir | ||
- emsi_containers | ||
- vibe-d | ||
- libdparse | ||
- pegged | ||
- lubeck |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# libdparse | ||
|
||
Experimente [libdparse](https://github.com/dlang-community/libdparse) | ||
|
||
## {SourceCode:fullWidth:incomplete} | ||
|
||
```d | ||
/+dub.sdl: | ||
dependency "libdparse" version="~>0.10" | ||
+/ | ||
import dparse.ast; | ||
import std.stdio; | ||
class TestVisitor : ASTVisitor | ||
{ | ||
alias visit = ASTVisitor.visit; | ||
override void visit(const FunctionDeclaration decl) | ||
{ | ||
decl.name.text.writeln; | ||
} | ||
} | ||
void main() | ||
{ | ||
import dparse.lexer; | ||
import dparse.parser : parseModule; | ||
import dparse.rollback_allocator : RollbackAllocator; | ||
import std.array : array; | ||
import std.string : representation; | ||
auto sourceCode = q{ | ||
void foo() @safe {} | ||
}.dup; | ||
LexerConfig config; | ||
auto cache = StringCache(StringCache.defaultBucketCount); | ||
auto tokens = getTokensForParser(sourceCode.representation, config, &cache); | ||
RollbackAllocator rba; | ||
auto m = parseModule(tokens.array, "test.d", &rba); | ||
auto visitor = new TestVisitor(); | ||
visitor.visit(m); | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Lubeck | ||
|
||
Biblioteca de álgebra linear de alto nível baseada em CBLAS, LAPACK e Mir Algorithm. | ||
|
||
## Dependências | ||
|
||
O Lubeck depende do CBLAS e da API do LAPACK. Talvez seja necessário instalá-los e atualizar o `dub.sdl`. | ||
O CBLAS e o LAPACK são pré-instalados no MacOS. | ||
Os backends [OpenBLAS](http://www.openblas.net) ou [Intel MKL](https://software.intel.com/en-us/mkl) são recomendados para Linux e Windows. | ||
|
||
## Links | ||
|
||
- [GitHub](https://github.com/kaleidicassociates/lubeck) | ||
- [Mir Algorithm API](http://mir-algorithm.libmir.org) | ||
- [Mir Random API](http://mir-random.libmir.org) | ||
- [Mir API](http://mir.libmir.org) | ||
|
||
## {SourceCode:incomplete} | ||
|
||
```d | ||
/+dub.sdl: | ||
dependency "lubeck" version="~>1.1" | ||
+/ | ||
import kaleidic.lubeck: mtimes; | ||
import mir.algorithm.iteration: each; | ||
import mir.ndslice: magic, repeat, as, | ||
slice, byDim; | ||
import std.stdio: writeln; | ||
void main() | ||
{ | ||
auto n = 5; | ||
// Magic Square | ||
auto matrix = n.magic.as!double.slice; | ||
// [1 1 1 1 1] | ||
auto vec = 1.repeat(n).as!double.slice; | ||
// Uses CBLAS for multiplication | ||
matrix.mtimes(vec).writeln; | ||
"-----".writeln; | ||
matrix.mtimes(matrix).byDim!0.each!writeln; | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Mir Algorithm | ||
|
||
Biblioteca principal para cálculos e uma base para o pacote de arrays multidimensionais - ndslice (equivalente ao numpy). | ||
|
||
## Links | ||
|
||
- [API Documentation](http://mir-algorithm.libmir.org) | ||
- [GitHub](https://github.com/libmir/mir-algorithm) | ||
- [Lubeck](https://github.com/kaleidicassociates/lubeck) - Linear Algebra Library based on NDSlice API. | ||
|
||
## Maiores detalhes | ||
|
||
[Magic Square on Wikipedia](https://en.wikipedia.org/wiki/Magic_square). | ||
|
||
## {SourceCode} | ||
|
||
```d | ||
/+dub.sdl: | ||
dependency "mir-algorithm" version="~>3.6" | ||
+/ | ||
import mir.algorithm.iteration: each; | ||
import mir.ndslice; | ||
import std.stdio: writeln; | ||
void main() | ||
{ | ||
auto matrix = slice!double(3, 4); | ||
matrix[] = 0; | ||
matrix.diagonal[] = 1; | ||
auto row = matrix[2]; | ||
row[3] = 6; | ||
// D & C index order | ||
assert(matrix[2, 3] == 6); | ||
matrix.byDim!0.each!writeln; | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Mir Random | ||
|
||
Gerador de números aleatórios avançado. | ||
|
||
## Links | ||
|
||
- [API Documentation](http://mir-random.libmir.org) | ||
- [GitHub](https://github.com/libmir/mir-random) | ||
- [Mir Algorithm Documentation](http://mir-algorithm.libmir.org) | ||
|
||
## {SourceCode} | ||
|
||
```d | ||
/+dub.sdl: | ||
dependency "mir-random" version="~>2.2" | ||
+/ | ||
import mir.random; | ||
import mir.random.algorithm: randomSlice; | ||
import mir.random.variable: normalVar; | ||
import std.stdio: writeln; | ||
void main() | ||
{ | ||
auto sample = normalVar.randomSlice(10); | ||
writeln(sample); | ||
// prints random element from the sample | ||
writeln(sample[$.randIndex]); | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Mir | ||
|
||
Este pacote inclui: | ||
|
||
- [mir-algorithm package](dub/mir-algorithm)- Biblioteca principal para cálculos e uma base para o pacote de arrays multidimensionais - ndslice (equivalente ao numpy). | ||
- [mir-random package](dub/mir-random) - Geradores de números aleatórios avançados. | ||
- Tensores esparsos | ||
- Hoffman | ||
|
||
## Links | ||
|
||
- [Mir Algorithm API](http://mir-algorithm.libmir.org) | ||
- [Mir Random API](http://mir-random.libmir.org) | ||
- [Mir API](http://mir.libmir.org) | ||
- [GitHub](https://github.com/libmir/mir) | ||
- [Lubeck](https://github.com/kaleidicassociates/lubeck) - Linear Algebra Library based on NDSlice API. | ||
|
||
## {SourceCode} | ||
|
||
```d | ||
/+dub.sdl: | ||
dependency "mir" version="~>3.2" | ||
+/ | ||
import mir.sparse; | ||
import std.stdio: writeln; | ||
void main() | ||
{ | ||
// DOK format | ||
auto sl = sparse!double(5, 8); | ||
sl[] = | ||
[[0, 2, 0, 0, 0, 0, 0, 1], | ||
[0, 0, 0, 0, 0, 0, 0, 4], | ||
[0, 0, 0, 0, 0, 0, 0, 0], | ||
[6, 0, 0, 0, 0, 0, 0, 9], | ||
[0, 0, 0, 0, 0, 0, 0, 5]]; | ||
// CRS/CSR format | ||
auto crs = sl.compress; | ||
writeln(crs); | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Pegged | ||
|
||
O Pegged é um parser gerador (PEG - parsing expression grammar). | ||
|
||
A partir dessa definição de gramática, será criado um conjunto de analisadores relacionados, | ||
para serem usados em tempo de execução ou de compilação. | ||
|
||
## Maiores detalhes | ||
|
||
- [Pegged on GitHub](https://github.com/PhilippeSigaud/Pegged) | ||
- [Reference article for Pegged's syntax](http://bford.info/pub/lang/peg) | ||
|
||
## {SourceCode:fullWidth:incomplete} | ||
|
||
```d | ||
/+dub.sdl: | ||
dependency "pegged" version="~>0.4" | ||
+/ | ||
import pegged.grammar; | ||
import std.stdio; | ||
mixin(grammar(` | ||
Arithmetic: | ||
Term < Factor (Add / Sub)* | ||
Add < "+" Factor | ||
Sub < "-" Factor | ||
Factor < Primary (Mul / Div)* | ||
Mul < "*" Primary | ||
Div < "/" Primary | ||
Primary < Parens / Neg / Pos / Number / Variable | ||
Parens < "(" Term ")" | ||
Neg < "-" Primary | ||
Pos < "+" Primary | ||
Number < ~([0-9]+) | ||
Variable <- identifier | ||
`)); | ||
void main() | ||
{ | ||
// Parsing at compile-time: | ||
enum parseTree1 = Arithmetic("1 + 2 - (3*x-5)*6"); | ||
pragma(msg, parseTree1.matches); | ||
assert(parseTree1.matches == ["1", "+", "2", "-", | ||
"(", "3", "*", "x", "-", "5", ")", "*", "6"]); | ||
writeln(parseTree1); | ||
// And at runtime too: | ||
auto parseTree2 = Arithmetic(" 0 + 123 - 456 "); | ||
assert(parseTree2.matches == ["0", "+", "123", "-", "456"]); | ||
} | ||
``` |
Oops, something went wrong.