@@ -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