2 people like it.

Turtle in Gtk#

Turtle interpreter example using Mono's Gtk# library with example paths for MonoDevelop (running on Linux) and Xamarin Studio (running on Mac and Windows).

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
// References to Mono's Gtk# library for MonoDevelop on Linux
#r "/usr/lib/cli/atk-sharp-2.0/atk-sharp.dll"
#r "/usr/lib/cli/glib-sharp-2.0/glib-sharp.dll"
#r "/usr/lib/cli/gdk-sharp-2.0/gdk-sharp.dll"
#r "/usr/lib/cli/gtk-sharp-2.0/gtk-sharp.dll"
// References to Mono's Gtk# library for Xamarin Studio on Mac
//#I "/Library/Frameworks/Mono.framework/Versions/3.10.0/lib/mono/gtk-sharp-2.0"
//#r "gdk-sharp.dll"
//#r "gtk-sharp.dll"
// References to Mono's Gtk# library for Xamarin Studio on Windows
//#I "C:/Program Files (x86)/GtkSharp/2.12/lib/gtk-sharp-2.0"
//#r "gdk-sharp.dll"
//#r "gtk-sharp.dll"

open Gtk
open System

/// Abstract Syntax Tree
module AST =
   type distance = int
   type degrees = int
   type count = int
   type command =
      | Forward of distance
      | Left of degrees
      | Right of degrees
      | Repeat of count * command list

open AST

// Turtle Type
type Turtle = { X:float; Y:float; A:int }

let width, height = 500, 500

let execute commands drawLine =
   let turtle = { X=float width/2.0; Y=float height/2.0; A = -90 }
   let rec perform turtle = function
      | Forward n ->
         let r = float turtle.A * Math.PI / 180.0
         let dx, dy = float n * cos r, float n * sin r
         let x, y =  turtle.X, turtle.Y
         let x',y' = x + dx, y + dy
         drawLine (x,y) (x',y')
         { turtle with X = x'; Y = y' }
      | Left n -> { turtle with A=turtle.A + n }
      | Right n -> { turtle with A=turtle.A - n }
      | Repeat(n,commands) ->
         let rec repeat turtle = function
            | 0 -> turtle
            | n -> repeat (performAll turtle commands) (n-1)
         repeat turtle n
   and performAll = List.fold perform
   performAll turtle commands |> ignore

let show commands =
   let window = new Window("Turtle")
   window.SetDefaultSize(width, height)
   window.DeleteEvent.Add(fun e -> window.Hide(); Application.Quit(); e.RetVal <- true)
   let drawing = new Gtk.DrawingArea()
   drawing.ExposeEvent.Add( fun x ->
       let gc = drawing.Style.BaseGC(StateType.Normal)
       let allocColor (r,g,b) =
          let col = ref (Gdk.Color(r,g,b))
          let _ = gc.Colormap.AllocColor(col, true, true)
          !col
       gc.Foreground <- allocColor (255uy,0uy,0uy)
       let drawLine (x1,y1) (x2,y2) =
            drawing.GdkWindow.DrawLine(gc, int x1, int y1, int x2, int y2) 
       execute commands drawLine
       )
   window.Add(drawing)
   window.ShowAll()
   window.Show()

let invoke action =   
    Application.Init()
    Application.Invoke(fun _ _ -> action())
    Application.Run()

let commands = [for i in 1..1000 do yield! [Forward 6; Right(i*7)]]
invoke (fun () -> show commands)
namespace System
type distance = int

Full name: Script.AST.distance
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
type degrees = int

Full name: Script.AST.degrees
type count = int

Full name: Script.AST.count
type command =
  | Forward of distance
  | Left of degrees
  | Right of degrees
  | Repeat of count * command list

Full name: Script.AST.command
union case command.Forward: distance -> command
union case command.Left: degrees -> command
union case command.Right: degrees -> command
union case command.Repeat: count * command list -> command
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
module AST

from Script


 Abstract Syntax Tree
type Turtle =
  {X: float;
   Y: float;
   A: int;}

Full name: Script.Turtle
Turtle.X: float
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
Turtle.Y: float
Turtle.A: int
val width : int

Full name: Script.width
val height : int

Full name: Script.height
val execute : commands:command list -> drawLine:(float * float -> float * float -> unit) -> unit

Full name: Script.execute
val commands : command list
val drawLine : (float * float -> float * float -> unit)
val turtle : Turtle
val perform : (Turtle -> command -> Turtle)
val n : distance
val r : float
type Math =
  static val PI : float
  static val E : float
  static member Abs : value:sbyte -> sbyte + 6 overloads
  static member Acos : d:float -> float
  static member Asin : d:float -> float
  static member Atan : d:float -> float
  static member Atan2 : y:float * x:float -> float
  static member BigMul : a:int * b:int -> int64
  static member Ceiling : d:decimal -> decimal + 1 overload
  static member Cos : d:float -> float
  ...

Full name: System.Math
field Math.PI = 3.14159265359
val dx : float
val dy : float
val cos : value:'T -> 'T (requires member Cos)

Full name: Microsoft.FSharp.Core.Operators.cos
val sin : value:'T -> 'T (requires member Sin)

Full name: Microsoft.FSharp.Core.Operators.sin
val x : float
val y : float
val x' : float
val y' : float
val n : degrees
val n : count
val repeat : (Turtle -> int -> Turtle)
val n : int
val performAll : (Turtle -> command list -> Turtle)
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val fold : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State

Full name: Microsoft.FSharp.Collections.List.fold
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val show : commands:'a -> 'b

Full name: Script.show
val commands : 'a
val window : obj
val drawing : obj
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val invoke : action:'a -> 'b

Full name: Script.invoke
val action : 'a
val commands : command list

Full name: Script.commands
val i : int

More information

Link:http://fssnip.net/p6
Posted:5 months ago
Author:Phillip Trelford
Tags: turtle , ast , interpreter , gtk#