From 922df92179266f39afec0ab72923501d3b31b3b4 Mon Sep 17 00:00:00 2001 From: Alesson Renato Lopes Valenca Date: Sat, 9 Mar 2019 23:12:16 -0300 Subject: [PATCH] paraCada (foreach) --- TABELA_DE_INSTRUCOES.md | 1 + examples/Basicos/paraCada/paraCada.ino | 59 +++++++++++++++++++++++++ src/Brasilino.h | 60 ++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 examples/Basicos/paraCada/paraCada.ino diff --git a/TABELA_DE_INSTRUCOES.md b/TABELA_DE_INSTRUCOES.md index b108d53..4785a62 100644 --- a/TABELA_DE_INSTRUCOES.md +++ b/TABELA_DE_INSTRUCOES.md @@ -19,6 +19,7 @@ Estruturas de controle são estruturas do tipo condicional, que irão analisar u | se | Analisa se a condição dentro do parâmetro é verdadeira e executa uma ação. | se(a == b) {
// ação caso "a = b"
} | | senao | Executa uma ação se o parâmetro da condição ``se`` for falso. | se(a == b) {
// ação caso "a = b"
}
senao {
// ação caso "a ≠ b"
} | | para | Executa um bloco de instruções enquanto uma condição for satisfeita. É utilizado um contador para incrementar, ou decrementar, e terminar o loop. | para(x = 0; x < 2; x = x+1) {
/\* executa este bloco enquanto "x" for menor que 2 \*/
} | +| paraCada | Executa uma varredura em um vetor/matriz enquanto não se chegar ao fim do mesmo ou ser forçada uma quebra de laço. | paraCada(celula,vetor){
/\* executa esse bloco ate o fim do vetor ser atingido \*/
} | | contarAte | Aplicação da função ``para`` onde se escolhe o número de iterações. | contarAte(5) {
/\* executa este bloco de instruções 5 vezes \*/
} | | enquanto | Esta função executa continuamente enquanto o teste do parâmetro for verdadeiro. | enquanto(x == 2) {
/\* ações a serem executadas enquanto o parâmetro for verdadeiro, ou seja, enquanto "x = 2" \*/
} | | comparar....caso | Compara o parâmetro da função com os casos definidos. No exemplo, "x" é comparado com os valores 1 e 2. É utilizado a instrução ``sair`` para que não se realize os próximos testes se algum já for o verdadeiro. | comparar(x) {

caso 1:
/\* ação caso "x = 1" \*/
sair;

caso 2:
/\* ação caso "x = 2" \*/
sair;

padrao:
/\* executa se não for nenhum dos casos \*/
sair;
} | diff --git a/examples/Basicos/paraCada/paraCada.ino b/examples/Basicos/paraCada/paraCada.ino new file mode 100644 index 0000000..fba906d --- /dev/null +++ b/examples/Basicos/paraCada/paraCada.ino @@ -0,0 +1,59 @@ +/* + paraCada(A,B) + Um melhoramento da função para(for) que auxilia o programador a percorrer um vetor ou matriz de dados até os seu fim. + + Uso: + + paraCada(A,B) + { + imprima(A); + } + + Variáveis: + A (Variável a ser preenchida com os valores do vetor/matriz que está sendo lido. É + necessário que tenha o mesmo tipo do vetor/matriz). + B (Vetor/matriz a ser percorrido durante o laço). + + O laço irá executar até o fim do vetor/matriz ser atingido ou uma condição de quebra seja + forçada. + + Este exemplo de código está em domínio público. + + criado em 28 de abril de 2018 + modificado em 12 de fevereiro de 2019 + Desenvolvido por Alesson Renato. + Contribuição a biblioteca Brasilino. + + Este exemplo é baseado em código aberto referente a linguagem C++. +*/ + +// Inclue a biblioteca Brasilino +#include + +// A funcao configurar executa uma vez quando a placa é ligada ou quando o botão de reset é pressionado +funcao configurar() { + // Inicializa a comunicação serial com a placa + iniciarSerial(); +} + +// A funcao repetir executa para sempre +funcao repetir() { + // Cria a variável celula que armazenará o conteudo das celulas do vetor, cria posição que demonstrará a posição da celula atual e por fim cria um vetor com valores inteiros + inteiro celula, posicao=1, vetor[10]{10,9,8,7,6,5,4,3,2,1}; + // Chama a função paraCada que guardará em celula um valor de posição do vetor que cada iteração + paraCada(celula,vetor){ + // Escreve Posicao na serial + escreverSerial("Posicao:"); + // Escreve a posição lida atual + escreverSerial(posicao); + // Escreve um espaço entre os valores e a palavra Valor: + escreverSerial(" Valor:"); + // Escreve o valor contido na celula atual e pula uma linha + escreverSerialn(celula); + esperar(0.5); // espera meio segundo + posicao++; // atualiza posição +} +/* + OBS: O exemplo foi criado usando o tipo de dado inteiro, contudo a função é compatível com + qualquer tipo de dado primitivo ou composto compatível com a linguagem C++ +*/ diff --git a/src/Brasilino.h b/src/Brasilino.h index 75f1cab..4d99a70 100644 --- a/src/Brasilino.h +++ b/src/Brasilino.h @@ -68,6 +68,66 @@ #define esperar(tempo) delay(tempo * 1000) #define esperarMili(tempo) delay(tempo) +//-------------paraCada(foreach)--------------- +//concatena +#define CONCAT(a,b) CONCAT_(a,b) +#define CONCAT_(a,b) a ## b + +/* Higiene nos macros */ +#define GENSYM(name) \ + CONCAT(CONCAT(CONCAT(_anon_variable_, name),__LINE__),__COUNTER__) + +/* funcoes de ajuda para paraCada*/ + +/* paraCada_COMP + Checa se o valor de indice e maior que o comprimento do array. + */ + +#define paraCada_COMP(INDEX, ARRAY, ARRAY_TYPE, SIZE) \ + paraCada_COMP_ (INDEX, ARRAY, ARRAY_TYPE, SIZE, GENSYM (ret)) +#define paraCada_COMP_(INDEX, ARRAY, ARRAY_TYPE, SIZE, ret) \ + __extension__ \ + ({ \ + bool ret = 0; \ + if (__builtin_types_compatible_p (const char*, ARRAY_TYPE)) \ + ret = INDEX < strlen ((const char*)ARRAY); \ + else \ + ret = INDEX < SIZE; \ + ret; \ + }) + +/* paraCada_ELEM + Retorna um ponteiro ao elemento no indice do array. + */ + +#define paraCada_ELEM(INDEX, ARRAY, TYPE) \ + paraCada_ELEM_ (INDEX, ARRAY, TYPE, GENSYM (tmp_array)) + +#define paraCada_ELEM_(INDEX, ARRAY, TYPE, tmp_array) \ + __extension__ \ + ({ \ + TYPE *tmp_array_ = ARRAY; \ + &tmp_array_[INDEX]; \ + }) + +/* paraCada + Aqui e onde a magia acontece :) + 'b' = garante o fim do laco + */ + +#define paraCada(VAR, ARRAY) \ + paraCada_ (VAR, ARRAY, GENSYM (array), GENSYM (i), GENSYM (b)) + +#define paraCada_(VAR, ARRAY, array, i, b) \ +for (void *array = (void*)(ARRAY); array; array = 0) \ +for (size_t i = 0; array && paraCada_COMP (i, array, \ + __typeof__ (ARRAY), \ + sizeof (ARRAY) / sizeof ((ARRAY)[0])); \ + i++) \ +for (bool b = 1; b; (b) ? array = 0 : 0, b = 0) \ +for (VAR = paraCada_ELEM (i, array, __typeof__ ((ARRAY)[0])); b; b = 0) + + //------------------Funções de Comando--------------------- #define ligar(pino) digitalWrite(pino, HIGH) #define desligar(pino) digitalWrite(pino, LOW)