mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-06-04 10:51:13 +00:00
Internal: finished enumeration of ZScript actor fields and methods
This commit is contained in:
parent
b42de7db6c
commit
ad5b542cd0
2 changed files with 528 additions and 51 deletions
|
@ -11,11 +11,380 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
{
|
||||
public sealed class ZScriptActorStructure : ActorStructure
|
||||
{
|
||||
private bool ParseDefaultBlock(ZScriptParser parser, Stream stream, ZScriptTokenizer tokenizer)
|
||||
{
|
||||
tokenizer.SkipWhitespace();
|
||||
ZScriptToken token = tokenizer.ExpectToken(ZScriptTokenType.OpenCurly);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected {, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo parse defaults block
|
||||
stream.Position--;
|
||||
List<ZScriptToken> tokens = parser.ParseBlock(false); // do nothing for now
|
||||
|
||||
return (tokens != null);
|
||||
}
|
||||
|
||||
private bool ParseStatesBlock(ZScriptParser parser, Stream stream, ZScriptTokenizer tokenizer)
|
||||
{
|
||||
tokenizer.SkipWhitespace();
|
||||
ZScriptToken token = tokenizer.ExpectToken(ZScriptTokenType.OpenParen, ZScriptTokenType.OpenCurly);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected ( or {, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// we can have some weirdass class name list after States keyword. handle that here.
|
||||
if (token.Type == ZScriptTokenType.OpenParen)
|
||||
{
|
||||
parser.ParseExpression(true);
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.CloseParen);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected ), got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.OpenCurly);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected {, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// todo parse states block
|
||||
stream.Position--;
|
||||
List<ZScriptToken> tokens = parser.ParseBlock(false); // do nothing for now
|
||||
|
||||
return (tokens != null);
|
||||
}
|
||||
|
||||
private string ParseTypeName(ZScriptParser parser, Stream stream, ZScriptTokenizer tokenizer)
|
||||
{
|
||||
ZScriptToken token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected type name, got " + ((Object)token ?? "<null>").ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
string outs = token.Value;
|
||||
|
||||
long cpos = stream.Position;
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ReadToken();
|
||||
if (token != null && token.Type == ZScriptTokenType.OpLessThan) // <
|
||||
{
|
||||
string internal_type = ParseTypeName(parser, stream, tokenizer);
|
||||
if (internal_type == null)
|
||||
return null;
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.OpGreaterThan);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected >, got " + ((Object)token ?? "<null>").ToString());
|
||||
return null;
|
||||
}
|
||||
return outs + "<" + internal_type + ">";
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.Position = cpos;
|
||||
return outs;
|
||||
}
|
||||
}
|
||||
|
||||
internal ZScriptActorStructure(ZDTextParser zdparser, DecorateCategoryInfo catinfo, string _classname, string _replacesname, string _parentname) : base(zdparser, catinfo)
|
||||
{
|
||||
ZScriptParser parser = (ZScriptParser)zdparser;
|
||||
Stream stream = parser.DataStream;
|
||||
ZScriptTokenizer tokenizer = new ZScriptTokenizer(parser.DataReader);
|
||||
parser.tokenizer = tokenizer;
|
||||
|
||||
classname = _classname;
|
||||
replaceclass = _replacesname;
|
||||
|
||||
|
||||
ZScriptToken cls_open = tokenizer.ExpectToken(ZScriptTokenType.OpenCurly);
|
||||
if (cls_open == null || !cls_open.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected {, got " + ((Object)cls_open ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
// in the class definition, we can have the following:
|
||||
// - Defaults block
|
||||
// - States block
|
||||
// - method signature: [native] [action] <type [, type [...]]> <name> (<arguments>);
|
||||
// - method: <method signature (except native)> <block>
|
||||
// - field declaration: [native] <type> <name>;
|
||||
// - enum definition: enum <name> <block>;
|
||||
// we are skipping everything, except Defaults and States.
|
||||
while (true)
|
||||
{
|
||||
tokenizer.SkipWhitespace();
|
||||
long ocpos = stream.Position;
|
||||
ZScriptToken token = tokenizer.ExpectToken(ZScriptTokenType.Identifier, ZScriptTokenType.CloseCurly);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected identifier, got " + ((Object)cls_open ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
if (token.Type == ZScriptTokenType.CloseCurly) // end of class
|
||||
break;
|
||||
|
||||
string b_lower = token.Value.ToLowerInvariant();
|
||||
switch (b_lower)
|
||||
{
|
||||
case "default":
|
||||
if (!ParseDefaultBlock(parser, stream, tokenizer))
|
||||
return;
|
||||
continue;
|
||||
|
||||
case "states":
|
||||
if (!ParseStatesBlock(parser, stream, tokenizer))
|
||||
return;
|
||||
continue;
|
||||
|
||||
case "enum":
|
||||
if (!parser.ParseEnum())
|
||||
return;
|
||||
continue;
|
||||
|
||||
case "const":
|
||||
if (!parser.ParseConst())
|
||||
return;
|
||||
continue;
|
||||
|
||||
// apparently we can have a struct inside a class, but not another class.
|
||||
case "struct":
|
||||
if (!parser.ParseClassOrStruct(true, false))
|
||||
return;
|
||||
continue;
|
||||
|
||||
default:
|
||||
stream.Position = ocpos;
|
||||
break;
|
||||
}
|
||||
|
||||
// try to read in a variable/method.
|
||||
bool bmethod = false;
|
||||
string[] availablemodifiers = new string[] { "static", "native", "action", "readonly", "protected", "private", "virtual", "override", "meta", "deprecated", "final" };
|
||||
string[] methodmodifiers = new string[] { "action", "virtual", "override", "final" };
|
||||
HashSet<string> modifiers = new HashSet<string>();
|
||||
List<string> types = new List<string>();
|
||||
List<string> names = new List<string>();
|
||||
List<int> arraylens = new List<int>();
|
||||
List<ZScriptToken> args = null; // this is for the future
|
||||
List<ZScriptToken> body = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
tokenizer.SkipWhitespace();
|
||||
long cpos = stream.Position;
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected modifier or name, got " + ((Object)cls_open ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
b_lower = token.Value.ToLowerInvariant();
|
||||
if (availablemodifiers.Contains(b_lower))
|
||||
{
|
||||
if (modifiers.Contains(b_lower))
|
||||
{
|
||||
parser.ReportError("Field/method modifier '" + b_lower + "' was specified twice");
|
||||
return;
|
||||
}
|
||||
|
||||
if (methodmodifiers.Contains(b_lower))
|
||||
bmethod = true;
|
||||
|
||||
modifiers.Add(b_lower);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.Position = cpos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// read in the type name(s)
|
||||
// type name can be:
|
||||
// - identifier
|
||||
// - identifier<identifier>
|
||||
while (true)
|
||||
{
|
||||
tokenizer.SkipWhitespace();
|
||||
string typename = ParseTypeName(parser, stream, tokenizer);
|
||||
if (typename == null)
|
||||
return;
|
||||
types.Add(typename.ToLowerInvariant());
|
||||
long cpos = stream.Position;
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ReadToken();
|
||||
if (token == null || token.Type != ZScriptTokenType.Comma)
|
||||
{
|
||||
stream.Position = cpos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
string name = null;
|
||||
int arraylen = 0;
|
||||
|
||||
// read in the method/field name
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected field/method name, got " + ((Object)token ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
name = token.Value.ToLowerInvariant();
|
||||
|
||||
// check the token. if it's a (, then it's a method. if it's a ;, then it's a field, if it's a [ it's an array field.
|
||||
// if it's a field and bmethod=true, report error.
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Comma, ZScriptTokenType.OpenParen, ZScriptTokenType.OpenSquare, ZScriptTokenType.Semicolon);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected comma, ;, [, or argument list, got " + ((Object)token ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (token.Type == ZScriptTokenType.OpenParen)
|
||||
{
|
||||
// if we have multiple names
|
||||
if (names.Count > 1)
|
||||
{
|
||||
parser.ReportError("Cannot have multiple names in a method");
|
||||
return;
|
||||
}
|
||||
|
||||
bmethod = true;
|
||||
// now, I could parse this properly, but it won't be used anyway, so I'll do it as a fake expression.
|
||||
args = parser.ParseExpression(true);
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.CloseParen);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected ), got " + ((Object)token ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
// also get the body block, if any.
|
||||
tokenizer.SkipWhitespace();
|
||||
long cpos = stream.Position;
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Semicolon, ZScriptTokenType.OpenCurly);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected ; or {, got " + ((Object)token ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (token.Type == ZScriptTokenType.OpenCurly)
|
||||
{
|
||||
stream.Position = cpos;
|
||||
body = parser.ParseBlock(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bmethod)
|
||||
{
|
||||
parser.ReportError("Cannot have virtual, override or action fields");
|
||||
return;
|
||||
}
|
||||
|
||||
// array
|
||||
if (token.Type == ZScriptTokenType.OpenSquare)
|
||||
{
|
||||
// read in the size or a constant.
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Integer, ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected integer or constant, got " + ((Object)token ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (token.Type == ZScriptTokenType.Integer)
|
||||
arraylen = token.ValueInt;
|
||||
else arraylen = -1;
|
||||
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.CloseSquare);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected ], got " + ((Object)token ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Semicolon, ZScriptTokenType.Comma);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
parser.ReportError("Expected ;, got " + ((Object)token ?? "<null>").ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
names.Add(name);
|
||||
arraylens.Add(arraylen);
|
||||
|
||||
if (token.Type != ZScriptTokenType.Comma) // next name
|
||||
break;
|
||||
}
|
||||
|
||||
// validate modifiers here.
|
||||
// protected and private cannot be combined.
|
||||
if (bmethod)
|
||||
{
|
||||
if (modifiers.Contains("protected") && modifiers.Contains("private"))
|
||||
{
|
||||
parser.ReportError("Cannot have protected and private on the same method");
|
||||
return;
|
||||
}
|
||||
// virtual and override cannot be combined.
|
||||
int cvirtual = modifiers.Contains("virtual")?1:0;
|
||||
cvirtual += modifiers.Contains("override")?1:0;
|
||||
cvirtual += modifiers.Contains("final")?1:0;
|
||||
if (cvirtual > 1)
|
||||
{
|
||||
parser.ReportError("Cannot have virtual, override and final on the same method");
|
||||
return;
|
||||
}
|
||||
// meta (what the fuck is that?) probably cant be on a method
|
||||
if (modifiers.Contains("meta"))
|
||||
{
|
||||
parser.ReportError("Cannot have meta on a method");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// finished method or field parsing.
|
||||
/*for (int i = 0; i < names.Count; i++)
|
||||
{
|
||||
string name = names[i];
|
||||
int arraylen = arraylens[i];
|
||||
|
||||
string _args = "";
|
||||
if (args != null) _args = " (" + ZScriptTokenizer.TokensToString(args) + ")";
|
||||
else if (arraylen != 0) _args = " [" + arraylen.ToString() + "]";
|
||||
parser.LogWarning(string.Format("{0} {1} {2}{3}", string.Join(" ", modifiers.ToArray()), string.Join(", ", types.ToArray()), name, _args));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +406,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
public long Position { get; internal set; }
|
||||
public BinaryReader DataReader { get; internal set; }
|
||||
public string SourceName { get; internal set; }
|
||||
public DataLocation DataLocation { get; internal set; }
|
||||
|
||||
// textresourcepath
|
||||
public string TextResourcePath { get; internal set; }
|
||||
|
@ -49,6 +419,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
Position = parser.datastream.Position;
|
||||
DataReader = parser.datareader;
|
||||
SourceName = parser.sourcename;
|
||||
DataLocation = parser.datalocation;
|
||||
TextResourcePath = parser.textresourcepath;
|
||||
|
||||
ClassName = classname;
|
||||
|
@ -63,6 +434,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
Parser.datastream.Position = Position;
|
||||
Parser.datareader = DataReader;
|
||||
Parser.sourcename = SourceName;
|
||||
Parser.datalocation = DataLocation;
|
||||
Parser.prevstreamposition = -1;
|
||||
}
|
||||
|
||||
|
@ -96,7 +468,10 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
{
|
||||
Actor = new ZScriptActorStructure(Parser, null, ClassName, ReplacementName, ParentName);
|
||||
if (Parser.HasError)
|
||||
{
|
||||
Actor = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check actor replacement.
|
||||
Parser.archivedactors[Actor.ClassName.ToLowerInvariant()] = Actor;
|
||||
|
@ -161,7 +536,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
private bool isdisposed;
|
||||
|
||||
// [ZZ] custom tokenizer class
|
||||
private ZScriptTokenizer tokenizer;
|
||||
internal ZScriptTokenizer tokenizer;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -291,7 +666,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
}
|
||||
|
||||
// read in an expression as a token list.
|
||||
private List<ZScriptToken> ParseExpression()
|
||||
internal List<ZScriptToken> ParseExpression(bool betweenparen = false)
|
||||
{
|
||||
List<ZScriptToken> ol = new List<ZScriptToken>();
|
||||
//
|
||||
|
@ -303,12 +678,12 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
ZScriptToken token = tokenizer.ReadToken();
|
||||
if (token == null)
|
||||
{
|
||||
ReportError("Expected a token.");
|
||||
ReportError("Expected a token");
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((token.Type == ZScriptTokenType.Semicolon ||
|
||||
token.Type == ZScriptTokenType.Comma) && nestingLevel == 0)
|
||||
token.Type == ZScriptTokenType.Comma) && nestingLevel == 0 && !betweenparen)
|
||||
{
|
||||
datastream.Position = cpos;
|
||||
return ol;
|
||||
|
@ -332,7 +707,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
}
|
||||
}
|
||||
|
||||
private List<ZScriptToken> ParseBlock(bool allowsingle)
|
||||
internal List<ZScriptToken> ParseBlock(bool allowsingle)
|
||||
{
|
||||
List<ZScriptToken> ol = new List<ZScriptToken>();
|
||||
//
|
||||
|
@ -376,7 +751,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
token = tokenizer.ReadToken();
|
||||
if (token == null)
|
||||
{
|
||||
ReportError("Expected a token.");
|
||||
ReportError("Expected a token");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -389,7 +764,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
nestingLevel--;
|
||||
if (nestingLevel < 0)
|
||||
{
|
||||
ReportError("Closing parenthesis without an opening one!");
|
||||
ReportError("Closing parenthesis without an opening one");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -407,7 +782,54 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
return ol;
|
||||
}
|
||||
|
||||
private bool ParseClassOrStruct(bool isstruct, bool extend)
|
||||
internal bool ParseConst()
|
||||
{
|
||||
// const blablabla = <expression>;
|
||||
tokenizer.SkipWhitespace();
|
||||
ZScriptToken token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected const name, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
string constname = token.Value;
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.OpAssign);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected =, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
tokenizer.SkipWhitespace();
|
||||
if (ParseExpression() == null) return false; // anything until a semicolon or a comma, + anything between parentheses
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Semicolon);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected ;, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
//LogWarning(string.Format("Parsed const {0}", constname));
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool ParseEnum()
|
||||
{
|
||||
// enum blablabla {}
|
||||
tokenizer.SkipWhitespace();
|
||||
ZScriptToken token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected enum name, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
tokenizer.SkipWhitespace();
|
||||
if (ParseBlock(false) == null) return false; // anything between { and }
|
||||
//LogWarning(string.Format("Parsed enum {0}", token.Value));
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool ParseClassOrStruct(bool isstruct, bool extend)
|
||||
{
|
||||
// 'class' keyword is already parsed
|
||||
tokenizer.SkipWhitespace();
|
||||
|
@ -430,7 +852,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
|
||||
if (token == null)
|
||||
{
|
||||
ReportError("Expected a token.");
|
||||
ReportError("Expected a token");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -440,13 +862,13 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
{
|
||||
if (tok_native != null)
|
||||
{
|
||||
ReportError("Cannot have replacement after native.");
|
||||
ReportError("Cannot have replacement after native");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tok_replacename != null)
|
||||
{
|
||||
ReportError("Cannot have two replacements per class.");
|
||||
ReportError("Cannot have two replacements per class");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -462,7 +884,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
{
|
||||
if (tok_native != null)
|
||||
{
|
||||
ReportError("Cannot have two native keywords.");
|
||||
ReportError("Cannot have two native keywords");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -477,13 +899,13 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
{
|
||||
if (tok_parentname != null)
|
||||
{
|
||||
ReportError("Cannot have two parent classes.");
|
||||
ReportError("Cannot have two parent classes");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tok_replacename != null || tok_native != null)
|
||||
{
|
||||
ReportError("Cannot have parent class after replacement class or native keyword.");
|
||||
ReportError("Cannot have parent class after replacement class or native keyword");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -521,7 +943,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
string clskey = cls.ClassName.ToLowerInvariant();
|
||||
if (allclasses.ContainsKey(clskey))
|
||||
{
|
||||
ReportError("Class "+cls.ClassName+" is double-defined.");
|
||||
ReportError("Class "+cls.ClassName+" is double-defined");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -639,45 +1061,12 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
return false;
|
||||
break;
|
||||
case "const":
|
||||
// const blablabla = <expression>;
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected const name, got " + ((Object)token ?? "<null>").ToString());
|
||||
if (!ParseConst())
|
||||
return false;
|
||||
}
|
||||
string constname = token.Value;
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.OpAssign);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected =, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
tokenizer.SkipWhitespace();
|
||||
if (ParseExpression() == null) return false; // anything until a semicolon or a comma, + anything between parentheses
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Semicolon);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected ;, got " + ((Object)token ?? "<null>").ToString());
|
||||
return false;
|
||||
}
|
||||
//LogWarning(string.Format("Parsed const {0}", constname));
|
||||
break;
|
||||
case "enum":
|
||||
// enum blablabla {}
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected enum name, got " + ((Object)token ?? "<null>").ToString());
|
||||
if (!ParseEnum())
|
||||
return false;
|
||||
}
|
||||
tokenizer.SkipWhitespace();
|
||||
if (ParseBlock(false) == null) return false; // anything between { and }
|
||||
//LogWarning(string.Format("Parsed enum {0}", token.Value));
|
||||
break;
|
||||
default:
|
||||
ReportError("Expected preprocessor statement, const, enum or class declaraction, got " + token);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue