10 #include "mop453.xpm" /* Ikona pro X Window System$^{\def\fntmag{\magstep.2}\rm TM}$ */
17 #define PI 3.14159265358979323846
21 typedef long da_num; /* budeme {\I dyna-add}it \type{long}y */
22 #define NEED_DA_POS /* potêebujeme \func{da_putpos}() a \func{da_getpos}() */
23 #include "dyna-add.c" /* modul dynamického pêidávání */
25 float curX,curY; /* souêadnice pera */
26 int curA; /* úhel natoçení pera */
28 static void draw_seq(void)
29 { /* vykresli posloupnost z~dyna-struktury */
30 long st1; /* první parametr dyna-struktury */
32 for (;;) { /* pro neomezený poçet dvojic */
33 i=da_get(&st1); assert(!!i); /* poslední prvek bude 0 */
34 if (!st1) return; /* ukonçení posloupnosti */
35 if (st1<0) { /* prvek$<0$ $\Longrightarrow$ dvë çísla */
36 long p1; /* vzdálenost */
37 float k=0/*fake for GCC*/; /* úhel v~radiánech */
38 i=da_get(&p1); assert(!!i); /* tento parametr také musí existovat */
39 curX+=p1*sin(k=(float)curA*PI/180); /* îoupni pérem */
40 wl_line((long)rint(curX*16),(long)rint((curY+=p1*cos(k))*16)); /* táhni! (\dots çáru) */
41 if ((curA+=st1)<0) curA+=360; /* natoç pero a moùná pêeteç */
43 else { /* opakuj posloupnost */
44 struct da_pos pos; /* zapamatování pozice pro opakování */
45 da_putpos(&pos); /* pamatuj! */
46 while (st1--) { /* \var{st1}-krát */
47 da_getpos(&pos); /* pro velký ohlas repríza */
48 draw_seq(); /* jedem znova posloupnost */
57 da_reset(); /* nainicializuj dyna-struktury na zaçátek */
58 wl_line((long)(curX=0),(long)(curY=0)); /* první bod je z~$(0,0)$ */
59 curA=0; /* natoçení ªna severº */
60 draw_seq(); /* zpracuj top-level posloupnost */
61 assert(!da_get(&n)); /* ujisti se, ùe to bylo vîe */
64 static long get_lex(void)
65 { /* naçti lexikální element a vraï çíslo,
66 çi LONG_MIN pro \sign[ nebo LONG_MAX pro \sign] */
67 int c,isn=0,neg=0; /* naçtený znak, kousek çísla?, záporné? */
68 long n=0; /* sestavované çíslo */
69 for (;;) { /* \dots a v~ùivotë to nikdo nezastaví */
70 if ((c=getchar())==EOF) iofail(); /* EOF má pêijít v~\func{main}()u */
71 if (c=='\n'||c=='\t') c=' '; /* white-space */
73 if (isn) break; /* je-li kousek çísla, potom oddëlovaç */
74 else continue; /* jinak ignoruj */
76 if (c=='['||c==']') break; /* terminují vùdy */
77 if (!neg&&c=='-') { neg=1; continue; } /* záporné çíslo? */
78 if (c<'0'||c>'9') iofailn(EINVAL); /* tady by to jiù mëla být cifra */
79 isn=1; /* jiù máme kousek çísla */
80 if (n>LONG_MAX/10) iofailn(ERANGE); /* nevyteçeme? */
81 n=n*10+c-'0'; /* pêedpoklady: desítková soustava a souvislé kódy cifer */
83 if (isn) { /* terminace uprostêed çísla */
84 if (neg) n=-n; /* negativní numero */
85 if (n==LONG_MIN||n==LONG_MAX) iofailn(ERANGE); /* check kolize návratových hodnot */
86 ungetc(c,stdin); /* byla-li to hranatka, bude jeîtë potêeba, white-space se sveze */
88 return(isn?n:(c=='['?LONG_MIN:LONG_MAX)); /* çíslo, çi typ hranatky */
91 long p1,p2; /* pro chroustání posloupnosti jsou jako auto-variábly zbyteçnë expensive */
93 static void do_seq(void)
94 { /* nachroustej jednu úroveñ posloupnosti */
95 while ((p1=get_lex())!=LONG_MAX) { /* dokud nenarazíî na \sign] */
96 if (p1==LONG_MIN) iofailn(EINVAL); /* $P_1$ musí být çíslo */
97 if ((p2=get_lex())==LONG_MAX) iofailn(EINVAL); /* $P_2$ nesmí být \sign] */
98 if (p2==LONG_MIN) { /* bylo-li $P_2$ \sign[ */
99 if (p1<=0) iofailn(EINVAL); /* $P_1$ musí být kladné */
100 da_put(p1); /* uloù kladné çíslo jako opakovaní */
101 do_seq(); /* rekurzivnë zpracuj opakovanou posloupnost */
103 else { /* budeme kreslit */
104 p2%=360; if (p2>=0) p2-=360; /* znormalizuj úhel do záporna */
105 da_put(p2); da_put(p1); /* nejdêív úhel ($P_2$ -- odliîení od opakování),
106 potom délka ($P_1$) */
109 da_put(0); /* terminátor posloupnosti */
112 int main(int argc,char **argv)
115 wl_init(&argc,argv,"MOP453"); /* inicializuj gfx */
116 if (get_lex()!=LONG_MIN) iofailn(EINVAL); /* první element musí být \sign[ */
117 do_seq(); /* zpracuj top-level posloupnost */
118 do i=getchar(); while (i==' '||i=='\n'||i=='\t'); /* seùer white-spacy */
119 if (i!=EOF) iofailn(EINVAL); /* musí být EOF, jinak ERROR */
120 wl_done(); /* gfx okno */
121 return(0); /* hotovo */