anchor.diff:                  | ArrayIndex index -> ArrayAccessExp {array=term; index=index}
                   | TypeConstraintType typ -> TypeConstraint {exp=term; typ=typ}
                   | FieldAccessName fieldName -> RecordAccessExp {record=term; fieldName=fieldName}
  -                | UnsafeTypeCastType typ -> UnsafeTypeCast {exp=term; typ=typ}) |> attempt
  +                | UnsafeTypeCastType typ -> UnsafeTypeCast {exp=term; typ=typ})
   
   // templateApply
   do
  
positive.code: ﻿module Parse
  open FParsec
  open Ast
  
  let singleLineComment = skipString "//" >>. restOfLine true >>% ()
  let multiLineComment = skipString "(*" >>. skipCharsTillString "*)" true System.Int32.MaxValue
  
negative.code:                 })
      let pLet =
          pipe2
              (pstring "let" >>. ws >>. fatalizeAnyError (pattern .>> ws .>> skipChar '=' .>> ws))
              (fatalizeAnyError (expr .>> ws))
              (fun pat expr ->
                  LetExp {left=pat; right=expr})
      let pVar =
          pipe2
              (pstring "var" >>. ws >>. fatalizeAnyError (pos id .>> ws))
              (fatalizeAnyError (skipChar ':' >>. ws >>. tyExpr))
              (fun varName ty ->
                  DeclVarExp { varName = varName; typ = ty} )
      let assign =
          pipe3
              (skipString "set" >>. ws >>. (fatalizeAnyError (skipString "ref" |> opt |>> Option.isSome |> pos) .>> ws))
              (fatalizeAnyError (leftAssign .>> ws .>> skipChar '=' .>> ws))
              (fatalizeAnyError expr)
              (fun ref_ left right -> AssignExp {left=left; right=right; ref=ref_})
      let forLoop =
          pipe6
              (pstring "for" >>. ws >>. fatalizeAnyError (pos id .>> ws))
              (fatalizeAnyError (skipChar ':' >>. ws >>. tyExpr .>> ws |> opt))
              (fatalizeAnyError (pstring "in" >>. ws >>. expr .>> ws))
              (fatalizeAnyError ((pstring "to" >>% Upto) <|> (pstring "downto" >>% Downto) |> pos .>> ws))
              (fatalizeAnyError expr)
              (fatalizeAnyError (pstring "do" >>. ws >>. expr .>> pstring "end"))
              (fun varName typ start direction end_ body ->
                  ForLoopExp {varName=varName; typ=typ; start=start; direction=direction; end_=end_; body=body})
      let doWhileLoop =
          pipe2
              (pstring "do" >>. ws >>. fatalizeAnyError (expr .>> ws))
              (fatalizeAnyError (pstring "while" >>. ws >>. expr .>> ws .>> pstring "end"))
              (fun body condition -> DoWhileLoopExp {body=body; condition=condition})
      let whileLoop =
          pipe2
              (pstring "while" >>. ws >>. fatalizeAnyError (expr .>> ws .>> pstring "do" .>> ws))
              (fatalizeAnyError (expr .>> ws .>> pstring "end"))
              (fun condition body -> WhileLoopExp {condition=condition; body=body})
      let fn = skipString "fn" >>. ws >>. fatalizeAnyError (functionClause "->" .>> ws .>> skipString "end") |> pos |>> LambdaExp
      let case =
          let caseClause = (pattern .>> ws) .>>. (pstring "=>" >>. ws >>. expr)
          pipe2
              (pstring "case" >>. ws >>. fatalizeAnyError (expr .>> pstring "of" .>> ws))
              (fatalizeAnyError ((skipChar '|' >>. ws >>. caseClause) |> many1 |> pos .>> ws .>> pstring "end"))
              (fun on clauses ->
                  CaseExp {on=on; clauses=clauses})
      let recordExpr =
          let fieldList = separatedList ((pos id .>> ws) .>>. (skipChar '=' >>. ws >>. expr)) ';'
          pipe3
              (pos (((attempt moduleQualifier |>> Choice2Of2) <|> (id |>> Choice1Of2))) .>> ws)
              (templateApply |> opt .>> ws)
              (betweenChar '{' (ws >>. fieldList .>> ws) '}' |> pos)
              (fun recordTy template fields ->
                  RecordExp {recordTy=recordTy; templateArgs=template; initFields=fields})
      let arrayLiteral = betweenChar '[' (separatedList expr ',') ']' |> pos |>> ArrayLitExp
      let pref = pstring "ref" >>. ws >>. (fatalizeAnyError expr) |>> RefExp
      let modQual = moduleQualifier |> pos |>> ModQualifierExp
      let varReference = attempt id |> pos |>> VarExp
      let arrayMake =
          pipe2
              (skipString "array" >>. ws >>. fatalizeAnyError (tyExpr .>> ws))
              (fatalizeAnyError ((skipString "of" >>. ws >>. expr |> opt) .>> ws .>> skipString "end"))
              (fun arrTy initializer -> ArrayMakeExp {typ=arrTy; initializer=initializer})
      let inlineCpp' = inlineCpp |>> InlineCode
      let tuple = betweenChar '(' (separatedList1 expr ',') ')' |>> TupleExp
      let smartpointer = (skipString "smartpointer" >>. ws >>. fatalizeAnyError (expr .>> ws .>> skipString "end")) |>> Smartpointer
      let nullexp = (skipString "null" |> pos |>> NullExp) .>> ws
      let e = choice ([punit; attempt parens; ptrue; pfalse; nullexp; charlist; str;
                      attempt pfloating; pint; smartpointer;
                      fn; quit; attempt tuple; attempt recordExpr; attempt applyTemplateToFunc; seq;
                      attempt modQual; forLoop; doWhileLoop; whileLoop;
                      pLet; pVar; pIf; assign; case;
                      arrayLiteral; pref; arrayMake; inlineCpp'; varReference]) .>> ws |> pos
      opp.TermParser <-
          leftRecurse
              e
  