Skip to content

Commit 4051570

Browse files
Merge pull request #4 from JoltedJon/gdscript-increment-decrement
Basic Testcases, tokenization and parsing completed for ++/-- 2
2 parents 3278547 + 115446d commit 4051570

19 files changed

Lines changed: 174 additions & 42 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ cppcheck-cppcheck-build-dir/
156156
# Gprof
157157
gmon.out
158158

159+
# GDB
160+
.gdbinit
161+
pretty_printer.py
162+
159163
# Jetbrains IDEs
160164
.idea/
161165
.fleet/

core/variant/variant.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,11 @@ class Variant {
581581
OP_MULTIPLY,
582582
OP_DIVIDE,
583583
OP_NEGATE,
584+
OP_DECREMENT,
585+
OP_POST_DECREMENT,
584586
OP_POSITIVE,
587+
OP_INCREMENT,
588+
OP_POST_INCREMENT,
585589
OP_MODULE,
586590
OP_POWER,
587591
//bitwise

core/variant/variant_op.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,11 @@ static const char *_op_names[Variant::OP_MAX] = {
11271127
"*",
11281128
"/",
11291129
"unary-",
1130+
"prefix--",
1131+
"postfix--",
11301132
"unary+",
1133+
"prefix++",
1134+
"postfix++",
11311135
"%",
11321136
"**",
11331137
"<<",

modules/gdscript/gdscript_analyzer.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5670,6 +5670,17 @@ void GDScriptAnalyzer::reduce_type_test(GDScriptParser::TypeTestNode *p_type_tes
56705670
}
56715671

56725672
void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op) {
5673+
switch (p_unary_op->operation) {
5674+
case GDScriptParser::UnaryOpNode::OpType::OP_INCREMENT:
5675+
case GDScriptParser::UnaryOpNode::OpType::OP_POST_INCREMENT:
5676+
case GDScriptParser::UnaryOpNode::OpType::OP_DECREMENT:
5677+
case GDScriptParser::UnaryOpNode::OpType::OP_POST_DECREMENT:
5678+
reduce_inc_dec_op(p_unary_op);
5679+
return;
5680+
default:
5681+
break;
5682+
}
5683+
56735684
reduce_expression(p_unary_op->operand);
56745685

56755686
GDScriptParser::DataType result;
@@ -5703,6 +5714,29 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op)
57035714
p_unary_op->set_datatype(result);
57045715
}
57055716

5717+
void GDScriptAnalyzer::reduce_inc_dec_op(GDScriptParser::UnaryOpNode *p_unary_op) {
5718+
reduce_expression(p_unary_op->operand);
5719+
5720+
GDScriptParser::DataType result;
5721+
5722+
if (p_unary_op->operand == nullptr) {
5723+
result.kind = GDScriptParser::DataType::VARIANT;
5724+
p_unary_op->set_datatype(result);
5725+
return;
5726+
}
5727+
5728+
GDScriptParser::DataType operand_type = p_unary_op->operand->get_datatype();
5729+
5730+
if (p_unary_op->operand->is_constant) {
5731+
push_error(vformat("Cannot assign a new value to a constant.", operand_type.to_string(), Variant::get_operator_name(p_unary_op->variant_op)), p_unary_op);
5732+
return;
5733+
}
5734+
5735+
// TODO more checks for valid operations on ++ and --
5736+
5737+
p_unary_op->set_datatype(operand_type);
5738+
}
5739+
57065740
Variant GDScriptAnalyzer::make_expression_reduced_value(GDScriptParser::ExpressionNode *p_expression, bool &is_reduced) {
57075741
Variant value;
57085742

modules/gdscript/gdscript_analyzer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class GDScriptAnalyzer {
120120
void reduce_ternary_op(GDScriptParser::TernaryOpNode *p_ternary_op, bool p_is_root = false);
121121
void reduce_type_test(GDScriptParser::TypeTestNode *p_type_test);
122122
void reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op);
123+
void reduce_inc_dec_op(GDScriptParser::UnaryOpNode *p_unary_op);
123124

124125
Variant make_expression_reduced_value(GDScriptParser::ExpressionNode *p_expression, bool &is_reduced);
125126
Variant make_array_reduced_value(GDScriptParser::ArrayNode *p_array, bool &is_reduced);

modules/gdscript/gdscript_parser.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2880,6 +2880,24 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_unary_operator(ExpressionN
28802880
push_error(R"(Expected expression after "+" operator.)");
28812881
}
28822882
break;
2883+
case GDScriptTokenizer::Token::MINUS_MINUS:
2884+
// Prefix -- operator
2885+
operation->operation = UnaryOpNode::OP_DECREMENT;
2886+
operation->variant_op = Variant::OP_DECREMENT;
2887+
operation->operand = parse_precedence(PREC_SIGN, false);
2888+
if (operation->operand == nullptr) {
2889+
push_error(R"(Expected expression after prefix "--" operator.)");
2890+
}
2891+
break;
2892+
case GDScriptTokenizer::Token::PLUS_PLUS:
2893+
// Prefix ++ operator
2894+
operation->operation = UnaryOpNode::OP_INCREMENT;
2895+
operation->variant_op = Variant::OP_INCREMENT;
2896+
operation->operand = parse_precedence(PREC_SIGN, false);
2897+
if (operation->operand == nullptr) {
2898+
push_error(R"(Expected expression after prefix "++" operator.)");
2899+
}
2900+
break;
28832901
case GDScriptTokenizer::Token::TILDE:
28842902
operation->operation = UnaryOpNode::OP_COMPLEMENT;
28852903
operation->variant_op = Variant::OP_BIT_NEGATE;
@@ -3766,6 +3784,32 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_invalid_token(ExpressionNo
37663784
return p_previous_operand;
37673785
}
37683786

3787+
GDScriptParser::ExpressionNode *GDScriptParser::parse_increment_decrement(ExpressionNode *p_previous_operand, bool p_can_assign) {
3788+
GDScriptTokenizer::Token::Type op_type = previous.type;
3789+
UnaryOpNode *operation = alloc_node<UnaryOpNode>();
3790+
reset_extents(operation, p_previous_operand);
3791+
update_extents(operation);
3792+
3793+
operation->operand = p_previous_operand;
3794+
3795+
switch (op_type) {
3796+
case GDScriptTokenizer::Token::MINUS_MINUS:
3797+
operation->operation = UnaryOpNode::OP_POST_DECREMENT;
3798+
operation->variant_op = Variant::OP_POST_DECREMENT;
3799+
break;
3800+
case GDScriptTokenizer::Token::PLUS_PLUS:
3801+
operation->operation = UnaryOpNode::OP_POST_INCREMENT;
3802+
operation->variant_op = Variant::OP_POST_INCREMENT;
3803+
break;
3804+
default:
3805+
complete_extents(operation);
3806+
return nullptr; // Unreachable.
3807+
}
3808+
complete_extents(operation);
3809+
3810+
return operation;
3811+
}
3812+
37693813
GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) {
37703814
TypeNode *type = alloc_node<TypeNode>();
37713815
make_completion_context(p_allow_void ? COMPLETION_TYPE_NAME_OR_VOID : COMPLETION_TYPE_NAME, type);
@@ -4164,7 +4208,9 @@ GDScriptParser::ParseRule *GDScriptParser::get_rule(GDScriptTokenizer::Token::Ty
41644208
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_BIT_SHIFT }, // GREATER_GREATER,
41654209
// Math
41664210
{ &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION_SUBTRACTION }, // PLUS,
4211+
{ &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_increment_decrement, PREC_ADDITION_SUBTRACTION }, // PLUS_PLUS,
41674212
{ &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION_SUBTRACTION }, // MINUS,
4213+
{ &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_increment_decrement, PREC_ADDITION_SUBTRACTION }, // MINUS_MINUS,
41684214
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // STAR,
41694215
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_POWER }, // STAR_STAR,
41704216
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // SLASH,
@@ -6318,8 +6364,27 @@ void GDScriptParser::TreePrinter::print_unary_op(UnaryOpNode *p_unary_op) {
63186364
case UnaryOpNode::OP_COMPLEMENT:
63196365
push_text("~");
63206366
break;
6367+
case UnaryOpNode::OP_INCREMENT:
6368+
push_text("++");
6369+
break;
6370+
case UnaryOpNode::OP_DECREMENT:
6371+
push_text("--");
6372+
break;
6373+
default:
6374+
break;
63216375
}
63226376
print_expression(p_unary_op->operand);
6377+
6378+
switch (p_unary_op->operation) {
6379+
case UnaryOpNode::OP_POST_DECREMENT:
6380+
push_text("--");
6381+
break;
6382+
case UnaryOpNode::OP_POST_INCREMENT:
6383+
push_text("++");
6384+
break;
6385+
default:
6386+
break;
6387+
}
63236388
// Surround in parenthesis for disambiguation.
63246389
push_text(")");
63256390
}

modules/gdscript/gdscript_parser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,11 @@ class GDScriptParser {
12661266
struct UnaryOpNode : public ExpressionNode {
12671267
enum OpType {
12681268
OP_POSITIVE,
1269+
OP_INCREMENT,
1270+
OP_POST_INCREMENT,
12691271
OP_NEGATIVE,
1272+
OP_DECREMENT,
1273+
OP_POST_DECREMENT,
12701274
OP_COMPLEMENT,
12711275
OP_LOGIC_NOT,
12721276
};
@@ -1626,6 +1630,7 @@ class GDScriptParser {
16261630
ExpressionNode *parse_type_test(ExpressionNode *p_previous_operand, bool p_can_assign);
16271631
ExpressionNode *parse_yield(ExpressionNode *p_previous_operand, bool p_can_assign);
16281632
ExpressionNode *parse_invalid_token(ExpressionNode *p_previous_operand, bool p_can_assign);
1633+
ExpressionNode *parse_increment_decrement(ExpressionNode *p_previous_operand, bool p_can_assign);
16291634
TypeNode *parse_type(bool p_allow_void = false);
16301635

16311636
#ifdef TOOLS_ENABLED

modules/gdscript/gdscript_tokenizer.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ static const char *token_names[] = {
7272
">>", // GREATER_GREATER,
7373
// Math
7474
"+", // PLUS,
75+
"++", // PLUS_PLUS,
7576
"-", // MINUS,
77+
"--", // MINUS_MINUS,
7678
"*", // STAR,
7779
"**", // STAR_STAR,
7880
"/", // SLASH,
@@ -1568,6 +1570,9 @@ GDScriptTokenizer::Token GDScriptTokenizerText::scan() {
15681570
if (_peek() == '=') {
15691571
_advance();
15701572
return make_token(Token::PLUS_EQUAL);
1573+
} else if (_peek() == '+') {
1574+
_advance();
1575+
return make_token(Token::PLUS_PLUS);
15711576
} else if (is_digit(_peek()) && !last_token.can_precede_bin_op()) {
15721577
// Number starting with '+'.
15731578
return number();
@@ -1578,6 +1583,9 @@ GDScriptTokenizer::Token GDScriptTokenizerText::scan() {
15781583
if (_peek() == '=') {
15791584
_advance();
15801585
return make_token(Token::MINUS_EQUAL);
1586+
} else if (_peek() == '-') {
1587+
_advance();
1588+
return make_token(Token::MINUS_MINUS);
15811589
} else if (is_digit(_peek()) && !last_token.can_precede_bin_op()) {
15821590
// Number starting with '-'.
15831591
return number();

modules/gdscript/gdscript_tokenizer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ class GDScriptTokenizer {
8383
GREATER_GREATER,
8484
// Math
8585
PLUS,
86+
PLUS_PLUS,
8687
MINUS,
88+
MINUS_MINUS,
8789
STAR,
8890
STAR_STAR,
8991
SLASH,

modules/gdscript/tests/scripts/parser/errors/mistaken_decrement_operator.gd

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)