Quick actions

cmd+k|ctrl+k

Navigation

Languages

Abstract Syntax Tree

Snippet info

Language

Fsharp

Visibility

public

Author

baeverfj

Created

2017-06-09T16:26:22Z

Updated

2017-06-10T13:24:01Z

open System

type Ops = | Ldc of int32 | Ldl of string | Stl of string | Dim of string * Exp list
           | Ld32 | St32
           | Call of string | Jump of string | Lea of string | Func of string * Exp
           | For of Exp
           | If of Exp * Exp
           | Add | Sub | Neg | Mul | Muls | Div | Divs
           | And | Or | Eor | Bic | Not | Flag | NFLag
           | Lsl | Lsr | Asr | Ror
           | Dup | Drop | Swap | Over | Rot | NRot
           | Return
and Exp = Ops list

type Sym = Var of int32 | Fun of Exp
let symbols = Map.empty
let (array:int []) = Array.zeroCreate 16

let rec exec (sym,stk) inst =
        printfn "Stk: %A" (List.rev stk)
        printfn "Exe: %A" inst
        match inst,stk with
        | Ldc n,xs        -> (sym,n::xs)
        | Ldl a,xs        -> match Map.tryFind a sym with
                             | Some(Var n) -> (sym,n::xs)
                             | _ -> failwith "Unknown variable!"
        | Stl a, x::xs    -> (Map.add a (Var x) sym,xs)
        | Add, x::y::xs   -> (sym,x+y::xs)
        | Sub, x::y::xs   -> (sym,y-x::xs)
        | Neg, x::xs      -> (sym,-x::xs)
        | Mul, x::y::xs   -> (sym,x*y::xs)
        | Div, x::y::xs   -> (sym,y/x::xs)
        | And, x::y::xs   -> (sym,(x&&&y)::xs)
        | Or, x::y::xs    -> (sym,(x|||y)::xs)
        | Eor, x::y::xs   -> (sym,(x^^^y)::xs)
        | Bic, x::y::xs   -> (sym,(x&&&(~~~y))::xs)
        | Not, x::xs      -> (sym,~~~x::xs)
        | Lsl, x::y::xs   -> (sym,(y<<<x)::xs)
        | Lsr, x::y::xs   -> (sym,(int32((uint32 y)>>>x))::xs)
        | Asr, x::y::xs   -> (sym,(y>>>x)::xs)
        | Dup, x::xs      -> (sym,x::x::xs)
        | Drop, x::xs     -> (sym,xs)
        | Swap, x::y::xs  -> (sym,y::x::xs)
        | Over, x::y::xs  -> (sym,y::x::y::xs)
        | Ld32, x::xs     -> (sym,array.[x]::xs) 
        | St32, x::y::xs  -> array.[x] <- y
                             (sym,xs) 
        | If (t,f), c::xs -> if c <> 0
                             then run (sym,xs) t
                             else run (sym,xs) f
        | For c,i::xs     -> let rec loop (sym,stk) i =
                              if i <= 0 then (sym,stk)
                              else loop (run (sym,stk) c) (i - 1)
                             loop (sym,xs) i
        | Func (s,c),xs   -> (Map.add s (Fun c) sym,xs)
        | Call f,xs       -> match Map.tryFind f sym with
                             | Some(Fun f) -> run (sym,xs) f
                             | _ -> failwithf "Unknown function '%s'!" f
        | _,[]            -> failwith "Stack underflow!"
        | op,_            -> failwithf "Unknown instruction '%A'!" op
    
and run (symbols,stack) code = List.fold exec (symbols,stack) code


[<EntryPoint>]
let main argv =
    let prg = [ Func ("LSL",[For [Dup; Add]])
                Func ("LSR",[For [Ldc 2; Div]])
                Ldc 1920
                Ldc 1080
                Stl "xRes"
                Stl "yRes"
                Ldl "xRes"
                Ldl "yRes"
                Mul
                Ldc 2
                Call "LSL" 
              ]

    let (sym,stk) = run (symbols,[]) prg
    printfn "Stk: %A" (List.rev stk)

    printfn "\nSymbols:"
    for s in sym do
        match s.Value with
        | Var n -> printfn "Variable: %s = %A" s.Key n
        | Fun n -> printfn "Function: %s = %A" s.Key n
    
    printfn "\nContent of Data stack:"
    List.iter (printfn "%A") stk
        

    0 // return an integer exit code
INFO