- started to make ZScript parser work on real-life data. It will now read a lump named ZSCRIPT which is a list of filenames to be compiled.

- place generated symbols into GlobalSymbols instead of a scratch table that will be discarded right away.
- allow the state object to change source file scanners (I hope this works, but the old implementation was unable to do more than one with with a parse state so I had to change it.)
- It can now parse constants.txt and insert everything in it into the global symbol table and make subsequent DECORATE compile properly.
This commit is contained in:
Christoph Oelckers 2016-10-08 01:05:27 +02:00
parent 04d4bda262
commit 994bb4fc7a
4 changed files with 75 additions and 53 deletions

View file

@ -445,6 +445,7 @@ static void FinishThingdef()
// Called from FActor::StaticInit() // Called from FActor::StaticInit()
// //
//========================================================================== //==========================================================================
void ParseScripts();
void LoadActors () void LoadActors ()
{ {
@ -456,19 +457,10 @@ void LoadActors ()
FScriptPosition::ResetErrorCounter(); FScriptPosition::ResetErrorCounter();
InitThingdef(); InitThingdef();
lastlump = 0; lastlump = 0;
ParseScripts();
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1) while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
{ {
FScanner sc(lump); FScanner sc(lump);
if (Wads.GetLumpFile(lump) == 0)
{
// define namespace 'zdoom'
}
else
{
// use namespace 'zdoom'
}
ParseDecorate (sc); ParseDecorate (sc);
} }
FinishThingdef(); FinishThingdef();

View file

@ -96,9 +96,9 @@ static void SetNodeLine(ZCC_TreeNode *name, int line)
} }
} }
} }
stat->sc.ScriptMessage("%s\n%s\n", unexpected.GetChars(), expecting.GetChars()); stat->sc->ScriptMessage("%s\n%s\n", unexpected.GetChars(), expecting.GetChars());
} }
%parse_accept { stat->sc.ScriptMessage("input accepted\n"); } %parse_accept { DPrintf(DMSG_SPAMMY, "Input accepted\n"); }
%parse_failure { /**failed = true;*/ } %parse_failure { /**failed = true;*/ }
%nonassoc EQ MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ OREQ XOREQ. %nonassoc EQ MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ OREQ XOREQ.
@ -124,7 +124,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line)
%type opt_func_body {ZCC_CompoundStmt *} %type opt_func_body {ZCC_CompoundStmt *}
%type function_body {ZCC_CompoundStmt *} %type function_body {ZCC_CompoundStmt *}
main ::= translation_unit(A). { stat->TopNode = A; stat->sc.ScriptMessage("Parse complete\n"); } main ::= translation_unit(A). { stat->TopNode = A; DPrintf(DMSG_SPAMMY, "Parse complete\n"); }
%type translation_unit {ZCC_TreeNode *} %type translation_unit {ZCC_TreeNode *}
translation_unit(X) ::= . { X = NULL; } translation_unit(X) ::= . { X = NULL; }
@ -339,7 +339,7 @@ enum_def(X) ::= ENUM(T) IDENTIFIER(A) enum_type(B) LBRACE opt_enum_list(C) RBRAC
X = def; X = def;
} }
enum_type(X) ::= . { X.Int = ZCC_IntAuto; X.SourceLoc = stat->sc.GetMessageLine(); } enum_type(X) ::= . { X.Int = ZCC_IntAuto; X.SourceLoc = stat->sc->GetMessageLine(); }
enum_type(X) ::= COLON int_type(A). { X = A; /*X-overwrites-A*/ } enum_type(X) ::= COLON int_type(A). { X = A; /*X-overwrites-A*/ }
enum_list(X) ::= error. { X = NULL; } enum_list(X) ::= error. { X = NULL; }
@ -398,7 +398,7 @@ states_def(X) ::= STATES(T) scanner_mode LBRACE states_body(A) RBRACE.
* set immediately after LBRACE is consumed, rather than immediately after * set immediately after LBRACE is consumed, rather than immediately after
* STATES is consumed. * STATES is consumed.
*/ */
scanner_mode ::= . { stat->sc.SetStateMode(true); } scanner_mode ::= . { stat->sc->SetStateMode(true); }
states_body(X) ::= . { X = NULL; } states_body(X) ::= . { X = NULL; }
states_body(X) ::= error. { X = NULL; } states_body(X) ::= error. { X = NULL; }
@ -538,7 +538,7 @@ type_name(X) ::= DOT dottable_id(A).
* straight away.) * straight away.)
*/ */
%token_class intconst INTCONST|UINTCONST. %token_class intconst INTCONST|UINTCONST.
vector_size(X) ::= . { X.Int = ZCC_Vector3; X.SourceLoc = stat->sc.GetMessageLine(); } vector_size(X) ::= . { X.Int = ZCC_Vector3; X.SourceLoc = stat->sc->GetMessageLine(); }
vector_size(X) ::= LT intconst(A) GT. vector_size(X) ::= LT intconst(A) GT.
{ {
if (A.Int >= 2 && A.Int <= 4) if (A.Int >= 2 && A.Int <= 4)
@ -548,7 +548,7 @@ vector_size(X) ::= LT intconst(A) GT.
else else
{ {
X.Int = ZCC_Vector3; X.Int = ZCC_Vector3;
stat->sc.ScriptMessage("Invalid vector size %d\n", A.Int); stat->sc->ScriptMessage("Invalid vector size %d\n", A.Int);
} }
X.SourceLoc = A.SourceLoc; X.SourceLoc = A.SourceLoc;
} }
@ -656,11 +656,11 @@ declarator(X) ::= decl_flags(A) type_list_or_void(B) variables_or_function(C).
{ // An invalid { // An invalid
if (B == NULL) if (B == NULL)
{ {
stat->sc.ScriptMessage("Variables may not be of type void.\n"); stat->sc->ScriptMessage("Variables may not be of type void.\n");
} }
else else
{ {
stat->sc.ScriptMessage("Variables may be of only one type.\n"); stat->sc->ScriptMessage("Variables may be of only one type.\n");
} }
X = NULL; X = NULL;
} }
@ -750,7 +750,7 @@ decl_flags(X) ::= decl_flags(A) ACTION(T). { X.Int = A.Int | ZCC_Action; X.Sour
decl_flags(X) ::= decl_flags(A) READONLY(T). { X.Int = A.Int | ZCC_ReadOnly; X.SourceLoc = A.SourceLoc ? A.SourceLoc : T.SourceLoc; } decl_flags(X) ::= decl_flags(A) READONLY(T). { X.Int = A.Int | ZCC_ReadOnly; X.SourceLoc = A.SourceLoc ? A.SourceLoc : T.SourceLoc; }
decl_flags(X) ::= decl_flags(A) DEPRECATED(T). { X.Int = A.Int | ZCC_Deprecated; X.SourceLoc = A.SourceLoc ? A.SourceLoc : T.SourceLoc; } decl_flags(X) ::= decl_flags(A) DEPRECATED(T). { X.Int = A.Int | ZCC_Deprecated; X.SourceLoc = A.SourceLoc ? A.SourceLoc : T.SourceLoc; }
func_const(X) ::= . { X.Int = 0; X.SourceLoc = stat->sc.GetMessageLine(); } func_const(X) ::= . { X.Int = 0; X.SourceLoc = stat->sc->GetMessageLine(); }
func_const(X) ::= CONST(T). { X.Int = ZCC_FuncConst; X.SourceLoc = T.SourceLoc; } func_const(X) ::= CONST(T). { X.Int = ZCC_FuncConst; X.SourceLoc = T.SourceLoc; }
opt_func_body(X) ::= SEMICOLON. { X = NULL; } opt_func_body(X) ::= SEMICOLON. { X = NULL; }

View file

@ -5,6 +5,7 @@
#include "w_wad.h" #include "w_wad.h"
#include "cmdlib.h" #include "cmdlib.h"
#include "m_alloc.h" #include "m_alloc.h"
#include "i_system.h"
#include "zcc_parser.h" #include "zcc_parser.h"
#include "zcc_compile.h" #include "zcc_compile.h"
@ -161,44 +162,26 @@ static void InitTokenMap()
#undef TOKENDEF #undef TOKENDEF
#undef TOKENDEF2 #undef TOKENDEF2
static void DoParse(const char *filename) static void ParseSingleFile(const char *filename, void *parser, ZCCParseState &state)
{ {
if (TokenMap.CountUsed() == 0)
{
InitTokenMap();
}
FScanner sc;
void *parser;
int tokentype; int tokentype;
int lump; int lump;
bool failed; //bool failed;
ZCCToken value; ZCCToken value;
FScanner sc;
lump = Wads.CheckNumForFullName(filename, true); lump = Wads.CheckNumForFullName(filename, true);
if (lump >= 0) if (lump >= 0)
{ {
sc.OpenLumpNum(lump); sc.OpenLumpNum(lump);
} }
else if (FileExists(filename))
{
sc.OpenFile(filename);
}
else else
{ {
Printf("Could not find script lump '%s'\n", filename); Printf("Could not find script lump '%s'\n", filename);
return; return;
} }
parser = ZCCParseAlloc(malloc); state.sc = &sc;
failed = false;
#ifdef _DEBUG
FILE *f = fopen("trace.txt", "w");
char prompt = '\0';
ZCCParseTrace(f, &prompt);
#endif
ZCCParseState state(sc);
while (sc.GetToken()) while (sc.GetToken())
{ {
value.SourceLoc = sc.GetMessageLine(); value.SourceLoc = sc.GetMessageLine();
@ -241,7 +224,7 @@ static void DoParse(const char *filename)
default: default:
TokenMapEntry *zcctoken = TokenMap.CheckKey(sc.TokenType); TokenMapEntry *zcctoken = TokenMap.CheckKey(sc.TokenType);
if (zcctoken != NULL) if (zcctoken != nullptr)
{ {
tokentype = zcctoken->TokenType; tokentype = zcctoken->TokenType;
value.Int = zcctoken->TokenName; value.Int = zcctoken->TokenName;
@ -254,20 +237,55 @@ static void DoParse(const char *filename)
break; break;
} }
ZCCParse(parser, tokentype, value, &state); ZCCParse(parser, tokentype, value, &state);
if (failed)
{
sc.ScriptMessage("Parse failed\n");
goto parse_end;
}
} }
parse_end: parse_end:
value.Int = -1; value.Int = -1;
ZCCParse(parser, ZCC_EOF, value, &state); ZCCParse(parser, ZCC_EOF, value, &state);
state.sc = nullptr;
}
static void DoParse(int lumpnum)
{
if (TokenMap.CountUsed() == 0)
{
InitTokenMap();
}
FScanner sc;
void *parser;
ZCCToken value;
parser = ZCCParseAlloc(malloc);
ZCCParseState state;
#ifdef _DEBUG
FILE *f = fopen("trace.txt", "w");
char prompt = '\0';
ZCCParseTrace(f, &prompt);
#endif
sc.OpenLumpNum(lumpnum);
// parse all files from this list in one go.
while (sc.GetString())
{
if (Wads.GetLumpFile(sc.LumpNum) == 0)
{
int includefile = Wads.GetLumpFile(Wads.CheckNumForFullName(sc.String, true));
if (includefile != 0)
{
I_FatalError("File %s is overriding core lump %s.",
Wads.GetWadFullName(includefile), sc.String);
}
}
ParseSingleFile(sc.String, parser, state);
}
value.Int = -1;
value.SourceLoc = sc.GetMessageLine();
ZCCParse(parser, 0, value, &state); ZCCParse(parser, 0, value, &state);
ZCCParseFree(parser, free); ZCCParseFree(parser, free);
PSymbolTable symbols(&GlobalSymbols); ZCCCompiler cc(state, NULL, GlobalSymbols);
ZCCCompiler cc(state, NULL, symbols);
cc.Compile(); cc.Compile();
#ifdef _DEBUG #ifdef _DEBUG
if (f != NULL) if (f != NULL)
@ -275,6 +293,7 @@ parse_end:
fclose(f); fclose(f);
} }
FString ast = ZCC_PrintAST(state.TopNode); FString ast = ZCC_PrintAST(state.TopNode);
FString filename = Wads.GetLumpFullName(lumpnum);
FString astfile = ExtractFileBase(filename, false); FString astfile = ExtractFileBase(filename, false);
astfile << ".ast"; astfile << ".ast";
f = fopen(astfile, "w"); f = fopen(astfile, "w");
@ -286,6 +305,16 @@ parse_end:
#endif #endif
} }
void ParseScripts()
{
int lump, lastlump = 0;
while ((lump = Wads.FindLump("ZSCRIPT", &lastlump)) != -1)
{
DoParse(lump);
}
}
/*
CCMD(parse) CCMD(parse)
{ {
if (argv.argc() == 2) if (argv.argc() == 2)
@ -293,6 +322,7 @@ CCMD(parse)
DoParse(argv[1]); DoParse(argv[1]);
} }
} }
*/
static FString ZCCTokenName(int terminal) static FString ZCCTokenName(int terminal)
{ {
@ -333,6 +363,6 @@ ZCC_TreeNode *ZCC_AST::InitNode(size_t size, EZCCTreeNodeType type, ZCC_TreeNode
ZCC_TreeNode *ZCCParseState::InitNode(size_t size, EZCCTreeNodeType type) ZCC_TreeNode *ZCCParseState::InitNode(size_t size, EZCCTreeNodeType type)
{ {
ZCC_TreeNode *node = ZCC_AST::InitNode(size, type, NULL); ZCC_TreeNode *node = ZCC_AST::InitNode(size, type, NULL);
node->SourceName = Strings.Alloc(sc.ScriptName); node->SourceName = Strings.Alloc(sc->ScriptName);
return node; return node;
} }

View file

@ -514,10 +514,10 @@ struct ZCC_AST
struct ZCCParseState : public ZCC_AST struct ZCCParseState : public ZCC_AST
{ {
ZCCParseState(FScanner &scanner) : sc(scanner) {} ZCCParseState(FScanner *scanner = nullptr) : sc(scanner) {}
ZCC_TreeNode *InitNode(size_t size, EZCCTreeNodeType type); ZCC_TreeNode *InitNode(size_t size, EZCCTreeNodeType type);
FScanner &sc; FScanner *sc;
}; };
#endif #endif