Merge branch 'main' of https://alm.pragmatismo.com.br/generalbots/gbserver
All checks were successful
GBCI / build (push) Successful in 7m22s

This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2025-10-03 08:04:56 -03:00
commit 2d15133555
5 changed files with 1442 additions and 51 deletions

201
docs/keywords/PROMPT.md Normal file
View file

@ -0,0 +1,201 @@
# Modelo de Prompt para Aprendizado de BASIC em Markdown
## 🎯 **ESTRUTURA PARA APRENDIZ DE BASIC**
```
**CONCEITO BASIC:**
[Nome do conceito ou comando]
**NÍVEL:**
☐ Iniciante ☐ Intermediário ☐ Avançado
**OBJETIVO DE APRENDIZADO:**
[O que você quer entender ou criar]
**CÓDIGO EXEMPLO:**
```basic
[Seu código ou exemplo aqui]
```
**DÚVIDAS ESPECÍFICAS:**
- [Dúvida 1 sobre o conceito]
- [Dúvida 2 sobre sintaxe]
- [Dúvida 3 sobre aplicação]
**CONTEXTO DO PROJETO:**
[Descrição do que está tentando fazer]
**RESULTADO ESPERADO:**
[O que o código deve fazer]
**PARTES QUE NÃO ENTENDE:**
- [Trecho específico do código]
- [Mensagem de erro]
- [Lógica confusa]
```
---
## 📚 **EXEMPLO PRÁTICO: LOOP FOR**
```
**CONCEITO BASIC:**
LOOP FOR
**NÍVEL:**
☒ Iniciante ☐ Intermediário ☐ Avançado
**OBJETIVO DE APRENDIZADO:**
Entender como criar um contador de 1 a 10
**CÓDIGO EXEMPLO:**
```basic
10 FOR I = 1 TO 10
20 PRINT "Número: "; I
30 NEXT I
```
**DÚVIDAS ESPECÍFICAS:**
- O que significa "NEXT I"?
- Posso usar outras letras além de "I"?
- Como fazer contagem regressiva?
**CONTEXTO DO PROJETO:**
Estou criando um programa que lista números
**RESULTADO ESPERADO:**
Que apareça: Número: 1, Número: 2, etc.
**PARTES QUE NÃO ENTENDE:**
- Por que precisa do número 10 na linha 10?
- O que acontece se esquecer o NEXT?
```
---
## 🛠️ **MODELO PARA RESOLVER ERROS**
```
**ERRO NO BASIC:**
[Mensagem de erro ou comportamento estranho]
**MEU CÓDIGO:**
```basic
[Coloque seu código completo]
```
**LINHA COM PROBLEMA:**
[Linha específica onde ocorre o erro]
**COMPORTAMENTO ESPERADO:**
[O que deveria acontecer]
**COMPORTAMENTO ATUAL:**
[O que está acontecendo de errado]
**O QUE JÁ TENTEI:**
- [Tentativa 1 de correção]
- [Tentativa 2]
- [Tentativa 3]
**VERSÃO DO BASIC:**
[QBASIC, GW-BASIC, FreeBASIC, etc.]
```
---
## 📖 **MODELO PARA EXPLICAR COMANDOS**
```
**COMANDO:**
[Nome do comando - ex: PRINT, INPUT, GOTO]
**SYNTAX:**
[Como escrever corretamente]
**PARÂMETROS:**
- Parâmetro 1: [Função]
- Parâmetro 2: [Função]
**EXEMPLO SIMPLES:**
```basic
[Exemplo mínimo e funcional]
```
**EXEMPLO PRÁTICO:**
```basic
[Exemplo em contexto real]
```
**ERROS COMUNS:**
- [Erro frequente 1]
- [Erro frequente 2]
**DICA PARA INICIANTES:**
[Dica simples para não errar]
**EXERCÍCIO SUGERIDO:**
[Pequeno exercício para praticar]
```
---
## 🎨 **FORMATAÇÃO MARKDOWN PARA BASIC**
### **Como documentar seu código em .md:**
```markdown
# [NOME DO PROGRAMA]
## 🎯 OBJETIVO
[O que o programa faz]
## 📋 COMO USAR
1. [Passo 1]
2. [Passo 2]
## 🧩 CÓDIGO FONTE
```basic
[Seu código aqui]
```
## 🔍 EXPLICAÇÃO
- **Linha X**: [Explicação]
- **Linha Y**: [Explicação]
## 🚀 EXEMPLO DE EXECUÇÃO
```
[Saída do programa]
```
```
---
## 🏆 **MODELO DE PROJETO COMPLETO**
```
# PROJETO BASIC: [NOME]
## 📝 DESCRIÇÃO
[Descrição do que o programa faz]
## 🎨 FUNCIONALIDADES
- [ ] Funcionalidade 1
- [ ] Funcionalidade 2
- [ ] Funcionalidade 3
## 🧩 ESTRUTURA DO CÓDIGO
```basic
[Seu código organizado]
```
## 🎯 APRENDIZADOS
- [Conceito 1 aprendido]
- [Conceito 2 aprendido]
## ❓ DÚVIDAS PARA EVOLUIR
- [Dúvida para melhorar]
- [O que gostaria de fazer depois]
```
gerenerate several examples
for this keyword written in rhai do this only for basic audience:

View file

@ -1,55 +1,402 @@
**FORMAT FUNCTION - PATTERN REFERENCE** # 📚 **BASIC LEARNING EXAMPLES - FORMAT Function**
**SYNTAX:** `FORMAT(value, pattern)` ## 🎯 **EXAMPLE 1: BASIC CONCEPT OF FORMAT FUNCTION**
**PATTERN TABLE:** ```
**BASIC CONCEPT:**
FORMAT FUNCTION - Value formatting
| CATEGORY | PATTERN | OUTPUT EXAMPLE | DESCRIPTION | **LEVEL:**
|----------|---------|----------------|-------------| ☒ Beginner ☐ Intermediate ☐ Advanced
| **DATE** | `yyyy` | 2024 | 4-digit year |
| | `yy` | 24 | 2-digit year |
| | `MM` | 01 | 2-digit month |
| | `M` | 1 | 1-2 digit month |
| | `dd` | 05 | 2-digit day |
| | `d` | 5 | 1-2 digit day |
| **TIME** | `HH` | 14 | 24-hour, 2-digit |
| | `H` | 14 | 24-hour, 1-2 digit |
| | `hh` | 02 | 12-hour, 2-digit |
| | `h` | 2 | 12-hour, 1-2 digit |
| | `mm` | 08 | 2-digit minutes |
| | `m` | 8 | 1-2 digit minutes |
| | `ss` | 09 | 2-digit seconds |
| | `s` | 9 | 1-2 digit seconds |
| | `tt` | PM | AM/PM designator |
| | `t` | P | A/P designator |
| | `fff` | 123 | Milliseconds |
| **CURRENCY** | `C` | $ | Currency symbol |
| | `c` | 123.45 | Currency amount |
| | `N` | 1,234.56 | Number with commas |
| | `n` | 1234.56 | Number without commas |
| | `F` | 123.00 | Fixed decimal |
| | `f` | 123.45 | Float decimal |
| | `0` | 0.00 | Zero placeholder |
| | `#` | #.## | Digit placeholder |
| **NUMERIC** | `0` | 0 | Required digit |
| | `#` | # | Optional digit |
| | `.` | . | Decimal point |
| | `,` | , | Thousands separator |
| | `%` | % | Percentage |
| **TEXT** | `@` | TEXT | Character placeholder |
| | `&` | text | Lowercase text |
| | `>` | TEXT | Uppercase text |
| | `<` | text | Force lowercase |
| | `!` | T | Force uppercase |
**COMMON COMBINATIONS:** **LEARNING OBJECTIVE:**
- `yyyy-MM-dd` → 2024-01-15 Understand how to format numbers, dates, and text
- `MM/dd/yy` → 01/15/24
- `HH:mm:ss` → 14:30:45
- `C0.00` → $123.45
- `N2` → 1,234.56
**USAGE:** **CODE EXAMPLE:**
`FORMAT(123.456, "C2")` → "$123.46" ```basic
`FORMAT(NOW(), "yyyy-MM-dd HH:mm")` → "2024-01-15 14:30" 10 NUMBER = 1234.56
`FORMAT(0.15, "0%")` → "15%" 20 TEXT$ = "John"
30 DATE$ = "2024-03-15 14:30:00"
40
50 PRINT FORMAT(NUMBER, "n") ' 1234.56
60 PRINT FORMAT(NUMBER, "F") ' 1234.56
70 PRINT FORMAT(TEXT$, "Hello @!") ' Hello John!
80 PRINT FORMAT(DATE$, "dd/MM/yyyy") ' 15/03/2024
```
**SPECIFIC QUESTIONS:**
- What's the difference between "n" and "F"?
- What does "@" mean in text?
- How to format dates in Brazilian format?
**PROJECT CONTEXT:**
I need to display data in a nicer way
**EXPECTED RESULT:**
Values formatted according to the pattern
**PARTS I DON'T UNDERSTAND:**
- When to use each type of formatting
- How it works internally
```
---
## 🛠️ **EXAMPLE 2: NUMERIC FORMATTING**
```
**BASIC CONCEPT:**
NUMBER FORMATTING
**LEVEL:**
☒ Beginner ☐ Intermediate ☐ Advanced
**LEARNING OBJECTIVE:**
Learn to format numbers as currency and with separators
**CODE EXAMPLE:**
```basic
10 VALUE = 1234567.89
20
30 PRINT "Standard: "; FORMAT(VALUE, "n") ' 1234567.89
40 PRINT "Decimal: "; FORMAT(VALUE, "F") ' 1234567.89
45 PRINT "Integer: "; FORMAT(VALUE, "f") ' 1234567
50 PRINT "Percentage: "; FORMAT(0.856, "0%") ' 86%
60
70 ' Formatting with locale
80 PRINT "Dollar: "; FORMAT(VALUE, "C2[en]") ' $1,234,567.89
90 PRINT "Real: "; FORMAT(VALUE, "C2[pt]") ' R$ 1.234.567,89
100 PRINT "Euro: "; FORMAT(VALUE, "C2[fr]") ' €1,234,567.89
```
**SPECIFIC QUESTIONS:**
- What does "C2[pt]" mean?
- How to change decimal places?
- Which locales are available?
**PROJECT CONTEXT:**
Multi-currency financial system
**EXPECTED RESULT:**
Numbers formatted according to regional standards
**PARTS I DON'T UNDERSTAND:**
- Syntax of complex patterns
- Differences between locales
```
---
## 📖 **EXAMPLE 3: EXPLAINING FORMAT COMMAND**
```
**COMMAND:**
FORMAT - Formats values
**SYNTAX:**
```basic
RESULT$ = FORMAT(VALUE, PATTERN$)
```
**PARAMETERS:**
- VALUE: Number, date or text to format
- PATTERN$: String with formatting pattern
**SIMPLE EXAMPLE:**
```basic
10 PRINT FORMAT(123.45, "n") ' 123.45
20 PRINT FORMAT("Mary", "Ms. @") ' Ms. Mary
```
**PRACTICAL EXAMPLE:**
```basic
10 INPUT "Name: "; NAME$
20 INPUT "Salary: "; SALARY
30 INPUT "Birth date: "; BIRTH_DATE$
40
50 PRINT "Record:"
60 PRINT "Name: "; FORMAT(NAME$, "!") ' UPPERCASE
70 PRINT "Salary: "; FORMAT(SALARY, "C2[en]") ' $1,234.56
80 PRINT "Birth: "; FORMAT(BIRTH_DATE$, "MM/dd/yyyy")
```
**COMMON ERRORS:**
- Using wrong pattern for data type
- Forgetting it returns string
- Formatting date without correct format
**BEGINNER TIP:**
Test each pattern separately before using in project
**SUGGESTED EXERCISE:**
Create a bank statement with professional formatting
```
---
## 🎨 **EXAMPLE 4: DATE AND TIME FORMATTING**
```
**BASIC CONCEPT:**
DATE AND TIME FORMATTING
**LEVEL:**
☐ Beginner ☒ Intermediate ☐ Advanced
**LEARNING OBJECTIVE:**
Learn all date formatting patterns
**CODE EXAMPLE:**
```basic
10 DATE$ = "2024-03-15 14:30:25"
20
30 PRINT "Brazilian: "; FORMAT(DATE$, "dd/MM/yyyy") ' 15/03/2024
40 PRINT "Complete: "; FORMAT(DATE$, "dd/MM/yyyy HH:mm") ' 15/03/2024 14:30
50 PRINT "US: "; FORMAT(DATE$, "MM/dd/yyyy") ' 03/15/2024
60 PRINT "International: "; FORMAT(DATE$, "yyyy-MM-dd") ' 2024-03-15
70
80 PRINT "24h Time: "; FORMAT(DATE$, "HH:mm:ss") ' 14:30:25
90 PRINT "12h Time: "; FORMAT(DATE$, "hh:mm:ss tt") ' 02:30:25 PM
100 PRINT "Long date: "; FORMAT(DATE$, "dd 'of' MMMM 'of' yyyy")
```
**SPECIFIC QUESTIONS:**
- What's the difference between HH and hh?
- How to show month name?
- What is "tt"?
**PROJECT CONTEXT:**
Scheduling system and reports
**EXPECTED RESULT:**
Dates formatted according to needs
**PARTS I DON'T UNDERSTAND:**
- All formatting codes
- How milliseconds work
```
---
## 🏆 **EXAMPLE 5: COMPLETE PROJECT - BANK STATEMENT**
```
# BASIC PROJECT: FORMATTED BANK STATEMENT
## 📝 DESCRIPTION
System that generates bank statement with professional formatting
## 🎨 FEATURES
- [x] Currency formatting
- [x] Date formatting
- [x] Value alignment
## 🧩 CODE STRUCTURE
```basic
10 ' Customer data
20 NAME$ = "Carlos Silva"
30 BALANCE = 12567.89
40
50 ' Transactions
60 DIM DATES$(3), DESCRIPTIONS$(3), AMOUNTS(3)
70 DATES$(1) = "2024-03-10 09:15:00" : DESCRIPTIONS$(1) = "Deposit" : AMOUNTS(1) = 2000
80 DATES$(2) = "2024-03-12 14:20:00" : DESCRIPTIONS$(2) = "Withdrawal" : AMOUNTS(2) = -500
90 DATES$(3) = "2024-03-14 11:30:00" : DESCRIPTIONS$(3) = "Transfer" : AMOUNTS(3) = -150.50
100
110 ' Header
120 PRINT FORMAT("BANK STATEMENT", "!")
130 PRINT "Customer: "; FORMAT(NAME$, "&")
140 PRINT "Date: "; FORMAT("2024-03-15 08:00:00", "dd/MM/yyyy HH:mm")
150 PRINT STRING$(40, "-")
160
170 ' Transactions
180 FOR I = 1 TO 3
190 FORMATTED_DATE$ = FORMAT(DATES$(I), "dd/MM HH:mm")
200 FORMATTED_AMOUNT$ = FORMAT(AMOUNTS(I), "C2[en]")
210
220 PRINT FORMATTED_DATE$; " - ";
230 PRINT DESCRIPTIONS$(I);
240 PRINT TAB(30); FORMATTED_AMOUNT$
250 NEXT I
260
270 ' Balance
280 PRINT STRING$(40, "-")
290 PRINT "Balance: "; TAB(30); FORMAT(BALANCE, "C2[en]")
```
## 🎯 LEARNINGS
- Currency formatting with locale
- Date formatting
- Composition of multiple formats
## ❓ QUESTIONS TO EVOLVE
- How to perfectly align columns?
- How to format negative numbers in red?
- How to add more locales?
```
---
## 🛠️ **EXAMPLE 6: TEXT FORMATTING**
```
**BASIC CONCEPT:**
STRING/TEXT FORMATTING
**LEVEL:**
☒ Beginner ☐ Intermediate ☐ Advanced
**LEARNING OBJECTIVE:**
Learn to use placeholders in text
**CODE EXAMPLE:**
```basic
10 NAME$ = "Mary"
20 CITY$ = "são paulo"
21 COUNTRY$ = "BRAZIL"
22 AGE = 25
30
40 PRINT FORMAT(NAME$, "Hello @!") ' Hello Mary!
50 PRINT FORMAT(NAME$, "Welcome, @") ' Welcome, Mary
60 PRINT FORMAT(CITY$, "City: !") ' City: SÃO PAULO
70 PRINT FORMAT(CITY$, "City: &") ' City: são paulo
80 PRINT FORMAT(COUNTRY$, "Country: &") ' Country: brazil
90
100 ' Combining with numbers
110 PRINT FORMAT(NAME$, "@ is ") + FORMAT(AGE, "n") + " years old"
120 ' Mary is 25 years old
```
**SPECIFIC QUESTIONS:**
- What's the difference between @, ! and &?
- Can I use multiple placeholders?
- How to escape special characters?
**PROJECT CONTEXT:**
Personalized report generation
**EXPECTED RESULT:**
Dynamic texts formatted automatically
**PARTS I DON'T UNDERSTAND:**
- Placeholder limitations
- How to mix different types
```
---
## 📚 **EXAMPLE 7: PRACTICAL EXERCISES**
```
# EXERCISES: PRACTICING WITH FORMAT
## 🎯 EXERCISE 1 - BASIC
Create a program that formats product prices.
**SOLUTION:**
```basic
10 DIM PRODUCTS$(3), PRICES(3)
20 PRODUCTS$(1) = "Laptop" : PRICES(1) = 2500.99
30 PRODUCTS$(2) = "Mouse" : PRICES(2) = 45.5
40 PRODUCTS$(3) = "Keyboard" : PRICES(3) = 120.75
50
60 FOR I = 1 TO 3
70 PRINT FORMAT(PRODUCTS$(I), "@: ") + FORMAT(PRICES(I), "C2[en]")
80 NEXT I
```
## 🎯 EXERCISE 2 - INTERMEDIATE
Make a program that shows dates in different formats.
**SOLUTION:**
```basic
10 DATE$ = "2024-12-25 20:00:00"
20
30 PRINT "Christmas: "; FORMAT(DATE$, "dd/MM/yyyy")
40 PRINT "US: "; FORMAT(DATE$, "MM/dd/yyyy")
50 PRINT "Dinner: "; FORMAT(DATE$, "HH'h'mm")
60 PRINT "Formatted: "; FORMAT(DATE$, "dd 'of' MMMM 'of' yyyy 'at' HH:mm")
```
## 🎯 EXERCISE 3 - ADVANCED
Create a school report card system with formatting.
**SOLUTION:**
```basic
10 NAME$ = "ana silva"
20 AVERAGE = 8.75
21 ATTENDANCE = 0.92
30 REPORT_DATE$ = "2024-03-15 10:00:00"
40
50 PRINT FORMAT("SCHOOL REPORT CARD", "!")
60 PRINT "Student: "; FORMAT(NAME$, "&")
70 PRINT "Date: "; FORMAT(REPORT_DATE$, "dd/MM/yyyy")
80 PRINT "Average: "; FORMAT(AVERAGE, "n")
90 PRINT "Attendance: "; FORMAT(ATTENDANCE, "0%")
```
## 💡 TIPS
- Always test patterns before using
- Use PRINT to see each formatting result
- Combine simple formats to create complex ones
```
---
## 🎨 **EXAMPLE 8: COMPLETE REFERENCE GUIDE**
```markdown
# FORMAT FUNCTION - COMPLETE GUIDE
## 🎯 OBJECTIVE
Format numbers, dates and text professionally
## 📋 SYNTAX
```basic
RESULT$ = FORMAT(VALUE, PATTERN$)
```
## 🔢 NUMERIC FORMATTING
| Pattern | Example | Result |
|---------|---------|--------|
| "n" | `FORMAT(1234.5, "n")` | 1234.50 |
| "F" | `FORMAT(1234.5, "F")` | 1234.50 |
| "f" | `FORMAT(1234.5, "f")` | 1234 |
| "0%" | `FORMAT(0.85, "0%")` | 85% |
| "C2[en]" | `FORMAT(1234.5, "C2[en]")` | $1,234.50 |
| "C2[pt]" | `FORMAT(1234.5, "C2[pt]")` | R$ 1.234,50 |
## 📅 DATE FORMATTING
| Code | Meaning | Example |
|------|---------|---------|
| yyyy | 4-digit year | 2024 |
| yy | 2-digit year | 24 |
| MM | 2-digit month | 03 |
| M | 1-2 digit month | 3 |
| dd | 2-digit day | 05 |
| d | 1-2 digit day | 5 |
| HH | 24h hour 2-digit | 14 |
| H | 24h hour 1-2 digit | 14 |
| hh | 12h hour 2-digit | 02 |
| h | 12h hour 1-2 digit | 2 |
| mm | 2-digit minute | 05 |
| m | 1-2 digit minute | 5 |
| ss | 2-digit second | 09 |
| s | 1-2 digit second | 9 |
| tt | AM/PM | PM |
| t | A/P | P |
## 📝 TEXT FORMATTING
| Placeholder | Function | Example |
|-------------|----------|---------|
| @ | Insert original text | `FORMAT("John", "@")` → John |
| ! | Text in UPPERCASE | `FORMAT("John", "!")` → JOHN |
| & | Text in lowercase | `FORMAT("John", "&")` → john |
## ⚠️ LIMITATIONS
- Dates must be in "YYYY-MM-DD HH:MM:SS" format
- Very large numbers may have issues
- Supported locales: en, pt, fr, de, es, it
```
These examples cover from basic to advanced applications of the FORMAT function! 🚀

348
docs/keywords/last.md Normal file
View file

@ -0,0 +1,348 @@
# 📚 **BASIC LEARNING EXAMPLES - LAST Function**
## 🎯 **EXAMPLE 1: BASIC CONCEPT OF LAST FUNCTION**
```
**BASIC CONCEPT:**
LAST FUNCTION - Extract last word
**LEVEL:**
☒ Beginner ☐ Intermediate ☐ Advanced
**LEARNING OBJECTIVE:**
Understand how the LAST function extracts the last word from text
**CODE EXAMPLE:**
```basic
10 PALAVRA$ = "The mouse chewed the clothes"
20 ULTIMA$ = LAST(PALAVRA$)
30 PRINT "Last word: "; ULTIMA$
```
**SPECIFIC QUESTIONS:**
- How does the function know where the last word ends?
- What happens if there are extra spaces?
- Can I use it with numeric variables?
**PROJECT CONTEXT:**
I'm creating a program that analyzes sentences
**EXPECTED RESULT:**
Should display: "Last word: clothes"
**PARTS I DON'T UNDERSTAND:**
- Why are parentheses needed?
- How does the function work internally?
```
---
## 🛠️ **EXAMPLE 2: SOLVING ERROR WITH LAST**
```
**BASIC ERROR:**
"Syntax error" when using LAST
**MY CODE:**
```basic
10 TEXTO$ = "Good day world"
20 RESULTADO$ = LAST TEXTO$
30 PRINT RESULTADO$
```
**PROBLEM LINE:**
Line 20
**EXPECTED BEHAVIOR:**
Show "world" on screen
**CURRENT BEHAVIOR:**
Syntax error
**WHAT I'VE TRIED:**
- Tried without parentheses
- Tried with different quotes
- Tried changing variable name
**BASIC VERSION:**
QBASIC with Rhai extension
**CORRECTED SOLUTION:**
```basic
10 TEXTO$ = "Good day world"
20 RESULTADO$ = LAST(TEXTO$)
30 PRINT RESULTADO$
```
```
---
## 📖 **EXAMPLE 3: EXPLAINING LAST COMMAND**
```
**COMMAND:**
LAST - Extracts last word
**SYNTAX:**
```basic
ULTIMA$ = LAST(TEXTO$)
```
**PARAMETERS:**
- TEXTO$: String from which to extract the last word
**SIMPLE EXAMPLE:**
```basic
10 FRASE$ = "The sun is bright"
20 ULTIMA$ = LAST(FRASE$)
30 PRINT ULTIMA$ ' Shows: bright
```
**PRACTICAL EXAMPLE:**
```basic
10 INPUT "Enter your full name: "; NOME$
20 SOBRENOME$ = LAST(NOME$)
30 PRINT "Hello Mr./Mrs. "; SOBRENOME$
```
**COMMON ERRORS:**
- Forgetting parentheses: `LAST TEXTO$`
- Using with numbers: `LAST(123)`
- Forgetting to assign to a variable
**BEGINNER TIP:**
Always use parentheses and ensure content is text
**SUGGESTED EXERCISE:**
Create a program that asks for a sentence and shows the first and last word
```
---
## 🎨 **EXAMPLE 4: COMPLETE PROJECT WITH LAST**
```
# BASIC PROJECT: SENTENCE ANALYZER
## 📝 DESCRIPTION
Program that analyzes sentences and extracts useful information
## 🎨 FEATURES
- [x] Extract last word
- [x] Count words
- [x] Show statistics
## 🧩 CODE STRUCTURE
```basic
10 PRINT "=== SENTENCE ANALYZER ==="
20 INPUT "Enter a sentence: "; FRASE$
30
40 ' Extract last word
50 ULTIMA$ = LAST(FRASE$)
60
70 ' Count words (simplified)
80 PALAVRAS = 1
90 FOR I = 1 TO LEN(FRASE$)
100 IF MID$(FRASE$, I, 1) = " " THEN PALAVRAS = PALAVRAS + 1
110 NEXT I
120
130 PRINT
140 PRINT "Last word: "; ULTIMA$
150 PRINT "Total words: "; PALAVRAS
160 PRINT "Original sentence: "; FRASE$
```
## 🎯 LEARNINGS
- How to use LAST function
- How to count words manually
- String manipulation in BASIC
## ❓ QUESTIONS TO EVOLVE
- How to extract the first word?
- How to handle punctuation?
- How to work with multiple sentences?
```
---
## 🏆 **EXAMPLE 5: SPECIAL CASES AND TESTS**
```
**BASIC CONCEPT:**
SPECIAL CASES OF LAST FUNCTION
**LEVEL:**
☐ Beginner ☒ Intermediate ☐ Advanced
**LEARNING OBJECTIVE:**
Understand how LAST behaves in special situations
**CODE EXAMPLES:**
```basic
' Case 1: Empty string
10 TEXTO$ = ""
20 PRINT LAST(TEXTO$) ' Result: ""
' Case 2: Single word only
30 TEXTO$ = "Sun"
40 PRINT LAST(TEXTO$) ' Result: "Sun"
' Case 3: Multiple spaces
50 TEXTO$ = "Hello World "
60 PRINT LAST(TEXTO$) ' Result: "World"
' Case 4: With tabs and newlines
70 TEXTO$ = "Line1" + CHR$(9) + "Line2" + CHR$(13)
80 PRINT LAST(TEXTO$) ' Result: "Line2"
```
**SPECIFIC QUESTIONS:**
- What happens with empty strings?
- How does it work with special characters?
- Is it case-sensitive?
**PROJECT CONTEXT:**
I need to robustly validate user inputs
**EXPECTED RESULT:**
Consistent behavior in all cases
**PARTS I DON'T UNDERSTAND:**
- How the function handles whitespace?
- What are CHR$(9) and CHR$(13)?
```
---
## 🛠️ **EXAMPLE 6: INTEGRATION WITH OTHER FUNCTIONS**
```
**BASIC CONCEPT:**
COMBINING LAST WITH OTHER FUNCTIONS
**LEVEL:**
☐ Beginner ☒ Intermediate ☐ Advanced
**LEARNING OBJECTIVE:**
Learn to use LAST in more complex expressions
**CODE EXAMPLE:**
```basic
10 ' Example 1: With concatenation
20 PARTE1$ = "Programming"
30 PARTE2$ = " in BASIC"
40 FRASE_COMPLETA$ = PARTE1$ + PARTE2$
50 PRINT LAST(FRASE_COMPLETA$) ' Result: "BASIC"
60 ' Example 2: With string functions
70 NOME_COMPLETO$ = "Maria Silva Santos"
80 SOBRENOME$ = LAST(NOME_COMPLETO$)
90 PRINT "Mr./Mrs. "; SOBRENOME$
100 ' Example 3: In conditional expressions
110 FRASE$ = "The sky is blue"
120 IF LAST(FRASE$) = "blue" THEN PRINT "The last word is blue!"
```
**SPECIFIC QUESTIONS:**
- Can I use LAST directly in IF?
- How to combine with LEFT$, RIGHT$, MID$?
- Is there a size limit for the string?
**PROJECT CONTEXT:**
Creating validations and text processing
**EXPECTED RESULT:**
Use LAST flexibly in different contexts
**PARTS I DON'T UNDERSTAND:**
- Expression evaluation order
- Performance with very large strings
```
---
## 📚 **EXAMPLE 7: PRACTICAL EXERCISES**
```
# EXERCISES: PRACTICING WITH LAST
## 🎯 EXERCISE 1 - BASIC
Create a program that asks for the user's full name and greets using only the last name.
**SOLUTION:**
```basic
10 INPUT "Enter your full name: "; NOME$
20 SOBRENOME$ = LAST(NOME$)
30 PRINT "Hello, Mr./Mrs. "; SOBRENOME$; "!"
```
## 🎯 EXERCISE 2 - INTERMEDIATE
Make a program that analyzes if the last word of a sentence is "end".
**SOLUTION:**
```basic
10 INPUT "Enter a sentence: "; FRASE$
20 IF LAST(FRASE$) = "end" THEN PRINT "Sentence ends with 'end'" ELSE PRINT "Sentence doesn't end with 'end'"
```
## 🎯 EXERCISE 3 - ADVANCED
Create a program that processes multiple sentences and shows statistics.
**SOLUTION:**
```basic
10 DIM FRASES$(3)
20 FRASES$(1) = "The sun shines"
30 FRASES$(2) = "The rain falls"
40 FRASES$(3) = "The wind blows"
50
60 FOR I = 1 TO 3
70 PRINT "Sentence "; I; ": "; FRASES$(I)
80 PRINT "Last word: "; LAST(FRASES$(I))
90 PRINT
100 NEXT I
```
## 💡 TIPS
- Always test with different inputs
- Use PRINT for debugging
- Start with simple examples
```
---
## 🎨 **EXAMPLE 8: MARKDOWN DOCUMENTATION**
```markdown
# LAST FUNCTION - COMPLETE GUIDE
## 🎯 OBJECTIVE
Extract the last word from a string
## 📋 SYNTAX
```basic
RESULTADO$ = LAST(TEXTO$)
```
## 🧩 PARAMETERS
- `TEXTO$`: Input string
## 🔍 BEHAVIOR
- Splits string by spaces
- Returns the last part
- Ignores extra spaces at beginning/end
## 🚀 EXAMPLES
```basic
10 PRINT LAST("hello world") ' Output: world
20 PRINT LAST("one word") ' Output: word
30 PRINT LAST(" spaces ") ' Output: spaces
```
## ⚠️ LIMITATIONS
- Doesn't work with numbers
- Requires parentheses
- Considers only spaces as separators
```
These examples cover from the basic concept to practical applications of the LAST function, always focusing on BASIC beginners! 🚀

View file

@ -191,3 +191,270 @@ fn apply_text_placeholders(value: &str, pattern: &str) -> String {
result result
} }
#[cfg(test)]
mod tests {
use super::*;
use rhai::Engine;
fn create_engine() -> Engine {
let mut engine = Engine::new();
format_keyword(&mut engine);
engine
}
#[test]
fn test_numeric_formatting_basic() {
let engine = create_engine();
// Teste formatação básica
assert_eq!(
engine.eval::<String>("FORMAT 1234.567 \"n\"").unwrap(),
"1234.57"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.5 \"F\"").unwrap(),
"1234.50"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.567 \"f\"").unwrap(),
"1234.567"
);
assert_eq!(
engine.eval::<String>("FORMAT 0.85 \"0%\"").unwrap(),
"85%"
);
}
#[test]
fn test_numeric_formatting_with_locale() {
let engine = create_engine();
// Teste formatação numérica com locale
assert_eq!(
engine.eval::<String>("FORMAT 1234.56 \"N[en]\"").unwrap(),
"1,234.56"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.56 \"N[pt]\"").unwrap(),
"1.234,56"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.56 \"N[fr]\"").unwrap(),
"1234,56"
);
}
#[test]
fn test_currency_formatting() {
let engine = create_engine();
// Teste formatação monetária
assert_eq!(
engine.eval::<String>("FORMAT 1234.56 \"C[en]\"").unwrap(),
"$1,234.56"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.56 \"C[pt]\"").unwrap(),
"R$ 1.234,56"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.56 \"C[fr]\"").unwrap(),
"€1234,56"
);
}
#[test]
fn test_numeric_decimals_precision() {
let engine = create_engine();
// Teste precisão decimal
assert_eq!(
engine.eval::<String>("FORMAT 1234.5678 \"N0[en]\"").unwrap(),
"1,235"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.5678 \"N1[en]\"").unwrap(),
"1,234.6"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.5678 \"N3[en]\"").unwrap(),
"1,234.568"
);
assert_eq!(
engine.eval::<String>("FORMAT 1234.5 \"C0[en]\"").unwrap(),
"$1,235"
);
}
#[test]
fn test_date_formatting() {
let engine = create_engine();
// Teste formatação de datas
let result = engine.eval::<String>("FORMAT \"2024-03-15 14:30:25\" \"yyyy-MM-dd HH:mm:ss\"").unwrap();
assert_eq!(result, "2024-03-15 14:30:25");
let result = engine.eval::<String>("FORMAT \"2024-03-15 14:30:25\" \"dd/MM/yyyy\"").unwrap();
assert_eq!(result, "15/03/2024");
let result = engine.eval::<String>("FORMAT \"2024-03-15 14:30:25\" \"MM/dd/yy\"").unwrap();
assert_eq!(result, "03/15/24");
let result = engine.eval::<String>("FORMAT \"2024-03-15 14:30:25\" \"HH:mm\"").unwrap();
assert_eq!(result, "14:30");
}
#[test]
fn test_date_formatting_12h() {
let engine = create_engine();
// Teste formato 12h
let result = engine.eval::<String>("FORMAT \"2024-03-15 14:30:25\" \"hh:mm tt\"").unwrap();
assert_eq!(result, "02:30 PM");
let result = engine.eval::<String>("FORMAT \"2024-03-15 09:30:25\" \"hh:mm tt\"").unwrap();
assert_eq!(result, "09:30 AM");
let result = engine.eval::<String>("FORMAT \"2024-03-15 00:30:25\" \"h:mm t\"").unwrap();
assert_eq!(result, "12:30 A");
}
#[test]
fn test_text_formatting() {
let engine = create_engine();
// Teste formatação de texto
assert_eq!(
engine.eval::<String>("FORMAT \"hello\" \"Prefix: @\"").unwrap(),
"Prefix: hello"
);
assert_eq!(
engine.eval::<String>("FORMAT \"HELLO\" \"Result: &!\"").unwrap(),
"Result: hello!"
);
assert_eq!(
engine.eval::<String>("FORMAT \"hello\" \"RESULT: >\"").unwrap(),
"RESULT: HELLO"
);
assert_eq!(
engine.eval::<String>("FORMAT \"Hello\" \"<>\"").unwrap(),
"hello>"
);
}
#[test]
fn test_mixed_patterns() {
let engine = create_engine();
// Teste padrões mistos
assert_eq!(
engine.eval::<String>("FORMAT \"hello\" \"@ World!\"").unwrap(),
"hello World!"
);
assert_eq!(
engine.eval::<String>("FORMAT \"test\" \"< & > ! @\"").unwrap(),
"test test TEST ! test"
);
}
#[test]
fn test_edge_cases() {
let engine = create_engine();
// Teste casos extremos
assert_eq!(
engine.eval::<String>("FORMAT 0 \"n\"").unwrap(),
"0.00"
);
assert_eq!(
engine.eval::<String>("FORMAT -1234.56 \"N[en]\"").unwrap(),
"-1,234.56"
);
assert_eq!(
engine.eval::<String>("FORMAT \"\" \"@\"").unwrap(),
""
);
assert_eq!(
engine.eval::<String>("FORMAT \"test\" \"\"").unwrap(),
""
);
}
#[test]
fn test_invalid_patterns_fallback() {
let engine = create_engine();
// Teste padrões inválidos (devem fallback para string)
assert_eq!(
engine.eval::<String>("FORMAT 123.45 \"invalid\"").unwrap(),
"123.45"
);
assert_eq!(
engine.eval::<String>("FORMAT \"text\" \"unknown\"").unwrap(),
"unknown"
);
}
#[test]
fn test_milliseconds_formatting() {
let engine = create_engine();
// Teste milissegundos
let result = engine.eval::<String>("FORMAT \"2024-03-15 14:30:25.123\" \"HH:mm:ss.fff\"").unwrap();
assert_eq!(result, "14:30:25.123");
}
#[test]
fn test_parse_pattern_function() {
// Teste direto da função parse_pattern
assert_eq!(parse_pattern("C[en]"), ("C".to_string(), 2, "en".to_string()));
assert_eq!(parse_pattern("N3[pt]"), ("N".to_string(), 3, "pt".to_string()));
assert_eq!(parse_pattern("C0[fr]"), ("C".to_string(), 0, "fr".to_string()));
assert_eq!(parse_pattern("N"), ("N".to_string(), 2, "en".to_string()));
assert_eq!(parse_pattern("C2"), ("C".to_string(), 2, "en".to_string()));
}
#[test]
fn test_locale_functions() {
// Teste funções de locale
assert!(matches!(get_locale("en"), Locale::en));
assert!(matches!(get_locale("pt"), Locale::pt));
assert!(matches!(get_locale("fr"), Locale::fr));
assert!(matches!(get_locale("invalid"), Locale::en)); // fallback
assert_eq!(get_currency_symbol("en"), "$");
assert_eq!(get_currency_symbol("pt"), "R$ ");
assert_eq!(get_currency_symbol("fr"), "");
assert_eq!(get_currency_symbol("invalid"), "$"); // fallback
}
#[test]
fn test_apply_text_placeholders() {
// Teste direto da função apply_text_placeholders
assert_eq!(apply_text_placeholders("Hello", "@"), "Hello");
assert_eq!(apply_text_placeholders("Hello", "&"), "hello");
assert_eq!(apply_text_placeholders("Hello", ">"), "HELLO");
assert_eq!(apply_text_placeholders("Hello", "Prefix: @!"), "Prefix: Hello!");
assert_eq!(apply_text_placeholders("Hello", "<>"), "hello>");
}
#[test]
fn test_expression_parameters() {
let engine = create_engine();
// Teste com expressões como parâmetros
assert_eq!(
engine.eval::<String>("let x = 1000.50; FORMAT x \"N[en]\"").unwrap(),
"1,000.50"
);
assert_eq!(
engine.eval::<String>("FORMAT (500 + 500) \"n\"").unwrap(),
"1000.00"
);
assert_eq!(
engine.eval::<String>("let pattern = \"@ World\"; FORMAT \"Hello\" pattern").unwrap(),
"Hello World"
);
}
}

View file

@ -3,7 +3,7 @@ use rhai::Engine;
pub fn last_keyword(engine: &mut Engine) { pub fn last_keyword(engine: &mut Engine) {
engine engine
.register_custom_syntax(&["LAST", "$expr$"], false, { .register_custom_syntax(&["LAST", "(", "$expr$", ")"], false, {
move |context, inputs| { move |context, inputs| {
let input_string = context.eval_expression_tree(&inputs[0])?; let input_string = context.eval_expression_tree(&inputs[0])?;
let input_str = input_string.to_string(); let input_str = input_string.to_string();
@ -20,3 +20,231 @@ pub fn last_keyword(engine: &mut Engine) {
}) })
.unwrap(); .unwrap();
} }
#[cfg(test)]
mod tests {
use super::*;
use rhai::{Engine, Scope};
#[test]
fn test_last_keyword_basic() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\"hello world\")").unwrap();
assert_eq!(result, "world");
}
#[test]
fn test_last_keyword_single_word() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\"hello\")").unwrap();
assert_eq!(result, "hello");
}
#[test]
fn test_last_keyword_empty_string() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\"\")").unwrap();
assert_eq!(result, "");
}
#[test]
fn test_last_keyword_multiple_spaces() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\"hello world \")").unwrap();
assert_eq!(result, "world");
}
#[test]
fn test_last_keyword_tabs_and_newlines() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\"hello\tworld\n\")").unwrap();
assert_eq!(result, "world");
}
#[test]
fn test_last_keyword_with_variable() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let mut scope = Scope::new();
scope.push("text", "this is a test");
let result: String = engine.eval_with_scope(&mut scope, "LAST(text)").unwrap();
assert_eq!(result, "test");
}
#[test]
fn test_last_keyword_whitespace_only() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\" \")").unwrap();
assert_eq!(result, "");
}
#[test]
fn test_last_keyword_mixed_whitespace() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\"hello\t \n world \t final\")").unwrap();
assert_eq!(result, "final");
}
#[test]
fn test_last_keyword_expression() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// Test with string concatenation
let result: String = engine.eval("LAST(\"hello\" + \" \" + \"world\")").unwrap();
assert_eq!(result, "world");
}
#[test]
fn test_last_keyword_unicode() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let result: String = engine.eval("LAST(\"hello 世界 мир world\")").unwrap();
assert_eq!(result, "world");
}
#[test]
fn test_last_keyword_in_expression() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// Test using the result in another expression
let result: bool = engine.eval("LAST(\"hello world\") == \"world\"").unwrap();
assert!(result);
}
#[test]
fn test_last_keyword_complex_scenario() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let mut scope = Scope::new();
scope.push("sentence", "The quick brown fox jumps over the lazy dog");
let result: String = engine.eval_with_scope(&mut scope, "LAST(sentence)").unwrap();
assert_eq!(result, "dog");
}
#[test]
#[should_panic] // This should fail because the syntax expects parentheses
fn test_last_keyword_missing_parentheses() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// This should fail - missing parentheses
let _: String = engine.eval("LAST \"hello world\"").unwrap();
}
#[test]
#[should_panic] // This should fail because of incomplete syntax
fn test_last_keyword_missing_closing_parenthesis() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// This should fail - missing closing parenthesis
let _: String = engine.eval("LAST(\"hello world\"").unwrap();
}
#[test]
#[should_panic] // This should fail because of incomplete syntax
fn test_last_keyword_missing_opening_parenthesis() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// This should fail - missing opening parenthesis
let _: String = engine.eval("LAST \"hello world\")").unwrap();
}
#[test]
fn test_last_keyword_dynamic_type() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// Test that the function returns the correct Dynamic type
let result = engine.eval::<Dynamic>("LAST(\"test string\")").unwrap();
assert!(result.is::<String>());
assert_eq!(result.to_string(), "string");
}
#[test]
fn test_last_keyword_nested_expression() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// Test with a more complex nested expression
let result: String = engine.eval("LAST(\"The result is: \" + \"hello world\")").unwrap();
assert_eq!(result, "world");
}
}
#[cfg(test)]
mod integration_tests {
use super::*;
#[test]
fn test_last_keyword_in_script() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let script = r#"
let sentence1 = "first second third";
let sentence2 = "alpha beta gamma";
let last1 = LAST(sentence1);
let last2 = LAST(sentence2);
last1 + " and " + last2
"#;
let result: String = engine.eval(script).unwrap();
assert_eq!(result, "third and gamma");
}
#[test]
fn test_last_keyword_with_function() {
let mut engine = Engine::new();
last_keyword(&mut engine);
// Register a function that returns a string
engine.register_fn("get_name", || -> String { "john doe".to_string() });
let result: String = engine.eval("LAST(get_name())").unwrap();
assert_eq!(result, "doe");
}
#[test]
fn test_last_keyword_multiple_calls() {
let mut engine = Engine::new();
last_keyword(&mut engine);
let script = r#"
let text1 = "apple banana cherry";
let text2 = "cat dog elephant";
let result1 = LAST(text1);
let result2 = LAST(text2);
result1 + "-" + result2
"#;
let result: String = engine.eval(script).unwrap();
assert_eq!(result, "cherry-elephant");
}
}