From f46b6b5be5cabb089ebe6cd3ba83e8ba335add22 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Oct 2016 00:04:30 +0200 Subject: [PATCH] - fixed some issues with the grammar for parsing states: * Goto did not support the class scope operator '::'. Like in DECORATE, this cannot be done with a simple '.' because it creates semantic problems with first part of a state label. This requires different syntax so that it can unambiguously distinguish between a scope identifier and the actual label * Goto used the incorrect token PLUS for '+' instead of ADD. * The state's duration was not stored in the AST. * Truncating the sprite name inside the parser is probably not the best idea because it used a simple Printf to report this. Let's do this during processing of the AST where this can be properly handled as an error. --- src/zscript/ast.cpp | 4 +++- src/zscript/zcc-parse.lemon | 28 +++++++++++++++++----------- src/zscript/zcc_parser.h | 4 +++- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/zscript/ast.cpp b/src/zscript/ast.cpp index 1f416f7ad..45b8053ba 100644 --- a/src/zscript/ast.cpp +++ b/src/zscript/ast.cpp @@ -405,6 +405,7 @@ static void PrintStateGoto(FLispString &out, ZCC_TreeNode *node) { ZCC_StateGoto *snode = (ZCC_StateGoto *)node; out.Open("state-goto"); + PrintNodes(out, snode->Qualifier); PrintNodes(out, snode->Label); PrintNodes(out, snode->Offset); out.Close(); @@ -414,7 +415,8 @@ static void PrintStateLine(FLispString &out, ZCC_TreeNode *node) { ZCC_StateLine *snode = (ZCC_StateLine *)node; out.Open("state-line"); - out.Add(snode->Sprite, 4); + out.Add(*(snode->Sprite)); + PrintNodes(out, snode->Duration); if (snode->bNoDelay) out.Add("nodelay", 7); if (snode->bBright) out.Add("bright", 6); if (snode->bFast) out.Add("fast", 4); diff --git a/src/zscript/zcc-parse.lemon b/src/zscript/zcc-parse.lemon index 1861463f9..ae03248cc 100644 --- a/src/zscript/zcc-parse.lemon +++ b/src/zscript/zcc-parse.lemon @@ -430,25 +430,31 @@ state_flow_type(X) ::= GOTO(T) dottable_id(A) state_goto_offset(B). NEW_AST_NODE(StateGoto, flow, T); flow->Label = A; flow->Offset = B; + flow->Qualifier = nullptr; + X = flow; +} + +state_flow_type(X) ::= GOTO(T) IDENTIFIER(C) SCOPE dottable_id(A) state_goto_offset(B). +{ + NEW_AST_NODE(StateGoto, flow, T); + flow->Label = A; + flow->Offset = B; + + NEW_AST_NODE(Identifier,id,C); + id->Id = C.Name(); + flow->Qualifier =id; X = flow; } state_goto_offset(X) ::= . { X = NULL; } -state_goto_offset(X) ::= PLUS expr(A). { X = A; /*X-overwrites-A*/ } /* Must evaluate to a non-negative integer constant. */ +state_goto_offset(X) ::= ADD expr(A). { X = A; /*X-overwrites-A*/ } /* Must evaluate to a non-negative integer constant. */ -state_line(X) ::= NWS(A) NWS(B) expr state_opts(C) state_action(D). +state_line(X) ::= NWS(A) NWS(B) expr(E) state_opts(C) state_action(D). { NEW_AST_NODE(StateLine, line, A); - const char *sprite = FName(A.Name()).GetChars(); - if (strlen(sprite) != 4) - { - Printf("Sprite name '%s' must be four characters", sprite); - } - else - { - memcpy(line->Sprite, sprite, 4); - } + line->Sprite = stat->Strings.Alloc(FName(A.Name()).GetChars()); line->Frames = stat->Strings.Alloc(FName(B.Name()).GetChars()); + line->Duration = E; line->bBright = C.Bright; line->bFast = C.Fast; line->bSlow = C.Slow; diff --git a/src/zscript/zcc_parser.h b/src/zscript/zcc_parser.h index 5d5c85827..0cb3f79ae 100644 --- a/src/zscript/zcc_parser.h +++ b/src/zscript/zcc_parser.h @@ -260,19 +260,21 @@ struct ZCC_Expression : ZCC_TreeNode struct ZCC_StateGoto : ZCC_StatePart { + ZCC_Identifier *Qualifier; ZCC_Identifier *Label; ZCC_Expression *Offset; }; struct ZCC_StateLine : ZCC_StatePart { - char Sprite[4]; + FString *Sprite; BITFIELD bBright : 1; BITFIELD bFast : 1; BITFIELD bSlow : 1; BITFIELD bNoDelay : 1; BITFIELD bCanRaise : 1; FString *Frames; + ZCC_Expression *Duration; ZCC_Expression *Offset; ZCC_TreeNode *Action; };