mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- changed assignment operators to be expressions, like they are in C and DECORATE.
This also means that for now Lua-style multi-assignments are disabled, those should be easy to enable by making some changes to the assignment_statement grammar so that it doesn't recognize single assignments, but for now this is low priority because it adds a significant amount of complexity to do this right with functions that have multiple return values.
This commit is contained in:
parent
1450c3dffb
commit
3e995d7aac
5 changed files with 102 additions and 60 deletions
|
@ -747,21 +747,6 @@ static void PrintAssignStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
{
|
||||
ZCC_AssignStmt *snode = (ZCC_AssignStmt *)node;
|
||||
out.Open("assign-stmt");
|
||||
switch (snode->AssignOp)
|
||||
{
|
||||
case ZCC_EQ: out.AddChar('='); break;
|
||||
case ZCC_MULEQ: out.Add("*=", 2); break;
|
||||
case ZCC_DIVEQ: out.Add("/=", 2); break;
|
||||
case ZCC_MODEQ: out.Add("%=", 2); break;
|
||||
case ZCC_ADDEQ: out.Add("+=", 2); break;
|
||||
case ZCC_SUBEQ: out.Add("-=", 2); break;
|
||||
case ZCC_LSHEQ: out.Add("<<=", 2); break;
|
||||
case ZCC_RSHEQ: out.Add(">>=", 2); break;
|
||||
case ZCC_ANDEQ: out.Add("&=", 2); break;
|
||||
case ZCC_OREQ: out.Add("|=", 2); break;
|
||||
case ZCC_XOREQ: out.Add("^=", 2); break;
|
||||
default: BadAssignOp(out, snode->AssignOp); break;
|
||||
}
|
||||
PrintNodes(out, snode->Dests);
|
||||
PrintNodes(out, snode->Sources);
|
||||
out.Close();
|
||||
|
|
|
@ -104,7 +104,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line)
|
|||
%parse_accept { DPrintf(DMSG_SPAMMY, "Input accepted\n"); }
|
||||
%parse_failure { /**failed = true;*/ }
|
||||
|
||||
%nonassoc EQ MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ OREQ XOREQ.
|
||||
%right EQ MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ OREQ XOREQ URSHEQ.
|
||||
%right QUESTION COLON.
|
||||
%left OROR.
|
||||
%left ANDAND.
|
||||
|
@ -1247,6 +1247,67 @@ expr(X) ::= expr(A) OROR expr(B). /* a || b */
|
|||
BINARY_EXPR(A,B,PEX_BoolOr);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) EQ expr(B). /* a = b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_Assign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) ADDEQ expr(B). /* a += b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_AddAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) SUBEQ expr(B). /* a -= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_SubAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) MULEQ expr(B). /* a *= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_MulAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) DIVEQ expr(B). /* a /= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_DivAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) MODEQ expr(B). /* a %= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_ModAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) LSHEQ expr(B). /* a <<= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_LshAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) RSHEQ expr(B). /* a >>= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_RshAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) URSHEQ expr(B). /* a >>>= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_URshAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) ANDEQ expr(B). /* a &= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_AndAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) OREQ expr(B). /* a |= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_OrAssign);
|
||||
X = expr2;
|
||||
}
|
||||
expr(X) ::= expr(A) XOREQ expr(B). /* a ^= b */
|
||||
{
|
||||
BINARY_EXPR(A,B,PEX_XorAssign);
|
||||
X = expr2;
|
||||
}
|
||||
|
||||
|
||||
expr(X) ::= expr(A) SCOPE expr(B).
|
||||
{
|
||||
|
@ -1402,7 +1463,7 @@ statement(X) ::= expression_statement(A) SEMICOLON. { X = A; /*X-overwrites-A*/
|
|||
statement(X) ::= selection_statement(X).
|
||||
statement(X) ::= iteration_statement(X).
|
||||
statement(X) ::= jump_statement(X).
|
||||
statement(X) ::= assign_statement(A) SEMICOLON. { X = A; /*X-overwrites-A*/ }
|
||||
//statement(X) ::= assign_statement(A) SEMICOLON. { X = A; /*X-overwrites-A*/ }
|
||||
statement(X) ::= local_var(A) SEMICOLON. { X = A; /*X-overwrites-A*/ }
|
||||
statement(X) ::= error SEMICOLON. { X = NULL; }
|
||||
|
||||
|
@ -1553,7 +1614,6 @@ for_init(X) ::= for_bump(A). { X = A /*X-overwrites-A*/; }
|
|||
%type for_bump{ZCC_Statement *}
|
||||
for_bump(X) ::= . { X = NULL; }
|
||||
for_bump(X) ::= expression_statement(A). { X = A; /*X-overwrites-A*/ }
|
||||
for_bump(X) ::= assign_statement(A). { X = A; /*X-overwrites-A*/ }
|
||||
|
||||
/*----- If Statements -----*/
|
||||
|
||||
|
@ -1614,28 +1674,19 @@ labeled_statement(X) ::= DEFAULT(T) COLON.
|
|||
|
||||
/*----- Assignment Statements -----*/
|
||||
|
||||
/* This is no longer being used, in favor of handling assignments as expressions, just like C and C++ do.
|
||||
Keep this here in case some other parts require assignment syntax or Lua-style multi-assignments become a thing.
|
||||
%type assign_statement{ZCC_AssignStmt *}
|
||||
|
||||
assign_statement(X) ::= expr_list(A) assign_op(OP) expr_list(B). [EQ]
|
||||
assign_statement(X) ::= expr_list(A) EQ expr_list(B). [EQ]
|
||||
{
|
||||
NEW_AST_NODE(AssignStmt,stmt,OP);
|
||||
stmt->AssignOp = OP.Int;
|
||||
NEW_AST_NODE(AssignStmt,stmt,A);
|
||||
stmt->AssignOp = ZCC_EQ;
|
||||
stmt->Dests = A;
|
||||
stmt->Sources = B;
|
||||
X = stmt;
|
||||
}
|
||||
|
||||
assign_op(X) ::= EQ(T). { X.Int = ZCC_EQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= MULEQ(T). { X.Int = ZCC_MULEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= DIVEQ(T). { X.Int = ZCC_DIVEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= MODEQ(T). { X.Int = ZCC_MODEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= ADDEQ(T). { X.Int = ZCC_ADDEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= SUBEQ(T). { X.Int = ZCC_SUBEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= LSHEQ(T). { X.Int = ZCC_LSHEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= RSHEQ(T). { X.Int = ZCC_RSHEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= ANDEQ(T). { X.Int = ZCC_ANDEQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= OREQ(T). { X.Int = ZCC_OREQ; X.SourceLoc = T.SourceLoc; }
|
||||
assign_op(X) ::= XOREQ(T). { X.Int = ZCC_XOREQ; X.SourceLoc = T.SourceLoc; }
|
||||
*/
|
||||
|
||||
/*----- Local Variable Definition "Statements" -----*/
|
||||
|
||||
|
|
|
@ -2373,33 +2373,6 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
|||
break;
|
||||
}
|
||||
|
||||
case AST_AssignStmt:
|
||||
{
|
||||
auto assign = static_cast<ZCC_AssignStmt *>(ast);
|
||||
switch (assign->AssignOp)
|
||||
{
|
||||
case ZCC_EQ:
|
||||
// this ignores multi-assign statements (these should probably be disabled in the grammar.)
|
||||
return new FxAssign(ConvertNode(assign->Dests), ConvertNode(assign->Sources));
|
||||
|
||||
case ZCC_MULEQ:
|
||||
case ZCC_DIVEQ:
|
||||
case ZCC_MODEQ:
|
||||
case ZCC_ADDEQ:
|
||||
case ZCC_SUBEQ:
|
||||
case ZCC_LSHEQ:
|
||||
case ZCC_RSHEQ:
|
||||
case ZCC_ANDEQ:
|
||||
case ZCC_OREQ:
|
||||
case ZCC_XOREQ:
|
||||
//break;
|
||||
default:
|
||||
Error(ast, "Invalid assign statement");
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AST_FuncParm:
|
||||
{
|
||||
auto fparm = static_cast<ZCC_FuncParm *>(ast);
|
||||
|
@ -2526,6 +2499,23 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
|||
case PEX_NEQ:
|
||||
return new FxCompareEq(op == PEX_NEQ ? TK_Neq : TK_Eq, left, right);
|
||||
|
||||
case PEX_Assign:
|
||||
return new FxAssign(left, right);
|
||||
/*
|
||||
case ZCC_MULEQ:
|
||||
case ZCC_DIVEQ:
|
||||
case ZCC_MODEQ:
|
||||
case ZCC_ADDEQ:
|
||||
case ZCC_SUBEQ:
|
||||
case ZCC_LSHEQ:
|
||||
case ZCC_RSHEQ:
|
||||
case ZCC_ANDEQ:
|
||||
case ZCC_OREQ:
|
||||
case ZCC_XOREQ:
|
||||
//break;
|
||||
default:
|
||||
Error(ast, "Invalid assign statement");
|
||||
*/
|
||||
|
||||
// todo: These do not have representations in DECORATE and no implementation exists yet.
|
||||
case PEX_LTGTEQ:
|
||||
|
@ -2537,6 +2527,8 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
|||
// vector operations will be done later.
|
||||
case PEX_CrossProduct:
|
||||
case PEX_DotProduct:
|
||||
|
||||
|
||||
default:
|
||||
I_Error("Binary operator %d not implemented yet", op);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,19 @@ xx(BitXor, )
|
|||
xx(BoolAnd, )
|
||||
xx(BoolOr, )
|
||||
|
||||
xx(Assign, )
|
||||
xx(AddAssign, )
|
||||
xx(SubAssign, )
|
||||
xx(MulAssign, )
|
||||
xx(DivAssign, )
|
||||
xx(ModAssign, )
|
||||
xx(LshAssign, )
|
||||
xx(RshAssign, )
|
||||
xx(URshAssign, )
|
||||
xx(AndAssign, )
|
||||
xx(OrAssign, )
|
||||
xx(XorAssign, )
|
||||
|
||||
xx(Scope, )
|
||||
|
||||
xx(Trinary, )
|
||||
|
|
|
@ -73,6 +73,7 @@ static void InitTokenMap()
|
|||
TOKENDEF (TK_SubEq, ZCC_SUBEQ);
|
||||
TOKENDEF (TK_LShiftEq, ZCC_LSHEQ);
|
||||
TOKENDEF (TK_RShiftEq, ZCC_RSHEQ);
|
||||
TOKENDEF (TK_URShiftEq, ZCC_URSHEQ);
|
||||
TOKENDEF (TK_AndEq, ZCC_ANDEQ);
|
||||
TOKENDEF (TK_OrEq, ZCC_OREQ);
|
||||
TOKENDEF (TK_XorEq, ZCC_XOREQ);
|
||||
|
|
Loading…
Reference in a new issue