@@ -80,6 +80,7 @@ namespace CodeGen.Engine
80
80
private canonicalNameLookup, @Dictionary<string, string>, new Dictionary<string, string>()
81
81
82
82
private allowsExpressions, @HashSet<string>, new HashSet<string>()
83
+ private expressionGlue, @HashSet<string>, new HashSet<string>()
83
84
84
85
private customValidity, @List<TokenValidity>
85
86
private userTokenValidity, @List<TokenValidity>
@@ -1064,6 +1065,18 @@ namespace CodeGen.Engine
1064
1065
expressions.Add("VOID_SUBROUTINE", TokenValidity.MethodLoop)
1065
1066
expressions.Add("WEB", TokenValidity.FieldLoop | TokenValidity.KeySegmentLoop | TokenValidity.RelationSegmentLoop)
1066
1067
1068
+ expressions.Add("AND", TokenValidity.Anywhere)
1069
+ expressions.Add("OR", TokenValidity.Anywhere)
1070
+ expressions.Add("NOT", TokenValidity.Anywhere)
1071
+ expressions.Add("(", TokenValidity.Anywhere)
1072
+ expressions.Add(")", TokenValidity.Anywhere)
1073
+
1074
+ expressionGlue.Add("AND")
1075
+ expressionGlue.Add("OR")
1076
+ expressionGlue.Add("NOT")
1077
+ expressionGlue.Add("(")
1078
+ expressionGlue.Add(")")
1079
+
1067
1080
if (context != ^null)
1068
1081
begin
1069
1082
data define, string
@@ -1433,7 +1446,7 @@ namespace CodeGen.Engine
1433
1446
1434
1447
while (ix < templateCode.Length) do
1435
1448
begin
1436
- data nextToken, @PossibleToken, nextPossibleToken(ix, templateCode)
1449
+ data nextToken, @PossibleToken, nextPossibleToken(ix, templateCode, tokens.LastOrDefault() )
1437
1450
1438
1451
if (nextToken == ^null) then
1439
1452
begin
@@ -1450,8 +1463,8 @@ namespace CodeGen.Engine
1450
1463
;; Is the token a closer?
1451
1464
data closer = nextTokenValue.StartsWith("/")
1452
1465
1453
- ;; The next token isn't here, so we have just text. Add a Text token.
1454
- if (nextToken.StartsAtPosition != ix)
1466
+ ;; The next token isn't here, so we have just text. Add a Text token.
1467
+ if (nextToken.StartsAtPosition != ix && nextToken.StartsAtPosition > ix )
1455
1468
tokens.Add(new Token(fileName, ix, nextToken.StartsAtPosition - 1, false, templateCode.Substring(ix, nextToken.StartsAtPosition - ix), TokenType.Text, TokenModifier.None, ^null, lineStarts, false, false))
1456
1469
1457
1470
if (nextToken.IsComment) then
@@ -1576,16 +1589,31 @@ namespace CodeGen.Engine
1576
1589
ix = nextToken.EndsAtPosition + 1
1577
1590
1578
1591
if (nextToken.IsExpression)
1579
- begin
1580
- data nextExpression, @Tuple<int, int, List<TokenValidity>>, nextExpressionToken(ix, templateCode)
1581
- if (nextExpression != ^null)
1592
+ begin
1593
+ data expressionError = ""
1594
+ data nextExpression, @Tuple<int, int, List<TokenValidity>>, nextExpressionToken(ix, templateCode, expressionError)
1595
+ if(!string.IsNullOrWhiteSpace(expressionError) && !nextToken.IsCloser)
1596
+ reportError(expressionError)
1597
+ while (nextExpression != ^null)
1582
1598
begin
1583
1599
data expressionValue, string, templateCode.Substring(nextExpression.Item1, nextExpression.Item2 - nextExpression.Item1)
1584
1600
;; TODO: Does this expression require repository structure processing?
1585
- data requiresRps, boolean, false
1601
+ data requiresRps, boolean, false
1586
1602
tokens.Add(new Token(fileName, nextExpression.Item1, nextExpression.Item2, false, expressionValue, TokenType.Expression, TokenModifier.None, nextExpression.Item3, lineStarts, requiresRps, false))
1587
- ix = nextExpression.Item2 + 1
1588
- end
1603
+ if(expressionValue == '(' || expressionValue == ')' || templateCode[nextExpression.Item2] == ')') then
1604
+ ix = nextExpression.Item2
1605
+ else
1606
+ begin
1607
+ ix = nextExpression.Item2 + 1
1608
+ if(templateCode[nextExpression.Item2] == '>')
1609
+ exitloop
1610
+ end
1611
+
1612
+ nextExpression = nextExpressionToken(ix, templateCode, expressionError)
1613
+ end
1614
+
1615
+ if(ix < templateCode.Length && templateCode[ix] == '>')
1616
+ incr ix
1589
1617
end
1590
1618
1591
1619
end
@@ -1663,21 +1691,22 @@ namespace CodeGen.Engine
1663
1691
;;; <returns>PossibleToken instance, or null if no possible tokens found.</returns>
1664
1692
private method nextPossibleToken, @PossibleToken
1665
1693
searchFrom, int
1666
- templateCode, string
1667
- proc
1668
- data foundPossibleToken = false
1694
+ templateCode, string
1695
+ lastToken, @Token
1696
+ proc
1697
+ data inTagTail = searchFrom > 0 && templateCode[searchFrom - 1] == '>'
1698
+ data foundPossibleToken = !inTagTail && lastToken != ^null ? lastToken.TypeOfToken == TokenType.Expression : false
1669
1699
data isCloser = false
1670
1700
data isComment = false
1671
- data isExpression = false
1672
- data possibleTokenStartsAt, int, -1
1701
+ data isExpression = foundPossibleToken
1702
+ data possibleTokenStartsAt, int, foundPossibleToken ? searchFrom - 1 : -1
1673
1703
1674
1704
;; Character by character looking for a token
1675
1705
data ix, int
1676
1706
for ix from searchFrom thru templateCode.Length - 1
1677
1707
begin
1678
1708
;; Did we find a newline?
1679
1709
data foundNewLine, boolean, (((templateCode[ix] == %char(13)) && (templateCode.Length > ix + 1) && (templateCode[ix + 1] == %char(10))) || (templateCode[ix] == %char(10)))
1680
-
1681
1710
;; Did we find the start of a template file comment (;//)?
1682
1711
if (templateCode.Length > ix + 2 && templateCode[ix] == ';' && templateCode[ix + 1] == '/' && templateCode[ix + 2] == '/') then
1683
1712
begin
@@ -1713,7 +1742,7 @@ namespace CodeGen.Engine
1713
1742
isCloser = false
1714
1743
foundPossibleToken = true
1715
1744
possibleTokenStartsAt = ix
1716
- end
1745
+ end
1717
1746
end
1718
1747
else
1719
1748
begin
@@ -1736,8 +1765,9 @@ namespace CodeGen.Engine
1736
1765
begin
1737
1766
;; So we found a > or a space after an <
1738
1767
1739
- ;; Get the start and end indexes of the VALUE of the possible token (withoit the < > or " ")
1740
- data realStartIndex, int, (possibleTokenStartsAt + 1)
1768
+ ;; Get the start and end indexes of the VALUE of the possible token (withoit the < > or " ")
1769
+ data skipStartLetter = templateCode[possibleTokenStartsAt] == '<' || templateCode[possibleTokenStartsAt] == ' '
1770
+ data realStartIndex, int, skipStartLetter ? possibleTokenStartsAt + 1 : possibleTokenStartsAt
1741
1771
data realEndIndex, int, ix - 1
1742
1772
if (isCloser)
1743
1773
realStartIndex += 1
@@ -1854,7 +1884,8 @@ namespace CodeGen.Engine
1854
1884
;;; <returns></returns>
1855
1885
private method nextExpressionToken, @Tuple<int, int, List<TokenValidity>>
1856
1886
startIndex, int
1857
- templateCode, string
1887
+ templateCode, string
1888
+ out errorText, string
1858
1889
proc
1859
1890
data startedToken, boolean, false
1860
1891
data startedTokenIndex, int, -1
@@ -1864,19 +1895,21 @@ namespace CodeGen.Engine
1864
1895
begin
1865
1896
if (!startedToken) then
1866
1897
begin
1867
- if (char.IsLetter(templateCode[ix]))
1898
+ if (char.IsLetter(templateCode[ix])) then
1868
1899
begin
1869
1900
startedToken = true
1870
1901
startedTokenIndex = ix
1871
- end
1902
+ end
1903
+ else if(templateCode[ix] == '(' || templateCode[ix] == ')')
1904
+ mreturn Tuple.Create(ix, ix + 1, userTokenValidity)
1872
1905
end
1873
1906
else
1874
- begin
1907
+ begin
1875
1908
if (char.IsLetterOrDigit(templateCode[ix]) || (templateCode[ix] == '_')) then
1876
1909
begin
1877
1910
nextloop
1878
1911
end
1879
- else if ((templateCode[ix] == ' ') || (templateCode[ix] == '>')) then
1912
+ else if ((templateCode[ix] == ' ') || (templateCode[ix] == '>') || (templateCode[ix] == ')') ) then
1880
1913
begin
1881
1914
data expressionType, @List<TokenValidity>
1882
1915
data expstring, string, templateCode.Substring(startedTokenIndex, ix - startedTokenIndex)
@@ -1909,12 +1942,16 @@ namespace CodeGen.Engine
1909
1942
& || expstring.StartsWith("TOTAL_ITEMS_")) then
1910
1943
begin
1911
1944
mreturn Tuple.Create(startedTokenIndex, ix, loopUtilityTokenValidity)
1912
- end
1945
+ end
1946
+ else if(expressionGlue.Contains(expstring)) then
1947
+ begin
1948
+ mreturn Tuple.Create(startedTokenIndex, ix, userTokenValidity)
1949
+ end
1913
1950
else
1914
1951
begin
1915
- ;; Invalid expression
1916
- reportError( String.Format("Invalid expression <IF {0}> at offset {1}!", expstring, startedTokenIndex - 4, "") )
1917
- exitloop
1952
+ ;; Invalid expression
1953
+ errorText = String.Format("Invalid expression <IF {0}> at offset {1}!", expstring, startedTokenIndex - 4, "")
1954
+ mreturn ^null
1918
1955
end
1919
1956
end
1920
1957
else if (char.IsControl(templateCode[ix])) then
0 commit comments