Nesta série, falarei com você sobre a programação LISP em BricsCAD. Esta postagem de blog irá guiá-lo através do que você precisa saber para se tornar um programador muito produtivo. Nas primeiras duas ou três postagens, apresentarei a terminologia, sintaxe e tipos de dados.

ATENÇÃO: Este artigo no Blog é transcrito aqui no idioma Português-Brasil, mas pelo fato do artigo original ter sido escrito em Inglês, é possível que algumas instruções (especialmente: códigos) possam gerar conflito entre os idiomas. Sugiro consultar também os códigos de origem (na versão em inglês deste post) para garantir que seu trabalho esteja bem resolvido.

O que é programação LISP?

LISP (LISt Processing) em BricsCAD é uma linguagem de programação fácil de aprender para o não-programador. Programar é simplesmente obter, usar e/ou reutilizar dados de forma inteligente.

Terminologia e Tipos de Dados

Estes são alguns termos comuns que levarão você na direção certa. Você notará que um fluxo se desenvolve à medida que avançamos na lista de termos. Lembre-se de que tudo isso é muito lógico. Não existem truques. É lógico. As coisas funcionam da mesma maneira todas as vezes. É lógico. Sempre o mesmo. Eu mencionei que é lógico?

Terminologia

  • Lista Qualquer coisa contida em um conjunto de parênteses ( )
  • Atom Os itens individuais (átomos) em uma lista
  • Function Os “comandos” do LISP (funções), normalmente o primeiro átomo em uma lista
  • Argument São os átomos que vem depois do nome da função. Esses são os dados dos quais a função precisa para concluir sua tarefa.
  • Expression Uma lista que envolve uma função e, possivelmente, argumentos

Tipos de Dados

  • Inteiros Números inteiros, sem casa decimal
  • Reais Números com vírgula flutuante, sempre tem um ponto decimal
  • Strings Texto, sempre contido entre aspas: “Assim”
  • Listas Pode não parecer lógico estarmos usando o mesmo termo duas vezes, mas isso será explicado!

Trabalho de Preparação para Praticar

Antes de praticar o uso de funções no prompt de comando, é vantajoso desligar a configuração de entrada dinâmica (DYN). Desative-o (torne escuro) usando a barra de Status em BricsCAD:

bricscad de entrada dinâmica

Além disso, é uma boa ideia fazer com que a área do prompt de comando mostre algumas linhas a mais “mais alta” do que o normal - talvez 8 ou 10 linhas. Para fazer isso, passe o mouse sobre o topo da borda da linha de comando até que uma seta dupla apareça e clique e arraste para alterar a altura da linha de comando:

configurações para lisp no prompt da barra de linha de comando do bricscad

Sintaxe Básica

(nome da função argumento1 argumento2 ...)

O tipo básico de lista com o qual trabalharemos pode ser referido como expressões. Uma expressão é uma lista que sempre assume o formato acima. O primeiro elemento (ou átomo) de uma expressão é sempre uma função. Os átomos adicionais na lista são chamados de argumentos. Os argumentos são as ferramentas ou “coisas” de que uma função precisa para funcionar corretamente. Os argumentos que são passados para uma função, para nossos propósitos, devem ser de um dos 4 tipos de dados: um Inteiro, um Real, uma String ou uma Lista.

Funções relacionadas à matemática

As funções simples a seguir nos ajudam a entender como a sintaxe e os termos listados anteriormente funcionam juntos. Funções simples e curtas podem ser digitadas diretamente na linha de comando. Isso torna o teste e a solução de problemas (e o aprendizado inicial !!) muito conveniente.

Sinta-se à vontade para digitar um pouco do que estou apresentando, à medida que avançamos...

(+ número número ...)

A função de adição (+) pega qualquer número de argumentos numéricos e os soma, e retorna a soma.

(- número número ...)

A função de subtração (-) aceita qualquer número de argumentos numéricos. O primeiro argumento pode ser considerado o número base. Todos os argumentos adicionais são subtraídos sucessivamente desse argumento base.

(* número número ...)

A função de multiplicação (*) pega qualquer número de argumentos numéricos e os multiplica juntos e retorna o produto.

(/ número número ...)

A função de divisão (/) aceita qualquer número de argumentos numéricos. O primeiro argumento pode ser considerado o número base. O número base é dividido sucessivamente por cada um dos argumentos adicionais.

Regras matemáticas:

  • Para usar um número negativo, basta colocar um sinal de menos na frente dele. (Opcionalmente, os números positivos podem ter um sinal de adição colocado na frente deles - mas é extremamente raro).
    -3.75, -42, +6.953
  • Números reais menores que 1 e maiores que -1 devem obrigatoriamente tem um zero (0) na frente da vírgula decimal. 125, 0,5, -0,67
  • Se todos os argumentos passados para uma função matemática são inteiros, um inteiro será retornado. E se no mínimo um dos argumentos é um número real, um número real é retornado.
  • Números Reais são armazenados com precisão em mais de 15 casas decimais, mas são “retornados” (exibidos no prompt de comando) para não mais de 15 dígitos significativos.

Exemplos de funções matemáticas inseridas na linha de comando:

funções matemáticas do LISP em uma linha de comando

Armazenamento de Dados

Ser capaz de realizar todas essas funções matemáticas é ótimo, mas não muito útil, a menos que se possa armazenar os valores. A função (setq) nos permite armazenar um valor ou dado, em uma variável ou símbolo.

(setq  sym  value)

A função setq requer um número par de argumentos. Os argumentos ímpares são os símbolos e os argumentos em número par são os valores a ser armazenados nesse símbolo. Para fins de aprendizado e de simplicidade, usaremos (setq) com apenas dois argumentos; o símbolo e o valor que ele manterá. O símbolo pode ser quase qualquer caractere digitado, mas não apenas um número. (Um número já contém um valor!) Alguns outros caracteres também são inválidos, como +, -, *, /, (,) ou qualquer nome de função já definido em LISP ... esses símbolos já têm significados ou valor em LISP. Exemplos de símbolos válidos:

A   B   X   PT   PT1   PT2   MIDPT   CNTRPT   CLR1  FIRST-NAME   DWGNUM

Podemos usar a função (setq) para armazenar alguns dos tipos de dados aos quais nos referimos anteriormente:

(setq A 1) retorna 1
(setq B 2.5) retorna 2.5
(setq C “BricsCAD LISP”) retorna “BricsCAD LISP”
(setq  X  1.25  Y  6.375  Z  0.0) retorna 0.0
(setq    CPT  3.5
OPT “Diâmetro”
RAD 4.0
)
retorna 4.0

As duas últimas expressões acima são uma forma válida de codificação, mas não são usadas com frequência. Isso pode tornar a solução de problemas, adicionar e/ou excluir códigos um tanto confusa.

Do penúltimo exemplo, parece que X e Y não foram “definidos” e, no último exemplo, parece que CPT e OPT não foram “definidos”. Mas, entre os dois exemplos, todos os 6 símbolos foram de fato “definidos”. A função (setq) retorna os resultados da avaliação do último argumento transmitido a ele. 

Expressões de aninhamento

A sequência de código anterior pode ser referida como “codificação permanente”. Os valores que os símbolos estão segurando não podem variar (X é absolutamente “1”, nunca mais nada!). Eles sempre serão exatamente como mostrados - o símbolo está segurando qualquer valor que o programador digitou como o segundo argumento. Não há permissão para entrada do usuário.

O LISP tem a funcionalidade de permitir que expressões sejam aninhadas em outras expressões. Para começar, as funções que aninharemos na função (setq) serão funções que nos permitem obter certos tipos de dados dos usuários de nossos programas.

Primeiro, veremos algumas funções de coleta de tipos de dados e, em seguida, aninharemos numa (setq) para armazenar seus valores. 

Obtendo Dados Específicos - Por TIPO de Dados

Anteriormente, mencionamos que o LISP depende do uso de dados de tipos específicos de maneira apropriada. Mencionamos 4 tipos específicos de dados: Inteiros, Reais, Strings e Lists. O LISP fornece funções para permitir especificamente ao programador, para permitir ao usuário de um programa, inserir valores que podem diferir quando necessário.

 

(getint  str)

Permite que o usuário insira um valor inteiro.

Opcionalmente, permite que um argumento de string seja usado como um prompt. Retorna o valor de entrada como um inteiro.

 

(getreal  str)

Permite que o usuário insira um valor real ou de ponto-flutuante.

Opcionalmente, permite que um argumento de string seja usado como um prompt. Retorna o valor de entrada como um real (número).

 

(getstring  flag str)

Permite que o usuário insira um valor inteiro.

Opcionalmente, permite que um argumento de string seja usado como um prompt. Também permite um argumento opcional, que se “tem valor” permite que espaços sejam incluídos na string de entrada. Retorna a string de entrada como uma string.

 

(getpoint  pt str)

Permite que o usuário insira um valor de ponto.

Opcionalmente, permite que um argumento de string seja usado como um prompt. Além disso, opcionalmente, permite um argumento de ponto de “partida”. Retorna o ponto de entrada como uma Lista.

 

Este é um pouco complicado de interpretar, mas uma vez compreendido, é de fato lógico!

Essa última sentença é a chave para entender a discussão anterior sobre os tipos de dados. Mencionamos que existem 4 tipos principais de dados e é óbvio que as 3 primeiras funções tratam dos 3 primeiros tipos de dados que mencionamos. A última função é (getpoint) - e não há nenhum tipo de dado chamado “ponto”. Mencionamos que existe um tipo de dados denominado “lista”. Para esclarecer… Mencionamos que uma lista é qualquer coisa contida em um conjunto de parênteses. Também mencionamos que uma expressão é um tipo específico de lista - uma que tem uma função como o primeiro átomo da lista, e quaisquer átomos adicionais são chamados de argumentos. A função (getpoint) retorna “apenas” uma lista - não uma expressão como todas as listas com as quais estivemos lidando até este ponto. A lista que esta função retorna é composta por três átomos. Todos os três átomos são do tipo de dados “real”. O primeiro átomo é o valor X do ponto, o segundo é o valor Y e o terceiro é o Z. Portanto, (getpoint) retorna uma lista, e muitas vezes é referido especificamente como uma "lista de pontos". Compreender a lógica por trás deste parágrafo é a chave para você começar a entender como a linguagem LISP funciona!

Usando os Dados Armazenados

Depois que os dados foram coletados do usuário, é comum usar esses dados para adicionar objetos a um desenho ou modificar objetos existentes em um desenho. Por enquanto, vamos usar os dados armazenados para desenhar alguns objetos.

A função (command) é uma maneira pela qual um programador pode adicionar ou modificar objetos em um desenho.

(command string argumento argumento …)

O primeiro argumento para o (command) será um nome de comando. É sempre expresso como uma string. O número de argumentos adicionais e seus tipos de dados dependem de qual comando está sendo usado. Isso ficará claro na próxima (e final desta vez!) seção.

Juntar Tudo

Iremos nos aprofundar muito em cada uma dessas funções e conceitos em postagens futuras, mas, por enquanto, vamso inserir algumas linhas de código no prompt de comando para amarrar tudo. Digite essas linhas de código diretamente no prompt de comando. Se algo der errado, por enquanto, apenas pressione a tecla Escape e redigite a linha de código.

(setq CPT (getpoint “Selecionar um ponto central:“))
(setq RAD (getreal “Entre um raio:“))
(setq OFF (getreal “Entre um valor do deslocamento:“))
(setq NEWRAD (+ RAD OFF))
(command “circle” CPT RAD)
(command “circle” CPT NEWRAD)

Acima, temos os ingredientes de um programa! Na próxima postagem, aprenderemos como armazenar essas linhas de código em um arquivo de texto para que não precisemos mais digitá-las na linha de comando toda vez que quisermos desenhar um círculo de deslocamento. (E, claro, levaremos nosso conhecimento recém-descoberto ainda mais profundo do que apenas desenhar alguns círculos!)

Nota do autor:

Ocasionalmente, minhas postagens podem parecer sobrepor e/ou repetir Publicações de LISP neste blog por Ralph Grabowski. Há muitos anos, aprecio os artigos do Ralph em várias fontes. Como leitor, acho que você gostará de ver material semelhante apresentado de maneira um pouco diferente - pode contribuir para uma compreensão mais completa dos tópicos.