aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL
diff options
context:
space:
mode:
authorMelanie Thielker2008-09-23 14:17:32 +0000
committerMelanie Thielker2008-09-23 14:17:32 +0000
commit8ac4437d9a9453b4ce7ef79b14b81bec7fadeb22 (patch)
tree859af1c18c5cf23323d532585e7c4d031790940c /OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL
parentRefactor XEngine parser as per suggestions from mikem (diff)
downloadopensim-SC-8ac4437d9a9453b4ce7ef79b14b81bec7fadeb22.zip
opensim-SC-8ac4437d9a9453b4ce7ef79b14b81bec7fadeb22.tar.gz
opensim-SC-8ac4437d9a9453b4ce7ef79b14b81bec7fadeb22.tar.bz2
opensim-SC-8ac4437d9a9453b4ce7ef79b14b81bec7fadeb22.tar.xz
Add constants wrapping code from XEngine to DNE. This syncs up the parsers
between the engines again. Also, committed r60 in opensim libs with the parser source changes.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs14
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs364
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
29using System;
30using System.Collections.Generic;
31using System.Text.RegularExpressions;
32
33namespace 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}