Program Run Loop

I tried to implement a RUN LOOP for my PILOT project and realized that the method I chose was too fragile…

The code exists in an Array [lineNum, Code] from 0 to n lines

func execute_program(next:Int = -1) {
    var lineTokens = [String]()
    if next<0 { lastErrorCODE=0 ; codePOINTER=0} // init for 1st line
    //   codePOINTER=next+1 // commented out to simulate a continous loop
    if codePOINTER<pgmCODE.count && lastErrorCODE == 0 {
        let ln  = String(format:"%5d",pgmCODE[codePOINTER].lineNum)
        let str = pgmCODE[codePOINTER].code
        print("->\(ln) \(str)")            // trace
        tokenize(str,&lineTokens)          // parse the line into TOKENS
        execute_subline(lineTokens,true)   // execute the line of TOKENS
        execute_program(next: codePOINTER) //
    }
    showREADY()
}

problem is… STACK OVERFLOW

I started with a recursive method as I need to pause execution, so I figured I could add a semaphore in this routine to sometimes NOT recurse, and have an external delegate call it later with the correct “next” value… but that is a secondary problem. to the Overflow

havent dived too deep into the syntax etc for pilot but does it support loops, goto, subroutines etc ?

yes it does…

10 *LABEL
20 U:*FRED // "gosub fred"
30 J:*LABEL // "goto label"
40 *FRED
50 E: // return

Ok… I got it… still needs a bit more work to monitor state etc.

func execute_program(next:Int = -1) {
    var lineTokens = [String]()
    codePOINTER = next
    if next<0 { lastErrorCODE=0; codePOINTER = 0 } // init for 1st line
    
    while codePOINTER>=0 && codePOINTER<pgmCODE.count && lastErrorCODE==0 {
        let ln  = String(format:"%5d",pgmCODE[codePOINTER].lineNum)
        let str = pgmCODE[codePOINTER].code
        print("->\(ln) \(str) \(isPAUSED)")            // trace
        tokenize(str,&lineTokens)          // parse the line into TOKENS
        execute_subline(lineTokens,true)   // execute the line of TOKENS
        if isPAUSED { return }
        codePOINTER+=1
    }
    showREADY()
    print("DONE")
}

func pauseExecution(state:Bool) {
    if isPAUSED == state { return } // state didn't change
    isPAUSED = state
    print("New State=\(state)")
    if state==false { execute_program(next: codePOINTER+1) }
}
``

When a command line needs to pause execution, it calls PauseExecution(true)
In the keyboard Delegate, I call PauseExecution(false) when the [RETURN] key is pressed