Created
April 15, 2016 10:55
-
-
Save mjul/9596111798e37567513c79618fe38810 to your computer and use it in GitHub Desktop.
F# Quoted Expressions (writing a compiler)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// F# Quoted Expressions | |
open Microsoft.FSharp.Quotations | |
open Microsoft.FSharp.Quotations.Patterns | |
open Microsoft.FSharp.Quotations.DerivedPatterns | |
// A typed code quotation. | |
let expr : Expr<int> = <@ 1 + 1 @> | |
// An untyped code quotation. | |
let expr2 : Expr = <@@ 1 + 1 @@> | |
/// Abstract Syntax Tree for our Lisp | |
module Lisp = | |
type Literal = | |
| String of string | |
| Integer of int | |
| Symbol of string | |
type Expression = | |
| Literal of Literal | |
| List of Expression list | |
let rec formatExpression (e:Expression) = | |
match e with | |
| List exprs -> | |
sprintf "(%s)" ((Seq.map formatExpression exprs) |> String.concat " " ) | |
| Literal (String s) -> | |
let quoted = s.Replace("\"","\\\"") | |
sprintf "\"%s\"" quoted | |
| Literal (Integer i) -> sprintf "%d" i | |
| Literal (Symbol name) -> sprintf "%s" name | |
/// Given an F# expression, compile it to a Lisp expression | |
let rec lisp expr = | |
match expr with | |
| Application (expr1, expr2) -> | |
// function Application | |
Lisp.List([lisp expr1; lisp expr2]) | |
| SpecificCall <@@ (+) @@> (_, _, exprList) -> | |
let exprs = exprList |> List.map lisp | |
Lisp.List (List.append [Lisp.Literal (Lisp.Symbol "+")] exprs) | |
| Int32(n) -> | |
Lisp.Literal (Lisp.Integer n) | |
| String(s) -> | |
Lisp.Literal (Lisp.String s) | |
| x -> | |
failwith "unknown expression: %A" | |
lisp <@ 1 + (2 + 3)@> |> Lisp.formatExpression |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment