mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +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;
|
ZCC_AssignStmt *snode = (ZCC_AssignStmt *)node;
|
||||||
out.Open("assign-stmt");
|
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->Dests);
|
||||||
PrintNodes(out, snode->Sources);
|
PrintNodes(out, snode->Sources);
|
||||||
out.Close();
|
out.Close();
|
||||||
|
|
|
@ -104,7 +104,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line)
|
||||||
%parse_accept { DPrintf(DMSG_SPAMMY, "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.
|
%right EQ MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ OREQ XOREQ URSHEQ.
|
||||||
%right QUESTION COLON.
|
%right QUESTION COLON.
|
||||||
%left OROR.
|
%left OROR.
|
||||||
%left ANDAND.
|
%left ANDAND.
|
||||||
|
@ -1247,6 +1247,67 @@ expr(X) ::= expr(A) OROR expr(B). /* a || b */
|
||||||
BINARY_EXPR(A,B,PEX_BoolOr);
|
BINARY_EXPR(A,B,PEX_BoolOr);
|
||||||
X = expr2;
|
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).
|
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) ::= selection_statement(X).
|
||||||
statement(X) ::= iteration_statement(X).
|
statement(X) ::= iteration_statement(X).
|
||||||
statement(X) ::= jump_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) ::= local_var(A) SEMICOLON. { X = A; /*X-overwrites-A*/ }
|
||||||
statement(X) ::= error SEMICOLON. { X = NULL; }
|
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 *}
|
%type for_bump{ZCC_Statement *}
|
||||||
for_bump(X) ::= . { X = NULL; }
|
for_bump(X) ::= . { X = NULL; }
|
||||||
for_bump(X) ::= expression_statement(A). { X = A; /*X-overwrites-A*/ }
|
for_bump(X) ::= expression_statement(A). { X = A; /*X-overwrites-A*/ }
|
||||||
for_bump(X) ::= assign_statement(A). { X = A; /*X-overwrites-A*/ }
|
|
||||||
|
|
||||||
/*----- If Statements -----*/
|
/*----- If Statements -----*/
|
||||||
|
|
||||||
|
@ -1614,28 +1674,19 @@ labeled_statement(X) ::= DEFAULT(T) COLON.
|
||||||
|
|
||||||
/*----- Assignment Statements -----*/
|
/*----- 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 *}
|
%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);
|
NEW_AST_NODE(AssignStmt,stmt,A);
|
||||||
stmt->AssignOp = OP.Int;
|
stmt->AssignOp = ZCC_EQ;
|
||||||
stmt->Dests = A;
|
stmt->Dests = A;
|
||||||
stmt->Sources = B;
|
stmt->Sources = B;
|
||||||
X = stmt;
|
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" -----*/
|
/*----- Local Variable Definition "Statements" -----*/
|
||||||
|
|
||||||
|
|
|
@ -2373,33 +2373,6 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
break;
|
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:
|
case AST_FuncParm:
|
||||||
{
|
{
|
||||||
auto fparm = static_cast<ZCC_FuncParm *>(ast);
|
auto fparm = static_cast<ZCC_FuncParm *>(ast);
|
||||||
|
@ -2526,6 +2499,23 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
case PEX_NEQ:
|
case PEX_NEQ:
|
||||||
return new FxCompareEq(op == PEX_NEQ ? TK_Neq : TK_Eq, left, right);
|
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.
|
// todo: These do not have representations in DECORATE and no implementation exists yet.
|
||||||
case PEX_LTGTEQ:
|
case PEX_LTGTEQ:
|
||||||
|
@ -2537,6 +2527,8 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
// vector operations will be done later.
|
// vector operations will be done later.
|
||||||
case PEX_CrossProduct:
|
case PEX_CrossProduct:
|
||||||
case PEX_DotProduct:
|
case PEX_DotProduct:
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
I_Error("Binary operator %d not implemented yet", op);
|
I_Error("Binary operator %d not implemented yet", op);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,19 @@ xx(BitXor, )
|
||||||
xx(BoolAnd, )
|
xx(BoolAnd, )
|
||||||
xx(BoolOr, )
|
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(Scope, )
|
||||||
|
|
||||||
xx(Trinary, )
|
xx(Trinary, )
|
||||||
|
|
|
@ -73,6 +73,7 @@ static void InitTokenMap()
|
||||||
TOKENDEF (TK_SubEq, ZCC_SUBEQ);
|
TOKENDEF (TK_SubEq, ZCC_SUBEQ);
|
||||||
TOKENDEF (TK_LShiftEq, ZCC_LSHEQ);
|
TOKENDEF (TK_LShiftEq, ZCC_LSHEQ);
|
||||||
TOKENDEF (TK_RShiftEq, ZCC_RSHEQ);
|
TOKENDEF (TK_RShiftEq, ZCC_RSHEQ);
|
||||||
|
TOKENDEF (TK_URShiftEq, ZCC_URSHEQ);
|
||||||
TOKENDEF (TK_AndEq, ZCC_ANDEQ);
|
TOKENDEF (TK_AndEq, ZCC_ANDEQ);
|
||||||
TOKENDEF (TK_OrEq, ZCC_OREQ);
|
TOKENDEF (TK_OrEq, ZCC_OREQ);
|
||||||
TOKENDEF (TK_XorEq, ZCC_XOREQ);
|
TOKENDEF (TK_XorEq, ZCC_XOREQ);
|
||||||
|
|
Loading…
Reference in a new issue