Brainf*ck - Java
This is a discussion on Brainf*ck - Java ; Mikie Harrop wrote:
> Jeff Higgins wrote:
>> Jon Harrop wrote:
>>> Anyone know of a Brainf*ck compiler written in Java that uses run-time
>>> code generation?
>>>
>>> I recently implemented compilers in OCaml using LLVM and F# using
...
-
Re: Brainf*ck
Mikie Harrop wrote:
> Jeff Higgins wrote:
>> Jon Harrop wrote:
>>> Anyone know of a Brainf*ck compiler written in Java that uses run-time
>>> code generation?
>>>
>>> I recently implemented compilers in OCaml using LLVM and F# using
>>> System.Reflection.Emit and I'd like to compare performance...
>>
>> Will you provide access to your implementations?
>
> Sure. The full articles describing the designs and implementations of
> these
> programs are available in the OCaml and F#.NET Journals:
>
> http://www.ffconsultancy.com/product..._journal/?cljp
> http://www.ffconsultancy.com/product..._journal/?cljp
By registration only?
>
> But I am happy to post the source code here. Here is the F# using
> System.Reflection.Emit and .NET 3.5:
>
>
> Here is the OCaml using LLVM:
>
Thank you.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Drug therapies are replacing a lot of medicines
as we used to know it."
--- Adolph Bush,
-
Brainf*ck
Anyone know of a Brainf*ck compiler written in Java that uses run-time code
generation?
I recently implemented compilers in OCaml using LLVM and F# using
System.Reflection.Emit and I'd like to compare performance...
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
-
Re: Brainf*ck
Jon Harrop wrote:
>
> Anyone know of a Brainf*ck compiler written in Java that uses run-time
> code
> generation?
>
> I recently implemented compilers in OCaml using LLVM and F# using
> System.Reflection.Emit and I'd like to compare performance...
>
Will you provide access to your implementations?
-
Re: Brainf*ck
Jon Harrop wrote:
> Jeff Higgins wrote:
>> Jon Harrop wrote:
>>> Anyone know of a Brainf*ck compiler written in Java that uses run-time
>>> code generation?
>>>
>>> I recently implemented compilers in OCaml using LLVM and F# using
>>> System.Reflection.Emit and I'd like to compare performance...
>>
>> Will you provide access to your implementations?
>
> Sure. The full articles describing the designs and implementations of
> these
> programs are available in the OCaml and F#.NET Journals:
>
> http://www.ffconsultancy.com/product..._journal/?cljp
> http://www.ffconsultancy.com/product..._journal/?cljp
By registration only?
>
> But I am happy to post the source code here. Here is the F# using
> System.Reflection.Emit and .NET 3.5:
>
>
> Here is the OCaml using LLVM:
>
Thank you.
-
Re: Brainf*ck
Jeff Higgins wrote:
> Jon Harrop wrote:
>> Anyone know of a Brainf*ck compiler written in Java that uses run-time
>> code generation?
>>
>> I recently implemented compilers in OCaml using LLVM and F# using
>> System.Reflection.Emit and I'd like to compare performance...
>
> Will you provide access to your implementations?
Sure. The full articles describing the designs and implementations of these
programs are available in the OCaml and F#.NET Journals:
http://www.ffconsultancy.com/product..._journal/?cljp
http://www.ffconsultancy.com/product..._journal/?cljp
But I am happy to post the source code here. Here is the F# using
System.Reflection.Emit and .NET 3.5:
#light
open System.Reflection.Emit
let putchar = typeof<System.Console>.GetMethod("Write", [|typeof<byte>|])
let getchar = typeof<System.Console>.GetMethod("Read")
let rec compile (il: ILGenerator) read =
let load_p() = il.Emit(OpCodes.Ldloc_0)
let load_d() =
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Ldloc_0)
il.Emit(OpCodes.Ldelem_I1)
let int (n: int) () = il.Emit(OpCodes.Ldc_I4, n)
let ( + ) f g () =
f()
g()
il.Emit(OpCodes.Add)
let store_p f =
f()
il.Emit(OpCodes.Stloc_0)
let store_d f =
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Ldloc_0)
f()
il.Emit(OpCodes.Stelem_I1)
let apply (f : System.Reflection.MethodInfo) x () =
x()
il.Emit(OpCodes.Call, f)
let nop() = ()
let c = read()
match c with
| Some '>' -> store_p(load_p + int 1)
| Some '<' -> store_p(load_p + int(-1))
| Some '+' -> store_d(load_d + int 1)
| Some '-' -> store_d(load_d + int(-1))
| Some '.' -> apply putchar load_d ()
| Some ',' -> store_d(apply getchar nop)
| Some '[' ->
let test = il.DefineLabel()
let rest = il.DefineLabel()
il.Emit(OpCodes.Br, test)
il.MarkLabel(test)
load_d()
int 0 ()
il.Emit(OpCodes.Beq, rest)
compile il read
il.Emit(OpCodes.Br, test)
il.MarkLabel(rest)
| _ -> ()
match c with
| Some ']' | None -> ()
| _ -> compile il read
let main (filename : string) =
let dm = DynamicMethod("bf", null, [|typeof<int8 array>|])
let il = dm.GetILGenerator()
let p = il.DeclareLocal(typeof<int>)
il.Emit(OpCodes.Ldc_I4, 0)
il.Emit(OpCodes.Stloc_0)
use reader = new System.IO.StreamReader(filename)
let read() =
if reader.EndOfStream then None else reader.Read() |> char |> Some
compile il read
il.Emit(OpCodes.Ret)
dm
[<System.STAThread>]
do
let dialog = Microsoft.Win32.OpenFileDialog()
let result = dialog.ShowDialog()
if result.HasValue && result.Value then
let dm = main dialog.FileName
let d = Array.create 65536 0y
dm.Invoke(null, [| box d |]) |> ignore
Here is the OCaml using LLVM:
open Llvm
open Llvm_executionengine
open Llvm_target
open Llvm_scalar_opts
let int_type = match Sys.word_size with
| 32 -> i32_type
| 64 -> i64_type
| _ -> exit 1
let int n = const_int int_type n
let int8 n = const_int i8_type n
let int32 n = const_int i32_type n
type state =
{
func: llvalue;
p: llvalue;
d: llvalue;
putchar: llvalue;
getchar: llvalue;
blk: llbasicblock;
}
let rec compile env ch =
let bb = builder_at_end env.blk in
match try Some(input_char ch) with End_of_file -> None with
| Some '>' ->
ignore(build_store
(build_add (build_load env.p "" bb) (int 1) "" bb)
env.p bb);
compile env ch
| Some '<' ->
ignore(build_store
(build_sub (build_load env.p "" bb) (int 1) "" bb)
env.p bb);
compile env ch
| Some '+' ->
let d = build_gep env.d [|int32 0; build_load env.p "" bb|] "" bb in
ignore(build_store
(build_add (build_load d "" bb) (int8 1) "" bb)
d bb);
compile env ch
| Some '-' ->
let d = build_gep env.d [|int32 0; build_load env.p "" bb|] "" bb in
ignore(build_store
(build_sub (build_load d "" bb) (int8 1) "" bb)
d bb);
compile env ch
| Some '.' ->
let d = build_gep env.d [|int32 0; build_load env.p "" bb|] "" bb in
ignore(build_call env.putchar [|build_load d "" bb|] "" bb);
compile env ch
| Some ',' ->
let d = build_gep env.d [|int32 0; build_load env.p "" bb|] "" bb in
ignore(build_store (build_call env.getchar [| |] "" bb) d bb);
compile env ch
| Some '[' ->
let test = append_block "test" env.func in
let body = append_block "body" env.func in
let rest = append_block "rest" env.func in
ignore(build_br test bb);
compile_test_body_rest { env with blk = test } body rest ch
| None | Some ']' -> env
| Some _ -> compile env ch
and compile_test_body_rest env body rest ch =
let bb = builder_at_end env.blk in
let d = build_gep env.d [|int32 0; build_load env.p "" bb|] "" bb in
ignore(build_cond_br
(build_icmp Icmp.Eq (build_load d "" bb) (int8 0) "" bb)
rest body bb);
compile_body_rest { env with blk = body } env.blk rest ch
and compile_body_rest env test rest ch =
let env = compile env ch in
let bb = builder_at_end env.blk in
ignore(build_br test bb);
compile { env with blk = rest } ch
let () =
let m = create_module "bf" in
let string_type = pointer_type i8_type in
let memset =
declare_function "memset"
(function_type void_type [| string_type; i8_type; int_type |]) m in
let main = define_function "main" (function_type int_type [| |]) m in
let blk = entry_block main in
let bb = builder_at_end blk in
let size = 65536 in
let env =
{
func = main;
p = build_alloca int_type "p" (builder_at_end blk);
d = build_malloc (array_type i8_type size) "d" (builder_at_end blk);
putchar =
declare_function "putchar" (function_type void_type [| i8_type |])
m;
getchar = declare_function "getchar" (function_type i8_type [| |])
m;
blk = blk;
} in
ignore(build_store (int 0) env.p bb);
let _ =
build_call memset
[|build_bitcast env.d string_type "" bb;
const_int i8_type 0; int size|] "" bb in
let env = compile env stdin in
let bb = builder_at_end env.blk in
ignore(build_free env.d bb);
ignore(build_ret (const_null int_type) bb);
let mp = ModuleProvider.create m in
let ee = ExecutionEngine.create mp in
ExecutionEngine.run_static_ctors ee;
ignore (ExecutionEngine.run_function main [| |] ee);
ExecutionEngine.run_static_dtors ee;
ExecutionEngine.dispose ee
Install OCaml, then install LLVM and finally compile this OCaml program
with:
ocamlopt -cc g++ llvm.cmxa llvm_executionengine.cmxa bf.ml -o bf
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
-
Re: Brainf*ck
"Jon Harrop" <jon@ffconsultancy.com> wrote in message
news:VbqdnZKJnpCsiFrVRVnytQA@bt.com...
> Jeff Higgins wrote:
>> Jon Harrop wrote:
>>> Jeff Higgins wrote:
>>>> Jon Harrop wrote:
>>>>> Anyone know of a Brainf*ck compiler written in Java that uses run-time
>>>>> code generation?
>>>>>
>>>>> I recently implemented compilers in OCaml using LLVM and F# using
>>>>> System.Reflection.Emit and I'd like to compare performance...
>>>>
>>>> Will you provide access to your implementations?
>>>
>>> Sure. The full articles describing the designs and implementations of
>>> these
>>> programs are available in the OCaml and F#.NET Journals:
>>>
>>> http://www.ffconsultancy.com/product..._journal/?cljp
>>> http://www.ffconsultancy.com/product..._journal/?cljp
>>
>> By registration only?
>
> Yes.
>
>>> But I am happy to post the source code here. Here is the F# using
>>> System.Reflection.Emit and .NET 3.5:
>>>
>>>
>>> Here is the OCaml using LLVM:
>>
>> Thank you.
>
> No problem. Do you have a Java equivalent?
>
No, but still looking.
Seems to be no shortage of examples shy
the run-time code generation requirement.
-
Re: Brainf*ck
Jeff Higgins wrote:
> Jon Harrop wrote:
>> Jeff Higgins wrote:
>>> Jon Harrop wrote:
>>>> Anyone know of a Brainf*ck compiler written in Java that uses run-time
>>>> code generation?
>>>>
>>>> I recently implemented compilers in OCaml using LLVM and F# using
>>>> System.Reflection.Emit and I'd like to compare performance...
>>>
>>> Will you provide access to your implementations?
>>
>> Sure. The full articles describing the designs and implementations of
>> these
>> programs are available in the OCaml and F#.NET Journals:
>>
>> http://www.ffconsultancy.com/product..._journal/?cljp
>> http://www.ffconsultancy.com/product..._journal/?cljp
>
> By registration only?
Yes.
>> But I am happy to post the source code here. Here is the F# using
>> System.Reflection.Emit and .NET 3.5:
>>
>>
>> Here is the OCaml using LLVM:
>
> Thank you.
No problem. Do you have a Java equivalent?
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
-
Re: Brainf*ck
Jeff Higgins wrote:
> No, but still looking.
> Seems to be no shortage of examples shy
> the run-time code generation requirement.
Yes, I've got lots of interpreters but it is the run-time code generation
that really interests me.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u