def comp(expr, target, linkage): _, variable, value = transformSugarDef(expr) return endWithLink( linkage, preserving( [ENV], compExp(value, VAL, NEX), InstrSeq([ENV, VAL], [target], [f'{CFunc}(NAMEOBJ("{variable}"), val, env);'])))
def compLambda(expr, target=VAL, linkage=NEX): (funcEntry, afterLambda), (funcEntryInfo, afterLambdaInfo) = \ branchesAndInfos(('ENTRY', 'AFTER_LAMBDA')) return appendInstrSeqs( tackOnInstrSeq( endWithLink( afterLambda if linkage == NEX else linkage, InstrSeq([ENV], [target], [f"{target} = COMPOBJ(_{funcEntry}, env);"])), compLambdaBody(expr, funcEntryInfo)), InstrSeq([], [], [afterLambdaInfo]))
def compApp(expr, target=VAL, linkage=NEX): function, *arguments = expr return preserving( [ENV, CONT], compExp(function, target=FUNC), preserving( [FUNC, CONT], constructArglist([compExp(arg) for arg in arguments]), compFuncCall(target, linkage) if function not in PRIMITIVES else endWithLink( linkage, InstrSeq([FUNC, ARGLIST], [target], [f"{target} = applyPrimitive(func, arglist);"]))))
def compFuncCall(target, linkage): branches, infos = branchesAndInfos(( 'PRIMITIVE', 'COMPOUND', 'COMPILED', 'AFTER_CALL', )) (primitiveBranch, compoundBranch, _, afterCall) = branches (primitiveBranchInfo, compoundBranchInfo, compiledBranchInfo, afterCallInfo) = infos endLabel = afterCall if linkage == NEX else linkage applyPrimitiveSeq = InstrSeq( [FUNC, ARGLIST], [target], [f"{target} = applyPrimitive(func, arglist);"]) def makeTestGotoSeq(testString, label): return InstrSeq([FUNC], [], [f"if ({testString}(func)) goto {label};"]) # calling compFuncApp twice generates two different endLabels return appendInstrSeqs( makeTestGotoSeq('isPrimitive', primitiveBranch), makeTestGotoSeq('isCompound', compoundBranch), parallelInstrSeqs( appendInstrSeqs(compiledBranchInfo, compFuncApp(target, endLabel, 'compiled')), parallelInstrSeqs( appendInstrSeqs(compoundBranchInfo, compFuncApp(target, endLabel, 'compound')), appendInstrSeqs(primitiveBranchInfo, endWithLink(linkage, applyPrimitiveSeq)))), afterCallInfo)
def compQuote(expr, target, linkage): _, text = expr return endWithLink( linkage, InstrSeq([], [target], [f'{target} = parse("{schemify(text)}\\n");']))
def compVar(expr, target, linkage): return endWithLink( linkage, InstrSeq([ENV], [target], [f'{target} = lookup(NAMEOBJ("{expr}"), env);']))
def compNum(expr, target, linkage): return endWithLink(linkage, InstrSeq([], [target], [f"{target} = NUMOBJ({expr});"]))