1 module feature.feature;
2 import std.stdio;
3 import std.string;
4 import dweb.view_engine;
5 import std.array;
6 import std.conv;
7 import feature.types;
8 public class Feature : ViewEngine{
9 	private Type function(string)[string] _types;
10 	private Type function(Type[])[string] functions; 
11 
12 	this(){
13 		this._types = [
14 			"string": &str,
15 			"int": &integer
16 		];
17 		this.functions = [
18 			"concat": &concatstr
19 		];
20 	}
21 	public override string render(string source){
22 		return srender(source);
23 	}
24 	private string srender(string source, Type[string] co = null){
25 		Type[string] constants;
26 		if(co !is null)
27 			constants = co;
28 		string res = source.dup;
29 		string[] src = source.split("\n");
30 		for(int i = 0; i < src.length; i++){
31 			string str = src[i];
32 			ptrdiff_t index = indexOf(str, "@define");
33 			if(index != -1){
34 				string ns = str.split("@define ")[1];
35 				string  val;
36 				string name;
37 				string type;
38 
39 				if(ns.split(' ').length > 0)
40 			 		type = ns.split(' ')[0];
41 			 	else
42 			 		throw new Exception("Type of constant has no wrote!");
43 			 	if(ns.split(' ').length > 1)
44 			 		name = ns.split(' ')[1];
45 			 	else
46 			 		throw new Exception("Name of constant has no wrote!");
47 			 	if(ns.split(' ').length > 2)
48 			 		val = ns.split(' ')[2 .. ns.split(' ').length].join(' ');
49 			 	else
50 			 		throw new Exception("Value of constant named as \"" ~ name ~ "\" has no wrote!");
51 			 	Type c = this._types[type](val);
52 			 	constants[name] = c;
53 
54 			 	src[i] = str.replace(name, "").replace("@define", "").replace(val, "").replace(type, "");
55 			}
56 			index = indexOf(str, "@repeat");
57 			if(index != -1){
58 				string ns = str.split("@repeat ")[1];
59 				int num;
60 				if(ns.split(' ').length > 0)
61 			 		num = ns.split(' ')[0].to!int();
62 			 	else
63 			 		throw new Exception("Number of repeats has no wrote!");
64 			 	string[] torepeat;
65 			 	int r = 1;
66 			 	int start = i;
67 			 	while(r > 0){
68 			 		i++;
69 			 		if(src[i].indexOf("@end") != -1){
70 			 			r--;
71 			 			if(r == 0){
72 			 				src[i] = "";
73 			 				continue;
74 			 			}
75 			 		}
76 			 		if(src[i].indexOf("@repeat") != -1){
77 			 			r++;
78 			 		}
79 			 		torepeat ~= [src[i]];
80 
81 			 	}
82 			 	int end = i;
83 			 	src = src[0 .. start] ~ src[end .. src.length];
84 			 	for(int j = 0; j < num; j++){
85 			 		constants["iteration"] = new IntType(j);
86 			 		src[start] ~= "\n" ~ srender(torepeat.join("\n"), constants) ~ "\n";
87 			 	}
88 			 	constants.remove("iteration");
89 
90 			}
91 			foreach(func; this.functions.byPair){
92 				if(indexOf(str, "@" ~ func.key ~ "(") != -1){
93 					string[] sargs =str.split("@" ~ func.key ~ "(")[1].split(")")[0].split(' ');
94 					Type[] args;
95 					for(int h = 0; h < sargs.length; h++){
96 						Type arg;
97 
98 						if(sargs[h][0] == '@'){
99 							arg = constants[sargs[h].replace("@", "")];
100 						}
101 						else{
102 							arg = new StringType(sargs[h]);
103 						}
104 						args ~= [arg];
105 					}
106 					str = str.replace("@" ~ func.key, func.value(args).ToString());
107 					str = str[0 .. indexOf(str, "(")] ~ str[indexOf(str, ")") + 1 .. str.length];
108 					src[i] = str; 
109 				}
110 			}
111 			foreach(constant; constants.byPair){
112 				if(indexOf(str, "@" ~ constant.key) != -1){
113 					str=str.replace("@" ~ constant.key, constant.value.ToString());
114 				
115 					src[i] = str;
116 				}
117 			}
118 			
119 		}
120 		return src.join("\n");
121 	}
122 }
123 
124 Type str(string val) {
125 	StringType s = new StringType(val);
126 
127 	return s;
128 }
129 Type integer(string val) {
130 	IntType s = new IntType(val);
131 
132 	return s;
133 }
134 Type concatstr(Type[] args){
135 	string str;
136 	foreach(arg; args){
137 		str ~= arg.ToString();
138 	}
139 	StringType s = new StringType(str);
140 
141 	return s;
142 }