Search code examples
compiler-constructionf#functional-programming

Circular function calls when evaluating AST nodes for interpreter


I have the following situation:

let private runStatement (vars : Map<identifier, value>) stmt =
    match stmt with
    | Assignment (id, expr) -> runAssignment vars id expr
    | Print exprs -> runPrint vars exprs
    | Read id -> runRead vars id
    | If (cond, stmts) -> runIf vars cond stmts

let rec private runStatements vars stmts =
    match stmts with
    | stmt::rest ->
        let newVars = runStatement vars stmt
        runStatements newVars rest
    | [] -> vars

let private runIf vars conditionalValue statements =
    match conditionalValue with
    | Boolean v when v -> runStatements vars statements
    | Boolean v -> vars
    | _ -> failwith "Not a boolean expression in if statement"

As you can see, function runStatement calls runIf, and runIf calls runStatement, because an if-statement is formed by some general statements, and a general statement can be an if-statement.

How can I solve this situation?

PS.: I have similar situations with other functions like runWhile, runIfElse et cetera.


Solution

  • Use the 'and' keyword

    let rec runx () = 
        printf "runx"
        runy ()
    and runy () =
        printf "runy"
        runx ()
    
    runx () |> ignore 
    

    prints

    runxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxruny