Jazyk dpic #
Programovací jazyk dpic bol špeciálne vytvorený na kreslenie grafov a diagramov s možnosťou ich exportu ako obrázkov alebo vkladania do textových dokumentov. Obsahuje príkazy pre kreslenie lineárnych objektov ako čiara, šipka, krivka, ako aj plošné objekty ako pravouholník, kružnica, elipsa, oblúk a umožňuje vytváranie zložených objektov. Zložitejšie grafických objekty ktoré sa v obrázkoch vyskytujú častejšie, ako sú značky elektronických súčiastok, je možné v dpic kresliť pomocou makier, ktoré obsahujú kód pre nakreslenie objektu. CircuitMacros je rozšírením dpic o knižnice makier pre kreslenie elektronických obvodov a zapojení. Podrobný popis syntaxe jazyka dpic je v dokumentácii.
Programovací jazyk dpic
Programovací jazyk dpic historicky vychádza z jazyka pic vytvoreného Brian W. Kernighan-om v roku 1991. Z programátorského hľadiska dpic patrí do skupiny tzv. mini-jazykov, (DSL) ktoré sú vytvorené pre nejaký konkrétny učel na rozdiel od všeobecne použiteľných jazykov (GPL). Syntax jazyka dpic je veľmi jednoduchá, okrem príkazov na kreslenie grafických objektov má aj základné jazykové konštrukcie na riadenie toku programu ako je podmienkové vetvenie a cyklus. Nie je v ňom možné ale vytvárať funkcie, ktorú sú formálne nahradené makrami. Makrá obsahujú kód pre kreslenie zložitejších objektov a pri ich použití kompilátor nahradí v programe meno makra týmto kódom.
Program #
Program je tvorený textovým súborom, ktorý začína znakmi .PS a končí znakmi .PE. Príkaz na riadku je ukončený bodkočiarkou ; alebo ukončenim riadku (neviditeľný znak \n). Bodkočiarka na ukončenie príkazu nie je povinná, na rozdiel napr. od jazyka C, ale využijeme ju vtedy, ak budeme do jedného riadku zadávať niekoľko príkazov.
.PS # zaciatok postupnosti prikazov
scale=2.54 # príkaz nastavenie parametrov velkosti obrazku
cct_init # príkaz pre inicializaciu kniznice makier
# s analogovými prvkami (rezistor, ...)
line from (1,1) to (2,2) # príkaz dpic pre vykreslenie čiary
resistor # makro pre vykreslenie rezistoru
rezistor(,,E); # makro s parametrami
resistor(2,,E); rlabel(,R1,); # niekolko príkazov v jednom riadku
.PE # koniec postupnosti prikazov
Text za koncom programu je ignorovaný. Ukončenie programu môžeme prakticky využiť pri hľadaní chýb v skripte, kedy pomocou .PE vyradíme zbytok programu zo spracovania.
Komentáre #
Komentáre začínajú znakom # a končia koncom riadku. Blokové komentáre nie sú definované, je ale možné použiť viacriadkové komentáre s riadkami ukončenými \\.
# toto je jednoriadkovy komentar
# toto je dvojriadkovy komentar \\
a jeho pokracovanie na dalsom riadku
Warning
White-space (tabulátory, medzery, znak nového riadku) sú vo v argumentoch makier ignorované pred argumentom, nie ale za argumentom.
name( x,
y, z )
je ekvivalent
name(x,y,z )
Hodnoty #
Jazyk dpic pozná len numerické hodnoty ktoré môžu byť zapísané v desatinnom tvare alebo môžu byť vo vedeckom formáte. Všetky numerické hodnoty sú interne uchovávané vo formáte floating-point. Všetky grafické prvky ako aj texty sú pokladané za objekty na ploche a sú reprezentované súradnicami polohy ich geometrického stredu.
Premenné #
Meno premennej musí začínať písmenom nasledovaným ľubovolným počtom alfanumerických znakov. Premenné sa vytvoria pri ich definícii, musia byť inicializované numerickou hodnotou a sú globálne t.j. majú platnosť v celom zdrojovom kóde.
d = 2;
pi = 3.14159265359;
q = 2*pi*8;
Pre premenné sú definované numerické a logické operácie
binárne aritmetické oprácie
+ - * / % ^
unárne aritmetické operácie
+= -= *= /= %=
relačné operácie
!= == < > >= <= || &&
Warning
Pretože dpic používa pre numerické hodnoty výhradne čísla typu floating point, v dôsledku internej reprezentácie tohoto číselného typu nemusí byť výsledok použitia relačného operátora jednoznačný, napríklad pri porovnaní formálne rovnakých hodnôt súradníc je vyhodnotená vetva False
R1: resistor
up_
R2: resistor # R1 a R2 majú rovnakú x-ovú súradnicu
if R1.x == R2.x then
{ ... } # vetva True
{ ... } # vetva False -
Súradnice #
Súradnice bodov sú reprezentované ako dvojice (x,y) a nemôžu byť použité ako hodnoty premennej, môžu ale byť reprezentované referenciou. Špeciálny význam má pomenovaná súadnica Here, ktorá obsahuje súradnice posledného vykresleného bodu. Súradnice majú preddefinované atribúty .x, .y, ktoré reprezentujú numerické hodnoty zložiek polohy. Pre prácu so súradnicami sú definované vektorové operácie.
Vytvorenie súradnice #
Novú súradnicu je možné vytvárať z numerických hodnôt ako aj pomocou iných súradníc.
P1: (3,4); # vytvorenie súradnice bodu
p1 = (3,4); # chyba
a = 1; b = 2; # konverzia numerických hodnôt na súradnice
P2 = (a, b);
P3 = (a, 0); # bod na osi x
# prístup k zložkám súradnice
px = P1.x # numerická hodnota x-ovej súradnice
py = P1.y # numerická hodnota y-ovej súradnice
nx = Here.x # hodnoty aktuálnej pozície
ny = Here.y
P4: (P1, P2) # ekvivalent (P1.x, P2.y)
P5: P4 # nová súradnica
P5: P1 # redefinícia súradnice
Poznámka
Je možné používať súradnice zapísané aj bez zátvoriek v tvare x, y, ale z dôvodu možných konfliktov pri expanzii makier je vhodnejší prehľadnejší zápis so zátvorkami (x, y).
line to 1,1
line to (1,1);
Vektorové operácie #
Výsledkom vektorovej operácie nad súradnicami je zase súradnica. Pre násobenie a delenie je platná len post-multiplikacia.
S1: (a,b) + (c,d) # súčet
S2: P1 + P2
S3: P1 + (c,d)
S4: Here + (dx,dy) # offset k aktuálnej polohe
D1: (a,b) - (c,d) # rozdiel
D2: P1 - P2
D3: P1 - (c,d)
M1: (a,b)*k # násobenie, k - numerická hodnota alebo premenná
M2: P1*k
M3: k*P1 # chyba
Q1: (a,b)/k # delenie
Q2: P1/k
Poloha medzi dvoma bodmi #
Pri kreslení zapojení často potrebujeme určiť polohu medzi dvoma bodmi, v dpic môžeme použiť konštrukciu between
PB: k between P1 and P2
Hodnota k určuje relatívnu vzdialenosť ku koncovým bodom, k=0.5 je stredom, k=0 a k=1 sú polohy koncových bodov. Pri hodnote k mimo intervalu 0…1 leží za krajnými bodmi P1 a P2.
Obr. 49 Použitie konštrukcie between.#
Textové reťazce #
Text je postupnosť znakov definované v obyčajných úvodzovkách a nemôže byť použitý ako hodnota premennej. Súradnice geometrického stredu zobrazeného textu ale môže byť reprezentovaná referenciou.
str = "Toto je text" # chyba
T1: "Toto je text" at (1,1); # ok, stred textu je v bode (1,1)
Inštrukcie #
Inštrukcia je jeden alebo viacej príkazov jazyka dpic končiacich znakom bodkočiarky ; alebo znakom konca riadku. Je vhodné implicitne používať znak konca riadku vždy, pri prípadnom dopĺňaní príkazu sa týmto obmedzí vznik chýb. Pretože v jazyku dpic nie je možné vytvárať funkcie a podprogramy, sú skupiny príkazov zoskupené do makier pomocou ktorých sa vykreslujú zložitejšie objekty. V CircuitMacros je program tvorený inštrukciami ktoré sú makrami ako aj samotnými príkazmi jazyka dpic. Formát inštrukcie v má tvar
[referencia:] objekt [ atributy] [ umiestnenie ] [ text ]
Príklady
line from (1,1) to (2,2) # inštrukcia jazyka dpic
resistor(,,E); # makro inštrukcia končí znakom ;
capacitor() # makro inštrukcia končí \n
resistor() rlabel(,R2,) # chyba, neoddelene inštrukcie
line to Here + (2,0); resistor() # dpic a makro inšrukcia
Referencie #
Každý zobrazený objekt v môže byť označený referenciou, ktorá reprezentuje polohu jeho geometrického stredu. Pomocou referncie je možné odkazovať sa aj na atribúty objektu. Referencie musí začínať veľkým písmenom nasledovaným ľubovolným počtom alfanumerických znakov.
L1: line from Here to Here + (2,2);
R1: resistor();
S: (5,6);
P1: R1.start # suradnica
P2: L1.end
px = R1.end.x # numericka hodnota
Referencie sú globálne, referencia definovaná v bloku alebo vetve je viditeľná v celom programe. Nové priradenie mena referencie inému objektu pôvodnú referenciu prepíše. Pri kreslení zapojení sa stáva, že musíme presne spojiť dva body zapojenia, ktorých absolútnu polohu nepoznáme. Využitím vektorvých operácií s referenciami na objekty získame spojenie, ktoré sa nepreruší ani pri dodatočnej uprave polohy objektov.
Obr. 50 Použitie referencií pre výpočtu koncového bodu čiary.#
Vetvy #
Vetva je tvorená kódom uzatvoreným do zložených zátvoriek {...}. Vetva umožňuje vytváranie časti obvodu alebo umiestnenie iných komponentov relatívne k poslednej hodnote Here, vo vetve sa vytvorí lokálna kópia Here. S výhodou ich použijeme v prípade, keď potrebujeme nakresliť samostatnú časť obvodu (vetvu) a potom pokračovať v kreslení zapojenia od pôvodnej pozície.
Uzatvorenie kódu do vetvy {...} neovplyvňuje viditeľnosť premenných. Vetvy je možné do seba vnárať.
d=3;
R1: resistor(right_ d,); # d -> 3
DT: dot;
{ d = 2; # Here -> DT
R2: resistor(down_ d,); # Here -> R2.end
ground(at Here, T);
d=1.5;
}
{ R3: resistor(up_ d,); # d -> 1.5 Here -> R3.end
tconn(0.5,O);
d=2.5;
}
# Here -> DT
R4: resistor(right_ d); # d -> 2.5 Here -> R4.end
Obr. 51 Použitie vetiev na kreslenie častí obvodu.#
Vetvy s výhodou využijeme pri popise prvkov zapojenie. Zobrazenie textu mení rovnako ako každý nový element zapojenia hodnotu Here, ak chceme v kreslení pokračovať s pôvodnou súradnicou, uzatvoríme text do vetvy. Príkazy pre popis dvojpólov (llabel …) hodnotu Here nemenia.
line -> 1;
box wid 2 ht 1;
{
"top of box" at last box.n above;
"bottom of box" at last box.s below;
line from last box.nw to last box.se;
line from last box.sw to last box.ne;
}
line -> 1;
box wid 2 ht 1;
Bloky a zložené objekty#
Časť kódu uzatvorená v hranatých zátvorkách [...] predstavuje blok alebo zložený objekt. Program v bloku má vlastnú absolútnu súradnicovú sústavu a po vytvorení má vlastnosti plošného objektu. Premenné v bloku sú rovnako ako vo vetve lokálne, vnútorné referencie vytvorené v bloku sú prístupné pomocou referencie na celý blok.
w=2;
move to (1,1.5); # poloha zloženého objektu
A:[ # blok s absolutnymi suradnicami
rr=0.25; # inicializácia vnútorných premenných
h=w/2; w=w+1/2; # použitie vonkajšej premennej
B: box at (0,0) wid w ht h;
C1: circle at (0, 0.5) rad rr;
C2: circle at (0,-0.5) rad rr;
C3: circle at B.w rad rr;
C4: circle at B.e rad rr;
]
Pre zložený objeky sú automaticky vypočítané vonkajšie rozmery a sú mu priradené štandardné atribúty
.s .n .w .e .c
.sw .se .nw .ne
.wid_ .ht_
Pre ukladanie a použitie zloženého objektu na ploche platia rovnaké pravidlá ako pre každý iný plošný objekt.
r = A.rr; # chyba, premenná rr nie je viditeľná
r = A.C1.rad # použitie vnútorných referncií
line <- from A.B.nw left_ 1 up_ 1;
line <- from A.ne right_ 1 up_ 1; # použitie vonkajších referencií a atribútov
right_; box at A.c wid A.wid_ ht A.ht_ dashed;
Obr. 53 Blok reprezentujúci zložený objekt a jeho vonkajší obrys.#
Riadenie toku #
Jazyk dpic obsahuje základnú konštrukciu pre cuklus a podmienkové vetvenie toku programu.
Cyklus #
Formát príkazu pre cyklu
for variable = expr to expr [by [*] incr ] do { anything }.
Jednoduchý cyklus s premennou \(x\) má tvar
for x = 0 to 200 do { line from (rand(), rand())*5 to (rand(),rand())*5; }
kde v zložených zátvorkách je telo cyklu, toto má vlastnosti bloku s relatívnymi súradnicami vztiahnutými k začiatku cyklu. Cykly sa môžu vnárať, počet vnorených cyklov nie je obmedzený. Pri opakovanom prechode telom cyklu sa hodnota kurzoru Here zachováva, čo je zrejmé zo zjednodušeného zápisu kódu
...
for q=0 to 2*pi by 0.1 do{
x = r*cos(a*q);
y = r*cos(b*q);
line to (x,y); <-- line from Here to (x,y); Here <- (x,y)
}
...
Vetvenie #
Formát vetvenia
if expression then { if-true } else { if-false }