@@ -2563,35 +2563,36 @@ func (p *Parser) evaluateTypeDefinition(ctx context) (Expression, error) {
25632563 }, nil
25642564}
25652565
2566- func (p * Parser ) evaluateStructEvaluation (importAlias string , ctx context ) (Expression , error ) {
2566+ func (p * Parser ) evaluateStructFields (importAlias string , stopOnLastStruct bool , ctx context ) (Expression , StructField , error ) {
25672567 identifierToken := p .peek () // Eat identifier token.
25682568
25692569 if identifierToken .Type () != lexer .IDENTIFIER {
2570- return nil , p .expectedIdentifierError (identifierToken )
2570+ return nil , StructField {}, p .expectedIdentifierError (identifierToken )
25712571 }
25722572 value , err := p .evaluateNamedValueEvaluation (ctx )
25732573
25742574 if err != nil {
2575- return nil , err
2575+ return nil , StructField {}, err
25762576 }
2577- var expr Expression
2577+ expr := value
2578+ var structField StructField
25782579
25792580 for {
25802581 dotToken := p .eat ()
25812582
25822583 if dotToken .Type () != lexer .DOT {
2583- return nil , p .expectedError (`"."` , dotToken )
2584+ return nil , StructField {}, p .expectedError (`"."` , dotToken )
25842585 }
25852586 fieldToken := p .eat ()
25862587
25872588 if fieldToken .Type () != lexer .IDENTIFIER {
2588- return nil , p .expectedError ("field name" , fieldToken )
2589+ return nil , StructField {}, p .expectedError ("field name" , fieldToken )
25892590 }
25902591 typeDeclaration := value .ValueType ().Type ()
25912592 typeDeclarationKind := typeDeclaration .Kind ()
25922593
25932594 if typeDeclarationKind != TypeKindStruct {
2594- return nil , p .expectedError (fmt .Sprintf ("%s but got %s" , TypeKindStruct , typeDeclarationKind ), identifierToken )
2595+ return nil , StructField {}, p .expectedError (fmt .Sprintf ("%s but got %s" , TypeKindStruct , typeDeclarationKind ), identifierToken )
25952596 }
25962597 structDefinition := typeDeclaration .(StructDefinition )
25972598
@@ -2600,20 +2601,32 @@ func (p *Parser) evaluateStructEvaluation(importAlias string, ctx context) (Expr
26002601 foundField , err := structDefinition .FindField (fieldName )
26012602
26022603 if err != nil {
2603- return nil , p .atError (err .Error (), fieldToken )
2604+ return nil , StructField {}, p .atError (err .Error (), fieldToken )
26042605 }
2605- expr = StructEvaluation {
2606+ structField = foundField
2607+ exprTemp := StructEvaluation {
26062608 value : value ,
26072609 field : foundField ,
26082610 }
2609-
2611+ exprTempKind := exprTemp .ValueType ().Type ().Kind ()
2612+
2613+ if exprTempKind != TypeKindStruct && stopOnLastStruct {
2614+ break
2615+ }
2616+ expr = exprTemp
2617+
26102618 // Allow chaining.
2611- if p .peek ().Type () != lexer .DOT || expr . ValueType (). Type (). Kind () != TypeKindStruct {
2619+ if p .peek ().Type () != lexer .DOT || exprTempKind != TypeKindStruct {
26122620 break
26132621 }
26142622 value = expr
26152623 }
2616- return expr , nil
2624+ return expr , structField , nil
2625+ }
2626+
2627+ func (p * Parser ) evaluateStructEvaluation (importAlias string , ctx context ) (Expression , error ) {
2628+ expr , _ , err := p .evaluateStructFields (importAlias , false , ctx )
2629+ return expr , err
26172630}
26182631
26192632func (p * Parser ) evaluateNamedValueEvaluation (ctx context ) (Expression , error ) {
@@ -3554,65 +3567,33 @@ func (p *Parser) evaluateSliceAssignment(ctx context) (Statement, error) {
35543567}
35553568
35563569func (p * Parser ) evaluateStructAssignment (ctx context ) (Statement , error ) {
3557- nameToken := p .eat ()
3558-
3559- if nameToken .Type () != lexer .IDENTIFIER {
3560- return nil , p .expectedError ("struct variable" , nameToken )
3561- }
3562- name := nameToken .Value ()
3563- namedValue , exists := ctx .findNamedValue (name , p .prefix , ctx .global ())
3564-
3565- if ! exists {
3566- return nil , p .variableNotDefinedError (name , nameToken )
3567- } else if namedValue .IsConstant () {
3568- return nil , p .constantError (name , nameToken )
3569- }
3570- namedValueValueType := namedValue .ValueType ()
3571- namedValueBaseType := namedValueValueType .Type ()
3572-
3573- if namedValueValueType .IsSlice () {
3574- return nil , p .expectedError ("struct but got slice" , nameToken )
3575- } else if namedValueBaseType .Kind () != TypeKindStruct {
3576- return nil , p .expectedError (fmt .Sprintf ("struct but variable is of type %s" , namedValueBaseType .Kind ()), nameToken )
3577- }
3578- structDefinition := namedValueBaseType .(StructDefinition )
3579- nextToken := p .eat ()
3580-
3581- if nextToken .Type () != lexer .DOT {
3582- return nil , p .expectedError (`"."` , nextToken )
3583- }
3584- nextToken = p .eat ()
3585-
3586- if nextToken .Type () != lexer .IDENTIFIER {
3587- return nil , p .expectedError (`struct field` , nextToken )
3588- }
3589- structField , err := structDefinition .FindField (nextToken .Value ())
3570+ expr , field , err := p .evaluateStructFields ("" , true , ctx ) // TODO: Find out if importAlias must be passed correctly.
35903571
35913572 if err != nil {
3592- return nil , p . atError ( err . Error (), nextToken )
3573+ return nil , err
35933574 }
3594- nextToken = p .eat ()
3575+ nextToken : = p .eat ()
35953576
35963577 if nextToken .Type () != lexer .ASSIGN_OPERATOR {
3597- return nil , p .expectedError (`"="` , nameToken )
3578+ return nil , p .expectedError (`"="` , nextToken )
35983579 }
3599- valueToken := p .peek ()
3600- value , err := p .evaluateExpression (ctx )
3580+ assignedValueToken := p .peek ()
3581+ assignedValue , err := p .evaluateExpression (ctx )
36013582
36023583 if err != nil {
36033584 return nil , err
36043585 }
3605- variableValueType := structField .ValueType ()
3606- assignedValueType := value .ValueType ()
3586+ fieldValueType := field .ValueType ()
3587+ assignedValueType := assignedValue .ValueType ()
36073588
3608- if ! variableValueType .Equals (assignedValueType ) {
3609- return nil , p .expectedError (fmt .Sprintf ("%s value but got %s" , variableValueType .String (), assignedValueType .String ()), valueToken )
3589+ if ! fieldValueType .Equals (assignedValueType ) {
3590+ return nil , p .expectedError (fmt .Sprintf ("%s value but got %s" , fieldValueType .String (), assignedValueType .String ()), assignedValueToken )
36103591 }
36113592 return StructAssignment {
3612- Variable : namedValue .( Variable ) ,
3613- value : StructValue {
3614- StructField : structField ,
3615- value : value ,
3593+ value : expr ,
3594+ assignment : StructValue {
3595+ StructField : field ,
3596+ value : assignedValue ,
36163597 },
36173598 }, nil
36183599}
0 commit comments