From cfbcfc440d134f6ed6642b45456bce449b6c0864 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 19 Oct 2016 13:07:44 +0200 Subject: [PATCH] - 'fixed' local variable declrations to work like C, not like some Lua-inspired nightmare. Also added proper initialization syntax for arrays. --- src/scripting/zscript/ast.cpp | 13 ++++- src/scripting/zscript/zcc-parse.lemon | 70 +++++++++++++++++++++++++-- src/scripting/zscript/zcc_parser.h | 10 +++- 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/scripting/zscript/ast.cpp b/src/scripting/zscript/ast.cpp index 45b8053ba..2f15c019e 100644 --- a/src/scripting/zscript/ast.cpp +++ b/src/scripting/zscript/ast.cpp @@ -437,6 +437,17 @@ static void PrintVarName(FLispString &out, ZCC_TreeNode *node) out.Close(); } +static void PrintVarInit(FLispString &out, ZCC_TreeNode *node) +{ + ZCC_VarInit *vnode = (ZCC_VarInit *)node; + out.Open("var-init"); + PrintNodes(out, vnode->ArraySize); + PrintNodes(out, vnode->Init); + if (vnode->InitIsArray) out.Add("array", 5); + out.AddName(vnode->Name); + out.Close(); +} + static void PrintType(FLispString &out, ZCC_TreeNode *node) { ZCC_Type *tnode = (ZCC_Type *)node; @@ -762,7 +773,6 @@ static void PrintLocalVarStmt(FLispString &out, ZCC_TreeNode *node) out.Open("local-var-stmt"); PrintNodes(out, snode->Type); PrintNodes(out, snode->Vars); - PrintNodes(out, snode->Inits); out.Close(); } @@ -859,6 +869,7 @@ void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FLispString &, ZCC_TreeNode * PrintStateGoto, PrintStateLine, PrintVarName, + PrintVarInit, PrintType, PrintBasicType, PrintMapType, diff --git a/src/scripting/zscript/zcc-parse.lemon b/src/scripting/zscript/zcc-parse.lemon index 45b7a99ff..43d7d02ab 100644 --- a/src/scripting/zscript/zcc-parse.lemon +++ b/src/scripting/zscript/zcc-parse.lemon @@ -1637,15 +1637,75 @@ assign_op(X) ::= XOREQ(T). { X.Int = ZCC_XOREQ; X.SourceLoc = T.SourceLoc; } %type local_var{ZCC_LocalVarStmt *} -local_var(X) ::= type(A) variable_list(B) var_init(C). +local_var(X) ::= type(A) variable_list_with_init(B). { NEW_AST_NODE(LocalVarStmt,vardef,A); vardef->Type = A; vardef->Vars = B; - vardef->Inits = C; X = vardef; } -%type var_init{ZCC_Expression *} -var_init(X) ::= . { X = NULL; } -var_init(X) ::= EQ expr_list(A). { X = A; /*X-overwrites-A*/ } +%type var_init{ZCC_VarInit *} +var_init(X) ::= IDENTIFIER(A). +{ + NEW_AST_NODE(VarInit,var,A); + var->Name = ENamedName(A.Int); + var->ArraySize = NULL; + var->Init = NULL; + var->InitIsArray = false; + X = var; +} + +var_init(X) ::= IDENTIFIER(A) array_size(B). +{ + NEW_AST_NODE(VarInit,var,A); + var->Name = ENamedName(A.Int); + var->ArraySize = B; + var->Init = NULL; + var->InitIsArray = false; + X = var; +} + +var_init(X) ::= IDENTIFIER(A) EQ expr(B). +{ + NEW_AST_NODE(VarInit,var,A); + var->Name = ENamedName(A.Int); + var->ArraySize = NULL; + var->Init = B; + var->InitIsArray = false; + X = var; +} + +var_init(X) ::= IDENTIFIER(A) EQ LBRACE expr_list(C) RBRACE. // this is for arrays which declare the size with the type +{ + NEW_AST_NODE(VarInit,var,A); + var->Name = ENamedName(A.Int); + var->ArraySize = NULL; + var->Init = C; + var->InitIsArray = true; + X = var; +} + +var_init(X) ::= IDENTIFIER(A) array_size(B) EQ LBRACE expr_list(C) RBRACE. +{ + NEW_AST_NODE(VarInit,var,A); + var->Name = ENamedName(A.Int); + var->ArraySize = B; + var->Init = C; + var->InitIsArray = true; + X = var; +} + +var_init(X) ::= IDENTIFIER EQ LBRACE error RBRACE. +{ + X = NULL; +} + +%type variable_list_with_init{ZCC_VarInit *} + +variable_list_with_init(X) ::= var_init(X). +variable_list_with_init(X) ::= variable_list_with_init(A) COMMA var_init(B). +{ + A->AppendSibling(B); + X = A; /*X-overwrites-A*/ +} diff --git a/src/scripting/zscript/zcc_parser.h b/src/scripting/zscript/zcc_parser.h index 5dae72ee0..503ef7e9e 100644 --- a/src/scripting/zscript/zcc_parser.h +++ b/src/scripting/zscript/zcc_parser.h @@ -62,6 +62,7 @@ enum EZCCTreeNodeType AST_StateGoto, AST_StateLine, AST_VarName, + AST_VarInit, AST_Type, AST_BasicType, AST_MapType, @@ -294,6 +295,12 @@ struct ZCC_VarName : ZCC_TreeNode ZCC_Expression *ArraySize; // NULL if not an array }; +struct ZCC_VarInit : ZCC_VarName +{ + ZCC_Expression *Init; + bool InitIsArray; // this is needed to distinguish one-element arrays from raw elements. +}; + struct ZCC_Type : ZCC_TreeNode { ZCC_Expression *ArraySize; // NULL if not an array @@ -446,8 +453,7 @@ struct ZCC_AssignStmt : ZCC_Statement struct ZCC_LocalVarStmt : ZCC_Statement { ZCC_Type *Type; - ZCC_VarName *Vars; - ZCC_Expression *Inits; + ZCC_VarInit *Vars; }; struct ZCC_FuncParamDecl : ZCC_TreeNode