-
Notifications
You must be signed in to change notification settings - Fork 4
Control Structures
We now have one final touch before we can call our Lisp dialect a programming language: we must implement conditions and function definitions. Once we get this done we can write a program that will, for example, compute the Fibonacci sequence - a sure sign of a language approaching Turing completeness! Fortunately doing this is rather simple - all we have to do is add two more functions to our interpreter. We can implement conditional statements like this:
blaiseIf [condExpr, expr1, expr2] =
do eval_cond <- eval condExpr
if (0 `notEqual` eval_cond) then eval expr1
else eval expr2
where notEqual val1 (BlaiseInt val2) = val1 /= val2
Function definitions can be done in a similar manner:
blaiseFnArgs = ["args", "..."]
blaiseFn = do
[(BlaiseList args), (BlaiseList body)] <- getSymbols blaiseFnArgs
let newFn = do evalBody <- mapM eval body
return $ last evalBody
return $ BlaiseFn newFn (map (\(BlaiseSymbol arg)->arg) args)
That's it! We can finally define fib to compute a Fibonacci sequence like so [3]:
(set fib (fn (n)
(if (eq n 0) 1
(if (eq n 1) 1
(+ (fib (- n 1)) (fib (- n 2)))))))
We can now call fib as if it were any other function!
(fib 4)
(fib 10)
[3] Because the interpreter doesn't support newlines you have to type the fib function definition on one line for it to work.