Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 890
Gabriel Avatar asked Jun 07 '16 23:06

Gabriel


1 Answers

Use the 'and' keyword

let rec runx () = 
    printf "runx"
    runy ()
and runy () =
    printf "runy"
    runx ()

runx () |> ignore 

prints

runxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxruny
like image 97
Phillip Scott Givens Avatar answered Nov 09 '22 12:11

Phillip Scott Givens