| import init.lean.name | |
| open Lean | |
| abbrev ConstantTable (α : Type) := HashMap Name α | |
| def mkSimpleFnTable : IO (IO.Ref (ConstantTable (Nat → Nat))) := | |
| IO.mkRef {} | |
| @[init mkSimpleFnTable] | |
| constant simpleFnTable : IO.Ref (ConstantTable (Nat → Nat)) := default _ | |
| def registerSimpleFn (n : Name) (fn : Nat → Nat) : IO Unit := | |
| do ini ← IO.initializing, | |
| unless ini (throw "we should only register functions during initialization"), | |
| simpleFnTable.modify (λ m, m.insert n fn) | |
| def add10 (n : Nat) := n+10 | |
| def mul10 (n : Nat) := n*10 | |
| def inc (n : Nat) := n+1 | |
| @[init] def regAdd10 : IO Unit := registerSimpleFn `add10 add10 | |
| @[init] def regMul10 : IO Unit := registerSimpleFn `mul10 mul10 | |
| @[init] def regInc : IO Unit := registerSimpleFn `inc inc | |
| def eval (fName : Name) (n : Nat) : IO Nat := | |
| do m ← simpleFnTable.get, | |
| match m.find fName with | |
| | some f := pure $ f n | |
| | none := throw (IO.userError "unknown function") | |
| def main (xs : List String) : IO Unit := | |
| do [f, x] ← pure xs | throw "invalid number of arguments", | |
| r ← eval (mkSimpleName f) x.toNat, | |
| IO.println r, | |
| pure () |