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é 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 jazyka 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.

Listing 3 : Štruktúra programu#
.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é, ale je 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 
!=   ==   <   >   >=   <=   ||   &&

Súradnice #

Súradnice bodov sú reprezentované ako dvojice hodnôt v tvare (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. 59:

_images/cm_0160z.png

Obr. 59 Použitie konštrukcie between.#

Objekty #

Programovací jazyk dpic je určený pre generovanie grafiky, ktorá je založená na elementárnych objektoch, s ktorými v programe pracujeme. Elementárnymi objektami jazyka dpic sú:

line, move, arrow, arc, box, ellipse, circle, spline, [], "text" 

Každý objekt má priradenú sadu atribútov, ktoré definujú polohu v rámci objektu. Všeobecná forma prístupu k atribútom má tvar:

objekt.pozícia 

Kód uzatvorený v hranatých zátvorkách [...] reprezentuje zložený objekt. Text je postupnosť znakov definované v obyčajných úvodzovkách. Vykreslený text na ploche má vlastnosti plošného objektu, je možné k nemu pristupovať pomocou refrerencie. Pretože rozmery textu nie sú počas vykreslovania známe, všetky atribúty objektu majú hodnotu súradnice jeho stredu. Objekty nemôžu byť použité ako hodnoty premennej.

str = "Toto je text"          # chyba   
line = line from A to B;      # chyba

T1: "Toto je text" at (1,1);  # stred textu je v bode (1,1)
L1: line from A to B;         # objekt s atribútmi .start, .end, .center

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 referencie je možné odkazovať sa aj na atribúty objektu. Referencia 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 vektorových operácií s referenciami na objekty získame spojenie, ktoré sa nepreruší ani pri dodatočnej úprave polohy objektov, Obr. 60.

_images/cm_0160c.png

Obr. 60 Použitie referencií pre výpočtu koncového bodu čiary.#

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, Obr. 61.

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;
_images/cm_0160d.png

Obr. 61 Blok reprezentujúci zložený objekt a jeho vonkajší obrys.#

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ť, Obr. 62.

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
_images/cm_0160f.png

Obr. 62 Použitie vetiev na kreslenie častí obvodu.#

Vetvy s výhodou využijeme pri popise prvkov zapojenia. 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, Obr. 63.

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;
_images/cm_0160e.png

Obr. 63 Lokálne súradnice vo vetve.#

Riadenie toku #

Jazyk dpic obsahuje základnú konštrukciu pre cyklus a podmienkové vetvenie toku programu.

Cyklus #

Formát príkazu pre prikaz 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 skráteného zápisu kódu, Obr. 64.

...
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)
}
...
_images/cm_0160b.png

Obr. 64 Príklad použitia cyklu.#

Vetvenie #

Formát príkazu pre vetvenie programu:

if expression then { if-true } else { if-false }

V nasledujúcom príklade je premennou type parametrizované vykreslenie sériového alebo paralelného zapojenia rezistorov, Obr. 65.

type=1;
if type==1 then{
    line 1; dot;
    parallel_(`R1:resistor; llabel(,R1,);',`R2:resistor; llabel(,R2,);')
    dot; line 1;
}else{
    line 0.5;
    series_(`R1:resistor; llabel(,R1,);',`R2:resistor; llabel(,R2,);')
    line 0.5;
}
_images/cm_0160w.png

Obr. 65 Príklad použitia vetvenia pre parametrizáciu vykresleného obvodu.#