2016-06-07 5 views
5

Ich habe folgende Situation:Kreis Funktion aufruft, wenn AST-Knoten für Dolmetscher Auswertung

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" 

Wie Sie sehen können, Funktion runStatementrunIf Anrufe und runIf Anrufe runStatement, weil eine if-Anweisung durch eine allgemeine gebildet wird Anweisungen, und eine allgemeine Anweisung kann eine if-Anweisung sein.

Wie kann ich diese Situation lösen?

PS .: Ich habe ähnliche Situationen mit anderen Funktionen wie runWhile, runIfElse und so weiter.

+2

Bitte legen Sie immer den gesamten Code (Typen, Funktionen 'open' Anweisungen) benötigt das Beispiel kompilieren zu machen. Dadurch können sich andere auf die Bereitstellung einer Lösung konzentrieren, ohne den Code erst reparieren zu müssen. – TeaDrivenDev

+2

Übergeben Sie die Funktionen als Argumente, anstatt sie zu verknüpfen. –

+0

Als Randnotiz: Ich nehme an, das ist Teil Ihres Compiler-Projekts, da Sie das Tag 'Compiler-Konstruktion' verwendet haben. Sie sollten den 'run' von den Funktionsnamen weglassen, weil Leute, die mit Parsern arbeiten, erwarten, dass der Name der Funktion derselbe ist wie der Ausdruck, den sie parsen. Daher sind die Begriffe "Aussage", "Aussagen" und "Wenn". Ich weiß, dass du einen Fehler bekommst, wenn du eine Funktion 'if' nennst, also würde ich es' ifParser' nennen, aber nicht run und das führt mich zu der Annahme, dass es eine Funktion ist, die von der Hauptsache aufgerufen werden kann Programm und während das möglich ist, ist nicht üblich. –

Antwort

8

Verwenden Sie das 'und' Stichwort

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

runx() |> ignore 

druckt

runxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxruny 
+0

Phillip, du hast recht, das ist die Lösung für meine Frage. - Als Nebenbemerkung: Nachdem ich meinen Code gelesen habe, habe ich bemerkt, dass meine Sprache Rekursion hinterlassen hat und deswegen stehe ich vor einem solchen Problem. Ich werde meine Sprache umgestalten, um diese linke Rekursion zu entfernen. (Ich sage es, weil es anderen helfen kann). – Gabriel

Verwandte Themen