Initial import
git-svn-id: https://lsleditor.svn.sourceforge.net/svnroot/lsleditor@1 3f4676ac-adda-40fd-8265-58d1435b1672
This commit is contained in:
commit
7d308772cf
453 changed files with 57506 additions and 0 deletions
642
Helpers/LSL2CSharp.cs
Normal file
642
Helpers/LSL2CSharp.cs
Normal file
|
@ -0,0 +1,642 @@
|
|||
// /**
|
||||
// ********
|
||||
// *
|
||||
// * ORIGIONAL CODE BASE IS Copyright (C) 2006-2010 by Alphons van der Heijden
|
||||
// * The code was donated on 4/28/2010 by Alphons van der Heijden
|
||||
// * To Brandon'Dimentox Travanti' Husbands & Malcolm J. Kudra which in turn Liscense under the GPLv2.
|
||||
// * In agreement to Alphons van der Heijden wishes.
|
||||
// *
|
||||
// * The community would like to thank Alphons for all of his hard work, blood sweat and tears.
|
||||
// * Without his work the community would be stuck with crappy editors.
|
||||
// *
|
||||
// * The source code in this file ("Source Code") is provided by The LSLEditor Group
|
||||
// * to you under the terms of the GNU General Public License, version 2.0
|
||||
// * ("GPL"), unless you have obtained a separate licensing agreement
|
||||
// * ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
// * the GPL can be found in the gplv2.txt document.
|
||||
// *
|
||||
// ********
|
||||
// * GPLv2 Header
|
||||
// ********
|
||||
// * LSLEditor, a External editor for the LSL Language.
|
||||
// * Copyright (C) 2010 The LSLEditor Group.
|
||||
//
|
||||
// * This program is free software; you can redistribute it and/or
|
||||
// * modify it under the terms of the GNU General Public License
|
||||
// * as published by the Free Software Foundation; either version 2
|
||||
// * of the License, or (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have received a copy of the GNU General Public License
|
||||
// * along with this program; if not, write to the Free Software
|
||||
// * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
// ********
|
||||
// *
|
||||
// * The above copyright notice and this permission notice shall be included in all
|
||||
// * copies or substantial portions of the Software.
|
||||
// *
|
||||
// ********
|
||||
// */
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace LSLEditor
|
||||
{
|
||||
class LSL2CSharp
|
||||
{
|
||||
public List<string> States;
|
||||
private XmlDocument xml;
|
||||
|
||||
public LSL2CSharp(XmlDocument xml)
|
||||
{
|
||||
this.xml = xml;
|
||||
this.States = new List<string>();
|
||||
}
|
||||
|
||||
private string CorrectGlobalEvaluator(Match m)
|
||||
{
|
||||
string strPrefix = m.Groups["prefix"].Value;
|
||||
string strPublic = m.Groups["public"].Value;
|
||||
string strPostfix = m.Groups["postfix"].Value;
|
||||
if (strPublic.EndsWith(";"))
|
||||
return strPrefix + "public static " + strPublic + strPostfix;
|
||||
// has to be static,
|
||||
// because the vars must keep their values between state changes
|
||||
|
||||
// 22 june 2007, added
|
||||
Regex regex = new Regex(@"\w*", RegexOptions.IgnorePatternWhitespace );
|
||||
int intCount=0;
|
||||
for (Match pm = regex.Match(strPublic); pm.Success; pm = pm.NextMatch())
|
||||
{
|
||||
if (pm.Value.Length > 0)
|
||||
intCount++;
|
||||
if (intCount > 1)
|
||||
break;
|
||||
}
|
||||
if(intCount==1)
|
||||
return strPrefix + "public void " + strPublic + strPostfix;
|
||||
else
|
||||
return strPrefix + "public " + strPublic + strPostfix;
|
||||
}
|
||||
|
||||
private string CorrectGlobal(string strC)
|
||||
{
|
||||
Regex regex = new Regex(
|
||||
@"(?<prefix>\s*)
|
||||
(?:
|
||||
(?<public>[^{};]*;)
|
||||
|
||||
|
|
||||
|
||||
(?<public>[^{;(]*)
|
||||
(?<postfix>
|
||||
\( [^{]* \) \s*
|
||||
\{
|
||||
(?>
|
||||
[^{}]+
|
||||
| \{ (?<number>)
|
||||
| \} (?<-number>)
|
||||
)*
|
||||
(?(number)(?!))
|
||||
\}
|
||||
)
|
||||
)",
|
||||
RegexOptions.IgnorePatternWhitespace);
|
||||
return regex.Replace(strC, new MatchEvaluator(CorrectGlobalEvaluator));
|
||||
}
|
||||
|
||||
private string RemoveComments(string strC)
|
||||
{
|
||||
if (Properties.Settings.Default.CommentCStyle)
|
||||
{
|
||||
int intI = strC.IndexOf("/*");
|
||||
while (intI > 0)
|
||||
{
|
||||
int intJ = strC.IndexOf("*" + "/", intI);
|
||||
if (intJ < 0)
|
||||
break;
|
||||
strC = strC.Remove(intI, intJ - intI + 2);
|
||||
intI = strC.IndexOf("/*");
|
||||
}
|
||||
}
|
||||
return AutoFormatter.RemoveCommentsFromLines(strC);
|
||||
}
|
||||
|
||||
private string CorrectStates(string strC,string strGlobalClass)
|
||||
{
|
||||
Regex regex;
|
||||
|
||||
// Default state
|
||||
regex = new Regex(@"^\s*(default)(\W)",
|
||||
RegexOptions.Multiline
|
||||
| RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled);
|
||||
strC = regex.Replace(strC, @"class State_$1 : " + strGlobalClass + "$2");
|
||||
|
||||
// Other states
|
||||
regex = new Regex(
|
||||
@"^state\s+([^\s]*)(\s*\{)",
|
||||
RegexOptions.Multiline
|
||||
| RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled
|
||||
);
|
||||
Match m = regex.Match(strC);
|
||||
while (m.Success)
|
||||
{
|
||||
string strStateName = m.Groups[1].ToString();
|
||||
this.States.Add(strStateName);
|
||||
m = m.NextMatch();
|
||||
}
|
||||
strC = regex.Replace(strC, "class State_$1 : " + strGlobalClass + "$2");
|
||||
|
||||
string strGlobal = "";
|
||||
|
||||
if (Properties.Settings.Default.StatesInGlobalFunctions)
|
||||
{
|
||||
// do nothing!
|
||||
}
|
||||
else
|
||||
{
|
||||
int intDefault = strC.IndexOf("class State_default");
|
||||
if (intDefault >= 0)
|
||||
{
|
||||
strGlobal = strC.Substring(0, intDefault);
|
||||
strC = strC.Substring(intDefault);
|
||||
}
|
||||
}
|
||||
|
||||
// State change, excluding global functions
|
||||
regex = new Regex(
|
||||
@"(\s+)state\s+(\w*)(\s*;)",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled
|
||||
);
|
||||
return strGlobal + regex.Replace(strC, @"$1state(""$2"")$3");
|
||||
}
|
||||
|
||||
private string PreCorrectReservedWords(string strC)
|
||||
{
|
||||
#region All PreCorrect reserved C# words
|
||||
Regex regex = new Regex(@"(\b)(public
|
||||
| class
|
||||
| override
|
||||
| namespace
|
||||
| void
|
||||
| SecondLife
|
||||
| GlobalClass
|
||||
| static
|
||||
| goto
|
||||
| String
|
||||
| Float
|
||||
|
||||
)(\b)",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled
|
||||
);
|
||||
#endregion
|
||||
return regex.Replace(strC, "$1_$2$3");
|
||||
}
|
||||
|
||||
private string CorrectReservedWords(string strC)
|
||||
{
|
||||
#region All reserved C# words
|
||||
Regex regex = new Regex(@"(\b)(new
|
||||
| abstract
|
||||
| as
|
||||
| base
|
||||
| bool
|
||||
| break
|
||||
| byte
|
||||
| case
|
||||
| catch
|
||||
| char
|
||||
| checked
|
||||
| const
|
||||
| continue
|
||||
| decimal
|
||||
| delegate
|
||||
| double
|
||||
| enum
|
||||
| event
|
||||
| explicit
|
||||
| extern
|
||||
| false
|
||||
| finally
|
||||
| fixed
|
||||
| foreach
|
||||
| implicit
|
||||
| in
|
||||
| int
|
||||
| interface
|
||||
| internal
|
||||
| is
|
||||
| lock
|
||||
| long
|
||||
| new
|
||||
| null
|
||||
| object
|
||||
| operator
|
||||
| out
|
||||
| params
|
||||
| private
|
||||
| protected
|
||||
| readonly
|
||||
| ref
|
||||
| sbyte
|
||||
| sealed
|
||||
| short
|
||||
| sizeof
|
||||
| stackalloc
|
||||
| struct
|
||||
| switch
|
||||
| this
|
||||
| throw
|
||||
| true
|
||||
| try
|
||||
| typeof
|
||||
| uint
|
||||
| ulong
|
||||
| unchecked
|
||||
| unsafe
|
||||
| ushort
|
||||
| using
|
||||
| virtual
|
||||
|
||||
)(\b)",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled
|
||||
);
|
||||
#endregion
|
||||
return regex.Replace(strC, "$1_$2$3");
|
||||
}
|
||||
|
||||
private string CorrectEvent(string strC, string strName)
|
||||
{
|
||||
Regex regex = new Regex(
|
||||
@"([^\w_])" + strName + @"(\s*)\(",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled
|
||||
);
|
||||
return regex.Replace(strC, "$1public override void " + strName + "$2(");
|
||||
}
|
||||
|
||||
private string CorrectEvents(string strC)
|
||||
{
|
||||
XmlNode words = xml.SelectSingleNode("//Words[@name='Appendix B. Events']");
|
||||
foreach (XmlNode xmlNode in words.SelectNodes(".//Word"))
|
||||
{
|
||||
string strName = xmlNode.Attributes["name"].InnerText;
|
||||
strC = CorrectEvent(strC, strName);
|
||||
}
|
||||
return strC;
|
||||
}
|
||||
|
||||
// old vector parser
|
||||
// <([^<>,;]*),([^<>,;]*),([^<>,;]*)>
|
||||
private string CorrectVector(string strC)
|
||||
{
|
||||
Regex regex = new Regex(@"
|
||||
<
|
||||
(?<vector_x>
|
||||
(?>
|
||||
[^=(),>]+
|
||||
| \( (?<nr>)
|
||||
| \) (?<-nr>)
|
||||
| ,
|
||||
)*
|
||||
(?(nr)(?!))
|
||||
)
|
||||
,
|
||||
(?<vector_y>
|
||||
(?>
|
||||
[^=(),>]+
|
||||
| \( (?<nr>)
|
||||
| \) (?<-nr>)
|
||||
| ,
|
||||
)*
|
||||
(?(nr)(?!))
|
||||
)
|
||||
,
|
||||
(?<vector_z>
|
||||
(?>
|
||||
[^=()>]+
|
||||
| \( (?<nr>)
|
||||
| \) (?<-nr>)
|
||||
| ,
|
||||
)*
|
||||
(?(nr)(?!))
|
||||
)
|
||||
>
|
||||
",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled
|
||||
);
|
||||
return regex.Replace(strC, "new vector(${vector_x},${vector_y},${vector_z})");
|
||||
}
|
||||
|
||||
// old rotation
|
||||
// <([^<>,;]*),([^<>,;]*),([^<>,;]*),([^<>,;]*)>
|
||||
private string CorrectRotation(string strC)
|
||||
{
|
||||
Regex regex = new Regex(@"
|
||||
<
|
||||
(?<rotation_x>
|
||||
(?>
|
||||
[^=(),>]+
|
||||
| \( (?<nr>)
|
||||
| \) (?<-nr>)
|
||||
| ,
|
||||
)*
|
||||
(?(nr)(?!))
|
||||
)
|
||||
,
|
||||
(?<rotation_y>
|
||||
(?>
|
||||
[^=(),>]+
|
||||
| \( (?<nr>)
|
||||
| \) (?<-nr>)
|
||||
| ,
|
||||
)*
|
||||
(?(nr)(?!))
|
||||
)
|
||||
,
|
||||
(?<rotation_z>
|
||||
(?>
|
||||
[^=(),>]+
|
||||
| \( (?<nr>)
|
||||
| \) (?<-nr>)
|
||||
| ,
|
||||
)*
|
||||
(?(nr)(?!))
|
||||
)
|
||||
,
|
||||
(?<rotation_s>
|
||||
(?>
|
||||
[^=()>]+
|
||||
| \( (?<nr>)
|
||||
| \) (?<-nr>)
|
||||
| ,
|
||||
)*
|
||||
(?(nr)(?!))
|
||||
)
|
||||
>
|
||||
",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled
|
||||
);
|
||||
return regex.Replace(strC, "new rotation(${rotation_x},${rotation_y},${rotation_z},${rotation_s})");
|
||||
}
|
||||
|
||||
private string CorrectQuaternion(string strC)
|
||||
{
|
||||
Regex regex = new Regex(
|
||||
@"(\b)quaternion(\b)",
|
||||
RegexOptions.Compiled
|
||||
| RegexOptions.IgnorePatternWhitespace
|
||||
);
|
||||
return regex.Replace(strC, "$1rotation$2");
|
||||
}
|
||||
|
||||
private string CorrectListsEvaluator(Match m)
|
||||
{
|
||||
string strValue = m.Value;
|
||||
return "new list(new object[] {" + CorrectLists(strValue.Substring(1, strValue.Length - 2)) + "})";
|
||||
}
|
||||
|
||||
private string CorrectLists(string strC)
|
||||
{
|
||||
Regex regex = new Regex(
|
||||
@"
|
||||
\[
|
||||
(?>
|
||||
[^\[\]]+
|
||||
| \[ (?<number>)
|
||||
| \] (?<-number>)
|
||||
)*
|
||||
(?(number)(?!))
|
||||
\]
|
||||
",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Compiled);
|
||||
return regex.Replace(strC, new MatchEvaluator(CorrectListsEvaluator));
|
||||
}
|
||||
|
||||
// changed 16 aug 2007
|
||||
private string CorrectJump(string strC)
|
||||
{
|
||||
// jump -> goto
|
||||
Regex regex = new Regex(
|
||||
@"(\b)jump(\s+)([^;]*;)",
|
||||
RegexOptions.Compiled
|
||||
| RegexOptions.IgnorePatternWhitespace
|
||||
);
|
||||
strC = regex.Replace(strC, "$1goto$2_$3");
|
||||
|
||||
// @label; -> label:;
|
||||
regex = new Regex(
|
||||
@"@\s*([a-z0-9_]+)\s*;",
|
||||
RegexOptions.Compiled
|
||||
| RegexOptions.IgnoreCase
|
||||
| RegexOptions.IgnorePatternWhitespace
|
||||
);
|
||||
return regex.Replace(strC, "_$1:;");
|
||||
}
|
||||
|
||||
|
||||
private string RemoveQuotedStrings(string strC, out List<string> h)
|
||||
{
|
||||
h = new List<string>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder QuotedString = null;
|
||||
for (int intI = 0; intI < strC.Length; intI++)
|
||||
{
|
||||
char chrC = strC[intI];
|
||||
if (chrC == '"')
|
||||
{
|
||||
if (QuotedString != null)
|
||||
{
|
||||
// end of a quoted string
|
||||
sb.Append('"');
|
||||
sb.Append(h.Count.ToString());
|
||||
sb.Append('"');
|
||||
h.Add(QuotedString.ToString());
|
||||
QuotedString = null;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chrC == '"')
|
||||
{
|
||||
// start of a new quoted string
|
||||
QuotedString = new StringBuilder();
|
||||
continue;
|
||||
}
|
||||
// it was just a newline char, and not in a string
|
||||
}
|
||||
}
|
||||
|
||||
if (QuotedString == null)
|
||||
sb.Append(chrC);
|
||||
else
|
||||
{
|
||||
if (chrC == '\n')
|
||||
{
|
||||
QuotedString.Append('\\');
|
||||
chrC = 'n';
|
||||
}
|
||||
if (chrC != '\\')
|
||||
{
|
||||
QuotedString.Append(chrC);
|
||||
}
|
||||
else // it is a backslash
|
||||
{
|
||||
intI++;
|
||||
chrC = strC[intI];
|
||||
if (chrC == 't') // tabs are 4 spaces in SL world!!
|
||||
{
|
||||
QuotedString.Append(" ");
|
||||
}
|
||||
else // nope, it is no tab, just output it all
|
||||
{
|
||||
QuotedString.Append('\\');
|
||||
QuotedString.Append(chrC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private string InsertQuotedStrings(string strC, List<string> h)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder QuotedString = null;
|
||||
for (int intI = 0; intI < strC.Length; intI++)
|
||||
{
|
||||
char chrC = strC[intI];
|
||||
if (chrC == '"')
|
||||
{
|
||||
if (QuotedString == null)
|
||||
{
|
||||
QuotedString = new StringBuilder();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append('"');
|
||||
int intNumber;
|
||||
// State("default") is not a number, result of 'CorrectStates'
|
||||
if (int.TryParse(QuotedString.ToString(), out intNumber))
|
||||
sb.Append(h[intNumber]);
|
||||
else
|
||||
sb.Append(QuotedString.ToString());
|
||||
sb.Append('"');
|
||||
QuotedString = null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (QuotedString == null)
|
||||
sb.Append(chrC);
|
||||
else
|
||||
QuotedString.Append(chrC);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private string MakeGlobalAndLocal(string strC)
|
||||
{
|
||||
Regex regexDefault = new Regex(@"^\s*(default)\W",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Multiline
|
||||
| RegexOptions.Compiled);
|
||||
|
||||
Match matchDefault = regexDefault.Match(strC);
|
||||
|
||||
string strGlobal;
|
||||
int intDefaultIndex;
|
||||
if (matchDefault.Groups.Count == 2)
|
||||
{
|
||||
States.Add("default");
|
||||
intDefaultIndex = matchDefault.Groups[1].Index;
|
||||
strGlobal = CorrectGlobal(strC.Substring(0, intDefaultIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
intDefaultIndex = 0;
|
||||
strGlobal = "";
|
||||
}
|
||||
return "class GlobalClass : SecondLife\n{\n" + strGlobal + "}\n" + strC.Substring(intDefaultIndex);
|
||||
}
|
||||
|
||||
private string Capitalize(string strC, string strName)
|
||||
{
|
||||
Regex regex = new Regex(@"(\W)"+strName+@"(\W)",
|
||||
RegexOptions.IgnorePatternWhitespace
|
||||
| RegexOptions.Multiline
|
||||
| RegexOptions.Compiled);
|
||||
string strCap = strName[0].ToString().ToUpper() + strName.Substring(1);
|
||||
return regex.Replace(strC, "$1"+strCap+"$2");
|
||||
}
|
||||
|
||||
private string RemoveSingleQuotes(string strC)
|
||||
{
|
||||
if (Properties.Settings.Default.SingleQuote)
|
||||
return strC.Replace("'", "");
|
||||
else
|
||||
return strC;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This Class translates LSL script into CSharp code
|
||||
/// </summary>
|
||||
/// <param name="strLSLCode">LSL scripting code</param>
|
||||
/// <returns>CSHarp code</returns>
|
||||
public string Parse(string strLSLCode)
|
||||
{
|
||||
List<string> quotedStrings;
|
||||
|
||||
string strGlobalClass = "GlobalClass";
|
||||
|
||||
string strC = strLSLCode;
|
||||
|
||||
strC = RemoveComments(strC);
|
||||
|
||||
strC = RemoveQuotedStrings(strC, out quotedStrings);
|
||||
|
||||
strC = RemoveSingleQuotes(strC);
|
||||
|
||||
strC = PreCorrectReservedWords(strC); // Experimental
|
||||
|
||||
strC = MakeGlobalAndLocal(strC);
|
||||
|
||||
strC = CorrectJump(strC);
|
||||
strC = CorrectEvents(strC);
|
||||
|
||||
strC = Capitalize(strC, "float");
|
||||
strC = Capitalize(strC, "string"); // llList2string is also translated
|
||||
|
||||
strC = CorrectStates(strC, strGlobalClass);
|
||||
|
||||
strC = CorrectReservedWords(strC); // Experimental
|
||||
|
||||
strC = CorrectRotation(strC);
|
||||
strC = CorrectQuaternion(strC);
|
||||
strC = CorrectVector(strC);
|
||||
strC = CorrectLists(strC);
|
||||
|
||||
strC = InsertQuotedStrings(strC, quotedStrings);
|
||||
|
||||
return strC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue