MiniPas
MiniPas es un lenguaje de programación interpretado inspirado en Turbo Pascal V7, diseñado para ser sencillo, educativo y fácil de usar.
⚠️ MiniPas no busca ser compatible con Pascal, Turbo Pascal V7 ó FreePascal: muchas características de Pascal no están soportadas.
Su objetivo principal es permitir experimentar con conceptos básicos de programación estructurada y scripting, ideal para aprendizaje ó pequeños proyectos.
☢️ MiniPas Es un lenguaje experimental y minimalista.
Ejemplo:
// example.mp
program helloworld;
var r: real;
begin
// comentarios de una linea
writeln("Hello World in minipas!");
r := 2.0;
writeln(); // un espacio en blanco
writeln("Circunferencia:", 2 * PI * r);// usamos PI
{ comentarios de
varias lineas
}
writeln("uso de pow:", pow(2,3));
writeln("uso de sqrt", sqrt(16));
writeln();
writeln("platform:", platform());
writeln("version:", version());
end.
proporciona una salida como la siguiente:
welcome to minipas v0.9.0
cargando archivo: 'example.mp'
Hello, World in minipas!
Circunferencia: 12.566370614359172
uso de pow: 8
uso de sqrt 4
platform: linux
version: 0.9.0 (MiniPas build, unknown, linux) [rustc]
Licencia
Este proyecto está disponible bajo dos licencias distintas.
Puede seleccionar la licencia que mejor se ajuste a sus necesidades, entre las siguientes opciones:
- Licencia Apache versión 2.0
- Licencia MIT
El texto completo de estas licencias, se encuentran en los archivos LICENSE-APACHE y LICENSE-MIT
Instalación (binarios)
Para empezar a utilizar Minipas , descarga el instalador, ejecuta el programa y sigue las instrucciones que aparecen en pantalla.
Gnu/Linux
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HomeInside/minipas/releases/download/1.9.1/minipas-installer.sh | sh
Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/HomeInside/minipas/releases/download/1.9.1/minipas-installer.ps1 | iex"
Instalación manual
-
Binarios precompilados para Gnu/Linux: descarga tarball para x86_64
-
Binarios precompilados para Windows: descarga zip para x86_64
Instalación desde el código fuente
La mejor manera de obtener la última y mejor versión de Minipas es instalarla desde el código fuente. Es fácil y solo lleva unos segundos:
Nota:
Si utilizas Windows, fuera de WSL, se recomienda utilizar MSVC, revisa los requisitos para esto, por aquí…
Clona el repo
$ git clone https://github.com/HomeInside/minipas.git
Construye
$ cd minipas
$ cargo build --release
Prueba
$ minipas run examples/hello_world.mp
Realiza las modificaciones que creas convenientes y envíanos un pull request.
Para cualquier duda, comentario, sugerencia ó aporte, dirigete a la seccion de issues.
Antes de abrir un issue nuevo, revisa los ya existentes en busca de una solución (posiblemente ya planteada) para el problema que se te presenta.
Linea de comandos
La herramienta de línea de comandos Minipas, se utiliza para compilar y revisar codigo fuente de archivos .mp. Una vez instalado Minipas, puede ejecutar el comando minipas --help en su terminal para ver los comandos disponibles.
Las siguientes secciones proporcionan información detallada sobre los diferentes comandos disponibles.
- minipas build Compila un archivo fuente, y genera el AST en formato binario.
- minipas run Ejecuta un archivo con extensión
.mp|.mpcde minipas. - minipas emit Genera los Pairs y el AST de un archivo fuente.
- minipas check Verifica un archivo fuente sin ejecutarlo.
extensiones de archivo
Minipas utiliza las siguientes extensiónes de archivos
- .mp archivo con código fuente de minipas.
- .mpc archivo en formato binario (similar a bytecode) de un archivo con código fuente .mp.
- .mpp archivo en formato JSON, que contiene las Reglas generadas por el parser, de un archivo con código fuente.
- .mpa archivo en formato JSON, que contiende información del AST generado por el interprete, de un archivo con código fuente.
build
El comando build es utilizado para compilar un archivo con código fuente de minipas.
$ minipas build hello_world.mp
ó de la forma
$ minipas b hello_world.mp
para ambos casos, la salida será algo como:
minipas v.1.9.0
building "hello_world.mp"...
generating AST file (bin): "a.mpc"
OK.
esto creará un archivo con formato binario (similar a bytecode) con la extensíon .mpc.
Nota:
Para más información sobre los archivos .mpc, consulte el comando run.
Importante:
el comando build/b solo acepta archivos con extensión .mp
en caso contrario obtendrá un error como este:
minipas v.1.9.0
minipas error: extensión de archivo de entrada, no valido.
utilice '.mp', para las extensiones de archivo.
try 'minipas --help' for more information
run
El comando run es utilizado para ejecutar un archivo con código fuente de minipas.
las extensiones de archivos permitidas son:
- .mp archivo con código fuente de minipas.
- .mpc archivo en formato binario (similar a bytecode) de un archivo con código fuente .mp.
$ minipas run hello_world.mp
ó de la forma
$ minipas r hello_world.mp
para ambos casos, la salida será algo como:
minipas v.1.9.0
Hello World in minipas!
archivos binarios
minipas soporta la ejecución de archivos previamente compilados (comando build)
$ minipas run a.mpc
ó de la forma
$ minipas r a.mpc
para ambos casos, la salida será algo como:
minipas v.1.9.0
Hello World in minipas!
Importante:
el comando run/r solo acepta archivos con extensión .mp ó .mpc.
en caso contrario obtendrá un error como este:
minipas v.1.9.0
minipas error: extensión de archivo no válida.
run: utilice '.mp' ó '.mpc', para extensiones de archivo.
try 'minipas --help' for more information
emit
El comando emit es utilizado para generar archivos que contienen información del parser y del interprete de minipas.
información util para depuración.
$ minipas emit hello_world.mp
ó de la forma
$ minipas e hello_world.mp
para ambos casos, la salida será algo como:
minipas v.1.9.0
generating Pairs file: "hello_world.mpp"
generating AST file (text): "hello_world.mpa"
OK.
esto creará dos archivos con formato JSON
-
archivo .mpp, información del parser
[ Pair { rule: program, span: Span { str: "program helloworld;\r\nbegin\r\n writeln(\"Hello World in minipas!\");\r\nend.\r\n", start: 0, end: 75, }, inner: [ Pair { rule: ident, span: Span { str: "helloworld", start: 8, end: 18, }, inner: [], }, Pair { rule: semicolon, span: Span { str: ";", start: 18, end: 19, }, inner: [], }, Pair { rule: block, span: Span { str: "begin\r\n writeln(\"Hello World in minipas!\");\r\nend", start: 21, end: 72, }, inner: [ Pair { rule: stmt, span: Span { str: "writeln(\"Hello World in minipas!\");", start: 32, end: 67, }, inner: [ Pair { rule: expr_stmt, span: Span { str: "writeln(\"Hello World in minipas!\");", start: 32, end: 67, }, inner: [ Pair { rule: expr, span: Span { str: "writeln(\"Hello World in minipas!\")", start: 32, end: 66, }, inner: [ Pair { rule: sum, span: Span { str: "writeln(\"Hello World in minipas!\")", start: 32, end: 66, }, inner: [ Pair { rule: product, span: Span { str: "writeln(\"Hello World in minipas!\")", start: 32, end: 66, }, inner: [ Pair { rule: method_chain, span: Span { str: "writeln(\"Hello World in minipas!\")", start: 32, end: 66, }, inner: [ Pair { rule: factor, span: Span { str: "writeln(\"Hello World in minipas!\")", start: 32, end: 66, }, inner: [ Pair { rule: func_call, span: Span { str: "writeln(\"Hello World in minipas!\")", start: 32, end: 66, }, inner: [ Pair { rule: ident, span: Span { str: "writeln", start: 32, end: 39, }, inner: [], }, Pair { rule: lparen, span: Span { str: "(", start: 39, end: 40, }, inner: [], }, Pair { rule: expr_list, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [ Pair { rule: expr_item, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [ Pair { rule: expr, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [ Pair { rule: sum, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [ Pair { rule: product, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [ Pair { rule: method_chain, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [ Pair { rule: factor, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [ Pair { rule: string_literal, span: Span { str: "\"Hello World in minipas!\"", start: 40, end: 65, }, inner: [], }, ], }, ], }, ], }, ], }, ], }, ], }, ], }, Pair { rule: rparen, span: Span { str: ")", start: 65, end: 66, }, inner: [], }, ], }, ], }, ], }, ], }, ], }, ], }, Pair { rule: semicolon, span: Span { str: ";", start: 66, end: 67, }, inner: [], }, ], }, ], }, ], }, Pair { rule: EOI, span: Span { str: "", start: 75, end: 75, }, inner: [], }, ], }, ] -
archivo .mpa, información del AST (interprete)
[ Block( [ Expr( Call { name: "writeln", args: [ StringLiteral( "Hello World in minipas!", ), ], }, ), ], ), ]
Importante:
El comando emit/e solo acepta archivos con extensión .mp
en caso contrario obtendrá un error como este:
minipas v.1.9.0
minipas error: extensión de archivo de entrada, no valido.
utilice '.mp', para las extensiones de archivo.
try 'minipas --help' for more information
check
Verifica un archivo fuente sin ejecutarlo.
El comando check es utilizado para validar el código fuente, buscando errores de sintaxis.
$ minipas check hello_world.mp
ó de la forma
$ minipas c hello_world.mp
para ambos casos, la salida será algo como:
minipas v.1.9.0
validando pairs...
validando AST...
OK.
Importante:
El comando check/c solo acepta archivos con extensión .mp
en caso contrarió obtendrá un error como este:
minipas v.1.9.0
minipas error: extensión de archivo de entrada, no valido.
utilice '.mp', para las extensiones de archivo.
try 'minipas --help' for more information
hola mundo
program helloworld;
begin
writeln("Hello World in minipas!");
end.
Guarda este fragmento de código, en un archivo llamado hello_world.mp, en lugar conveniente.
Ahora haz lo siguiente:
$ minipas run hello_world.mp
la salida será algo como:
minipas v.1.9.0
Hello World in minipas!
y eso es todo!
para conocer más acerca de como crear programas en Minipas, consulta Estructura de un programa.
Estructura de un programa
Un programa en minipas, sigue una estructura específica que incluye distintos componentes.
A continuación, se detallan los elementos clave:
Nombre (declaración) del programa
el programa comienza con la palabra clave program, seguido de un nombre cualquiera, este nombre no debe:
- iniciar con numeros
- incluir espacios
- utilizar guión medio (-),
se acepta el guión bajo (_)
program helloworld;
Declaraciones de Variables
Se declaran las variables que se usarán en el programa, especificando su tipo de dato.
var r: real;
var result: real;
Declaraciones de funciones y procedimientos
Incluye la lógica que se ejecutará cuando se llame al procedimiento y/ó función, en caso de que las definas en tu programa.
function calcular(radio:real): real;
begin
return 2 * PI * radio;
end
Cuerpo del programa
comienza con la palabra clave begin después de la declaración del programa.
begin
Código del Programa
Aquí es donde se implementa la lógica principal, incluyendo operaciones, condiciones, ciclos, etc.
r := 2.0;
result := calcular(r);
writeln("el valor de la Circunferencia es:", result);
Final del Programa
Todo programa en minipas finaliza con la palabra end y un signo de punto (.), al final.
end.
ejemplo completo
program helloworld;
var r: real;
var result: real;
function calcular(radio:real): real;
begin
return 2 * PI * radio;
end
begin
r := 2.0;
result := calcular(r);
writeln("el valor de la Circunferencia es:", result);
end.
salida
la salida será algo como:
minipas v.1.9.0
el valor de la Circunferencia es: 12.566370614359172
Sintaxis Básica
Ya hemos visto la estructura básica de un programa en minipas, por lo que te resultará fácil comprender otros componentes básicos del lenguaje.
Su objetivo principal es permitir experimentar con conceptos básicos de programación estructurada y scripting, ideal para el aprendizaje ó pequeños proyectos.
Minipas toma muchas caracteristicas y referencias del lenguage Pascal, sin embargo, hay que recalcar algunas cosas:
-
⚠️ MiniPas no busca ser compatible con Pascal, Turbo Pascal V7 ó FreePascal: muchas características de Pascal no están soportadas.
-
MiniPas es un lenguaje interpretado, inspirado en Turbo Pascal V7, diseñado para ser sencillo, educativo y fácil de usar, la gran mayoría (si no todos…) de los dialectos de Pascal son compilados.
-
Pascal es un lenguaje que no distingue entre mayúsculas y minúsculas (Case Insensitive), lo que significa que puedes escribir tus variables, funciones y procedimientos con cualquiera de las dos. En Minipas no se acepta esto, todas las palabras claves deben escribirse en minúsculas, salvo muy pequeñas excepciones.
-
En minipas, cada sentencia debe terminar en punto y coma (
;). -
☢️ MiniPas Es un lenguaje experimental y minimalista.
Comentarios
Los comentarios en Minipas pueden ser de la siguiente forma:
-
una sola linea, usando
//// un comentario antes de todo program helloworld; begin // dentro del bloque principal writeln("Hello World in minipas!"); // al lado de una sentencia end. // un comentario despues del bloque principal -
una sola linea, usando
{}program helloworld; begin { dentro del bloque principal } writeln("Hello World in minipas!"); end. -
varias lineas, usando
{}{ programming in Minipas demo with comments Author: John Doe <johndoe@example.com> } program helloworld; begin { dentro del bloque principal } writeln("Hello World in minipas!"); end. -
anidados, usando
{}program helloworld; begin { programming in Minipas demo with comments Author: John Doe <johndoe@example.com> // aqui un comentario de una linea // dentro de las llaves } writeln("Hello World in minipas!"); end.
Tenga en cuenta:
Los comentarios en minipas pueden ir en cualquier parte del programa, o incluso estar anidados y estos serán ignorados por el interprete, aunque se recomienda precaución en estos casos.
Operadores
lista operadores soportandos en minipas.
:= asignación
Operadores aritmeticos
+ suma integer, real, strings
- diferencia integer, real
* producto integer, real
div cociente integer, real
/ cociente integer, real
mod residuo integer, real
% residuo integer, real
Operadores relacionales
> mayor qué
< menor qué
>= mayor ó igual
<= menor ó igual
<> diferente de
= igualdad
Operadores de asignación (abreviados)
+= suma y asigna el resultado
-= resta y asigna el resultado
*= multiplica y asigna el resultado
/= divide y asigna el resultado
%= calcula el residuo de la división y asigna el resultado
Variables
La definición de una variable se coloca en un bloque que comienza con la palabra clave var, seguida de las definiciones de las variables como se muestra a continuación:
-
ejemplo 1:
// cada variable en una linea var nombre: string; var edad: integer; var mayor_de_edad: boolean; -
ejemplo 2:
// si son del mismo tipo, pueden ir en una sola sentencia var nombre, apellidos: string; -
ejemplo 3:
// en un bloque de definición var nombre: string; edad: integer; mayor_de_edad: boolean;
Este tipo de variables definidas despues de la declaracion del programa serán variables globales y estarán disponibles para cualquier función, procedimiento y el bloque principal del programa, durante su ejecución.
Es decir, las variables globales se definen después del encabezado del programa.
Constantes
⚠️ Minipas no admite Constantes
Gramática
La definición de la gramática actual de minipas.
// Minipas grammar.pest 1.8.0
//
WHITESPACE = _{ (" " | "\t" | NEWLINE | comment)+ }
NEWLINE = _{ "\n" | "\r\n" }
comment_single = { "//" ~ (!NEWLINE ~ ANY)* }
comment_braces = { "{" ~ (!"}" ~ ANY)* ~ "}" }
comment = { comment_single | comment_braces }
string_literal = @{
("\"" ~ ("\\\"" | "\\\\" | (!"\"" ~ ANY))* ~ "\"")
| ("'" ~ ("\\'" | "\\\\" | (!"'" ~ ANY))* ~ "'")
}
boolean_literal = { "True" | "False" | "TRUE" | "FALSE" }
// Tokens
keyword_var = { "var" }
keyword_program = { "program" }
keyword_integer = { "integer" }
keyword_real = { "real" }
keyword_string = { "string" }
keyword_boolean = { "boolean" }
keyword_byte = { "byte" }
keyword_writeln = { "writeln" }
keyword_if = { "if" }
keyword_then = { "then" }
keyword_else = { "else" }
keyword_const = { "const" }
keyword_and = { "and" }
keyword_array = { "array" }
keyword_for = { "for" }
keyword_while = { "while" }
keyword_repeat = { "repeat" }
keyword_until = { "until" }
keyword_function = { "function" }
keyword_procedure = { "procedure" }
keyword_nil = { "nil" }
// for loop
keyword_to = { "to" }
keyword_do = { "do" }
keyword_downto = { "downto" }
// break/continue in loops
keyword_break = { "break" }
keyword_continue = { "continue" }
break_stmt = { keyword_break ~ semicolon }
continue_stmt = { keyword_continue ~ semicolon }
// abbreviated operations
assign_add = { "+=" }
assign_sub = { "-=" }
assign_mul = { "*=" }
assign_div = { "/=" }
assign_mod = { "%=" }
ident = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
number = @{ "-"? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
real = @{ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT+ }
assign_op = { ":=" }
add_op = { "+" }
sub_op = { "-" }
mul_op = { "*" }
div_op = { "/" }
idiv_op = { "div" }
mod_op = { "%" | "mod" }
cmp_op = { ">=" | "<=" | "<>" | ">" | "<" | "=" }
semicolon = { ";" }
comma = { "," }
colon = { ":" }
lparen = { "(" }
rparen = { ")" }
expr = { sum ~ (cmp_op ~ sum)? }
sum = { product ~ ((add_op | sub_op) ~ product)* }
method_chain = { factor ~ ("." ~ ident ~ lparen ~ (expr_list)? ~ rparen)* }
product = { method_chain ~ ((mul_op | div_op | idiv_op |mod_op) ~ method_chain)* }
//product = { factor ~ ((mul_op | div_op | idiv_op |mod_op) ~ factor)* }
//
// llamadas a función/ procedimiento
func_call = { ident ~ lparen ~ (expr_list)? ~ rparen }
factor = { number | string_literal | boolean_literal | func_call | ident | keyword_nil | "(" ~ expr ~ ")" }
// Aquí el `-` delante del número se reconoce como operador unario.
// Esto permite -1 y también expresiones como -(2+3).
//
// factor = { ("-"? ~ number) | string_literal | boolean_literal | func_call | ident | "(" ~ expr ~ ")" }
string = @{ "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
expr_item = { expr | string_literal }
expr_list = { expr_item ~ (comma ~ expr_item)* }
expr_stmt = { expr ~ semicolon }
// Sentencias
block = { "begin" ~ stmt* ~ "end" }
//stmt = { comment* ~ (if_stmt | for_stmt | while_stmt | repeat_stmt | block | assignment | expr_stmt | return_stmt) }
stmt = { comment* ~ (if_stmt | for_stmt | while_stmt | repeat_stmt | break_stmt | continue_stmt | block | assignment | expr_stmt | return_stmt) }
if_stmt = { keyword_if ~ expr ~ keyword_then ~ stmt ~ (keyword_else ~ stmt)? }
var_decl = { ident ~ ("," ~ ident)* ~ ":" ~ (keyword_integer | keyword_real | keyword_string | keyword_boolean | keyword_byte) ~ ";" }
//assignment = { ident ~ assign_op ~ expr ~ semicolon }
assignment = {ident ~ (assign_op | assign_add | assign_sub | assign_mul | assign_div|assign_mod) ~ expr ~ semicolon}
var_section = { ("var" ~ var_decl+)+ }
// procedures
proc_decl = {
keyword_procedure ~ ident ~ lparen ~ (param_list)? ~ rparen ~ semicolon ~ var_section? ~ block ~ semicolon?
}
// functions
func_decl = {
keyword_function ~ ident ~ lparen ~ (param_list)? ~ rparen ~ colon ~ (keyword_integer | keyword_real | keyword_string | keyword_boolean | keyword_byte) ~ semicolon ~ (var_section)? ~ block ~ semicolon?
}
// return
return_stmt = { "return" ~ expr ~ semicolon }
// FOR LOOP
for_stmt = {
keyword_for ~ ident ~ assign_op ~ expr // ~ ("to" | "downto") ~ expr
~ (keyword_to | keyword_downto) ~ expr ~ keyword_do ~ stmt
}
// WHILE LOOP
while_stmt = {
keyword_while ~ expr_boolean ~ keyword_do ~ stmt
}
expr_boolean = _{ expr }
// REPEAT LOOP
repeat_stmt = {
keyword_repeat ~ stmt+ ~ keyword_until ~ expr ~ semicolon
}
param_list = { param ~ (semicolon ~ param)* }
param = { ident ~ colon ~ type_keyword }
type_keyword = { keyword_integer | keyword_real | keyword_string | keyword_boolean | keyword_byte }
//
program = {
SOI ~ comment* ~ "program" ~ ident ~ semicolon ~ var_section? ~ (proc_decl | func_decl)* ~ block ~ "." ~ EOI
}
Tipos de datos
Los tipos de datos indican el significado, las restricciones, los valores posibles, las operaciones, las funciones y el modo de almacenamiento de un valor asociado a el.
Cada valor en minipas es de un determinado tipo de dato, lo que le indica cómo trabajar con ellos al al interprete.
Ten en cuenta que minipas es un lenguaje de tipado fuerte y estático, lo que significa que se debe definir y conocer los tipos de todas las variables antes de la ejecución del programa.
minipas soporta los siguientes tipos de datos:
- integer números enteros.
- real números con parte decimal.
- string cadenas de caracteres.
- boolean indica solo dos posibles valores, verdadero o falso.
- byte número entero sin signo que tiene un valor entre 0 y 255.
Valor especial Nulo
minipas usa el valor especial nil (nulo), sin embargo nil, no es un tipo de dato en sí mismo, sino más bien un valor especial que indica la ausencia de un valor ó un valor no asignado.
A tener en cuenta:
En minipas, no puedes asignar un valor nulo (nil) a una variable de la misma manera que en otros lenguajes de programación.
numéricos
Integer
Un entero es un número sin componente fraccionario. Esto incluye todos los números sin parte decimal, tanto positivos como negativos.
Rango de Valores
El rango específico de valores que puede almacenar un integer puede variar dependiendo de la implementación, pero generalmente en Pascal es de -32,768 a 32,767. En minipas, este valor se incrementa ya que se utiliza i64 de Rust, lo que amplía significativamente el valor a usar en una variable.
-
Turbo Pascal v 7 \begin{cases} \text -2^{15} \text{ hasta }\ 2^{15} - 1 \ \end{cases}
-
Minipas \begin{cases} \text -2^{63} \text{ hasta }\ 2^{63} - 1 \ \end{cases}
Ejemplo
program hello_integers;
var
a,b,c: integer;
begin
writeln("Hello World in minipas!");
writeln();
writeln("el valor de a es:", a);
writeln("el valor de b es:", b);
writeln("el valor de c es:", c);
end.
Real
Se refiere a un tipo de dato que se utiliza para representar números que tienen parte decimal. Estos tipos son esenciales para realizar cálculos que requieren precisión con decimales, como operaciones matemáticas complejas, mediciones, y otros casos donde los números enteros no son suficientes.
Rango de Valores
El rango específico de valores que puede almacenar un integer puede variar dependiendo de la implementación, pero generalmente en Pascal es de -32,768 a 32,767. En minipas, este valor se incrementa ya que se utiliza f64 de Rust, lo que amplía significativamente el valor a usar en una variable.
-
Turbo Pascal v 7 \begin{cases} \text 2.9 \times 10^{-39} ;\text{ hasta }; 1.7 \times 10^{38} \ \end{cases}
-
Minipas \begin{cases} \text 1.8 \times 10^{308} \ \end{cases}
Ejemplo
program hello_real;
var
a,b,c: real;
begin
writeln("Hello World in minipas!");
writeln();
writeln("el valor de a es:", a);
writeln("el valor de b es:", b);
writeln("el valor de c es:", c);
end.
Byte
Es un tipo especial de entero que tiene un rango de valores de 0 a 255, por lo que no soporta valores negativos.
Ejemplo
program hello_byte;
var
edad: byte;
begin
writeln("Hello World in minipas!");
writeln();
edad:= 256; //genera un error, ya que el valor maximo es 255
writeln("el valor de edad es:", edad);
end.
Nota:
Para una mejor compresión recomendamos leer
strings
Se utilizan para representar cadenas de caracteres, el rango de un tipo de dato string depende de la longitud de la cadena y del uso de memoria.
Las cadenas de caracteres, son en realidad una secuencia de caracteres con una especificación de tamaño opcional. Los caracteres pueden ser numéricos, letras, espacios en blanco, caracteres especiales o una combinación de todos ellos. Extended Pascal proporciona numerosos tipos de objetos de cadena dependiendo del sistema y la implementación. Analizaremos los tipos de cadenas más comunes utilizados en los programas.
En minipas un tipo de dato string es internamente String de Rust, para asignar un valor se puede utilizar indistintamente comillas ("") o apóstrofos (''), aquí recomendamos el uso de comillas.
Ejemplo
program hello_strings;
var
nombres: string;
begin
writeln("Hello World in minipas!");
writeln();
nombres := "john";
writeln("el nombres es:", nombres);
end.
Nota:
Para una mejor compresión recomendamos leer
boleanos
Representan valores de verdad. Generalmente, un boleano puede tener solo dos posibles valores.
En Minipas, un valor boleano se representa de la siguiente manera, con la primera letra en Mayúscula:
- True (verdadero)
- False (falso)
Recuerda que los valores booleanos son lógicos y no numéricos. Esto lo hace útil para la toma de decisiones en la lógica de programación y control de flujo.
Ejemplo
program hello_booleans;
var
esMayorDeEdad: boolean;
begin
writeln("esMayorDeEdad al inicio es:", esMayorDeEdad);
esMayorDeEdad := True;
if esMayorDeEdad then
writeln('Es mayor de edad.');
else
writeln('No es mayor de edad.');
end.
Nota:
Para una mejor compresión recomendamos leer
arrays
⚠️ Minipas no admite arreglos(Arrays)
Control de flujo
Las estructuras de toma de decisiones requieren que el programador especifique una o más condiciones que el programa debe evaluar o comprobar, junto con una o varias instrucciones que se ejecutarán si la condición se determina como verdadera y, opcionalmente, otras instrucciones que se ejecutarán si la condición se determina como falsa.
A continuación se muestra la forma general de una estructura de toma de decisiones típica.
flowchart TD
A([ ]) --> B{condición}
B -- "si la condición se cumple" --> C[código condicional]
B -- "la condición NO se cumple" --> D(( ))
C --> D
%% Estilos
style A fill:#fff,stroke:#000
style D fill:#fff,stroke:#000
style B fill:#000,stroke:#fff,color:#fff
style C fill:#000,stroke:#fff,color:#fff
linkStyle 0 stroke:#000,stroke-width:2px
linkStyle 1 stroke:#000,stroke-width:2px
linkStyle 2 stroke:#000,stroke-width:2px
linkStyle 3 stroke:#000,stroke-width:2px
Minipas proporciona los siguientes tipos de sentencias de toma de decisiones:
-
Sentencia if-then: Una sentencia if-then consta de una expresión booleana seguida de una o más sentencias.
-
Sentencia if-then-else: Una sentencia if-then puede ir seguida de una sentencia else opcional, que se ejecuta cuando la expresión booleana es falsa.
-
Sentencias if anidadas: Se puede utilizar una sentencia if o else if dentro de otra sentencia if o else if.
-
sentencia case:
⚠️ Minipas no admite case
sentencia if
Sentencia if-then
La instrucción if-then es la forma más simple de instrucción de control, utilizada con frecuencia en la toma de decisiones y para cambiar el flujo de control de la ejecución del programa.
La sintaxis de la instrucción if-then es:
if condición then sentencias;
Donde condición es una condición booleana o relacional y sentencias es una instrucción simple o compuesta. Un ejemplo de una instrucción if-then es:
if a <= 20 then
c := c+1;
Si la condición de la expresión booleana se evalúa como verdadera, se ejecutará el bloque de código dentro de la instrucción if. Si la expresión booleana se evalúa como falsa, se ejecutará el primer conjunto de código después del final de la instrucción if.
Miremos con un ejemplo completo:
Ejemplo
program ifExample;
var a: integer;
begin
a:= 10;
// se puede usar parentesis
//
// if (a < 20) then
//
if a < 20 then
writeln("a menor que 20");
end.
salida
la salida será algo como:
minipas v.1.9.0
a menor que 20
Sentencia if-then-else
Una instrucción if-then puede ir seguida de una instrucción else opcional, que se ejecuta cuando la expresión booleana es falsa.
La sintaxis de la instrucción if-then-else es:
if condición then Sentencias1; else Sentencias2;
Donde Sentencias1 y Sentencias2 son sentencias diferentes.
En las sentencias if-then-else, cuando la condición de prueba es verdadera, se ejecuta la sentencia Sentencias1 y se omite Sentencias2, cuando la condición de prueba es falsa, se omite Sentencias1 y se ejecuta la sentencia Sentencias2.
A tener en cuenta:
En Minipas, cada sentencia debe terminar en punto y coma (;).
Ejemplo
program ifElseExample;
var
a : integer;
begin
a := 100;
// se puede usar parentesis
//
// if (a < 20) then
//
if a < 20 then
writeln("a es menor que 20");
else
writeln("a es mayor, el valor de a es:", a);
end.
salida
la salida será algo como:
minipas v.1.9.0
a es mayor, el valor de a es: 100
Sentencias if-then else if-then
Una instrucción if-then puede ir seguida de una instrucción else if-then-else opcional, lo cual resulta muy útil para comprobar varias condiciones utilizando una única instrucción if-then-else.
Ejemplo
program ifElse_ifElseExample;
var
a: integer;
begin
a := 100;
if a = 10 then
writeln("el valor de a es: 10");
else if a = 20 then
writeln("el valor de a es: 20");
else if a = 30 then
writeln("el valor de a es: 30");
else
writeln("Ninguno de los valores coincide.");
end.
salida
la salida será algo como:
minipas v.1.9.0
Ninguno de los valores coincide.
Instrucciones simples ó compuestas
Una instrucción simple es una línea de código que realiza una única acción. Estas instrucciones son directas:
if a <= 20 then
c := c+1; // <- instrucción simple
Una instrucción compuesta es un bloque de código que puede contener cero o más instrucciones simples, ó incluso instrucciones compuestas dentro (anidadas). Se utiliza para agrupar varias acciones bajo un mismo control de flujo.
La sintaxis de una instrucción compuesta incluye begin y end, que delimitan el bloque de instrucciones:
if a <= 20 then begin // <- 'begin' indica el inicio del bloque
c := c+1;
writeln("El valor de C es:", c);
end // <- 'end' indica el fin del bloque
A tener en cuenta:
En minipas, cada bloque begin debe terminar con un end, pero este end no debe llevar punto y coma (;) al final.
Los ejemplos anteriores se componen de sentencias simples, ahora veamos un ejemplo utilizando sentencias compuestas:
Ejemplo
program ifStatemensExample;
var a: integer;
begin
a := 50;
if a = 10 then begin
writeln("el valor de a es 10");
a := a + 1;
writeln("el valor de a es:", a);
end
else if a = 20 then begin
writeln("el valor de a es 20");
a := a * 2;
writeln("el valor de a es:", a);
end
else begin
writeln("el valor de a es diferente de 10 y 20");
a := a - 1;
writeln("el valor de a es:", a);
end
end.
salida
la salida será algo como:
minipas v.1.9.0
el valor de a es diferente de 10 y 20
el valor de a es: 49
A tener en cuenta:
Se recomienda usar un bloque begin/end, cuando se tenga dos ó más instrucciones en un bloque if-then, if-then-else etc…
Sentencias if anidadas
Siempre es legal anidar sentencias if-else, lo que significa que se puede utilizar una sentencia if o else if dentro de otra sentencia if o else if. Minipas permite anidar hasta cualquier nivel, sin embargo, las sentencias anidadas pueden volverse complicadas, así que es importante mantener el código legible y organizado.
La sintaxis de una instrucción if anidada es la siguiente:
if condicion_1 then
if condicion_2 then sentencias1;
else
sentencias2;
otro ejemplo:
if condicion_1 then
if condicion_2 then begin
sentencias1
sentencias2
end
else begin
if condicion_3 then begin
if condicion_4 then begin
sentencias3;
sentencias4;
end
end
end
A tener en cuenta:
Recuerda que las sentencias anidadas pueden volverse complicadas, así que es importante mantener el código legible y organizado.
Ejemplo
program NestedIfElseExample;
var
a, b: integer;
begin
a := 100;
b := 200;
if a = 100 then
if b = 200 then
writeln("el valor de a es 100 y el valor de b es 200");
end.
salida
la salida será algo como:
minipas v.1.9.0
el valor de a es 100 y el valor de b es 200
Uso de if Anidadas en Situaciones Prácticas
Las sentencias if anidadas son útiles, por ejemplo, en situaciones donde deban verificarse múltiples criterios para cumplir con ciertas condiciones lógicas. Esto puede incluir:
- Validaciones en entradas de usuario.
- Cálculos que dependen de diferentes rangos.
- Procesamiento de datos donde ciertos parámetros dependen de otros.
Consideraciones
- Legibilidad: Las sentencias anidadas pueden volverse complicadas, así que es importante mantener el código legible y organizado. si anidas mucho, considera el uso de bloques begin/end.
- Indentación: Usar una buena indentación ayuda a visualizar mejor la estructura anidada y la lógica del flujo del programa.
- Manejo de Errores: Las sentencias anidadas pueden dificultar la identificación de errores, así que es aconsejable descomponer problemas complejos en funciones más manejables cuando sea posible.
funciones
Una función es un grupo de sentencias que juntas realizan una tarea.
Definición de una función
Una declaración de función le indica al interprete el nombre, el tipo de retorno y los parámetros de una función. Una definición de función proporciona el cuerpo real de la función.
Las funciones pueden aceptar (ó no) parámetros (que son variables definidas en la cabecera de la función) y estos parámetros son utilizados para recibir valores al momento de invocar la función.
En Minipas, una función se define utilizando la palabra clave function.
La forma general de una definición de función es la siguiente:
ejemplo de función que acepta argumentos:
function nombre_funcion(param1: tipo1; param2: tipo2; ...): tipo_de_retorno;
// declaraciones locales usando `var`, si aplica
begin // <- el cuerpo de la funcion, comienza con 'begin'
sentencia1;
sentencia2;
...
return valor, ó sentencia
end // <- el cuerpo de la funcion, finaliza con 'end'
ejemplo de función que no acepta argumentos:
function nombre_funcion(): tipo_de_retorno;
// declaraciones locales usando `var`, si aplica
begin // <- el cuerpo de la funcion, comienza con 'begin'
sentencia1;
sentencia2;
...
return valor, ó sentencia
end // <- el cuerpo de la funcion, finaliza con 'end'
Parámetros: establecen el vínculo entre el programa de llamada y los identificadores de función, y también se denominan parámetros formales. Un parámetro es como un marcador de posición. Cuando se invoca una función, se pasa un valor al parámetro. Este valor se denomina parámetro real o argumento. La lista de parámetros se refiere al tipo, el orden y el número de parámetros de una función. El uso de dichos parámetros formales es opcional. Estos parámetros pueden tener un tipo de dato estándar, un tipo de datos definido por el usuario o un tipo de datos de subrango.
Argumento: por otro lado, es el valor real que se pasa a la función o procedimiento al momento de su invocación. Es el dato que ocupa la posición del parámetro definido en la cabecera.
resumiendo un poco:
- Parámetros son las variable en la declaración de la función.
- Argumentos son los valores reales pasado en la llamada, usados en la invocación de la función.
Tipo de retorno: todas las funciones deben devolver un valor, por lo que a todas las funciones se les debe asignar un tipo. El tipo de función es el tipo de datos del valor que devuelve la función. Puede ser un tipo estándar, escalar, definido por el usuario o de subrango, pero no puede ser un tipo estructurado.
Declaraciones locales: las declaraciones locales se refieren a las declaraciones de etiquetas, variables, que se aplican únicamente al cuerpo de la función.
Cuerpo de la función: contiene un conjunto de sentencias que definen lo que hace la función. Siempre debe estar entre las palabras reservadas begin y end. Es la parte de una función donde se realizan todos los cálculos.
Retorno: cada función termina con la palabra reservada return y una valor asociado a un tipo de dato ó una expresión.
Llamar a una función
Al crear una función, se define lo que debe hacer dicha función. Para utilizar una función, hay que llamarla(ó invocarla) para que realice la tarea definida. Cuando un programa llama a una función, el control del programa se transfiere a la función llamada, esta realiza la tarea definida y, cuando se ejecuta su instrucción de retorno (return), devuelve el control del programa, al programa principal.
Llamar/invocar a una función implica:
- usar el nombre definido para ella
- enviarle argumentos (si los acepta)
- esperar (ó no) una respuesta
// si la función recibe argumentos
nombre_funcion(arg1, arg2, ...);
// si la función NO recibe argumentos
nombre_funcion();
veamos un ejemplo
Ejemplo
program test_functions;
// nombre de la función, parametros y tipo de retorno
function sumar(a:integer; b:integer): integer;
// declaraciones locales
var c: integer;
//cuerpo de la función
begin
writeln("el valor de a es:", a);
writeln("el valor de b es:", b);
c := a + b;
writeln("el valor de c es:", c);
// valor ó sentencia de retorno
return c;
end // fin de la función
// bloque principal del programa
begin
writeln();
writeln("3 + 5 = ", sumar(3, 5)); // <- llamada a la función
writeln("10 + 20 = ", sumar(10, 20)); // <- llamada a la función
writeln();
sumar(2, 9); // <- llamada a la función
writeln();
end.
salida
la salida será algo como:
minipas v.1.9.0
el valor de a es: 3
el valor de b es: 5
el valor de c es: 8
3 + 5 = 8
el valor de a es: 10
el valor de b es: 20
el valor de c es: 30
10 + 20 = 30
el valor de a es: 2
el valor de b es: 9
el valor de c es: 11
A tener en cuenta:
Recuerda que las funciones (definidas usando function) siempre devuelven un valor.
valor de retorno
Como se especificó anteriormente, las funciones siempre devuelven un valor, asi que podemos “capturar” ese valor en una variable y hacer alguna operación ó simplemente mostralo.
Ejemplo
el mismo ejemplo sin comentarios, y omitiendo mostrar muchos valores por la consola.
program test_functions;
var resultado: integer;
function sumar(a:integer; b:integer): integer;
var c: integer;
begin
c := a + b;
return c;
end
begin
resultado := sumar(2, 9);
writeln("el resultado de la suma es:", resultado);
end.
salida
la salida será algo como:
minipas v.1.9.0
el resultado de la suma es: 11
Consideraciones
Definición Clara: Asegúrate de que la función tenga un propósito específico y bien definido.
Nombres descriptivos: Usa nombres significativos que reflejen la acción que realiza la función (por ejemplo, sumar).
Número de parámetros y argumentos: Los argumentos deben coincidir en número y tipo con los parámetros definidos en la función.
Limita el número de parámetros para mantener la simplicidad.
Valor de retorno: Especifica el tipo de retorno de la función claramente y asegúrate de que devuelve un valor adecuado.
Documentación: Comenta el código para explicar qué hace la función, sus parámetros y valor de retorno.
Evitando efectos secundarios: Trata de evitar modificar variables globales a menos que sea necesario; esto ayuda a mantener la función predecible.
Pruebas y validaciones: Implementa pruebas para garantizar que la función produzca los resultados esperados con varios datos de entrada.
Considera agregar validaciones de entrada para evitar errores.
Código modular: Divide la lógica del programa en funciones más pequeñas y manejables; esto facilita la lectura y el mantenimiento del código.
Anidamiento: Puedes llamar a otras funciones dentro de una función, pero ten cuidado con la profundidad anidada para no complicar la lógica.
Gestión de errores: Implementa manejo de errores donde sea necesario para evitar fallos inesperados durante la ejecución.
Recursividad: Si usas funciones recursivas, asegúrate de tener una condición de salida clara para evitar bucles infinitos.
procedimientos
Los procedimientos (a diferencia de las funciones) no devuelven un único valor, sino que realizan una serie de acciones, su propósito principal es ejecutar tareas específicas en lugar de calcular y retornar un valor único.
Definición de un procedimiento
Se define utilizando la palabra clave procedure. La forma general de la definición de un procedimiento es la siguiente:
ejemplo de un procedimiento que acepta argumentos:
procedure nombre_procedimiento(param1: tipo1; param2: tipo2; ...);
// declaraciones locales usando `var`, si aplica
begin // <- el cuerpo del procedimiento, comienza con 'begin'
sentencia1;
sentencia2;
...
end // <- el cuerpo del procedimiento, finaliza con 'end'
ejemplo de un procedimiento que no acepta argumentos:
procedure nombre_procedimiento();
// declaraciones locales usando `var`, si aplica
begin // <- el cuerpo del procedimiento, comienza con 'begin'
sentencia1;
sentencia2;
...
end // <- el cuerpo del procedimiento, finaliza con 'end'
Parámetros: establecen el vínculo entre el programa de llamada y los identificadores del procedimiento, y también se denominan parámetros formales. Un parámetro es como un marcador de posición. Cuando se invoca a un procedimiento, se pasa un valor al parámetro. Este valor se denomina parámetro real o argumento. La lista de parámetros se refiere al tipo, el orden y el número de parámetros de un procedimiento. El uso de dichos parámetros formales es opcional. Estos parámetros pueden tener un tipo de dato estándar, un tipo de datos definido por el usuario o un tipo de datos de subrango.
Argumento: por otro lado, es el valor real que se pasa al procedimiento al momento de su invocación. Es el dato que ocupa la posición del parámetro definido en la cabecera.
resumiendo un poco:
- Parámetros son las variable en la declaración del procedimiento.
- Argumentos son los valores reales pasado en la llamada, usados en la invocación del procedimiento.
Declaraciones locales: las declaraciones locales se refieren a las declaraciones de etiquetas, variables, que se aplican únicamente al cuerpo del procedimiento.
Cuerpo del procedimiento: contiene un conjunto de sentencias que definen lo que hace el procedimiento. Siempre debe estar entre las palabras reservadas begin y end. Es la parte de un procedimiento donde se realizan todos los cálculos.
Llamar a un procedimiento
Al crear un procedimiento, se define lo que debe hacer dicho procedimiento. Para utilizar un procedimiento, hay que llamarlo(ó invocarlo) para que realice la tarea definida. Cuando un programa llama a un procedimiento, el control del programa se transfiere al procedimiento llamado, este realiza la tarea definida y, cuando se ejecuta su ultima instrucción, devuelve el control del programa, al programa principal.
Llamar/invocar a un procedimiento implica:
- usar el nombre definido para él
- enviarle argumentos (si los acepta)
// si el procedimiento recibe argumentos
nombre_procedimiento(arg1, arg2, ...);
// si el procedimiento NO recibe argumentos
nombre_procedimiento();
veamos un ejemplo
Ejemplo
program test_procedures;
procedure saludo(nombre: string);
begin
writeln("Hola", nombre, "saludos desde un procedimiento");
end
begin
saludo("Pedro");
end.
salida
la salida será algo como:
minipas v.1.9.0
Hola Pedro saludos desde un procedimiento
A tener en cuenta:
Recuerda que los procedimientos (definidos usando procedure) NO devuelven un valor.
Consideraciones
Definición clara: Asegúrate de que el procedimiento tenga un propósito específico y bien definido.
Nombres descriptivos: Usa nombres significativos que reflejen la acción que realiza el procedimiento (por ejemplo, saludo).
Número de parámetros y argumentos: Los argumentos deben coincidir en número y tipo con los parámetros definidos en el procedimiento.
Limita el número de parámetros para mantener la simplicidad.
Valor de retorno: Especifica el tipo de retorno del procedimiento claramente.
Documentación: Comenta el código para explicar qué hace el procedimiento, sus parámetros y en general que hace.
Evitando efectos secundarios: Trata de evitar modificar variables globales a menos que sea necesario; esto ayuda a mantener el procedimiento predecible.
Pruebas y validaciones: Implementa pruebas para garantizar que el procedimiento produzca los resultados esperados con varios datos de entrada.
Considera agregar validaciones de entrada para evitar errores.
Código modular: Divide la lógica del programa en funciones y procedimientos más pequeños y manejables; esto facilita la lectura y el mantenimiento del código.
Anidamiento: Puedes llamar a otras funciones y procedimientos dentro de un procedimiento, pero ten cuidado con la profundidad anidada para no complicar la lógica.
Gestión de errores: Implementa manejo de errores donde sea necesario para evitar fallos inesperados durante la ejecución.
Recursividad: Si usas procedimientos recursivos, asegúrate de tener una condición de salida clara para evitar bucles infinitos, La clave está en gestionar adecuadamente las condiciones de salida para asegurar que la recursión se detenga de manera adecuada.
Ciclos
En general, las sentencias se ejecutan secuencialmente: primero se ejecuta la primera sentencia de una función/procedimiento, seguida de la segunda, y así sucesivamente. Los lenguajes de programación proporcionan diversas estructuras de control que permiten rutas de ejecución más complejas.
Los bucles (ó ciclos) son otra estructura de control de flujo, que nos permite ejecutar algunas partes del código varias veces.
En este capítulo veremos tres tipos de bucles, disponibles en Minipas:
- ciclo for: se ejecuta un número determinado de veces.
- ciclo while: se ejecuta mientras se cumpla una condición.
- ciclo repeat: ejecuta el bloque de código al menos una vez y luego continúa repitiéndolo hasta que se cumpla una condición.
for
El ciclo for for-do) se utiliza para iterar sobre un rango específico de valores. Es ideal cuando se conoce de antemano cuántas veces se debe repetir el bloque de código.
La sintaxis del bucle for-do es la siguiente:
to
La palabra clave to indica que el ciclo se ejecutará desde un valor inicial hasta un valor final, incrementando la variable de control en cada iteración.
for nombre_variable := valor_inicial to valor_final do
Sentencia;
usando un bloque begin/end (recomendado)
for nombre_variable := valor_inicial to valor_final do
begin
Sentencia1;
Sentencia2;
...
end
Donde:
nombre_variable especifica una variable de tipo ordinal, denominada variable de control o variable índice; los valores valor_inicial y valor_final son valores que puede tomar la variable de control; y Sentencia (ó Sentencia1, Sentencia2 …) es el cuerpo del bucle for-do, que puede ser una instrucción simple o un grupo de instrucciones.
A tener en cuenta:
La variable nombre_variable debe ser declarada antes de ser utilizada en el ciclo for.
Para el ciclo/bucle for se recomienda utilizar siempre un bloque begin/end.
Ejemplo
cuando existe una sola sentencia, se puede utilizar el ciclo for-do en una linea.
for i := 1 to 5 do writeln("hello foor loop in minipas", i);
sin embargo, por legibilidad, siempre recomendaremos el uso de un bloque begin/end.
for i := 1 to 5 do
begin
writeln("hello foor loop in minipas", i);
end
salida
la salida para ambos casos, será algo como:
minipas v.1.9.0
hello foor loop in minipas 1
hello foor loop in minipas 2
hello foor loop in minipas 3
hello foor loop in minipas 4
hello foor loop in minipas 5
down-to
La palabra clave downto se utiliza para iterar de manera decreciente, comenzando desde un valor final hasta un valor inicial, decrementando la variable de control en cada iteración.
for nombre_variable := valor_final downto valor_inicial do
Sentencia;
usando un bloque begin/end (recomendado)
for nombre_variable := valor_final downto valor_inicial do
begin
Sentencia1;
Sentencia2;
...
end
Donde:
nombre_variable especifica una variable de tipo ordinal, denominada variable de control o variable índice; los valores valor_inicial y valor_final son valores que puede tomar la variable de control; y Sentencia (ó Sentencia1, Sentencia2 …) es el cuerpo del bucle for-do, que puede ser una instrucción simple o un grupo de instrucciones.
A tener en cuenta:
La variable nombre_variable debe ser declarada antes de ser utilizada en el ciclo for.
Para el ciclo/bucle for se recomienda utilizar siempre un bloque begin/end.
Ejemplo
cuando existe una sola sentencia, se puede utilizar el ciclo for-do en una linea.
for i := 5 downto 1 do writeln("hello foor loop in minipas", i);
sin embargo, por legibilidad, siempre recomendaremos el uso de un bloque begin/end.
for i := 5 downto 1 do
begin
writeln("hello foor loop in minipas", i);
end
salida
la salida para ambos casos, será algo como:
minipas v.1.9.0
hello foor loop in minipas 5
hello foor loop in minipas 4
hello foor loop in minipas 3
hello foor loop in minipas 2
hello foor loop in minipas 1
Recomendaciones
Definición clara de los límites: Asegúrate de que los límites de inicio y fin sean claros y correctos para evitar bucles que no se comportan como se esperaba.
Evitar bucles infinitos: Verifica que las condiciones de terminación de tus ciclos estén bien definidas para evitar que tu programa se quede atrapado en un bucle infinito.
Incrementos y decrementos correctos: En ciclos for, asegúrate de que el incremento (usando to) o el decremento (usando downto) sean apropiados para la lógica del programa.
Uso de variables de control: Mantén el uso de la variable de control (como i) simple y único dentro del ciclo para evitar confusiones y errores en la lógica.
Comentarios claros: Agrega comentarios para explicar la lógica detrás de los ciclos, especialmente si tienen condiciones complejas o no evidentes.
Ciclos anidados: Si utilizas ciclos anidados, mantén la claridad en el control de las variables para evitar errores lógicos y verifica que la lógica sea comprensible.
Preferir for para iteraciones contables: Usa for-do cuando sepas de antemano cuántas veces necesitas iterar, ya que es más legible y fácil de entender.
Evaluar el rendimiento: Considera el impacto en el rendimiento de bucles anidados o extensos, y optimiza cuando sea necesario para evitar problemas de eficiencia.
Pruebas exhaustivas: Realiza pruebas con diferentes valores de entrada para asegurar que los ciclos funcionan como se espera en todos los casos, especialmente en los límites.
Evitar lógica complicada dentro del ciclo: Mantén las instrucciones dentro del ciclo simples y directas. Si la lógica es compleja, considera extraerla en funciones o procedimientos separados.
while
El ciclo while(while-do) se repite mientras la condición especificada sea verdadera. Es útil cuando no se conoce de antemano el número de iteraciones.
La sintaxis del bucle while-do es la siguiente:
while condición do
begin
Sentencia1;
Sentencia2;
...
end
Condición: La expresión booleana que se evalúa antes de cada iteración. Si la condición es verdadera, el bloque de instrucciones se ejecuta. Si es falsa, el ciclo termina.
Recuerda que debes controlar la condición, para evitar caer en un ciclo infinito.
A tener en cuenta:
Aunque es posible hacer que un ciclo while ocupe una sola línea:
while condición do Sentencia;
se recomienda siempre utilizar un bloque begin/end.
Usar un estilo claro y mantener una buena legibilidad del código es fundamental para evitar errores en la lógica tu programa.
Ejemplo
- ejemplo 1:
⚠️ Este ejemplo causa un bucle infinito, debido a que la sentencia termina en el punto y coma (;) despues de writeln y no al final del incremento de i;
program test_loops;
var i: integer;
begin
i := 1; // inicializamos el valor de `i` en 1
// este ejemplo causa un bucle infinito ⚠️
while i <= 5 do writeln("el número es:", i); i := i + 1;
end.
por eso siempre se recomienda el uso de un bloque begin/end.
- ejemplo 2:
program test_loops;
var i: integer;
begin
i := 1; // inicializamos el valor de `i` en 1
while i <= 5 do
begin
writeln("el número es:", i);
i := i + 1; // incrementamos `i`
end
end.
en el ejemplo anterior, la condición i <= 5 se evalúa en cada iteración del ciclo, y al final del bloque del ciclo se utiliza i := i + 1; como control, para poder validar la condición y poder salir del ciclo while-do.
salida
la salida será algo como:
minipas v.1.9.0
el número es: 1
el número es: 2
el número es: 3
el número es: 4
el número es: 5
Ejemplo
hagamos el clasico ejemplo de las tablas de multiplicar:
program test_loops;
var i,j: integer;
var resultado: integer;
begin
writeln("tablas de multiplicar");
writeln();
// inicializamos el valor de `i` en 1
i := 1;
while (i <= 10) do // <- primer ciclo while
begin
// inicializamos el valor de `j` en 1
// en cada iteración del ciclo principal
j := 1;
while j <= 10 do // <- ciclo while anidado
begin
resultado := i * j;
writeln(i, " x ", j, " = ", resultado);
j := j + 1; // incrementamos `j`
end
writeln("----------------------");
i := i + 1; // incrementamos `i`
end
end.
Aquí utilizamos ciclos anidados!.
salida
la salida será algo como:
minipas v.1.9.0
tablas de multiplicar
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
1 x 5 = 5
1 x 6 = 6
1 x 7 = 7
1 x 8 = 8
1 x 9 = 9
1 x 10 = 10
----------------------
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
2 x 10 = 20
----------------------
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
3 x 10 = 30
----------------------
...
Recomendaciones
Evitar bucles infinitos: Verifica que las condiciones de terminación de tus ciclos estén bien definidas para evitar que tu programa se quede atrapado en un bucle infinito.
Uso de variables de control: Mantén el uso de la variable de control (como i) simple y único dentro del ciclo para evitar confusiones y errores en la lógica.
Comentarios claros: Agrega comentarios para explicar la lógica detrás de los ciclos, especialmente si tienen condiciones complejas o no evidentes.
Ciclos anidados: Si utilizas ciclos anidados, mantén la claridad en el control de las variables para evitar errores lógicos y verifica que la lógica sea comprensible.
Evaluar el rendimiento: Considera el impacto en el rendimiento de bucles anidados o extensos, y optimiza cuando sea necesario para evitar problemas de eficiencia.
Pruebas exhaustivas: Realiza pruebas con diferentes valores de entrada para asegurar que los ciclos funcionan como se espera en todos los casos, especialmente en los límites.
Evitar lógica complicada dentro del ciclo: Mantén las instrucciones dentro del ciclo simples y directas. Si la lógica es compleja, considera extraerla en funciones o procedimientos separados.
repeat
A diferencia de los bucles for y while, que comprueban la condición del bucle en la parte superior del mismo, el bucle repeat … until comprueba su condición en la parte inferior del bucle.
Un ciclo/bucle repeat … until es similar a un bucle while, excepto que este garantiza que se ejecutará al menos una vez, y luego continúa repitiéndolo hasta que se cumpla una condición.
La sintaxis del bucle repeat … until es la siguiente:
repeat
Setencia1;
Setencia2;
...
SetenciaN;
until condición;
Observa que la expresión condicional aparece al final del bucle, por lo que las instrucciones dentro, se ejecutan una vez antes de que se compruebe la condición.
Si la condición es falsa, el flujo de control vuelve al principio para repetirse, y las instrucciones del bucle se ejecutan de nuevo. Este proceso se repite hasta que la condición dada se vuelve verdadera.
A tener en cuenta:
Recuerda que debes controlar la condición, para evitar caer en un ciclo infinito.
El ciclo repeat … until no necesariamente necesita de un bloque begin/end.
Usar un estilo claro y mantener una buena legibilidad del código es fundamental para evitar errores en la lógica tu programa.
Ejemplo
program test_loops;
var
i, j: integer;
resultado: integer;
begin
writeln("Tablas de multiplicar");
writeln();
// Inicializamos el valor de `i` en 1
i := 1;
repeat
// Inicializamos el valor de `j` en 1
j := 1;
repeat
resultado := i * j;
writeln(i, " x ", j, " = ", resultado);
j := j + 1; // incrementamos `j`
until j > 10; // condición de terminación para el ciclo anidado
writeln("----------------------");
i := i + 1; // incrementamos `i`
until i > 10; // condición de terminación para el ciclo principal
end.
salida
la salida será algo como:
minipas v.1.9.0
Tablas de multiplicar
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
1 x 5 = 5
1 x 6 = 6
1 x 7 = 7
1 x 8 = 8
1 x 9 = 9
1 x 10 = 10
----------------------
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
2 x 10 = 20
----------------------
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
3 x 10 = 30
----------------------
...
A tener en cuenta:
Recuerda que debes controlar la condición, para evitar caer en un ciclo infinito.
Recomendaciones
Evitar bucles infinitos: Verifica que las condiciones de terminación de tus ciclos estén bien definidas para evitar que tu programa se quede atrapado en un bucle infinito.
Uso de variables de control: Mantén el uso de la variable de control (como i) simple y único dentro del ciclo para evitar confusiones y errores en la lógica.
Comentarios claros: Agrega comentarios para explicar la lógica detrás de los ciclos, especialmente si tienen condiciones complejas o no evidentes.
Ciclos anidados: Si utilizas ciclos anidados, mantén la claridad en el control de las variables para evitar errores lógicos y verifica que la lógica sea comprensible.
Evaluar el rendimiento: Considera el impacto en el rendimiento de bucles anidados o extensos, y optimiza cuando sea necesario para evitar problemas de eficiencia.
Pruebas exhaustivas: Realiza pruebas con diferentes valores de entrada para asegurar que los ciclos funcionan como se espera en todos los casos, especialmente en los límites.
Evitar lógica complicada dentro del ciclo: Mantén las instrucciones dentro del ciclo simples y directas. Si la lógica es compleja, considera extraerla en funciones o procedimientos separados.
break y continue
break
Es una instrucción que se utiliza para salir inmediatamente de un ciclo (como for, while o repeat…until). Cuando se utiliza, control de flujo se transfiere a la siguiente línea después del ciclo que contiene la instrucción break.
program breakExample;
var a: integer;
begin
a := 10;
while a < 20 do
begin
writeln("el valor de a es:", a);
a:= a+1;
if a > 15 then
break; // <- uso de break
end
end.
la salida será algo como
minipas v.1.9.0
el valor de a es: 10
el valor de a es: 11
el valor de a es: 12
el valor de a es: 13
el valor de a es: 14
el valor de a es: 15
continue
Esta instrucción se utiliza para saltar directamente a la siguiente iteración de un ciclo. Al encontrar un continue, el resto del código en la iteración actual se omite y se pasa a la siguiente.
En el bucle for, la instrucción continue hace que se ejecuten las partes de prueba condicional e incremento del bucle. En los bucles while y repeat...until, la instrucción continue hace que el control del programa pase a las pruebas condicionales.
program continueExample;
var i: integer;
begin
for i := 1 to 10 do
begin
if i mod 2 = 0 then
continue; // salta la iteración para números pares
writeln("número impar:", i);
end
end.
la salida será algo como
minipas v.1.9.0
número impar: 1
número impar: 3
número impar: 5
número impar: 7
número impar: 9
goto
⚠️ Minipas no admite la sentencia goto.
Recomendaciones
al utilizar break:
Claridad: Usa break solamente cuando sea necesario salir de un ciclo prematuramente, demasiados break pueden hacer que el flujo del código sea confuso.
Uso Moderado: si encuentras que estás usando break frecuentemente, considera reestructurar el ciclo o la lógica para que sea más clara.
Documenta su Uso: comenta por qué es necesario para que futuros lectores del código comprendan la lógica detrás de su uso.
al utilizar continue:
Claridad: usa continue para mejorar la legibilidad del código al evitar anidamientos excesivos de condicionales dentro de un ciclo.
Cuidado con Saltos: asegúrate de que utilizar continue no cause que se omitan acciones críticas en el ciclo.
Comentarios: similar a break, documenta el uso de continue, haciendo explícito el motivo de saltar ciertas iteraciones.
Funciones integradas
Las funciones integradas (o built-in functions) son funciones predefinidas que están disponibles en Minipas sin necesidad de que el programador las defina explícitamente. Estas funciones permiten realizar operaciones comunes y son parte del runtime del lenguaje, facilitando tareas de programación frecuentes.
Características
Disponibilidad: Están siempre accesibles durante la programación sin necesidad de definiciones adicionales o importaciones.
Tipos de Operaciones: Realizan una variedad de tareas, incluyendo:
- Manipulación de cadenas.
- Operaciones matemáticas.
- Entrada y salida de datos.
- Conversión de tipos de datos.
y muchas cosas más!.
Ventajas
- Ahorro de Tiempo: Permiten realizar tareas complejas sin necesidad de codificarlas desde cero.
- Reducción de Errores: Al utilizar funciones ya probadas y testeadas, se minimizan los errores en el código.
- Facilidad de Mantenimiento: El uso de funciones integradas puede hacer el código más limpio y fácil de mantener.
Lista de funciones integradas
A continuación se describe la lista de funciones integradas en Minipas.
entrada/salida
- writeln: Escribe un texto en la salida estándar y añade un salto de línea al final.
writeln("hola mundo en minipas!");
- write: Escribe un texto en la salida estándar sin añadir un salto de línea.
write("esto");
write("va");
write("en");
write("la");
write("misma");
write("linea");
// la salida será algo como:
esto va en la misma linea
- readln: Lee una línea de texto de la entrada estándar y la asigna a una variable.
writeln("Escriba un nombre");
name:= readln();
writeln("el nombre es:", name);
- format: Da formato a cadenas de texto, permitiendo la inclusión de variables de manera estructurada.
constantes
- PI: Constante que representa el valor de π (pi), aproximadamente 3.141592653589793.
writeln("el valor de PI es:", PI);
- E: Constante que representa el número e (conocido en ocasiones como número de Euler o constante de Napier), la base del logaritmo natural, aproximadamente 2.718281828459045.
writeln("el valor de E es:", E);
funciones matemáticas básicas
- pow: Calcula la potencia de un número dado, elevando una base a un exponente.
a := 2;
b := 8;
writeln("2^8 = ", pow(a, b));
- abs: Devuelve el valor absoluto de un número, eliminando cualquier signo negativo.
writeln("abs(0)", abs(0));
writeln("abs(-1)", abs(-1));
writeln("abs(-1.25)", abs(-1.25));
writeln("abs(1.234)", abs(1.234));
funciones trigonométricas
- sin: Calcula el seno de un ángulo dado en radianes.
writeln("sin(-1.234)", sin(-1.234));
- cos: Calcula el coseno de un ángulo dado en radianes.
writeln("cos(-1.234)", cos(-1.234));
- tan: Calcula la tangente de un ángulo dado en radianes.
writeln("tan(PI/4) = ", tan(PI/4));
- cot: Calcula la cotangente de un ángulo dado en radianes.
writeln("cot(PI/4) = ", cot(PI/4));
- asin: Calcula el arco seno, retornando el ángulo correspondiente a un valor dado.
writeln("asin(1) = ", asin(1));
- acos: Calcula el arco coseno, retornando el ángulo correspondiente a un valor dado.
writeln("acos(0) = ", acos(0));
- atan: Calcula el arco tangente, retornando el ángulo correspondiente a un valor dado.
writeln("atan(1) = ", atan(1));
funciones logarítmicas y exponenciales
- exp: Calcula el valor de e elevado a la potencia de un número.
writeln("exp(1) = ", exp(1));
- ln: Devuelve el logaritmo natural (base e) de un número.
writeln("ln(E) = ", ln(E));
- log10: Calcula el logaritmo en base 10 de un número.
writeln("log10(100) = ", log10(100));
- sqrt: Devuelve la raíz cuadrada de un número.
writeln("sqrt(16) = ", sqrt(16));
funciones auxiliares
- floor: Retorna el mayor número entero menor o igual al número dado.
writeln("floor(3.7) = ", floor(3.7));
- ceil: Retorna el menor número entero mayor o igual al número dado.
writeln("ceil(3.2) = ", ceil(3.2));
- round: Redondea un número al entero más cercano.
writeln("round(2.6) = ", round(2.6));
- trunc: Elimina la parte decimal de un número, retornando solo la parte entera.
writeln("trunc(-2.71828) = ", trunc(-2.71828));
- fract: Devuelve la parte fraccionaria de un número.
⚠️ missing example
- max: Retorna el mayor de dos o más números proporcionados.
writeln("max(3,7) = ", max(3,7));
- min: Retorna el menor de dos o más números proporcionados.
writeln("min(3,7) = ", min(3,7));
- sign: Devuelve el signo de un número: 1 si es positivo, -1 si es negativo, y 0 si es cero.
writeln("sign(-5) = ", sign(-5));
writeln("sign(0) = ", sign(0));
writeln("sign(7) = ", sign(7));
sistema
- random: Genera un número aleatorio dentro de un rango especificado, el valor debe ser mayor que cero (0)
writeln("funcion random 1:", random(0)); // <- genera un error ⚠️
writeln("funcion random 2:", random(1));
writeln("funcion random 3:", random(10));
writeln("funcion random 4:", random(1.234));
- exit: Termina la ejecución del programa en cualquier punto.
program testSys;
begin
writeln("usando el modulo sys");
exit();
writeln("terminado"); // nunca se ejecuta
end.
- clrscr: Limpia la pantalla de la consola, eliminando todo el texto visible.
program testSys;
begin
clrscr();
end.
- typeinfo: Proporciona información sobre el tipo de dato de una variable en tiempo de ejecución.
writeln("uso de Integer:", typeinfo(123));
writeln("uso de toString:", typeinfo(123.toString()));
fechas
- date: Retorna la fecha actual del sistema en un formato específico.
writeln("Fecha actual:", date());
- time: Retorna la hora actual del sistema en un formato específico.
writeln("Hora actual:", time());
- date_time: Devuelve la fecha y hora actuales combinadas en un solo valor.
writeln("Fecha y hora:", date_time());
cadenas de caracteres
- len: Retorna la longitud de una cadena de caracteres.
cadena:= " Anita lava la tinA ";
total := len(cadena);
writeln("la cantidad de caracteres es (len):", total);
- concat: permite unir dos ó más valores en una cadena de caracteres.
writeln("concatenar:", concat("caracteres", "y", PI, "ademas", "de", 1.234));
conversiones de tipos
- to_int: Convierte un valor a su representación entera.
writeln("Ingresa un número entero");
num1 := to_int(readln());
- to_real: Convierte un valor a su representación de punto flotante (real).
writeln("Ingresa un número con parte decimal");
num2 := to_real(readln());
- to_str: Convierte un valor a su representación como cadena de texto.
writeln(42.to_str());
writeln(True.to_str());
pruebas
- assert: Verifica si una condición es verdadera y genera un error si no lo es.
assert((4 % 2) = 0);
- assert_equals: Compara dos valores y asegura que sean iguales, generando un error si no lo son.
assert_equals(1, 1);
assert_equals(True, False);
- panic: Termina el programa y despliega un mensaje de error en caso de una situación crítica, espera un argumento.
program testSys;
begin
panic("error al salir!");
writeln("terminado"); // nunca se ejecuta
end.
Testing
Aunque Turbo Pascal V7 (del cual se inspira Minipas) no existía la función assert, en Minipas se incluye para comprobar condiciones y manejar errores de una manera más controlada en tu programa.
A tener en cuenta:
El uso de assert y de assert_equals causan pánico (el programa se detiene) si las condiciones no se cumplen:
assert
verifica que una condición sea verdadera. Si la condición no se cumple, se lanza una excepción y se detiene la ejecución del programa, indicando que se ha producido un error.
Ejemplo
program testExample;
var a,b:integer;
begin
a:= 1;
b:= 1;
assert(2 * 2 = 4);
assert(a<>b); // <- falla
end.
Salida
la salida es algo como:
minipas v.1.9.0
thread 'main' panicked at src\runtime\std_lib\testing.rs:11:13:
Assertion failed: expected `true`, got `false`
assert_equals
compara dos valores: uno esperado y otro real. Si los valores no son iguales, se lanza una excepción y se detiene la ejecución del programa, indicando que se ha producido un error.
Ejemplo
program testSys;
var msg1: string;
begin
msg1 := "Hola";
assert_equals(msg1.lower(), "hola");
writeln();
writeln("el valor de PI es:", PI);
assert_equals(PI, 3.141592); // <- falla
end.
Salida
la salida es algo como:
minipas v.1.9.0
el valor de PI es: 3.141592653589793
thread 'main' panicked at src\runtime\std_lib\testing.rs:46:9:
Assertion failed: expected left: `3.141592653589793`, got right: `3.141592`
Apéndice I: Palabras clave
Minipas no tiene palabras claves en sí, sin embargo hace uso intensivo de las siguientes:
integer
real
boolean
byte
begin
div
else
if
mod
not
program
repeat
string
then
until
var
while
True
False
writeln
write
readln
do
to
downto
end
for
function
procedure
nil
Guía de estilo
Minipas 1.9.0
Este documento define el estilo oficial de código para Minipas. Su objetivo es garantizar que todos los programas escritos en Minipas sean:
- claros
- consistentes
- fáciles de leer
- simples de mantener
- didácticos
La guía se inspira en prácticas de Free Pascal, GNU Pascal, Object Pascal y otras guías de estilo.
1. Filosofía del lenguaje
Minipas toma muchas caracteristicas y referencias del lenguage Pascal, sin embargo, hay que recalcar algunas cosas:
-
⚠️ MiniPas no busca ser compatible con Pascal, Turbo Pascal V7 ó FreePascal: muchas características de Pascal no están soportadas.
-
MiniPas es un lenguaje interpretado, inspirado en Turbo Pascal V7, diseñado para ser sencillo, educativo y fácil de usar, la gran mayoría (si no todos…) de los dialectos de Pascal son compilados.
-
Pascal es un lenguaje que no distingue entre mayúsculas y minúsculas (Case Insensitive), lo que significa que puedes escribir tus variables, funciones y procedimientos con cualquiera de las dos. En Minipas no se acepta esto, todas las palabras claves deben escribirse en minúsculas, salvo muy pequeñas excepciones.
-
En minipas, cada sentencia debe terminar en punto y coma (
;). -
☢️ MiniPas Es un lenguaje experimental y minimalista.
-
Minipas es un lenguaje minimalista y educativo, por lo que la guía enfatiza:
- simplicidad sobre optimización
- claridad sobre trucos
- coherencia sobre preferencias personales
Cuando existan dudas, elegir siempre lo más legible.
2. Organización de archivos
2.1 Un archivo, un programa
Cada archivo de Minipas debe contener un único programa o módulo.
2.2 Nombre del archivo
Utilizar siempre minúsculas y evitar espacios:
calculadora.mp
mi_programa.mp
2.3 Estructura básica del archivo
Un archivo debe seguir este orden lógico:
# Comentarios iniciales / propósito
# Declaraciones globales (si las hay)
# Programa principal
Mantener el archivo limpio y sin secciones huérfanas.
3. Estilo de nombres
Minipas adopta un estilo snake_case simple, consistente y fácil de leer.
3.1 Variables
- minúsculas
- palabras separadas con
_ - nombres descriptivos
Ejemplos:
contador
suma_total
nombre_usuario
3.2 Constantes
⚠️ Minipas no admite constantes, cuando llegue el momento…
- MAYÚSCULAS
- separadas por
_
Ejemplo:
MAX_INTENTOS = 3;
PI = 3.14159;
3.3 Funciones / procedimientos
Igual que las variables:
leer_archivo();
calcular_area(base, altura);
3.4 Boleanos
De ser necesario, preferir nombres que indiquen verdadero/falso:
es_valido
tiene_error
modo_debug
4. Formato e indentación
4.1 Indentación estándar
Usar 2 espacios por nivel. No usar tabs.
Ejemplo:
if x > 0 then
writeln("positivo");
4.2 Líneas
- longitud recomendada: máximo 120 caracteres
- sin espacios al final
4.3 Espacios alrededor de operadores
Correcto:
a := b + c;
x := y * 2;
Incorrecto:
a:=b+c;
4.4 Paréntesis
Sin espacios internos:
Correcto:
imprimir(x + 1);
Incorrecto:
imprimir( x + 1 );
5. Bloques y estructuras de control
5.1 Bloques siempre multilínea
Siempre abrir un bloque en la línea siguiente.
Correcto:
program test_loops;
var i: integer;
begin
i := 1;
while i <= 5 do
begin
writeln("el número es:", i);
i := i + 1;
end
end.
Incorrecto:
program test_loops;
var i: integer;
begin
while i <= 5 do writeln("el número es:", i); i := i + 1;
end.
5.2 Estructura de control estándar
If:
if condicion then
Sentencia1;
else
Sentencia2;
Bucle:
while condicion do
begin
Sentencia1;
Sentencia2;
...
SentenciaN;
end
5.3 Evitar goto
⚠️ Minipas no admite la sentencia goto.
6. Comentarios
6.1 Comentarios de línea
Usar //.
// Este bucle acumula el total
6.2 Comentar el por qué, no el qué
❌ No útil:
// suma dos números
suma := a + b;
✔ Mejor:
// Reiniciamos suma para evitar arrastre de valores previos
suma := a + b;
6.3 Comentarios de bloque
Permitido para documentación o explicaciones largas:
{
Este módulo valida el archivo de entrada,
convierte el contenido a una estructura útil
y luego ejecuta el programa principal.
}
7. Buenas prácticas del lenguaje
7.1 Código simple y claro
Evitar expresiones complejas. Evitar magia o algoritmos innecesariamente enredados.
7.2 No duplicar código
Extraer funciones cuando sea posible.
7.3 Evitar efectos colaterales ocultos
Una función debería hacer solo una cosa.
7.4 Inicializar variables
No depender de valores implícitos.
7.5 Manipulación defensiva
Comprobar casos especiales si aplica (divisiones, rangos, etc.).
8. Ejemplos oficiales
8.1 Ejemplo completo
{
La sucesión de Fibonacci es una sucesión `Fn` de números
naturales definida de forma recursiva.
- https://www.calculatorsoup.com/calculators/discretemathematics/fibonacci-calculator.php
- https://rosettacode.org/wiki/Fibonacci_sequence
}
program test_fibonacci;
var numero, resultado: integer;
function fibonacci(num:integer): integer;
begin
if num < 2 then
return num;
return fibonacci(num-1) + fibonacci(num-2);
end
begin
writeln("calcular numeros de fibonacci");
writeln("Introduce un número entero (no muy grande)");
numero := to_int(readln());
resultado := fibonacci(numero);
writeln("el fibonacci de", numero, "es", resultado);
end.
9. Errores comunes a evitar
- nombres como
x,t,c1sin contexto - bloques en una sola línea
- comentarios redundantes
- confiar en comportamiento no definido
- mezclar estilos
- indentación inconsistente
10. Resumen rápido (cheat-sheet)
- Indentación: 2 espacios
- Nombres: snake_case
- Constantes: cuando se soporten serán en MAYÚSCULAS
- Bloques: siempre multilínea
- Comentarios: explicar el porqué
- Longitud de línea: 120 caracteres
- Priorizar: claridad, simpleza, consistencia