• R/O
  • SSH
  • HTTPS

nina: Commit


Commit MetaInfo

Revisión653 (tree)
Tiempo2017-07-08 09:26:20
Autory-moriguchi

Log Message

Example: m4 macro processor

Cambiar Resumen

Diferencia incremental

--- nina/examples/m4/m4.cs (revision 652)
+++ nina/examples/m4/m4.cs (revision 653)
@@ -69,6 +69,7 @@
6969 private string commentBegin;
7070 private string commentEnd;
7171 public ACNode Special { get; private set; }
72+ public bool SuppressComment { get; private set; }
7273 public string QuoteBegin
7374 {
7475 get
@@ -212,13 +213,13 @@
212213
213214 if(mname.Equals("define"))
214215 {
215- if(lst.Count < 2)
216+ if(lst.Count < 1)
216217 {
217218 WriteUnevalMacro(mname, lst);
218219 }
219220 else
220221 {
221- DefineMacro(lst[0], lst[1]);
222+ DefineMacro(lst[0], lst.Count > 1 ? lst[1] : "");
222223 }
223224 return true;
224225 }
@@ -236,7 +237,7 @@
236237 }
237238 else if(mname.Equals("pushdef"))
238239 {
239- if(lst.Count < 2)
240+ if(lst.Count < 1)
240241 {
241242 WriteUnevalMacro(mname, lst);
242243 return true;
@@ -250,7 +251,7 @@
250251 mstk = new List<string>();
251252 macros.Add(lst[0], mstk);
252253 }
253- mstk.Add(lst[1]);
254+ mstk.Add(lst.Count > 1 ? lst[1] : "");
254255 return true;
255256 }
256257 else if(mname.Equals("popdef"))
@@ -270,6 +271,20 @@
270271 }
271272 return true;
272273 }
274+ else if(mname.Equals("defn"))
275+ {
276+ if(lst.Count < 1)
277+ {
278+ WriteUnevalMacro(mname, lst);
279+ return true;
280+ }
281+ else if(macros.ContainsKey(lst[0]))
282+ {
283+ mstk = macros[lst[0]];
284+ Write(mstk[mstk.Count - 1]);
285+ }
286+ return true;
287+ }
273288 else if(mname.Equals("ifdef"))
274289 {
275290 if(lst.Count < 2)
@@ -444,6 +459,35 @@
444459 }
445460 return true;
446461 }
462+ else if(mname.Equals("substr"))
463+ {
464+ int pos, len;
465+
466+ if(lst.Count < 3)
467+ {
468+ WriteUnevalMacro(mname, lst);
469+ }
470+ else
471+ {
472+ if(!int.TryParse(lst[1], out pos) || !int.TryParse(lst[2], out len))
473+ {
474+ throw new M4Exception();
475+ }
476+ else if(pos < 0 && pos >= lst[0].Length)
477+ {
478+ throw new M4Exception();
479+ }
480+ else if(len < 0 && len + pos >= lst[0].Length)
481+ {
482+ throw new M4Exception();
483+ }
484+ else
485+ {
486+ Write(lst[0].Substring(pos, len));
487+ }
488+ }
489+ return true;
490+ }
447491 else if(mname.Equals("translit"))
448492 {
449493 if(lst.Count < 3)
@@ -530,8 +574,11 @@
530574 {
531575 M4Object m4obj = new M4Object(this);
532576 List<string> mstk = macros[mname];
577+ string mbody;
533578
534- m4obj.Reader = new StringReader(mstk[mstk.Count - 1]);
579+ m4obj.SuppressComment = true;
580+ mbody = ScanArgs(mstk[mstk.Count - 1], mname, lst);
581+ m4obj.Reader = new StringReader(mbody);
535582 m4obj.macroName = mname;
536583 m4obj.args = lst;
537584 M4p.Eval(m4obj);
@@ -538,6 +585,93 @@
538585 }
539586 }
540587
588+ private string ScanArgs(string body, string macroName, List<string> args)
589+ {
590+ int arg;
591+ char c;
592+ StringBuilder b = new StringBuilder(), n;
593+
594+ for(int i = 0; i < body.Length; i++)
595+ {
596+ c = body[i];
597+ if(c == '$')
598+ {
599+ if(++i >= body.Length)
600+ {
601+ b.Append(c);
602+ }
603+ else if((c = body[i]) >= '0' && c <= '9')
604+ {
605+ n = new StringBuilder();
606+ for(; i < body.Length && (c = body[i]) >= '0' && c <= '9'; i++)
607+ {
608+ n.Append(c);
609+ }
610+ i--;
611+ arg = int.Parse(n.ToString());
612+ if(arg == 0 && macroName != null)
613+ {
614+ b.Append(macroName);
615+ }
616+ else if(arg > 0 && args != null)
617+ {
618+ if(arg - 1 < args.Count)
619+ {
620+ b.Append(args[arg - 1]);
621+ }
622+ }
623+ }
624+ else if("#@*".IndexOf(c) >= 0)
625+ {
626+ switch(c)
627+ {
628+ case '#':
629+ b.Append(args.Count);
630+ break;
631+ case '*':
632+ for(int j = 0; j < args.Count; j++)
633+ {
634+ b.Append(args[j]);
635+ if(j < args.Count - 1)
636+ {
637+ b.Append(',');
638+ }
639+ }
640+ break;
641+ case '@':
642+ for(int j = 0; j < args.Count; j++)
643+ {
644+ b.Append(QuoteBegin + args[j] + QuoteEnd);
645+ if(j < args.Count - 1)
646+ {
647+ b.Append(',');
648+ }
649+ }
650+ break;
651+ }
652+ }
653+ else
654+ {
655+ b.Append('$');
656+ b.Append(c);
657+ }
658+ }
659+ else if(c == '\u0001')
660+ {
661+ b.Append(QuoteBegin);
662+ }
663+ else if(c == '\u0002')
664+ {
665+ b.Append(QuoteEnd);
666+ }
667+ else
668+ {
669+ b.Append(c);
670+ }
671+ }
672+ return b.ToString();
673+ }
674+
541675 private void AddAllSplited(List<string> nlst, string text)
542676 {
543677 int cnt = 0, par = 0;
@@ -549,13 +683,13 @@
549683 c = text[i];
550684 if(cnt > 0)
551685 {
552- if(text.IndexOf(QuoteBegin) == i + QuoteBegin.Length)
686+ if(text.IndexOf(QuoteBegin) == i)
553687 {
554688 b.Append(QuoteBegin);
555689 i += QuoteBegin.Length - 1;
556690 cnt++;
557691 }
558- else if(text.IndexOf(QuoteEnd) == i + QuoteEnd.Length)
692+ else if(text.IndexOf(QuoteEnd) == i)
559693 {
560694 b.Append(QuoteEnd);
561695 i += QuoteEnd.Length - 1;
@@ -580,7 +714,7 @@
580714 }
581715 else
582716 {
583- if(text.IndexOf(QuoteBegin) == i + QuoteBegin.Length)
717+ if(text.IndexOf(QuoteBegin) == i)
584718 {
585719 b.Append(QuoteBegin);
586720 i += QuoteBegin.Length - 1;
@@ -612,7 +746,7 @@
612746
613747 foreach(string str in lst)
614748 {
615- evd = EvalToString(str);
749+ evd = EvalToString(Regex.Replace(str, "^[ \n\t]+", ""));
616750 AddAllSplited(nlst, evd);
617751 }
618752 EvalMacroEvaled(mname, nlst);
@@ -622,6 +756,7 @@
622756 {
623757 M4Object m4obj = new M4Object(this);
624758
759+ m4obj.SuppressComment = true;
625760 m4obj.Reader = new StringReader(text);
626761 M4p.Eval(m4obj);
627762 }
@@ -632,6 +767,7 @@
632767 TextWriter tmp;
633768 StringWriter sw;
634769
770+ m4obj.SuppressComment = true;
635771 m4obj.Reader = new StringReader(text);
636772 tmp = divertBuffers[divnum];
637773 m4obj.divertBuffers[divnum] = sw = new StringWriter();
@@ -640,51 +776,6 @@
640776 return sw.ToString();
641777 }
642778
643- public void WriteArg(int arg)
644- {
645- if(arg == 0 && macroName != null)
646- {
647- Eval(macroName);
648- }
649- else if(arg > 0 && args != null)
650- {
651- if(arg - 1 < args.Count)
652- {
653- Eval(args[arg - 1]);
654- }
655- }
656- }
657-
658- public void WriteArgFunny(int ch)
659- {
660- switch(ch)
661- {
662- case '#':
663- Write(args.Count);
664- break;
665- case '*':
666- for(int i = 0; i < args.Count; i++)
667- {
668- Eval(args[i]);
669- if(i < args.Count - 1)
670- {
671- Write(',');
672- }
673- }
674- break;
675- case '@':
676- for(int i = 0; i < args.Count; i++)
677- {
678- Write(args[i]);
679- if(i < args.Count - 1)
680- {
681- Write(',');
682- }
683- }
684- break;
685- }
686- }
687-
688779 public void Flush() {
689780 for(int i = 1; i < MaxDivert; i++)
690781 {
@@ -949,19 +1040,20 @@
9491040 using(StreamReader sr = new StreamReader(args[cnt]))
9501041 {
9511042 m4obj = new M4Object(m4obj, sr);
952- M4p.Eval(m4obj);
1043+ m4obj = M4p.Eval(m4obj);
1044+ m4obj.Flush();
9531045 }
9541046 }
9551047 }
9561048 else
9571049 {
958- while(!M4p.EvalFromConsole(m4obj))
1050+ while((m4obj = M4p.EvalFromConsole(m4obj)) != null)
9591051 {
9601052 Console.WriteLine();
9611053 m4obj.DnlFlg = false;
1054+ m4obj.Flush();
9621055 }
9631056 }
964- m4obj.Flush();
9651057 Environment.Exit(0);
9661058 }
9671059 }
--- nina/examples/m4/m4t.sh (nonexistent)
+++ nina/examples/m4/m4t.sh (revision 653)
@@ -0,0 +1,25 @@
1+rm test/testtmp*.txt
2+
3+awk '
4+BEGIN { no = 1; }
5+/^-+$/ { close(sprintf("test/testtmp%04d.txt", no)); no++; next; }
6+{ print > (sprintf("test/testtmp%04d.txt", no)); }
7+' test.txt
8+
9+for i in test/testtmp*.txt
10+do
11+ j=`echo $i | sed 's/\.txt//'`
12+ if ! m4 $i > $j.out1.txt
13+ then
14+ echo "$i - original failed"
15+ elif ! mono --debug m4.exe $i > $j.out2.txt
16+ then
17+ echo "$i - exe failed"
18+ elif diff $j.out1.txt $j.out2.txt
19+ then
20+ echo "$i - Success"
21+ else
22+ echo "$i - failed"
23+ fi
24+done
25+
--- nina/examples/m4/test.txt (nonexistent)
+++ nina/examples/m4/test.txt (revision 653)
@@ -0,0 +1,242 @@
1+This is a plain text.
2+-------------
3+define(`plain',`macro')
4+This is a plain text.
5+-------------
6+define(`plain',`macro')
7+This is a `plain' text.
8+-------------
9+define(`plain',`macro')
10+This is a ``plain'' text.
11+-------------
12+define(`plain', `macro')
13+This is a plain text.
14+-------------
15+define(`plain', macro)
16+This is a plain text.
17+-------------
18+define(`plain',macro )
19+This is a plain text.
20+-------------
21+define(`plain' ,macro )
22+This is a plain text.
23+-------------
24+define( plain, macro)
25+This is a plain text.
26+-------------
27+define(X,Y)
28+define(Y,`macro')
29+This is a X text.
30+-------------
31+define(X,`macro
32+newline')
33+This is a X text.
34+-------------
35+define(X,`test')
36+define(`test',`macro')
37+This is a X text.
38+-------------
39+define(X,``test'')
40+define(`test',`macro')
41+This is a X text.
42+-------------
43+define(X,`$1 -> $2')
44+X(a,b)
45+X(`a',`b')
46+X( a , b )
47+X(a)
48+X( a )
49+X()
50+-------------
51+define(X,`$0$#')
52+X(a)
53+-------------
54+define(`echo1',`$*')
55+define(pen,pineapple)
56+echo1(`I',`have',`a',`pen')
57+echo1(`I',`have',`a',``pen'')
58+-------------
59+define(`echo1',`$@')
60+define(pen,pineapple)
61+echo1(`I',`have',`a',`pen')
62+echo1(`I',`have',`a',``pen'')
63+-------------
64+define(`X',`XJapan')
65+X : Kurenai
66+undefine(`X')
67+X : Kurenai
68+-------------
69+define(`X',`XJapan')
70+X : Kurenai
71+pushdef(`X',``X'')
72+X : Kurenai
73+popdef(`X')
74+X : Kurenai
75+-------------
76+include(`zinc.txt')
77+-------------
78+sinclude(`zinc.txt')
79+-------------
80+define(`inc', sinclude(`zinc.txt'))
81+inc
82+Syoko Hoshi : Kurenai
83+inc
84+-------------
85+ifdef(`COND',``COND' is defined...
86+`COND' is COND.',`COND is *NOT* defined!')
87+-------------
88+define(`COND')
89+ifdef(`COND',``COND' is defined...
90+`COND' is COND.',`COND is *NOT* defined!')
91+-------------
92+define(`COND', `condition A')
93+ifdef(`COND',``COND' is defined...
94+`COND' is COND.',`COND is *NOT* defined!')
95+-------------
96+define(`COND', 1)
97+ifelse(COND,1,``COND' is one',``COND' is COND')
98+-------------
99+define(`COND', 3)
100+ifelse(COND,1,``COND' is one',``COND' is COND')
101+-------------
102+define(`COND', 1)
103+ifelse(COND,1,``COND' is one',COND,2,``COND' is two',``COND' is COND')
104+-------------
105+define(`COND', 2)
106+ifelse(COND,1,``COND' is one',COND,2,``COND' is two',``COND' is COND')
107+-------------
108+define(`COND', 3)
109+ifelse(COND,1,``COND' is one',COND,2,``COND' is two',``COND' is COND')
110+-------------
111+define(`last',`ifelse($#,1,$1,`last(shift($@))')')
112+last(foo,bar,baz,quux)
113+-------------
114+define(`reverse',`ifelse($#,1,$1,`reverse(shift($@)) $1')')
115+reverse(`foo',`bar',`baz',`quux')
116+-------------
117+define(`forloop',
118+ `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
119+define(`_forloop',
120+ `$4`'ifelse($1, `$3', ,
121+ `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
122+forloop(`i', 1, 8, `i ')
123+forloop(`i', 1, 4, `forloop(`j', 1, 8, `(i, j) ')
124+')
125+-------------
126+changequote(/*,*/)
127+define(/*reverse*/,/*ifelse($#,1,$1,/*reverse(shift($@)) $1*/)*/)
128+reverse(/*foo*/,/*bar*/,/*baz*/,/*quux*/)
129+-------------
130+changecom(/*,*/)
131+define(`X',`XFree86')
132+/* comment for X */
133+# for X Window System
134+-------------
135+X
136+define(`X',`test')
137+X
138+define(`X',`test')dnl
139+X
140+-------------
141+incr(1)
142+decr(2)
143+-------------
144+eval(1)
145+eval(+1)
146+eval(-1)
147+eval(2 ** 3)
148+eval(5 * 3)
149+eval(5 / 3)
150+eval(5 % 3)
151+eval(5 + 3)
152+eval(5 - 3)
153+eval(5 == 3)
154+eval(3 == 3)
155+eval(5 != 3)
156+eval(3 != 3)
157+eval(5 >= 3)
158+eval(3 >= 3)
159+eval(2 >= 3)
160+eval(5 <= 3)
161+eval(3 <= 3)
162+eval(2 <= 3)
163+eval(5 > 3)
164+eval(3 > 3)
165+eval(2 > 3)
166+eval(5 < 3)
167+eval(3 < 3)
168+eval(2 < 3)
169+eval(!5)
170+eval(~5)
171+eval(7 & 3)
172+eval(5 | 3)
173+eval(7 ^ 3)
174+eval(5 && 3)
175+eval(5 && 0)
176+eval(0 && 3)
177+eval(0 && 0)
178+eval(5 || 3)
179+eval(5 || 0)
180+eval(0 || 3)
181+eval(0 || 0)
182+eval(2 ** +3)
183+eval(2 ** 3 * 2)
184+eval(2 ** (3 * 2))
185+eval(2 + 3 * 5)
186+eval(5 * (3 + 2))
187+eval(2 - 3 * 5)
188+eval(5 / (3 + 2))
189+eval(2 % 3 * 5)
190+eval(5 % (3 + 2))
191+eval(2 == 5 + 3)
192+eval(2 == 5 - 3)
193+eval(2 != 5 + 3)
194+eval(2 != 5 - 3)
195+eval(2 <= 5 + 3)
196+eval(2 <= 5 - 3)
197+eval(2 >= 5 + 3)
198+eval(2 >= 5 - 3)
199+eval(2 < 5 + 3)
200+eval(2 < 5 - 3)
201+eval(2 > 5 + 3)
202+eval(2 > 5 - 3)
203+eval(5 + (3 == 2))
204+eval(5 - (3 == 2))
205+eval(5 + (3 != 2))
206+eval(5 - (3 != 2))
207+eval(5 + (3 <= 2))
208+eval(5 - (3 <= 2))
209+eval(5 + (3 >= 2))
210+eval(5 - (3 >= 2))
211+eval(5 + (3 < 2))
212+eval(5 - (3 < 2))
213+eval(5 + (3 > 2))
214+eval(5 - (3 > 2))
215+eval(!5 == 1)
216+eval(!5 != 1)
217+eval(!5 <= 1)
218+eval(!5 >= 1)
219+eval(!5 < 1)
220+eval(!5 > 1)
221+eval(~5 == 1)
222+eval(~5 != 1)
223+eval(~5 <= 1)
224+eval(~5 >= 1)
225+eval(~5 < 1)
226+eval(~5 > 1)
227+eval(2 & !5)
228+eval(2 | 3 & 5)
229+eval(2 ^ 3 & 5)
230+eval(2 && 3 | 5)
231+eval(2 || 3 && 5)
232+-------------
233+define(`reverse',`ifelse($#,1,$1,`reverse(shift($@)) $1')')
234+defn(`reverse')
235+-------------
236+len(aaaaaaa)
237+substr(abcdefg,3,2)
238+substr(abcdefg,0,7)
239+substr(abcdefg,6,1)
240+-------------
241+define(`X',`I have a pen. I have an apple.')
242+translit(X,`a-z',`A-Z')
\ No newline at end of file
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Show on old repository browser