Skip to content

Commit f63a0a2

Browse files
committed
add a().b = 1 support
1 parent ce90472 commit f63a0a2

1 file changed

Lines changed: 100 additions & 90 deletions

File tree

UndertaleModLib/Compiler/Parser.cs

Lines changed: 100 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -757,11 +757,7 @@ private static Statement ParseFunction(CompileContext context)
757757
Statement isConstructor = new Statement();
758758
isConstructor.Text = "";
759759
if (IsNextTokenDiscard(TokenKind.KeywordConstructor)) {
760-
if (context.Data.IsVersionAtLeast(2, 3)) {
761-
isConstructor.Text = "constructor";
762-
} else {
763-
ReportCodeError("Cannot use constructors prior to GMS2.3.", result.Token, true);
764-
}
760+
isConstructor.Text = "constructor";
765761
}
766762
result.Children.Add(isConstructor);
767763

@@ -840,66 +836,70 @@ private static Statement ParseFor(CompileContext context)
840836
return result;
841837
}
842838

843-
private static Statement ParseAssign(CompileContext context)
844-
{
845-
Statement left = ParsePostAndRef(context);
846-
if (left != null)
839+
private static Statement ParseAssignInner(CompileContext context, Statement left) {
840+
if (left.Kind != Statement.StatementKind.Pre && left.Kind != Statement.StatementKind.Post)
847841
{
848-
if (left.Kind != Statement.StatementKind.Pre && left.Kind != Statement.StatementKind.Post)
849-
{
850-
// hack because I don't know what I'm doing
851-
string name;
852-
if (left.Children.Count == 0 || left.Kind == Statement.StatementKind.ExprSingleVariable)
853-
name = left.Text;
854-
else
855-
name = left.Children[left.Children.Count - 1]?.Text;
856-
if (name == null)
857-
return null;
858-
859-
VariableInfo vi;
860-
if ((context.BuiltInList.GlobalNotArray.TryGetValue(name, out vi) ||
861-
context.BuiltInList.GlobalArray.TryGetValue(name, out vi) ||
862-
context.BuiltInList.Instance.TryGetValue(name, out vi) ||
863-
context.BuiltInList.InstanceLimitedEvent.TryGetValue(name, out vi)
864-
) && !vi.CanSet)
865-
{
866-
ReportCodeError("Attempt to set a read-only variable.", left.Token, false);
867-
}
842+
// hack because I don't know what I'm doing
843+
string name;
844+
if (left.Children.Count == 0 || left.Kind == Statement.StatementKind.ExprSingleVariable)
845+
name = left.Text;
846+
else
847+
name = left.Children[left.Children.Count - 1]?.Text;
848+
if (name == null)
849+
return null;
868850

869-
if (remainingStageOne.Count == 0)
870-
{
871-
ReportCodeError("Malformed assignment statement.", true);
872-
return null;
873-
}
874-
Statement assign = new Statement(Statement.StatementKind.Assign, remainingStageOne.Dequeue().Token);
875-
assign.Children.Add(left);
876-
877-
if (assign.Token.Kind.In(
878-
TokenKind.Assign,
879-
TokenKind.AssignAnd,
880-
TokenKind.AssignDivide,
881-
TokenKind.AssignMinus,
882-
TokenKind.AssignMod,
883-
TokenKind.AssignOr,
884-
TokenKind.AssignPlus,
885-
TokenKind.AssignTimes,
886-
TokenKind.AssignXor
887-
))
888-
{
889-
assign.Children.Add(new Statement(Statement.StatementKind.Token, assign.Token));
890-
assign.Children.Add(ParseExpression(context));
891-
}
892-
else
893-
{
894-
ReportCodeError("Expected assignment operator.", assign.Token, true);
895-
}
851+
VariableInfo vi;
852+
if ((context.BuiltInList.GlobalNotArray.TryGetValue(name, out vi) ||
853+
context.BuiltInList.GlobalArray.TryGetValue(name, out vi) ||
854+
context.BuiltInList.Instance.TryGetValue(name, out vi) ||
855+
context.BuiltInList.InstanceLimitedEvent.TryGetValue(name, out vi)
856+
) && !vi.CanSet)
857+
{
858+
ReportCodeError("Attempt to set a read-only variable.", left.Token, false);
859+
}
896860

897-
return assign;
861+
if (remainingStageOne.Count == 0)
862+
{
863+
ReportCodeError("Malformed assignment statement.", true);
864+
return null;
865+
}
866+
Statement assign = new Statement(Statement.StatementKind.Assign, remainingStageOne.Dequeue().Token);
867+
assign.Children.Add(left);
868+
869+
if (assign.Token.Kind.In(
870+
TokenKind.Assign,
871+
TokenKind.AssignAnd,
872+
TokenKind.AssignDivide,
873+
TokenKind.AssignMinus,
874+
TokenKind.AssignMod,
875+
TokenKind.AssignOr,
876+
TokenKind.AssignPlus,
877+
TokenKind.AssignTimes,
878+
TokenKind.AssignXor
879+
))
880+
{
881+
assign.Children.Add(new Statement(Statement.StatementKind.Token, assign.Token));
882+
assign.Children.Add(ParseExpression(context));
898883
}
899884
else
900885
{
901-
return left;
886+
ReportCodeError("Expected assignment operator.", assign.Token, true);
902887
}
888+
889+
return assign;
890+
}
891+
else
892+
{
893+
return left;
894+
}
895+
}
896+
897+
private static Statement ParseAssign(CompileContext context)
898+
{
899+
Statement left = ParsePostAndRef(context);
900+
if (left != null)
901+
{
902+
return ParseAssignInner(context, left);
903903
}
904904
else
905905
{
@@ -1152,6 +1152,12 @@ private static Statement ParseFunctionCall(CompileContext context, bool expressi
11521152
ReportCodeError(string.Format("Function {0} expects {1} arguments, got {2}.",
11531153
s.Text, fi.ArgumentCount, (result.Children.Count - 1))
11541154
, s.Token, false);
1155+
1156+
if (!expression && IsNextToken(TokenKind.Dot)) {
1157+
// Actually an assignment
1158+
result.Kind = Statement.StatementKind.ExprFunctionCall;
1159+
return ParseAssignInner(context, ParsePostAndRefInner(context, result));
1160+
}
11551161

11561162
return result;
11571163
}
@@ -1434,43 +1440,47 @@ private static Statement ParseMulDiv(CompileContext context)
14341440
}
14351441
}
14361442

1443+
private static Statement ParsePostAndRefInner(CompileContext context, Statement left) {
1444+
// Parse chain variable reference
1445+
Statement result = new Statement(Statement.StatementKind.ExprVariableRef, remainingStageOne.Peek().Token);
1446+
bool combine = false;
1447+
if (left.Kind != Statement.StatementKind.ExprConstant || left.Constant.kind == ExpressionConstant.Kind.Reference /* TODO: will this ever change? */)
1448+
result.Children.Add(left);
1449+
else
1450+
combine = true;
1451+
while (remainingStageOne.Count > 0 && IsNextTokenDiscard(TokenKind.Dot))
1452+
{
1453+
Statement next = ParseSingleVar(context);
1454+
if (combine)
1455+
{
1456+
if (left.Constant.kind != ExpressionConstant.Kind.Number)
1457+
ReportCodeError("Expected constant to be number in variable reference.", left.Token, false);
1458+
if (next != null)
1459+
next.ID = (int)left.Constant.valueNumber;
1460+
combine = false;
1461+
}
1462+
result.Children.Add(next);
1463+
}
1464+
1465+
// Post increment/decrement check
1466+
if (remainingStageOne.Count > 0 && IsNextToken(TokenKind.Increment, TokenKind.Decrement))
1467+
{
1468+
Statement newResult = new Statement(Statement.StatementKind.Post, remainingStageOne.Dequeue().Token);
1469+
newResult.Children.Add(result);
1470+
return newResult;
1471+
}
1472+
else
1473+
{
1474+
return result;
1475+
}
1476+
}
1477+
14371478
private static Statement ParsePostAndRef(CompileContext context)
14381479
{
14391480
Statement left = ParseLowLevel(context);
14401481
if (!hasError && IsNextToken(TokenKind.Dot))
14411482
{
1442-
// Parse chain variable reference
1443-
Statement result = new Statement(Statement.StatementKind.ExprVariableRef, remainingStageOne.Peek().Token);
1444-
bool combine = false;
1445-
if (left.Kind != Statement.StatementKind.ExprConstant || left.Constant.kind == ExpressionConstant.Kind.Reference /* TODO: will this ever change? */)
1446-
result.Children.Add(left);
1447-
else
1448-
combine = true;
1449-
while (remainingStageOne.Count > 0 && IsNextTokenDiscard(TokenKind.Dot))
1450-
{
1451-
Statement next = ParseSingleVar(context);
1452-
if (combine)
1453-
{
1454-
if (left.Constant.kind != ExpressionConstant.Kind.Number)
1455-
ReportCodeError("Expected constant to be number in variable reference.", left.Token, false);
1456-
if (next != null)
1457-
next.ID = (int)left.Constant.valueNumber;
1458-
combine = false;
1459-
}
1460-
result.Children.Add(next);
1461-
}
1462-
1463-
// Post increment/decrement check
1464-
if (remainingStageOne.Count > 0 && IsNextToken(TokenKind.Increment, TokenKind.Decrement))
1465-
{
1466-
Statement newResult = new Statement(Statement.StatementKind.Post, remainingStageOne.Dequeue().Token);
1467-
newResult.Children.Add(result);
1468-
return newResult;
1469-
}
1470-
else
1471-
{
1472-
return result;
1473-
}
1483+
return ParsePostAndRefInner(context, left);
14741484
}
14751485
else
14761486
{

0 commit comments

Comments
 (0)