And I very much wonder what an expression has to do where a type non-terminal was expected.
if you really do it "very much" - there are soruces.
I do not, though. Not THAT much.
Guess that is rooted somehow in the need to transit "initialized variables" to AST
The token then get some attibutes, like type, value, sizeof/address, mutability (const/var)
Then later some sanity check is applied to make sure different flags and attributes are consistent, like typed const should have non-zero sezeof and address, and untyped one should lack them.
Type expressions and value expressions are intertwined anyway (because of
array <set expression> of type) just tend to use different operators (^ in types, * in values).
Also, why you evaluate value-expressions it might include type-casts, especially implicit ones (that very
1 / 2 == 0 in C but
= 0.5 in Pascal )
So, perhaps, unified parser emitting both evaluation tree and adjusted data type was a reasonable implementation.
Having both
type ident = type-expr and
var ident : type-expr FPC had to run that dual-evaluator after both colon and quality.
As initialized vars were introduced - the parser had to be permitted to create both type and value in var context.
And that is how it ended.
Just speculating.
Also, i remember colon is also used in some more places of the language: goto labelsand variant records. I wonder if the latter have some pinnatas too :-)