anchor.diff:          | ""  -> failwith "ReaderError: Unmatched parenthesis"
           | _ -> rec_read_list (read_form reader :: result)
       new MalList(rec_read_list []) :> _
  +
  +  let read_quote (reader:Reader) : MalType =
  +    let quote_symbol = reader.next
  +    if reader.peek = "" then
  +      failwith "ReaderError: Quote requires one argument"
  +    let quote_name =
  +      match quote_symbol with
  +        | "'" -> "quote"
  +        | "`" -> "quasiquote"
  +        | "~" -> "unquote"
  +        | "~@" -> "splice-unquote"
  +        | _ -> failwith "ReaderError: \"" + quote_symbol + "\" is not a quote symbol"
  +    new MalList([ new MalSymbol(quote_name) ; read_form reader]) :> _
     
     let read_atom (reader:Reader) : MalType =
       let str = reader.next
  
positive.code:       | (true, int) -> new MalNumber(int) :> _
        | _ -> new MalSymbol(str) :> _
    
    let first = reader.peek
    if first = "(" then
      reader.next |> ignore
      read_list reader
    else
      read_atom reader
  
  let read_str (str:string) : MalType = 
    read_form (new Reader(tokenizer str))
  
negative.code: type private TokenAndRest = { token: string ; rest: string }
  
  let private tokenizer (str:string) =
    let token_reg = "(~@|[\[\]{}()'`~^@]|\"(.|(\\\"))*\"|;.*|[^\s\[\]{}('\"`,;)]*)"
    
    let cut_down_token_by_regex (str:string) (reg:string) =
      let m = Regex.Match(str, "^[\s,]*(" + reg + ")(.*$)")
      if m.Success then
        let values = [ for x in m.Groups -> x.Value ]
        { token = values.[1] ; rest = List.last values }
  