@@ -55,13 +55,22 @@ func parse(tokens: [Token]) throws -> Program {
55
55
try StringLiteral ( value: expect ( type: . text, error: " Expected text token " ) . value)
56
56
}
57
57
58
- func parseCallExpression( callee: Expression ) throws -> CallExpression {
58
+ func parseCallExpression( callee: Expression ) throws -> Expression {
59
59
let args = try parseArgs ( )
60
- var callExpression = CallExpression ( callee: callee, args: args)
60
+ var expression : Expression = CallExpression ( callee: callee, args: args)
61
+ // Handle potential array indexing after method call
62
+ if typeof ( . openSquareBracket) {
63
+ expression = MemberExpression (
64
+ object: expression,
65
+ property: try parseMemberExpressionArgumentsList ( ) ,
66
+ computed: true
67
+ )
68
+ }
69
+ // Handle potential chained method calls
61
70
if typeof ( . openParen) {
62
- callExpression = try parseCallExpression ( callee: callExpression )
71
+ expression = try parseCallExpression ( callee: expression )
63
72
}
64
- return callExpression
73
+ return expression
65
74
}
66
75
67
76
func parseMemberExpressionArgumentsList( ) throws -> Expression {
@@ -73,7 +82,19 @@ func parse(tokens: [Token]) throws -> Program {
73
82
current += 1 // consume colon
74
83
isSlice = true
75
84
} else {
76
- slices. append ( try parseExpression ( ) )
85
+ // Handle negative numbers as indices
86
+ if typeof ( . additiveBinaryOperator) && tokens [ current] . value == " - " {
87
+ current += 1 // consume the minus sign
88
+ if typeof ( . numericLiteral) {
89
+ let num = tokens [ current] . value
90
+ current += 1
91
+ slices. append ( NumericLiteral ( value: - Int( num) !) )
92
+ } else {
93
+ throw JinjaError . syntax ( " Expected number after minus sign in array index " )
94
+ }
95
+ } else {
96
+ slices. append ( try parseExpression ( ) )
97
+ }
77
98
if typeof ( . colon) {
78
99
current += 1 // consume colon
79
100
isSlice = true
@@ -111,6 +132,23 @@ func parse(tokens: [Token]) throws -> Program {
111
132
if !( property is Identifier ) {
112
133
throw JinjaError . syntax ( " Expected identifier following dot operator " )
113
134
}
135
+ // Handle method calls
136
+ if typeof ( . openParen) {
137
+ let methodCall = CallExpression (
138
+ callee: MemberExpression ( object: object, property: property, computed: false ) ,
139
+ args: try parseArgs ( )
140
+ )
141
+ // Handle array indexing after method call
142
+ if typeof ( . openSquareBracket) {
143
+ current += 1 // consume [
144
+ let index = try parseExpression ( )
145
+ try expect ( type: . closeSquareBracket, error: " Expected closing square bracket " )
146
+ object = MemberExpression ( object: methodCall, property: index, computed: true )
147
+ continue
148
+ }
149
+ object = methodCall
150
+ continue
151
+ }
114
152
}
115
153
object = MemberExpression (
116
154
object: object,
@@ -364,12 +402,14 @@ func parse(tokens: [Token]) throws -> Program {
364
402
func parseSetStatement( ) throws -> Statement {
365
403
let left = try parseExpression ( )
366
404
if typeof ( . equals) {
367
- current += 1
405
+ current += 1 // consume equals
368
406
// Parse the right-hand side as an expression
369
407
let value = try parseExpression ( )
370
- // Explicitly cast 'value' to 'Expression'
408
+ try expect ( type : . closeStatement , error : " Expected closing statement token " )
371
409
return Set ( assignee: left, value: value)
372
410
}
411
+ // If there's no equals sign, treat it as an expression statement
412
+ try expect ( type: . closeStatement, error: " Expected closing statement token " )
373
413
return left
374
414
}
375
415
@@ -552,11 +592,11 @@ func parse(tokens: [Token]) throws -> Program {
552
592
// Consume {% %} tokens
553
593
try expect ( type: . openStatement, error: " Expected opening statement token " )
554
594
var result : Statement
595
+
555
596
switch tokens [ current] . type {
556
597
case . set:
557
598
current += 1 // consume 'set' token
558
599
result = try parseSetStatement ( )
559
- try expect ( type: . closeStatement, error: " Expected closing statement token " )
560
600
case . if:
561
601
current += 1 // consume 'if' token
562
602
result = try parseIfStatement ( )
@@ -576,8 +616,11 @@ func parse(tokens: [Token]) throws -> Program {
576
616
try expect ( type: . endFor, error: " Expected endfor token " )
577
617
try expect ( type: . closeStatement, error: " Expected %} token " )
578
618
default :
579
- throw JinjaError . syntax ( " Unknown statement type: \( tokens [ current] . type) " )
619
+ // Handle expressions within statements
620
+ result = try parseExpression ( )
621
+ try expect ( type: . closeStatement, error: " Expected closing statement token " )
580
622
}
623
+
581
624
return result
582
625
}
583
626
0 commit comments