1: <?php
2: 3: 4: 5: 6:
7:
8: namespace Peg\Lib\Generator;
9:
10: 11: 12:
13: abstract class Base
14: {
15:
16: 17: 18: 19: 20:
21: public $symbols;
22:
23: 24: 25: 26:
27: public $templates_path;
28:
29: 30: 31: 32:
33: public $output_path;
34:
35: 36: 37: 38: 39:
40: public $generator_name;
41:
42: 43: 44: 45: 46: 47: 48: 49:
50: public function __construct(
51: $templates,
52: $output,
53: $generator_name,
54: \Peg\Lib\Definitions\Symbols &$symbols
55: )
56: {
57: $this->symbols =& $symbols;
58: $this->templates_path = rtrim($templates, "\\/") . "/";
59: $this->output_path = rtrim($output, "\\/") . "/";
60: $this->generator_name = $generator_name;
61:
62:
63:
64: $this->output_path = str_replace(
65: "/$generator_name/",
66: "/",
67: $this->output_path
68: ) . $generator_name . "/";
69:
70: $this->templates_path = str_replace(
71: "/$generator_name/",
72: "/",
73: $this->templates_path
74: ) . $generator_name . "/";
75: }
76:
77: 78: 79: 80: 81: 82:
83: public function Indent($code, $spaces)
84: {
85: $indent = "";
86:
87: for($i=0; $i<$spaces; $i++)
88: {
89: $indent .= " ";
90: }
91:
92: if(substr_count($code, "\n") <= 1)
93: return $indent . $code;
94:
95: $code = str_replace("\n", "\n$indent", $code);
96:
97: return $code;
98: }
99:
100: 101: 102: 103: 104: 105:
106: public function ($name)
107: {
108: return "PHP_" . strtoupper(
109: str_replace(
110: array("/", ".", "-"),
111: "_",
112: $name
113: )
114: );
115: }
116:
117: 118: 119: 120: 121: 122:
123: public function ($name)
124: {
125: return "php_" . strtolower(
126: str_replace(
127: array("/", "-"),
128: "_",
129: $name
130: )
131: );
132: }
133:
134: 135: 136: 137: 138: 139:
140: public function GetSourceNamePHP($name)
141: {
142: return str_replace(
143: ".h",
144: ".cpp",
145: $this->GetHeaderNamePHP($name)
146: );
147: }
148:
149: 150: 151: 152: 153:
154: public function GetCustomSources()
155: {
156: $sources = scandir($this->templates_path . "custom_sources");
157:
158: foreach($sources as $index=>$source)
159: {
160:
161: if(strpos($source, ".php") === false)
162: {
163: unset($sources[$index]);
164: continue;
165: }
166:
167: $sources[$index] = str_replace(".php", "", $source);
168: }
169:
170: return $sources;
171: }
172:
173: 174: 175: 176: 177: 178: 179: 180: 181: 182:
183: public function GetTemplatePath(
184: $name, $type, $subtype, $dir, $overrides_prefix="", $namespace=""
185: )
186: {
187: if($namespace)
188: {
189: $namespace = strtolower(
190: str_replace(
191: array("\\", "::"),
192: "_",
193: $namespace
194: )
195: ) . "_";
196: }
197:
198: if($overrides_prefix)
199: {
200: $overrides_prefix = rtrim($overrides_prefix, "_") . "_";
201: }
202:
203: $override = $this->templates_path
204: . "{$dir}/{$overrides_prefix}overrides/"
205: . "{$subtype}_" . $namespace . strtolower(
206: str_replace(
207: array("/", "-", "."),
208: "_",
209: $name
210: )
211: )
212: . ".php"
213: ;
214:
215: if(file_exists($override))
216: {
217: return $override;
218: }
219:
220: if($type)
221: $type .= "_";
222:
223: return $this->templates_path
224: . "{$dir}/"
225: . "{$type}{$subtype}.php"
226: ;
227: }
228:
229: 230: 231: 232: 233: 234:
235: public function GetGenericTemplate($name, $subdir="")
236: {
237: if($subdir)
238: $subdir = trim($subdir, "\\/") . "/";
239:
240: return $this->templates_path
241: . $subdir
242: . "{$name}.php"
243: ;
244: }
245:
246: 247: 248: 249: 250: 251: 252: 253: 254:
255: public function GetParameterTemplate(
256: \Peg\Lib\Definitions\Element\Parameter $parameter,
257: $namespace="",
258: $type="declare"
259: )
260: {
261: if(!$this->generator_name)
262: {
263: throw new \Exception(t("The generator name wasn't set."));
264: }
265:
266: if($namespace)
267: {
268: $namespace = str_replace(
269: array("\\", "::"),
270: "_",
271: $namespace
272: ) . "_";
273: }
274:
275: $function_name = strtolower($parameter->overload->function->name);
276:
277: $parameter_type = strtolower($parameter->type);
278:
279: $const = "";
280: if($parameter->is_const)
281: {
282: $const .= "_const";
283: }
284:
285: $ptr = "";
286: if($parameter->is_pointer)
287: {
288: for($i=0; $i<$parameter->indirection_level; $i++)
289: {
290: $ptr .= "_ptr";
291: }
292: }
293:
294: $ref = "";
295: if($parameter->is_reference)
296: {
297: $ref .= "_ref";
298: }
299:
300: $array = "";
301: if($parameter->is_array)
302: {
303: $array .= "_arr";
304: }
305:
306: $override_function = $this->templates_path
307: . "parameters/{$type}/overrides/"
308: . $function_name . "_" . $parameter_type
309: . $const
310: . $ptr
311: . $ref
312: . $array
313: . ".php"
314: ;
315:
316: if(file_exists($override_function))
317: {
318: return $override_function;
319: }
320:
321: $override = $this->templates_path
322: . "parameters/{$type}/overrides/"
323: . $parameter_type
324: . $const
325: . $ptr
326: . $ref
327: . $array
328: . ".php"
329: ;
330:
331: if(file_exists($override))
332: {
333: return $override;
334: }
335:
336: $standard_type = $this->symbols->GetStandardType($parameter);
337:
338: $template = $this->templates_path
339: . "parameters/{$type}/"
340: . $standard_type
341: . $const
342: . $ptr
343: . $ref
344: . $array
345: . ".php"
346: ;
347:
348: if(!file_exists($template))
349: {
350: return $this->templates_path
351: . "parameters/{$type}/"
352: . "default.php"
353: ;
354: }
355:
356: return $template;
357: }
358:
359: 360: 361: 362: 363: 364: 365: 366:
367: public function GetReturnTemplate(
368: \Peg\Lib\Definitions\Element\ReturnType $return,
369: $namespace="",
370: $type="function"
371: )
372: {
373: if(!$this->generator_name)
374: {
375: throw new \Exception(t("The generator name wasn't set."));
376: }
377:
378: if($namespace)
379: {
380: $namespace = str_replace(
381: array("\\", "::"),
382: "_",
383: $namespace
384: ) . "_";
385: }
386:
387: $function_name = strtolower($return->overload->function->name);
388:
389: $return_type = strtolower($return->type);
390:
391: $const = "";
392: if($return->is_const)
393: {
394: $const .= "_const";
395: }
396:
397: $ptr = "";
398: if($return->is_pointer)
399: {
400: for($i=0; $i<$return->indirection_level; $i++)
401: {
402: $ptr .= "_ptr";
403: }
404: }
405:
406: $ref = "";
407: if($return->is_reference)
408: {
409: $ref .= "_ref";
410: }
411:
412: $array = "";
413: if($return->is_array)
414: {
415: $array .= "_arr";
416: }
417:
418: $override_function = $this->templates_path
419: . "return/{$type}/overrides/"
420: . $function_name . "_" . $return_type
421: . $const
422: . $ptr
423: . $ref
424: . $array
425: . ".php"
426: ;
427:
428: if(file_exists($override_function))
429: {
430: return $override_function;
431: }
432:
433: $override = $this->templates_path
434: . "return/{$type}/overrides/"
435: . $return_type
436: . $const
437: . $ptr
438: . $ref
439: . $array
440: . ".php"
441: ;
442:
443: if(file_exists($override))
444: {
445: return $override;
446: }
447:
448: $standard_type = $this->symbols->GetStandardType($return);
449:
450: $template = $this->templates_path
451: . "return/{$type}/"
452: . $standard_type
453: . $const
454: . $ptr
455: . $ref
456: . $array
457: . ".php"
458: ;
459:
460: if(!file_exists($template))
461: {
462: return $this->templates_path
463: . "return/{$type}/"
464: . "default.php"
465: ;
466: }
467:
468: return $template;
469: }
470:
471: 472: 473: 474:
475: public function ($header_name)
476: {
477: $header = $this->output_path
478: . "includes/"
479: . $this->GetHeaderNamePHP($header_name)
480: ;
481:
482: $source = $this->output_path
483: . "src/"
484: . $this->GetSourceNamePHP($header_name)
485: ;
486:
487: if(file_exists($header))
488: unlink($header);
489:
490: if(file_exists($source))
491: unlink($source);
492: }
493:
494: 495: 496: 497: 498: 499:
500: public function ($header_name, &$content, $subdir="includes")
501: {
502: if($subdir)
503: {
504: $subdir = trim($subdir, "\\/") . "/";
505:
506: if(!file_exists($this->output_path . $subdir))
507: \Peg\Lib\Utilities\FileSystem::MakeDir(
508: $this->output_path . $subdir,
509: 0755,
510: true
511: );
512: }
513:
514: $header = $this->output_path
515: . $subdir
516: . $this->GetHeaderNamePHP($header_name)
517: ;
518:
519: \Peg\Lib\Utilities\FileSystem::WriteFileIfDifferent($header, $content);
520: }
521:
522: 523: 524: 525: 526: 527:
528: public function AddSource($header_name, &$content, $subdir="src")
529: {
530: if($subdir)
531: {
532: $subdir = trim($subdir, "\\/") . "/";
533:
534: if(!file_exists($this->output_path . $subdir))
535: \Peg\Lib\Utilities\FileSystem::MakeDir(
536: $this->output_path . $subdir,
537: 0755,
538: true
539: );
540: }
541:
542: $header = $this->output_path
543: . $subdir
544: . $this->GetSourceNamePHP($header_name)
545: ;
546:
547: \Peg\Lib\Utilities\FileSystem::WriteFileIfDifferent($header, $content);
548: }
549:
550: 551: 552: 553: 554: 555:
556: public function AddGenericFile($file_name, &$content, $subdir="")
557: {
558: if($subdir)
559: {
560: $subdir = trim($subdir, "\\/") . "/";
561:
562: if(!file_exists($this->output_path . $subdir))
563: \Peg\Lib\Utilities\FileSystem::MakeDir(
564: $this->output_path . $subdir,
565: 0755,
566: true
567: );
568: }
569:
570: $output_file = $this->output_path
571: . $subdir
572: . $file_name
573: ;
574:
575: \Peg\Lib\Utilities\FileSystem::WriteFileIfDifferent(
576: $output_file,
577: $content
578: );
579: }
580:
581: 582: 583:
584: abstract public function Start();
585:
586: 587: 588: 589: 590:
591: abstract public function ($header_name);
592:
593: 594: 595: 596: 597:
598: abstract public function GenerateSource($header_name);
599:
600: 601: 602: 603: 604:
605: abstract public function GenerateFunction(
606: \Peg\Lib\Definitions\Element\FunctionElement $function_object
607: );
608: }