Created
March 26, 2017 00:34
-
-
Save jdh30/01964c37221b6fea817bc1bf029e47c0 to your computer and use it in GitHub Desktop.
Reverse polish compiler in F# using LLVM, derived from this 35-line Racket example http://beautifulracket.com/stacker/source-listing.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let (|Int|_|) s = | |
let mutable x = 0 | |
if System.Int32.TryParse(s, &x) then Some x else None | |
LLVM.NativeLibrary.LLVMDLL.Load() | |
LLVM.Target.InitializeNative() | |
let context = LLVM.Context.Global | |
let i32 = LLVM.IntegerType.GetInt32 context | |
let compile lines : System.Func<int> = | |
let mdl = LLVM.Module("main", context) | |
let ee = LLVM.ExecutionEngine mdl | |
let fnType = LLVM.FunctionType i32 | |
let fn = mdl.CreateFunction("calc", fnType) | |
let blk = LLVM.Block("blk", context, fn) | |
let gen = LLVM.InstructionBuilder(context, blk) | |
let constant x = i32.Constant(uint64 x, true) :> LLVM.Value | |
let rec (|Parse|) = function | |
| Int x::t -> constant x, t | |
| "+"::Parse(x, Parse(y, t)) -> gen.Add(x, y), t | |
| "*"::Parse(x, Parse(y, t)) -> gen.Multiply(x, y), t | |
let (Parse(f, _)) = lines | |
ignore(gen.Return f) | |
let interop = LLVM.Interop.ClrInterop ee | |
interop.GetDelegate(fn, mdl) | |
let lines = stdin.ReadToEnd().Split '\n' |> List.ofSeq |> List.rev | |
printfn "%d" ((compile lines).Invoke()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment