From f4aa4e3065a7801bc4434b91bc6f56a4bd0f5c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20Catarino=20Fran=C3=A7a?= Date: Sat, 17 Feb 2024 09:50:12 -0300 Subject: [PATCH] new chapters translated --- byexample/code-generation-parser.md | 85 +++++++++++++++++++++++++++++ byexample/index.yml | 3 + dub/emsi_containers.md | 20 +++++++ dub/index.yml | 10 ++++ dub/libdparse.md | 44 +++++++++++++++ dub/lubeck.md | 42 ++++++++++++++ dub/mir-algorithm.md | 38 +++++++++++++ dub/mir-random.md | 30 ++++++++++ dub/mir.md | 42 ++++++++++++++ dub/pegged.md | 53 ++++++++++++++++++ dub/vibe-d.md | 26 +++++++++ index.yml | 2 + 12 files changed, 395 insertions(+) create mode 100644 byexample/code-generation-parser.md create mode 100644 byexample/index.yml create mode 100644 dub/emsi_containers.md create mode 100644 dub/index.yml create mode 100644 dub/libdparse.md create mode 100644 dub/lubeck.md create mode 100644 dub/mir-algorithm.md create mode 100644 dub/mir-random.md create mode 100644 dub/mir.md create mode 100644 dub/pegged.md create mode 100644 dub/vibe-d.md diff --git a/byexample/code-generation-parser.md b/byexample/code-generation-parser.md new file mode 100644 index 0000000..e5d4f27 --- /dev/null +++ b/byexample/code-generation-parser.md @@ -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."); + } +} +``` diff --git a/byexample/index.yml b/byexample/index.yml new file mode 100644 index 0000000..18b6bd5 --- /dev/null +++ b/byexample/index.yml @@ -0,0 +1,3 @@ +title: Exemplos feito em D +ordering: +- code-generation-parser diff --git a/dub/emsi_containers.md b/dub/emsi_containers.md new file mode 100644 index 0000000..1cca4db --- /dev/null +++ b/dub/emsi_containers.md @@ -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; +} +``` diff --git a/dub/index.yml b/dub/index.yml new file mode 100644 index 0000000..112d035 --- /dev/null +++ b/dub/index.yml @@ -0,0 +1,10 @@ +title: Pacotes DUB +ordering: +- mir-algorithm +- mir-random +- mir +- emsi_containers +- vibe-d +- libdparse +- pegged +- lubeck diff --git a/dub/libdparse.md b/dub/libdparse.md new file mode 100644 index 0000000..c1cfc7a --- /dev/null +++ b/dub/libdparse.md @@ -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); +} +``` diff --git a/dub/lubeck.md b/dub/lubeck.md new file mode 100644 index 0000000..d6fc24f --- /dev/null +++ b/dub/lubeck.md @@ -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; +} +``` diff --git a/dub/mir-algorithm.md b/dub/mir-algorithm.md new file mode 100644 index 0000000..39778d1 --- /dev/null +++ b/dub/mir-algorithm.md @@ -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; +} +``` diff --git a/dub/mir-random.md b/dub/mir-random.md new file mode 100644 index 0000000..2da0076 --- /dev/null +++ b/dub/mir-random.md @@ -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]); +} +``` diff --git a/dub/mir.md b/dub/mir.md new file mode 100644 index 0000000..cd0ba7e --- /dev/null +++ b/dub/mir.md @@ -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); +} +``` diff --git a/dub/pegged.md b/dub/pegged.md new file mode 100644 index 0000000..adcc321 --- /dev/null +++ b/dub/pegged.md @@ -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"]); +} +``` diff --git a/dub/vibe-d.md b/dub/vibe-d.md new file mode 100644 index 0000000..235bf51 --- /dev/null +++ b/dub/vibe-d.md @@ -0,0 +1,26 @@ +# Vibe-d + +Experimente [vibe.d](http://vibed.org). + +## {SourceCode:fullWidth:incomplete} + +```d +/+ dub.sdl: +dependency "vibe-d" version="~>0.8" ++/ +import vibe.d; +import std.stdio; + +void main() +{ + listenHTTP(":8080", (req, res) { + res.writeBody("Hello, World: " ~ req.path); + }); + runTask({ + scope (exit) exitEventLoop(); + auto req = requestHTTP("http://localhost:8080"); + req.bodyReader.readAllUTF8.writeln; + }); + runApplication(); +} +``` diff --git a/index.yml b/index.yml index c7213b7..d2766cf 100644 --- a/index.yml +++ b/index.yml @@ -7,3 +7,5 @@ ordering: - gems - multithreading - vibed +- byexample +- dub