ho la seguente situazione:funzione circolare le chiamate quando si valutano i nodi AST per interprete
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"
Come si può vedere, la funzione runStatement
chiama runIf
, e runIf
chiamate runStatement
, perché un se-dichiarazione è formata da alcuni generali dichiarazioni e una dichiarazione generale può essere un'istruzione if.
Come posso risolvere questa situazione?
PS .: Ho situazioni simili con altre funzioni come runWhile
, runIfElse
e così via.
Si prega di inserire sempre tutto il codice (tipi, funzioni, 'dichiarazioni open') necessari per consentire l'esempio di compilazione. Ciò consente ad altri di concentrarsi sulla fornitura di una soluzione senza dover prima risolvere il codice. – TeaDrivenDev
Passa le funzioni come argomenti anziché accoppiarle. –
Come nota a margine: suppongo che faccia parte del progetto del compilatore poiché hai usato il tag 'compiler-construction'. Dovresti rilasciare 'run' dai nomi delle funzioni perché le persone usano per lavorare con i parser si aspettano che il nome della funzione sia lo stesso del termine che stanno analizzando. Quindi per questo i termini sono 'statement',' statements' e 'if'. So che si verificherà un errore se si chiama una funzione 'if', quindi quello che farei è chiamarlo' ifParser', ma non usare run e questo mi porta a credere che sia una funzione che può essere chiamata dal principale programma e mentre ciò è possibile non è personalizzato. –