35. Rozšírenia jazyka: CONST, ENUM, CASE, hodnoty z porovnaní, pretypovanie
Na čo to je
Jazyk Action! je z roku 1983 a niektoré veci, ktoré sú dnes bežné, v ňom chýbajú. action26 ich vie doplniť. Sú vypnuté, kým si o ne nepovieš – starý program sa tak nikdy nepokazí tým, že má napríklad premennú menom CASE.
Rozšírenia zapneš riadkom na začiatku zdrojáka:
;@modern
alebo voľbou --modern na príkazovom riadku. Program s rozšíreniami pôvodný Action! nepreloží. Ak má tvoj program bežať aj v ňom, túto a ďalšie kapitoly nepoužívaj.
Každé rozšírenie má v tejto kapitole vlastný krátky program. Všetky sa prekladajú rovnako – ;@modern si nesú v sebe:
action26 m-const.act --simCONST: pomenované konštanty
Na čo to je
DEFINE z kapitoly 17 nahrádza text a má pascu: DEFINE SIZE="5+5" a SIZE*2 dá 15. CONST je pomenovaná hodnota: prekladač ju vypočíta raz a ďalej s ňou narába ako s číslom.
Ako sa to píše
CONST MENO=výraz
CONST MENO1=výraz, MENO2=výraz
CONST TYP MENO=výrazVýraz môže obsahovať čísla, znaky, skoršie konštanty a operátory. Hodnota sa píše bez úvodzoviek.
Celý program
Súbor examples/m-const.act:
;@modern
; CONST: named values worked out by the compiler
CONST WIDTH=20, HEIGHT=3
CONST CELLS=WIDTH*HEIGHT ; a constant may use earlier ones
CONST SIZE=5+5
CONST CHAR FRAME='#
PROC Main()
BYTE x, y
FOR y=1 TO HEIGHT
DO
FOR x=1 TO WIDTH
DO
Put(FRAME)
OD
PutE()
OD
Print("Cells: ")
PrintBE(CELLS)
Print("SIZE*2: ")
PrintBE(SIZE*2) ; 20 - with DEFINE it would be 15
RETURN####################
####################
####################
Cells: 60
SIZE*2: 20Ako to funguje
CELLS je 60 už pri preklade – v programe sa nič nenásobí. SIZE*2 je 20, lebo SIZE je hodnota 10, nie text 5+5. Konštanta nezaberá pamäť a nedá sa do nej priradiť.
ENUM: vlastný typ s pomenovanými hodnotami
Na čo to je
Stav semaforu, smer pohybu, druh nepriateľa – veci, ktoré majú niekoľko pevných možností. S číslami (0 = červená, 1 = zelená) sa ľahko pomýliš. ENUM dá možnostiam mená a prekladač stráži, aby sa nepomiešali s obyčajnými číslami.
Ako sa to píše
TYPE Meno=ENUM [PRVA, DRUHA, TRETIA]
Meno premenna
premenna=Meno.PRVAHodnota sa píše s menom typu a bodkou: Light.RED. Členy dostanú čísla 0, 1, 2 …
Celý program
Súbor examples/m-enum.act:
;@modern
; ENUM: a type of your own with named values
TYPE Light=ENUM [RED, GREEN, YELLOW]
Light FUNC Next(Light now)
IF now=Light.RED THEN
RETURN(Light.GREEN)
FI
IF now=Light.GREEN THEN
RETURN(Light.YELLOW)
FI
RETURN(Light.RED)
PROC Show(Light l)
CASE l OF
WHEN Light.RED THEN
PrintE("red - stop")
WHEN Light.GREEN THEN
PrintE("green - go")
WHEN Light.YELLOW THEN
PrintE("yellow - wait")
ESAC
RETURN
PROC Main()
Light l=[Light.RED]
BYTE i
FOR i=1 TO 5
DO
Show(l)
l=Next(l)
OD
Print("The last value as a number: ")
PrintBE(BYTE(l))
RETURNred - stop
green - go
yellow - wait
red - stop
green - go
The last value as a number: 2Ako to funguje
Light sa používa ako každý typ: pre premennú, parameter aj výsledok funkcie. Prekladač nedovolí l=1 ani PrintB(l) – hodnota typu Light nie je číslo. Keď číslo naozaj potrebuješ, povieš to výslovne: BYTE(l). Opačne Light(2) spraví z čísla člen.
CASE: výber z viacerých možností
Na čo to je
Dlhá reťaz IF … ELSEIF … ELSEIF …, ktorá skúša stále tú istú premennú, sa číta ťažko. CASE ju zapíše prehľadne.
Ako sa to píše
CASE výraz OF
WHEN hodnota THEN
príkazy
WHEN hodnota1, hodnota2 THEN ; viac hodnôt
príkazy
WHEN od TO do THEN ; rozsah vrátane hraníc
príkazy
WHEN od TO do IF podmienka THEN ; rozsah a navyše podmienka
príkazy
ELSE
príkazy ; keď nesedelo nič
ESACVykoná sa prvá vetva, ktorá sedí, a žiadna ďalšia. ELSE je nepovinné. ESAC (CASE odzadu) príkaz končí.
Celý program
Súbor examples/m-case.act:
;@modern
; CASE: choose one branch by a value
PROC Describe(BYTE n)
PrintB(n)
Print(": ")
CASE n OF
WHEN 0 THEN
PrintE("zero")
WHEN 1 TO 9 THEN
PrintE("one digit")
WHEN 10, 100 THEN
PrintE("ten or a hundred")
WHEN 11 TO 99 IF n MOD 11=0 THEN
PrintE("two digits, both the same")
WHEN 11 TO 99 THEN
PrintE("two digits")
ELSE
PrintE("a big number")
ESAC
RETURN
PROC Main()
Describe(0)
Describe(7)
Describe(10)
Describe(33)
Describe(42)
Describe(100)
Describe(200)
RETURN0: zero
7: one digit
10: ten or a hundred
33: two digits, both the same
42: two digits
100: ten or a hundred
200: a big numberAko to funguje
Číslo 33 sedí do rozsahu 11 TO 99 a spĺňa aj podmienku za IF (je deliteľné jedenástimi), takže sa vykoná prvá z dvoch vetiev. Číslo 42 do rozsahu sedí, ale podmienku nespĺňa – ide sa na ďalšiu vetvu. Podmienke pri WHEN sa hovorí stráž.
Prekladač stráži aj teba: keby sa tá istá hodnota vyskytla v dvoch vetvách bez stráže, druhá by sa nikdy nevykonala – a to je chyba prekladu (ACT234).
Porovnanie, IF a CASE ako hodnota; pretypovanie
Na čo to je
V pôvodnom Action! patrí porovnanie len do podmienky. S rozšíreniami je porovnanie aj hodnota – 1, keď platí, 0, keď neplatí. Hodnotou môže byť aj celý IF a CASE. A pretypovanie povie, v akom type sa má počítať.
Ako sa to píše
| Zápis | Hodnota |
|---|---|
(a>b) | 1 alebo 0 |
IF podm THEN x ELSE y FI | x alebo y; ELSE je povinné |
CASE v OF WHEN … THEN x … ELSE y ESAC | hodnota zvolenej vetvy |
BYTE(x), CARD(x), INT(x), CHAR(x) | x čítané ako daný typ |
Celý program
Súbor examples/m-value.act:
;@modern
; Comparisons, IF and CASE as values, and casts
PROC Main()
CHAR ARRAY text="one, two, three, four"
BYTE a, b, bigger, commas, i
CHAR grade
CARD sum
a=7
b=12
bigger=IF a>b THEN a ELSE b FI ; IF as a value
Print("The bigger one: ")
PrintBE(bigger)
commas=0
FOR i=1 TO text(0)
DO
commas==+(text(i)=',) ; a comparison is 1 or 0
OD
Print("Commas in the text: ")
PrintBE(commas)
grade=CASE b OF ; CASE as a value
WHEN 0 TO 4 THEN 'C
WHEN 5 TO 9 THEN 'B
ELSE 'A
ESAC
Print("Grade: ")
Put(grade)
PutE()
a=200
b=100
sum=a+b ; BYTE + BYTE overflows
Print("200 + 100 as BYTE: ")
PrintCE(sum)
sum=CARD(a)+b ; the cast makes it a CARD sum
Print("200 + 100 with CARD(a): ")
PrintCE(sum)
RETURNThe bigger one: 12
Commas in the text: 3
Grade: A
200 + 100 as BYTE: 44
200 + 100 with CARD(a): 300Ako to funguje
bigger=IF a>b THEN a ELSE b FInahrádza štyri riadky sIFa dvoma priradeniami.commas==+(text(i)=',)pripočíta 1 za každú čiarku a 0 za každý iný znak – počítanie bezIF.- Posledná časť rieši pascu z kapitoly 7:
BYTE + BYTEsa počíta vBYTEa pretečie.CARD(a)povie „beraakoCARD“, a tým sa celý súčet počíta vCARD.
Časté chyby
| Čo sa stalo | Čo povie prekladač |
|---|---|
chýba ;@modern | chyby na prvom rozšírení – napr. error ACT011: unexpected '*' pri CONST |
| priradenie do konštanty | chyba – konštanta nie je premenná |
číslo do premennej typu ENUM (l=1) | error ACT237 |
tá istá hodnota v dvoch vetvách CASE | error ACT234 |
IF ako hodnota bez ELSE | error ACT235 |
;@modern spolu s ;@quirks | error ACT231 |
Vyskúšaj si
- Prepíš
define.actz kapitoly 17 pomocouCONST. - Pridaj semaforu štvrtý stav
RED_YELLOWmedzi červenú a zelenú. - Napíš
CASE, ktorý podľa čísla mesiaca vypíše ročné obdobie.
Zhrnutie
;@modernzapne rozšírenia; pôvodný Action! taký program nepreloží.CONSTje pomenovaná hodnota vypočítaná pri preklade.TYPE X=ENUM […]je typ s pomenovanými hodnotami, ktorý sa nemieša s číslami.CASE … OF … WHEN … ESACvyberá jednu vetvu podľa hodnoty; pozná rozsahy a stráže.- Porovnanie je 1 alebo 0;
IFaCASEmôžu byť hodnotou;CARD(x)volí typ výpočtu.
Podrobnejšie lekcie ku každému rozšíreniu sú v priečinku examples/modern/ (lekcie 6 až 11).
Späť: 34. Disky · Ďalej: 36. Rozšírenia pre dáta