.: Definição das classes do projeto RPNCalc

==========
RPNLib 0.1
==========

O presente documento servirá como orientação para a construção da RPNLib, uma
biblioteca de classes que será utilizada para a construção da RPNCalc.

Veja o anúncio completo do projeto em:
http://br.groups.yahoo.com/group/objectpascal/message/43

Os detalhes do projeto serão discutidos na lista:
http://br.groups.yahoo.com/group/rpncalc-dev/

Para contato ou em caso de dúvidas sobre o projeto:
rpncalc-dev-owner@yahoogrupos.com.br

Projeto criado e administrado por:
João Morais
http://www.joaomorais.com.br/


======
RPNLib
======
Unidade principal da RPNLib

Tentarei explicar a sintaxe e a utilidade de cada uma das classes e tipos de
dados que serão criados para a RPNLib. A explicação será dada da forma mais
suscinta possível, apenas como orientação dos trabalhos que vêm pela frente.


ERPNLib = class(Exception);
-------
Classe antecessora de todas as classes de exceções (erros) da RPNLib.

ESintaxe = class(ERPNLib);
--------
Classe antecessora de todas as classes de erros de sintaxe. Ocorre na entrada
dos dados à Biblioteca (geralmente, entradas efetuadas pelo usuário)

ESintaxeExpressao = class(ESintaxe);
ESintaxeNumero = class(ESintaxe);
ESintaxeString = class(ESintaxe);
ESintaxeMatriz = class(ESintaxe);
ESintaxeLista = class(ESintaxe);
ESintaxeBinario = class(ESintaxe);

EParametro = class(ERPNLib);
----------
Número de parâmetros é insuficiente

EFormula = class(ERPNLib);
--------
Fórmula com sintaxe incorreta

EIdentificador = class(ERPNLib);
--------------
Identificador duplicado (ao instalar função interna ou externa) ou
identificador com caracteres inválidos
:: Está sujeito a criação de classes herdeiras

EEstatistica = class(ERPNLib);
------------
Erro nos módulos de cálculo estatístico
:: Está sujeito a criação de classes herdeiras

O grupo "TItemData", listado abaixo, identifica um tipo de dado (nativo ou
implementado, tal como TParser) para cada tipo de dado possível na nossa
Pilha[2].

TItemDataFormula = TParser;
----------------
Fórmula matemática - inicia sempre com um ' (apóstrofe)

TItemDataNumero = TParserFloat;
---------------
Número decimal de ponto flutuante

TItemDataString = string;
---------------
String - inicia sempre com uma " (aspas)

TItemDataMatriz = TStringList;
---------------
Matriz uni ou bidimensional - inicia sempre com um [ (abre colchete)
Cada item do TStringList aponta para um Objeto TItemPilha

TItemDataLista = TStringList;
--------------
Lista - conjunto de qualquer outro tipo de dado, inclusive outra(s) lista(s)
Inicia sempre com um { (abre-chave)

TItemDataBinario = record
----------------
Número inteiro usado para transformação de base numérica - a base é identificada
com uma das letras 'b', 'o', 'd', 'h' ao final do número - inicia sempre com
um # (sustenido, cancela, cerquinha, jogo da velha, conforme o gosto :) )

TTipoDado = (
tdExpressao, tdNumero, tdString, tdMatriz, tdLista,
tdBinario, tdFuncao, tdNulo, tdErro);
---------
Identifica o tipo de dado. Necessário para criar a instância[1] correta na
Pilha[2] de dados.

TFormatoAngulo = (
faGraus, faGrados, faRadianos);
--------------
Utilizado para identificar o tipo de ângulo atual nos cálculos trigonométricos

TFNApresentacao = (
fnPadrao, fnFixo, fnCientifico, fnEngenharia);
---------------
Identifica o formato de apresentação dos números decimais com ponto flutuante
O detalhamento de cada formato está fora do escopo deste documento

TFormatoNumero = class(TObject)
--------------
Classe com instância[1] única dentro da RPNLib. Utilizada para controlar o
formato numérico atual, aonde podemos destacar tipo de ângulo, formato,
número de casas decimais, ponto ou vírgula no decimal, entre outros.

TItemPilha = class(TObject)
----------
Classe antecessora de todos os tipos de dados possíveis na Pilha[2] de Dados.
Possui métodos virtuais[3] de formatação, tal como AsString, que retorna o dado
atual no formato string para apresentação no visor.

TItemFormula = class(TItemPilha)
TItemNumero = class(TItemPilha)
TItemString = class(TItemPilha)
TItemMatriz = class(TItemPilha)
TItemLista = class(TItemPilha)
TItemBinario = class(TItemPilha)
------------
Cada classe acima controla o tipo de dado a que foi designada, herdando e
implementando os métodos virtuais[3] de TItemPilha.

TPilha = class(TObject)
------
Classe de instância[1] única dentro da RPNLib. Possui uma lista com todos
os ItemPilha criados, e diversos métodos para controle desses dados, aonde
podemos destacar: incluir e eliminar itens, interpretação da entrada do
usuário e consequente empilhamento dos dados, entre outros.

TBibl = class(TObject)
-----
Classe de instância[1] única dentro da RPNLib. Possui todas as funções internas
(implementadas em código) e externas (implementadas como fórmulas - TParser), e
todas as variáveis atualmente disponíveis. Possui diversos métodos para
controle dessas funções e variáveis, tal como instalar função, instalar
variável, entre outros.


===============
Unidade RPNPars
===============
Unidade responsálvel pelo parsing[4] de fórmulas matemáticas.

O Parsing da RPNLib (RPNPars) merece um tratamento especial e diferenciado
devido a sua complexidade. Aqui serão compiladas, executadas e gerenciadas
todas as fórmulas utilizadas na RPNLib.

ERPNParsing = class(ERPNLib);
-----------
Classe antecessora de todas as exceções ocorridas durante o parsing[4] de uma
fórmula

EParsingErroSintaxe = class(ERPNParsing);
EParsingBrancos = class(ERPNParsing);
EParsingComplexa = class(ERPNParsing);
EParsingAninhamentos = class(ERPNParsing);
EParsingParenteses = class(ERPNParsing);
EParsingNomeImproprio = class(ERPNParsing);
EParsingErroInterno = class(ERPNParsing);
-------------------
As classes descritas acima foram trazidas da TParser, um componente avaliador
de fórmulas matemáticas, que pode ser encontrado em
http://www.joaomorais.com.br/pascal/download.php?cat=101 Pretendo reescrever
toda a rotina, primeiro para termos uma solução 100% própria, e também para
fins de estudo (não estamos construindo essa Lib atoa, correto?) Assim sendo,
estas classes descritas acima estão altamente sujeitas a alterações.

TToken = (
variab, constant, minus, sum, diff, prod, divis, modulo, IntDiv,
integerpower, realpower, square, third, fourth, FuncOneVar, FuncTwoVar);
------
Utilizado internamente pela rotina para identificar o token atual
:: Está sujeito a pequenas alterações

TParserFloat = extended;
------------
Todos os números decimais utilizados para os cálculos internos e para o
resultado serão tratados como TParserFloat. A alteração indiscriminada do tipo
definido aqui pode causar alguns estragos devido a erros de arredondamento.

PParserFloat = ^TParserFloat;
------------
Ponteiro ao tipo TParserFloat (prefiro não entrar em detalhes ainda ;-) )

POperation = ^TOperation;
----------
Ponteiro à TOperation. Esta estrutura é explicada em seguida.

TMathProcedure = procedure(AnOp: POperation);
--------------
Toda função interna é uma procedure controlada pela classe TBibl. Este tipo é
utilizado para criar um Typecast[5] para executar determinada função interna.

TParser = class(TObject)
-------
Classe responsável pela manutenção de uma fórmula. Possui a sua versão em
string e um ponteiro ao primeiro token (TOperation) de uma sequência utilizada
para executá-la.

TFuncao = class(TObject)
-------
Classe antecessora de todas as funções matemáticas da Biblioteca (TBibl) da
RPNLib.

TFuncaoExterna = class(TFuncao)
--------------
Função que utiliza um TParser para alcançar um resultado.

TFuncaoInterna = class(TFuncao)
--------------
Função que utiliza uma procedure em determinado endereço de memória para
alcançar um resultado.

TOperation = record
----------
Estrutura de uma lista encadeada (por ponteiros) para execução de uma função
externa. Esta lista é criada pelo algoritmo de Parsing[4] de fórmulas
matemáticas.

=========
GLOSSÁRIO
=========

[1] Instância
É um objeto criado na memória. Toda classe precisa 'instanciar' um objeto
(criar um objeto) para que seja possível trabalhar com ele. Cada instância
é totalmente independente de outra, mesmo que seja da mesma classe. Elas apenas
compartilham a mesma estrutura e regras internas.

[2] Pilha
Área de armazenamento de dados LIFO (Last In, First Out - o último que entra é
o primeiro que sai). A Pilha da RPNLib armazena objetos da classe TItemPilha,
ou seja, números, strings, matrizes, fórmulas, etc.

[3] Método Virtual
É um método sujeito a implementação por uma classe herdeira. É muito útil para
a construção de uma rotina genérica que possuirá diversas implementações
diferentes. O conceito e a utilidade de métodos virtuais ficarão mais claras
com o decorrer do acompanhamento deste projeto.

[4] Parsing
É um equivalente a 'interpretação', 'compilação', 'codificação'. O Parsing de
fórmulas em formato string, tal como 'SIN(X)', é a sua transformação em uma
lista encadeada (por ponteiros) de tokens que serão responsáveis pelas etapas
do cálculo.

[5] Typecast
Método utilizado para identificação do tipo real de um objeto. Em português
claro, o Typecast é utilizado para informar ao compilador com qual tipo de dado
ele está trabalhando. Neste projeto é utilizado em duas situações:
:: Typecast de classes: uma variável de uma classe antecessora pode guardar um
objeto de uma classe herdeira. Ex.: uma variável do tipo TItemPilha pode
armazenar um objeto da classe TItemFormula. Se tivermos certeza que o objeto
seja deste tipo, usamos TItemFormula(VarItemPilha).Formula para capturar a
propriedade Formula do objeto. Devemos usar Typecast porque TItemPilha (o tipo
de VarItemPilha) não possui uma propriedade Formula. (ih... piorou, né? :) )
:: Typecast de procedure: o endereço das procedures das funções internas são
armazenadas em uma variável TObject. Para que possamos executar a procedure,
devemos fazer um Typecast da variável, desta forma:
TMathProcedure(VarObject)(Parâmetro);


©2002 joaomorais.com.br