Advertisement
ptrelford

Turtle in Gtk#

Jan 5th, 2015
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.33 KB | None | 0 0
  1. module AST =
  2.    type distance = int
  3.    type degrees = int
  4.    type count = int
  5.    type command =
  6.       | Forward of distance
  7.       | Left of degrees
  8.       | Right of degrees
  9.       | Repeat of count * command list
  10.  
  11. // Reference Gtk#
  12. #r "atk-sharp.dll"
  13. #r "glib-sharp.dll"
  14. #r "gdk-sharp.dll"
  15. #r "gtk-sharp.dll"
  16.  
  17. module Interpreter =
  18.    open AST
  19.    open Gtk
  20.    open System
  21.  
  22.    type Turtle = { X:float; Y:float; A:int }
  23.  
  24.    let width, height = 500, 500
  25.  
  26.    let draw commands drawLine =
  27.       let turtle = { X=float width/2.0; Y=float height/2.0; A = -90 }
  28.       let rec perform turtle = function
  29.          | Forward n ->
  30.             let r = float turtle.A * Math.PI / 180.0
  31.             let dx, dy = float n * cos r, float n * sin r
  32.             let x, y =  turtle.X, turtle.Y
  33.             let x',y' = x + dx, y + dy
  34.             drawLine (x,y) (x',y')
  35.             { turtle with X = x'; Y = y' }
  36.          | Left n -> { turtle with A=turtle.A + n }
  37.          | Right n -> { turtle with A=turtle.A - n }
  38.          | Repeat(n,commands) ->
  39.             let rec repeat turtle = function
  40.                | 0 -> turtle
  41.                | n -> repeat (performAll turtle commands) (n-1)
  42.             repeat turtle n
  43.       and performAll = List.fold perform
  44.       performAll turtle commands |> ignore
  45.  
  46.    let show commands =
  47.       let window = new Window("Turtle")
  48.       window.SetDefaultSize(width, height)
  49.       window.DeleteEvent.Add(fun e -> window.Hide(); Application.Quit(); e.RetVal <- true)
  50.       let drawing = new DrawingArea()
  51.       drawing.ExposeEvent.Add( fun x ->
  52.          let gc = drawing.Style.BaseGC(StateType.Normal)
  53.          let allocColor (r,g,b) =
  54.             let col = ref (Gdk.Color(r,g,b))
  55.             let _ = gc.Colormap.AllocColor(col, true, true)
  56.             !col
  57.          gc.Foreground <- allocColor (255uy,0uy,0uy)
  58.          let drawLine (x1,y1) (x2,y2) =
  59.             drawing.GdkWindow.DrawLine(gc, int x1, int y1, int x2, int y2)
  60.          draw commands drawLine
  61.          )
  62.       window.Add(drawing)
  63.       window.ShowAll()
  64.       window.Show()
  65.  
  66.    let invoke action =  
  67.        Application.Init()
  68.        Application.Invoke(fun _ _ -> action())
  69.        Application.Run()
  70.  
  71.    let execute commands = invoke (fun () -> show commands)
  72.  
  73. // Refrence FParsec
  74. #r "./lib/FParsecCS.dll"
  75. #r "./lib/FParsec.dll"
  76.  
  77. module Parser =
  78.    open AST
  79.    open FParsec
  80.  
  81.    let pforward =
  82.       (pstring "forward" <|> pstring "fd") >>. spaces1 >>. pfloat
  83.       |>> fun x -> Forward(int x)
  84.    let pleft =
  85.       (pstring "left" <|> pstring "lt") >>. spaces1 >>. pfloat
  86.       |>> fun x -> Left(int x)
  87.    let pright =
  88.       (pstring "right" <|> pstring "rt") >>. spaces1 >>. pfloat
  89.       |>> fun x -> Right(int x)
  90.  
  91.    let prepeat, prepeatimpl = createParserForwardedToRef ()
  92.  
  93.    let pcommand = pforward <|> pleft <|> pright <|> prepeat
  94.  
  95.    let block = between (pstring "[") (pstring "]") (many1 (pcommand .>> spaces))
  96.  
  97.    prepeatimpl :=
  98.       pstring "repeat" >>. spaces1 >>. pfloat .>> spaces .>>. block
  99.       |>> fun (n,commands) -> Repeat(int n, commands)
  100.  
  101.    let parse code =
  102.       match run (many pcommand) code with
  103.       | Success(result,_,_) -> result
  104.       | Failure(msg,_,_) -> failwith msg
  105.  
  106. let code = "repeat 10 [right 36 repeat 5 [forward 54 right 72]]"
  107. let program = Parser.parse code
  108. Interpreter.execute program
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement