Just got a solution. It took me some hours on a few days (3 days ?). I don’t know if it is the intended solution but it works. I knew JonAult was right stating:
The real problem was to find a way to do that. I said to myself that instead of returning only an array of Token (that is [Token]), one must return a connected pair of information: that is a token with an associated String.Index. I decided to try having func lex() to return an array of tupples [(Token, String.Index)] like:
func lex() throws -> [(token: Token, stringIndex: String.Index)] {
var tokensWithPositions = [(token: Token, stringIndex: String.Index)]()
while let nextCharacter = peek() {
switch nextCharacter {
case "0" ... "9":
let value = getNumber()
tokensWithPositions.append((.number(value), input.index(before: position)))
...
so Parser.Error.invalidToken could throw a tokenWithPosition tupple.
After these changes, I had to work on eliminating errors found by Xcode. There were a lot of them. In Parser for instance, cases in switch statements had to use tupples like :
case (.plus, tokenWithPosition.stringIndex):
let nextNumber = try getNumber()
value += nextNumber
and I had to add a default case throwing an invalidToken error.
Then, it worked. I still had to make some adjustments (count of character was different wether the faulty character was a number or a sign (+ or -) and printing the Lexer output had plenty of Swift.String.Index [an easy fix using map to print only the tokens as was previously done]) but everything looks OK now.
That was hard to do, I must admit, but no new concept was involved. It is just that a seemingly simple modification had plenty of implications. But, as what had been said elsewhere in the book, one just has to follow indications from the debugger.
Keep going if you want, you could be rewarded. Success is fun.