aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/CodeTools
diff options
context:
space:
mode:
authorMelanie Thielker2008-09-21 21:47:00 +0000
committerMelanie Thielker2008-09-21 21:47:00 +0000
commit94aaf67dfaafbcbd4d871f674c465a34c1c1f332 (patch)
tree33476e5660a95bdf7d29d14beae67a6294af28a7 /OpenSim/Region/ScriptEngine/Shared/CodeTools
parent* minor: warnings removal (diff)
downloadopensim-SC-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.zip
opensim-SC-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.tar.gz
opensim-SC-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.tar.bz2
opensim-SC-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.tar.xz
Change the scirpt engine loading mechanism. Script engines are now
ordinary region modules and are able to coexist in one instance. See http://opensimulator.org/wiki/ScriptEngines for details. There were changes to OpenSim.ini.example, please note DefaultScriptEngine. Also see the User docs and FAQ on the Wiki. Default is DotNetEngine.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/CodeTools')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs43
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs374
2 files changed, 13 insertions, 404 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index c88cd05..b14e7ac 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -82,7 +82,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
82 82
83 // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files 83 // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files
84 private static UInt64 scriptCompileCounter = 0; // And a counter 84 private static UInt64 scriptCompileCounter = 0; // And a counter
85 private bool m_UseCompiler = true;
86 85
87 public IScriptEngine m_scriptEngine; 86 public IScriptEngine m_scriptEngine;
88 public Compiler(IScriptEngine scriptEngine) 87 public Compiler(IScriptEngine scriptEngine)
@@ -93,8 +92,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
93 public bool in_startup = true; 92 public bool in_startup = true;
94 public void ReadConfig() 93 public void ReadConfig()
95 { 94 {
96 m_UseCompiler = m_scriptEngine.Config.GetBoolean("UseNewCompiler", true);
97
98 // Get some config 95 // Get some config
99 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", true); 96 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", true);
100 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); 97 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true);
@@ -327,14 +324,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
327 { 324 {
328 // Its LSL, convert it to C# 325 // Its LSL, convert it to C#
329 //compileScript = LSL_Converter.Convert(Script); 326 //compileScript = LSL_Converter.Convert(Script);
330 if (m_UseCompiler) 327 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
331 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
332 else
333 LSL_Converter = (ICodeConverter)new LSL2CSConverter();
334 compileScript = LSL_Converter.Convert(Script); 328 compileScript = LSL_Converter.Convert(Script);
335 329
336 if (m_UseCompiler) 330 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
337 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
338 331
339 l = enumCompileType.cs; 332 l = enumCompileType.cs;
340 } 333 }
@@ -549,31 +542,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
549 severity = "Warning"; 542 severity = "Warning";
550 } 543 }
551 544
552 if (m_UseCompiler) 545 KeyValuePair<int, int> lslPos;
553 {
554 KeyValuePair<int, int> lslPos;
555
556 try
557 {
558 lslPos = m_positionMap[new KeyValuePair<int, int>(CompErr.Line, CompErr.Column)];
559 }
560 catch (KeyNotFoundException) // we don't have this line/column mapped
561 {
562 m_scriptEngine.Log.Debug(String.Format("[Compiler]: Lookup of C# line {0}, column {1} failed.", CompErr.Line, CompErr.Column));
563 lslPos = new KeyValuePair<int, int>(-CompErr.Line, -CompErr.Column);
564 }
565
566 // The Second Life viewer's script editor begins
567 // countingn lines and columns at 0, so we subtract 1.
568 errtext += String.Format("Line {0}, column {1}, {4} Number: {2}, '{3}'\r\n", lslPos.Key - 1, lslPos.Value - 1, CompErr.ErrorNumber, CompErr.ErrorText, severity);
569 546
547 try
548 {
549 lslPos = m_positionMap[new KeyValuePair<int, int>(CompErr.Line, CompErr.Column)];
570 } 550 }
571 else 551 catch (KeyNotFoundException) // we don't have this line/column mapped
572 { 552 {
573 errtext += "Line number " + (CompErr.Line - LinesToRemoveOnError) + 553 m_scriptEngine.Log.Debug(String.Format("[Compiler]: Lookup of C# line {0}, column {1} failed.", CompErr.Line, CompErr.Column));
574 ", " + severity + " Number: " + CompErr.ErrorNumber + 554 lslPos = new KeyValuePair<int, int>(-CompErr.Line, -CompErr.Column);
575 ", '" + CompErr.ErrorText + "'\r\n";
576 } 555 }
556
557 // The Second Life viewer's script editor begins
558 // countingn lines and columns at 0, so we subtract 1.
559 errtext += String.Format("Line {0}, column {1}, {4} Number: {2}, '{3}'\r\n", lslPos.Key - 1, lslPos.Value - 1, CompErr.ErrorNumber, CompErr.ErrorText, severity);
577 } 560 }
578 561
579 Console.WriteLine("[COMPILER MESSAGES]: " + errtext); 562 Console.WriteLine("[COMPILER MESSAGES]: " + errtext);
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs
deleted file mode 100644
index 57efb2e..0000000
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs
+++ /dev/null
@@ -1,374 +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.Shared.CodeTools
34{
35 public class LSL2CSConverter : ICodeConverter
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 }
63
64 public string Convert(string Script)
65 {
66 quotes.Clear();
67 string Return = String.Empty;
68 Script = " \r\n" + Script;
69
70 //
71 // Prepare script for processing
72 //
73
74 // Clean up linebreaks
75 Script = Regex.Replace(Script, @"\r\n", "\n");
76 Script = Regex.Replace(Script, @"\n", "\r\n");
77
78 // QUOTE REPLACEMENT
79 // temporarily replace quotes so we can work our magic on the script without
80 // always considering if we are inside our outside quotes's
81 // TODO: Does this work on half-quotes in strings? ;)
82 string _Script = String.Empty;
83 string C;
84 bool in_quote = false;
85 bool quote_replaced = false;
86 string quote_replacement_string = "Q_U_O_T_E_REPLACEMENT_";
87 string quote = String.Empty;
88 bool last_was_escape = false;
89 int quote_replaced_count = 0;
90
91 string removefwnoncomments = nonCommentFwsl.Replace(Script, "\"\";");
92
93 string removecomments = conelinecomments.Replace(removefwnoncomments, "");
94 removecomments = cstylecomments.Replace(removecomments, "");
95 string[] localscript = removecomments.Split('"');
96 string checkscript = String.Empty;
97 bool flip = true;
98
99 for (int p = 0; p < localscript.Length; p++)
100 {
101 //if (localscript[p].Length >= 1)
102 //{
103 if (!localscript[p].EndsWith(@"\"))
104 {
105 flip = !flip;
106 //System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p] + " ! " + localscript[p].EndsWith(@"\").ToString());
107 }
108 //}
109 //else
110 //{
111 // flip = !flip;
112 // System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p]);
113 //}
114 if (!flip)
115 checkscript += localscript[p];
116 }
117
118 //System.Console.WriteLine("SCRIPT:" + checkscript);
119
120 // checks for alpha.alpha way of referring to objects in C#
121 // ignores alpha.X alpha.Y, alpha.Z for refering to vector components
122 Match SecurityM;
123
124 // BROKEN: this check is very wrong. It block's any url in strings.
125 SecurityM = Regex.Match(checkscript, @"(?:[a-zA-Z])\.(?:[a-rt-wA-Z]|[a-zA-Z][a-zA-Z])", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
126
127 if (SecurityM.Success)
128 throw new Exception("CS0103: 'The . symbol cannot be used in LSL except in float values or vector components'. Detected around: " + SecurityM.Captures[0].Value);
129
130 SecurityM = Regex.Match(checkscript, @"typeof\s", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
131 if (SecurityM.Success)
132 throw new Exception("CS0103: 'The object.typeof method isn't allowed in LSL'");
133
134 SecurityM = Regex.Match(checkscript, @"GetType\(", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
135 if (SecurityM.Success)
136 throw new Exception("CS0103: 'The object.GetType method isn't allowed in LSL'");
137
138 for (int p = 0; p < Script.Length; p++)
139 {
140 C = Script.Substring(p, 1);
141 while (true)
142 {
143 // found " and last was not \ so this is not an escaped \"
144 if (C == "\"" && last_was_escape == false)
145 {
146 // Toggle inside/outside quote
147 in_quote = !in_quote;
148 if (in_quote)
149 {
150 quote_replaced_count++;
151 }
152 else
153 {
154 if (quote == String.Empty)
155 {
156 // We didn't replace quote, probably because of empty string?
157 _Script += quote_replacement_string +
158 quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
159 }
160 // We just left a quote
161 quotes.Add(
162 quote_replacement_string +
163 quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]), quote);
164 quote = String.Empty;
165 }
166 break;
167 }
168
169 if (!in_quote)
170 {
171 // We are not inside a quote
172 quote_replaced = false;
173 }
174 else
175 {
176 // We are inside a quote
177 if (!quote_replaced)
178 {
179 // Replace quote
180 _Script += quote_replacement_string +
181 quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
182 quote_replaced = true;
183 }
184 quote += C;
185 break;
186 }
187 _Script += C;
188 break;
189 }
190 last_was_escape = false;
191 if (C == @"\")
192 {
193 last_was_escape = true;
194 }
195 }
196 Script = _Script;
197 //
198 // END OF QUOTE REPLACEMENT
199 //
200
201 //
202 // PROCESS STATES
203 // Remove state definitions and add state names to start of each event within state
204 //
205 int ilevel = 0;
206 int lastlevel = 0;
207 string ret = String.Empty;
208 string cache = String.Empty;
209 bool in_state = false;
210 string current_statename = String.Empty;
211 for (int p = 0; p < Script.Length; p++)
212 {
213 C = Script.Substring(p, 1);
214 while (true)
215 {
216 // inc / dec level
217 if (C == @"{")
218 ilevel++;
219 if (C == @"}")
220 ilevel--;
221 if (ilevel < 0)
222 ilevel = 0;
223 cache += C;
224
225 // if level == 0, add to return
226 if (ilevel == 1 && lastlevel == 0)
227 {
228 // 0 => 1: Get last
229 Match m =
230 //Regex.Match(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{",
231 Regex.Match(cache, @"(?![a-zA-Z_]+)\s*(state\s+)?(?<statename>[a-zA-Z_][a-zA-Z_0-9]*)[^a-zA-Z_0-9\(\)]*{",
232
233 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
234
235 in_state = false;
236 if (m.Success)
237 {
238 // Go back to level 0, this is not a state
239 in_state = true;
240 current_statename = m.Groups["statename"].Captures[0].Value;
241 //Console.WriteLine("Current statename: " + current_statename);
242 cache =
243 //@"(?<s1>(?![a-zA-Z_]+)\s*)" + @"([a-zA-Z_]+)(?<s2>[^a-zA-Z_\(\)]*){",
244 Regex.Replace(cache,
245 @"(?<s1>(?![a-zA-Z_]+)\s*)" + @"(state\s+)?([a-zA-Z_][a-zA-Z_0-9]*)(?<s2>[^a-zA-Z_0-9\(\)]*){",
246 "${s1}${s2}",
247 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
248 }
249 ret += cache;
250 cache = String.Empty;
251 }
252 if (ilevel == 0 && lastlevel == 1)
253 {
254 // 1 => 0: Remove last }
255 if (in_state == true)
256 {
257 cache = cache.Remove(cache.Length - 1, 1);
258 //cache = Regex.Replace(cache, "}$", String.Empty, RegexOptions.Multiline | RegexOptions.Singleline);
259
260 //Replace function names
261 // void dataserver(key query_id, string data) {
262 //cache = Regex.Replace(cache, @"([^a-zA-Z_]\s*)((?!if|switch|for)[a-zA-Z_]+\s*\([^\)]*\)[^{]*{)", "$1" + "<STATE>" + "$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
263 //Console.WriteLine("Replacing using statename: " + current_statename);
264 cache =
265 Regex.Replace(cache,
266 @"^(\s*)((?!(if|switch|for|while)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
267 @"$1public " + current_statename + "_event_$2",
268 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
269 }
270
271 ret += cache;
272 cache = String.Empty;
273 in_state = true;
274 current_statename = String.Empty;
275 }
276
277 break;
278 }
279 lastlevel = ilevel;
280 }
281 ret += cache;
282 cache = String.Empty;
283
284 Script = ret;
285 ret = String.Empty;
286
287 foreach (string key in dataTypes.Keys)
288 {
289 string val;
290 dataTypes.TryGetValue(key, out val);
291
292 // Replace CAST - (integer) with (int)
293 Script =
294 Regex.Replace(Script, @"\(" + key + @"\)", @"(" + val + ")",
295 RegexOptions.Compiled | RegexOptions.Multiline);
296 // Replace return types and function variables - integer a() and f(integer a, integer a)
297 Script =
298 Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s+)", @"$1$2" + val + "$3",
299 RegexOptions.Compiled | RegexOptions.Multiline);
300 Script =
301 Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)[,]", @"$1$2" + val + "$3,",
302 RegexOptions.Compiled | RegexOptions.Multiline);
303 }
304
305 // Change jumps into goto's and prefix its label
306 Script =
307 Regex.Replace(Script,
308 @"(\W)jump\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*;",
309 @"$1goto label_$2;", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
310 // and prefix labels so the do not clash with C#'s reserved words
311 Script =
312 Regex.Replace(Script,
313 @"@([a-zA-Z_][a-zA-Z_0-9]*)\s*;",
314 @"label_$1: ;", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
315
316 // Add "void" in front of functions that needs it
317 Script =
318 Regex.Replace(Script,
319 @"^(\s*public\s+)?((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
320 @"$1void $2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
321
322 // Replace <x,y,z> and <x,y,z,r>
323 Script =
324 Regex.Replace(Script, @"<([^,>;]*,[^,>;]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Quaternion($1)",
325 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
326 Script =
327 Regex.Replace(Script, @"<([^,>;)]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Vector3($1)",
328 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
329
330 // Replace List []'s
331 Script =
332 Regex.Replace(Script, @"\[([^\]]*)\]", @"new LSL_Types.list($1)",
333 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
334
335 // Replace (string) to .ToString() //
336 Script =
337 Regex.Replace(Script, @"\(string\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.ToString()",
338 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
339 Script =
340 Regex.Replace(Script, @"\((float|int)\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.Parse($2)",
341 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
342
343 // Replace "state STATENAME" with "state("statename")"
344 Script =
345 Regex.Replace(Script, @"(state)\s+([^;\n\r]+)(;[\r\n\s])", "$1(\"$2\")$3",
346 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
347
348 // REPLACE BACK QUOTES
349 foreach (string key in quotes.Keys)
350 {
351 string val;
352 quotes.TryGetValue(key, out val);
353 Script = Script.Replace(key, "\"" + val + "\"");
354 }
355
356 //System.Console.WriteLine(Script);
357 Return = String.Empty;// +
358 //"using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;";
359
360 //Return += String.Empty +
361 // "namespace SecondLife { ";
362 //Return += String.Empty +
363 // //"[Serializable] " +
364 // "public class Script : OpenSim.Region.ScriptEngine.Shared.LSL_BaseClass { ";
365 //Return += @"public Script() { } ";
366 Return += Script;
367 //Return += "} }\r\n";
368
369 quotes.Clear();
370
371 return Return;
372 }
373 }
374}