Closed GlowingScrewdriver closed 4 months ago
I can think of a policy to handle this. Perhaps we can implement this in C-Lisp, and leave Brilisp unchanged.
Let's just not allow implicit returns in c-lisp.
Alright. But we still have to deal with things like
(define ((main int))
(if #t
(ret 1)
(ret 0)))
Because if we don't deal with it, we are encouraging code like this:
(define ((main int))
(if #t
(ret 1))
(ret 0))
Either we can scan the function body and remove empty labels, or we can implement an unreachable
instruction like LLVM.
LLVM's unreachable
instruction marks a location in the code as unreachable; but it is also a terminating instruction. So, if we implemented unreachable
, we could expect the programmer to be explicit and write code like this:
(define ((main int))
(if #t
(ret 1)
(ret 0))
(unreachable))
Write equivalent C code, try compiling and put llvm IR output if it does
Closed by #49
One of LLVM's conditions for a well-formed program is that every basic block must be terminated. That means that the last instruction must be a terminating instruction, like a return, branch, or anything that transfers control away from the basic block.
There is one edge case that we need to look into: the end of a function. Currently, neither Brilisp nor C-Lisp handle this
If a program is written in such a way that there is no terminating instruction at the end of a function, neither Brilisp nor C-Lisp correct it, and it is eventually Clang/LLVM that throws the error. For example, trying to compile the following program:
will cause this (rather cryptic) error to be thrown by LLVM: