diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/Compiler')
3 files changed, 9 insertions, 370 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs index 631aa54..b16577d 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs | |||
@@ -728,14 +728,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL | |||
728 | int dotIndex = c.Value.IndexOf('.') + 1; | 728 | int dotIndex = c.Value.IndexOf('.') + 1; |
729 | if (0 < dotIndex && (dotIndex == c.Value.Length || !Char.IsDigit(c.Value[dotIndex]))) | 729 | if (0 < dotIndex && (dotIndex == c.Value.Length || !Char.IsDigit(c.Value[dotIndex]))) |
730 | c.Value = c.Value.Insert(dotIndex, "0"); | 730 | c.Value = c.Value.Insert(dotIndex, "0"); |
731 | c.Value = "new LSL_Types.LSLFloat("+c.Value+")"; | ||
732 | } | ||
733 | else if("LSL_Types.LSLInteger" == c.Type) | ||
734 | { | ||
735 | c.Value = "new LSL_Types.LSLInteger("+c.Value+")"; | ||
736 | } | ||
737 | else if("LSL_Types.LSLString" == c.Type) | ||
738 | { | ||
739 | c.Value = "new LSL_Types.LSLString(\""+c.Value+"\")"; | ||
731 | } | 740 | } |
732 | 741 | ||
733 | // need to quote strings | ||
734 | if ("LSL_Types.LSLString" == c.Type) | ||
735 | retstr += Generate("\""); | ||
736 | retstr += Generate(c.Value, c); | 742 | retstr += Generate(c.Value, c); |
737 | if ("LSL_Types.LSLString" == c.Type) | ||
738 | retstr += Generate("\""); | ||
739 | 743 | ||
740 | return retstr; | 744 | return retstr; |
741 | } | 745 | } |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs index fa3e35b..d689f93 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs | |||
@@ -72,7 +72,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL | |||
72 | private string FilePrefix; | 72 | private string FilePrefix; |
73 | private string ScriptEnginesPath = "ScriptEngines"; | 73 | private string ScriptEnginesPath = "ScriptEngines"; |
74 | 74 | ||
75 | //private static LSL2CSConverter LSL_Converter = new LSL2CSConverter(); | ||
76 | private static CSCodeGenerator LSL_Converter = new CSCodeGenerator(); | 75 | private static CSCodeGenerator LSL_Converter = new CSCodeGenerator(); |
77 | private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap; // mapping between LSL and C# line/column numbers | 76 | private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap; // mapping between LSL and C# line/column numbers |
78 | private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); | 77 | private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs deleted file mode 100644 index cf1d489..0000000 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs +++ /dev/null | |||
@@ -1,364 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Text.RegularExpressions; | ||
32 | |||
33 | namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL | ||
34 | { | ||
35 | public class LSL2CSConverter | ||
36 | { | ||
37 | // Uses regex to convert LSL code to C# code. | ||
38 | |||
39 | //private Regex rnw = new Regex(@"[a-zA-Z0-9_\-]", RegexOptions.Compiled); | ||
40 | private Dictionary<string, string> dataTypes = new Dictionary<string, string>(); | ||
41 | private Dictionary<string, string> quotes = new Dictionary<string, string>(); | ||
42 | // c Style | ||
43 | private Regex cstylecomments = new Regex(@"/\*(.|[\r\n])*?\*/", RegexOptions.Compiled | RegexOptions.Multiline); | ||
44 | // c# one liners | ||
45 | private Regex nonCommentFwsl = new Regex("\"[a-zA-Z0-9.,:/\\n ]+//[^\"+]+([\\\\\\\"+]+)?(\\s+)?[\"+](\\s+)?(;)?", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
46 | private Regex conelinecomments = new Regex(@"[^:].?([\/]{2}[^\n]*)|([\n]{1,}[\/]{2}[^\n]*)", RegexOptions.Compiled | RegexOptions.Multiline); | ||
47 | // ([^\"])((?:[a-zA-Z])\.[a-zA-Z].?)([^\"]) | ||
48 | |||
49 | // value we're looking for: (?:[a-zA-Z])\.[a-zA-Z] | ||
50 | public LSL2CSConverter() | ||
51 | { | ||
52 | // Only the types we need to convert | ||
53 | dataTypes.Add("void", "void"); | ||
54 | dataTypes.Add("integer", "LSL_Types.LSLInteger"); | ||
55 | dataTypes.Add("float", "LSL_Types.LSLFloat"); | ||
56 | dataTypes.Add("string", "LSL_Types.LSLString"); | ||
57 | dataTypes.Add("key", "LSL_Types.LSLString"); | ||
58 | dataTypes.Add("vector", "LSL_Types.Vector3"); | ||
59 | dataTypes.Add("rotation", "LSL_Types.Quaternion"); | ||
60 | dataTypes.Add("list", "LSL_Types.list"); | ||
61 | dataTypes.Add("null", "null"); | ||
62 | dataTypes.Add("Int32", "LSL_Types.LSLInteger"); | ||
63 | dataTypes.Add("int", "LSL_Types.LSLInteger"); | ||
64 | } | ||
65 | |||
66 | public string Convert(string Script) | ||
67 | { | ||
68 | quotes.Clear(); | ||
69 | string Return = String.Empty; | ||
70 | Script = " \r\n" + Script; | ||
71 | |||
72 | // | ||
73 | // Prepare script for processing | ||
74 | // | ||
75 | |||
76 | // Clean up linebreaks | ||
77 | Script = Regex.Replace(Script, @"\r\n", "\n"); | ||
78 | Script = Regex.Replace(Script, @"\n", "\r\n"); | ||
79 | |||
80 | // QUOTE REPLACEMENT | ||
81 | // temporarily replace quotes so we can work our magic on the script without | ||
82 | // always considering if we are inside our outside quotes's | ||
83 | // TODO: Does this work on half-quotes in strings? ;) | ||
84 | string _Script = String.Empty; | ||
85 | string C; | ||
86 | bool in_quote = false; | ||
87 | bool quote_replaced = false; | ||
88 | string quote_replacement_string = "Q_U_O_T_E_REPLACEMENT_"; | ||
89 | string quote = String.Empty; | ||
90 | bool last_was_escape = false; | ||
91 | int quote_replaced_count = 0; | ||
92 | |||
93 | string removefwnoncomments = nonCommentFwsl.Replace(Script, "\"\";"); | ||
94 | |||
95 | string removecomments = conelinecomments.Replace(removefwnoncomments, ""); | ||
96 | removecomments = cstylecomments.Replace(removecomments, ""); | ||
97 | string[] localscript = removecomments.Split('"'); | ||
98 | string checkscript = String.Empty; | ||
99 | bool flip = true; | ||
100 | |||
101 | for (int p = 0; p < localscript.Length; p++) | ||
102 | { | ||
103 | //if (localscript[p].Length >= 1) | ||
104 | //{ | ||
105 | if (!localscript[p].EndsWith(@"\")) | ||
106 | { | ||
107 | flip = !flip; | ||
108 | //System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p] + " ! " + localscript[p].EndsWith(@"\").ToString()); | ||
109 | } | ||
110 | //} | ||
111 | //else | ||
112 | //{ | ||
113 | // flip = !flip; | ||
114 | // System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p]); | ||
115 | //} | ||
116 | if (!flip) | ||
117 | checkscript += localscript[p]; | ||
118 | } | ||
119 | |||
120 | //System.Console.WriteLine("SCRIPT:" + checkscript); | ||
121 | |||
122 | // checks for alpha.alpha way of referring to objects in C# | ||
123 | // ignores alpha.X alpha.Y, alpha.Z for refering to vector components | ||
124 | Match SecurityM; | ||
125 | |||
126 | |||
127 | SecurityM = Regex.Match(checkscript, @"([a-zA-Z])\.(?:[a-rt-wA-Z]|[a-zA-Z][a-zA-Z])", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
128 | if (SecurityM.Success) | ||
129 | throw new Exception("CS0103: 'The . symbol cannot be used in LSL except in float values or vector components'. Detected around: " + SecurityM.Captures[0].Value); | ||
130 | |||
131 | SecurityM = Regex.Match(checkscript, @"typeof\s", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
132 | if (SecurityM.Success) | ||
133 | throw new Exception("CS0103: 'The object.typeof method isn't allowed in LSL'"); | ||
134 | |||
135 | SecurityM = Regex.Match(checkscript, @"GetType\(", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
136 | if (SecurityM.Success) | ||
137 | throw new Exception("CS0103: 'The object.GetType method isn't allowed in LSL'"); | ||
138 | |||
139 | for (int p = 0; p < Script.Length; p++) | ||
140 | { | ||
141 | C = Script.Substring(p, 1); | ||
142 | while (true) | ||
143 | { | ||
144 | // found " and last was not \ so this is not an escaped \" | ||
145 | if (C == "\"" && last_was_escape == false) | ||
146 | { | ||
147 | // Toggle inside/outside quote | ||
148 | in_quote = !in_quote; | ||
149 | if (in_quote) | ||
150 | { | ||
151 | quote_replaced_count++; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | if (quote == String.Empty) | ||
156 | { | ||
157 | // We didn't replace quote, probably because of empty string? | ||
158 | _Script += quote_replacement_string + | ||
159 | quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]); | ||
160 | } | ||
161 | // We just left a quote | ||
162 | quotes.Add( | ||
163 | quote_replacement_string + | ||
164 | quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]), quote); | ||
165 | quote = String.Empty; | ||
166 | } | ||
167 | break; | ||
168 | } | ||
169 | |||
170 | if (!in_quote) | ||
171 | { | ||
172 | // We are not inside a quote | ||
173 | quote_replaced = false; | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | // We are inside a quote | ||
178 | if (!quote_replaced) | ||
179 | { | ||
180 | // Replace quote | ||
181 | _Script += quote_replacement_string + | ||
182 | quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]); | ||
183 | quote_replaced = true; | ||
184 | } | ||
185 | quote += C; | ||
186 | break; | ||
187 | } | ||
188 | _Script += C; | ||
189 | break; | ||
190 | } | ||
191 | last_was_escape = false; | ||
192 | if (C == @"\") | ||
193 | { | ||
194 | last_was_escape = true; | ||
195 | } | ||
196 | } | ||
197 | Script = _Script; | ||
198 | // | ||
199 | // END OF QUOTE REPLACEMENT | ||
200 | // | ||
201 | |||
202 | // | ||
203 | // PROCESS STATES | ||
204 | // Remove state definitions and add state names to start of each event within state | ||
205 | // | ||
206 | int ilevel = 0; | ||
207 | int lastlevel = 0; | ||
208 | string ret = String.Empty; | ||
209 | string cache = String.Empty; | ||
210 | bool in_state = false; | ||
211 | string current_statename = String.Empty; | ||
212 | for (int p = 0; p < Script.Length; p++) | ||
213 | { | ||
214 | C = Script.Substring(p, 1); | ||
215 | while (true) | ||
216 | { | ||
217 | // inc / dec level | ||
218 | if (C == @"{") | ||
219 | ilevel++; | ||
220 | if (C == @"}") | ||
221 | ilevel--; | ||
222 | if (ilevel < 0) | ||
223 | ilevel = 0; | ||
224 | cache += C; | ||
225 | |||
226 | // if level == 0, add to return | ||
227 | if (ilevel == 1 && lastlevel == 0) | ||
228 | { | ||
229 | // 0 => 1: Get last | ||
230 | Match m = | ||
231 | //Regex.Match(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{", | ||
232 | Regex.Match(cache, @"(?![a-zA-Z_]+)\s*(state\s+)?(?<statename>[a-zA-Z_][a-zA-Z_0-9]*)[^a-zA-Z_0-9\(\)]*{", | ||
233 | |||
234 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
235 | |||
236 | in_state = false; | ||
237 | if (m.Success) | ||
238 | { | ||
239 | // Go back to level 0, this is not a state | ||
240 | in_state = true; | ||
241 | current_statename = m.Groups["statename"].Captures[0].Value; | ||
242 | //Console.WriteLine("Current statename: " + current_statename); | ||
243 | cache = | ||
244 | //@"(?<s1>(?![a-zA-Z_]+)\s*)" + @"([a-zA-Z_]+)(?<s2>[^a-zA-Z_\(\)]*){", | ||
245 | Regex.Replace(cache, | ||
246 | @"(?<s1>(?![a-zA-Z_]+)\s*)" + @"(state\s+)?([a-zA-Z_][a-zA-Z_0-9]*)(?<s2>[^a-zA-Z_0-9\(\)]*){", | ||
247 | "${s1}${s2}", | ||
248 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); | ||
249 | } | ||
250 | ret += cache; | ||
251 | cache = String.Empty; | ||
252 | } | ||
253 | if (ilevel == 0 && lastlevel == 1) | ||
254 | { | ||
255 | // 1 => 0: Remove last } | ||
256 | if (in_state == true) | ||
257 | { | ||
258 | cache = cache.Remove(cache.Length - 1, 1); | ||
259 | //cache = Regex.Replace(cache, "}$", String.Empty, RegexOptions.Multiline | RegexOptions.Singleline); | ||
260 | |||
261 | //Replace function names | ||
262 | // void dataserver(key query_id, string data) { | ||
263 | //cache = Regex.Replace(cache, @"([^a-zA-Z_]\s*)((?!if|switch|for)[a-zA-Z_]+\s*\([^\)]*\)[^{]*{)", "$1" + "<STATE>" + "$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
264 | //Console.WriteLine("Replacing using statename: " + current_statename); | ||
265 | cache = | ||
266 | Regex.Replace(cache, | ||
267 | @"^(\s*)((?!(if|switch|for|while)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)", | ||
268 | @"$1public " + current_statename + "_event_$2", | ||
269 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); | ||
270 | } | ||
271 | |||
272 | ret += cache; | ||
273 | cache = String.Empty; | ||
274 | in_state = true; | ||
275 | current_statename = String.Empty; | ||
276 | } | ||
277 | |||
278 | break; | ||
279 | } | ||
280 | lastlevel = ilevel; | ||
281 | } | ||
282 | ret += cache; | ||
283 | cache = String.Empty; | ||
284 | |||
285 | Script = ret; | ||
286 | ret = String.Empty; | ||
287 | |||
288 | foreach (string key in dataTypes.Keys) | ||
289 | { | ||
290 | string val; | ||
291 | dataTypes.TryGetValue(key, out val); | ||
292 | |||
293 | // Replace CAST - (integer) with (int) | ||
294 | Script = | ||
295 | Regex.Replace(Script, @"\(" + key + @"\)", @"(" + val + ")", | ||
296 | RegexOptions.Compiled | RegexOptions.Multiline); | ||
297 | // Replace return types and function variables - integer a() and f(integer a, integer a) | ||
298 | Script = | ||
299 | Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s+)", @"$1$2" + val + "$3", | ||
300 | RegexOptions.Compiled | RegexOptions.Multiline); | ||
301 | Script = | ||
302 | Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)[,]", @"$1$2" + val + "$3,", | ||
303 | RegexOptions.Compiled | RegexOptions.Multiline); | ||
304 | } | ||
305 | |||
306 | // Add "void" in front of functions that needs it | ||
307 | Script = | ||
308 | Regex.Replace(Script, | ||
309 | @"^(\s*public\s+)?((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)", | ||
310 | @"$1void $2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
311 | |||
312 | // Replace <x,y,z> and <x,y,z,r> | ||
313 | Script = | ||
314 | Regex.Replace(Script, @"<([^,>;]*,[^,>;]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Quaternion($1)", | ||
315 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
316 | Script = | ||
317 | Regex.Replace(Script, @"<([^,>;)]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Vector3($1)", | ||
318 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
319 | |||
320 | // Replace List []'s | ||
321 | Script = | ||
322 | Regex.Replace(Script, @"\[([^\]]*)\]", @"new LSL_Types.list($1)", | ||
323 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
324 | |||
325 | // Replace (string) to .ToString() // | ||
326 | Script = | ||
327 | Regex.Replace(Script, @"\(string\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.ToString()", | ||
328 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
329 | Script = | ||
330 | Regex.Replace(Script, @"\((float|int)\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.Parse($2)", | ||
331 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); | ||
332 | |||
333 | // Replace "state STATENAME" with "state("statename")" | ||
334 | Script = | ||
335 | Regex.Replace(Script, @"(state)\s+([^;\n\r]+)(;[\r\n\s])", "$1(\"$2\")$3", | ||
336 | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); | ||
337 | |||
338 | // REPLACE BACK QUOTES | ||
339 | foreach (string key in quotes.Keys) | ||
340 | { | ||
341 | string val; | ||
342 | quotes.TryGetValue(key, out val); | ||
343 | Script = Script.Replace(key, "\"" + val + "\""); | ||
344 | } | ||
345 | |||
346 | //System.Console.WriteLine(Script); | ||
347 | Return = String.Empty;// + | ||
348 | //"using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;"; | ||
349 | |||
350 | //Return += String.Empty + | ||
351 | // "namespace SecondLife { "; | ||
352 | //Return += String.Empty + | ||
353 | // //"[Serializable] " + | ||
354 | // "public class Script : OpenSim.Region.ScriptEngine.Common.LSL_BaseClass { "; | ||
355 | //Return += @"public Script() { } "; | ||
356 | Return += Script; | ||
357 | //Return += "} }\r\n"; | ||
358 | |||
359 | quotes.Clear(); | ||
360 | |||
361 | return Return; | ||
362 | } | ||
363 | } | ||
364 | } | ||