archivesOfToyLang/tshunhue/nimllvm/factorial.nim

60 lines
1.6 KiB
Nim
Raw Normal View History

2023-09-30 22:30:08 +08:00
import
llvm_core, llvm_analysis, llvm_target
proc factorial =
discard initializeNativeTarget()
discard initializeNativeAsmPrinter()
let module = moduleCreateWithName("fac_module")
var facArgs = [int32Type()]
let facType = functionType(int32Type(), facArgs[0].addr, 1, 0)
let fac = module.addFunction("fac", facType)
fac.setFunctionCallConv(CCallConv)
let n = fac.getParam(0)
let
entry = fac.appendBasicBlock("entry")
ifTrue = fac.appendBasicBlock("iftrue")
ifFalse = fac.appendBasicBlock("iffalse")
endBB = fac.appendBasicBlock("end")
builder = createBuilder()
builder.positionBuilderAtEnd(entry)
let ifCmp = builder.buildICmp(IntEQ, n, constInt(int32Type(), 0, 0), "n == 0")
discard builder.buildCondBr(ifCmp, ifTrue, ifFalse)
builder.positionBuilderAtEnd(ifTrue)
let resIfTrue = constInt(int32Type(), 1, 0)
discard builder.buildBr(endBB)
builder.positionBuilderAtEnd(ifFalse)
var
nMinus = builder.buildSub(n, constInt(int32Type(), 1, 0), "n - 1")
callFacArgs = [nMinus]
callFac = builder.buildCall(fac, callFacArgs[0].addr, 1, "fac(n - 1)")
resIfFalse = builder.buildMul(n, callFac, "n * fac(n - 1)")
discard builder.buildBr(endBB)
builder.positionBuilderAtEnd(endBB)
var
res = builder.buildPhi(int32Type(), "result")
phiVals = [resIfTrue, resIfFalse]
phiBlocks = [ifTrue, ifFalse]
res.addIncoming(phiVals[0].addr, phiBlocks[0].addr, 2)
discard builder.buildRet(res)
var error: cstring
let errorP = cast[cstringArray](error.addr)
discard verifyModule(module, AbortProcessAction, errorP)
disposeMessage(error)
module.dumpModule()
factorial()