Skip to content

Instantly share code, notes, and snippets.

@red75prime
Created August 11, 2015 06:13
Show Gist options
  • Save red75prime/ce6260c918a17019a02f to your computer and use it in GitHub Desktop.
Save red75prime/ce6260c918a17019a02f to your computer and use it in GitHub Desktop.
let generateRouting (mname, nname, mannot, parms, rty)=
if mannot=MADontImplement then
([],[])
else
let locVarNum=ref 1
let getNextLocVar()=
let lvname=sprintf "lv%d" !locVarNum
locVarNum := !locVarNum+1
lvname
let genTypeNum=ref 0
let getNextGT()=
let gtname=if !genTypeNum=0 then "T" else sprintf "T%d" !genTypeNum
genTypeNum := !genTypeNum+1
gtname
let genTypes = ref Map.empty
let localVars = ref Map.empty
let nativeParms = ref Map.empty
let safeParms = ref Map.empty
let returnVal = ref "hr";
let errors = ref List.empty;
let addError err=
errors := err :: !errors
let addSafeParm spname sptype =
safeParms := Map.add spname (sptype,None) !safeParms
let addSafeParmInit spname sptype init=
safeParms := Map.add spname (sptype,Some(init)) !safeParms
let addNativeParm npname spname initExpr=
nativeParms := Map.add npname (spname, fun _ -> initExpr) !nativeParms
let addNativeParmFun npname spname initFun=
nativeParms := Map.add npname (spname, initFun) !nativeParms
let addLocalVar lvname lvtype lvinit=
localVars := Map.add lvname {ty=lvtype; initExpression=lvinit} !localVars
let newGenType constraints=
let gtn=getNextGT()
genTypes := Map.add gtn constraints !genTypes
gtn
// Let's attach list of references to every native parameter
let parmsr=
List.map (
fun (pname, pannot, pty) ->
let refs=parms |> List.filter (fun (_,pannot,_) -> List.contains pname (getReferencedParameters pannot))
(pname, pannot, pty, refs)
) parms
// Let's generate routing
for (pname, pannot, pty, refs) in parmsr do
let safeParmName=toSnake pname // TODO: Process prefixes ("p", "pp" and such)
match pannot with
|AThis ->
if List.isEmpty refs then
addNativeParm pname None "self.0"
else
addError "_This parameter: shouldn't be referenced in annotation"
|ANone ->
match refs with
|[] ->
match pty with
|_ when isVoidPtr pty ->
addError (sprintf "%s parameter: ANone annotation cannot be applied to void pointer" pname)
|_ when (match (removeConst pty) with Ptr(Ptr(_)) -> true |_ -> false) ->
addError (sprintf "%s parameter: ANone annotation cannot be used with double indirection" pname)
|Primitive _ ->
// No processing. Pass as is
addSafeParm safeParmName (convertTypeToRustNoArray pty pannot)
addNativeParm pname (Some(safeParmName)) safeParmName
|EnumRef e ->
addSafeParm safeParmName (RType e)
addNativeParm pname (Some(safeParmName)) (safeParmName+".0")
|TypedefRef "LPCWSTR" ->
let locVar=getNextLocVar()
addLocalVar locVar (RType "Vec<u16>") ("str_to_vec_u16("+safeParmName+")")
addSafeParm safeParmName (RType "Cow<String, &str>")
addNativeParm pname (Some(safeParmName)) (locVar+".as_ptr()")
|Ptr(Const(cty)) ->
addSafeParm safeParmName (RBorrow(convertTypeToRustNoArray cty pannot))
addNativeParm pname (Some(safeParmName)) safeParmName
|Ptr(cty) ->
addSafeParm safeParmName (RMutBorrow(convertTypeToRustNoArray cty pannot))
addNativeParm pname (Some(safeParmName)) safeParmName
|Array(cty,num) ->
// C array in function parameters means pointer to first element of array
addSafeParm safeParmName (RMutBorrow(RArray(convertTypeToRustNoArray cty pannot,num)))
addNativeParm pname (Some(safeParmName)) (safeParmName+".as_ptr()")
|_ ->
addSafeParm safeParmName (convertTypeToRustNoArray pty pannot)
addNativeParm pname (Some(safeParmName)) safeParmName
|[(rname, InOutOfSize _, _)] |[(rname, OutOfSize _, _)] ->
// this parametes conveys the size of another parameter
match pty with
|Ptr(Primitive _) |Ptr(TypedefRef _) ->
addSafeParmInit safeParmName (convertTypeToRustNoArray pty pannot) (fun m -> "*"+safeParmName+" = mem::size_of_val("+(Map.find rname m)+")")
addNativeParm pname (Some(safeParmName)) safeParmName
|Primitive _ |TypedefRef _ ->
addNativeParmFun pname None (fun m -> "mem::size_of_val("+(Map.find rname m)+")")
|_ -> addError ("Unexpected type for "+pname+", referent of [InOutOfSize]"+rname)
([{nativeName = nname;
safeName = mname;
unsafe = mannot=MAUnsafe;
genericTypes = !genTypes;
localVars = !localVars;
nativeParms = !nativeParms;
safeParms = !safeParms;
returnVal = !returnVal;
}], !errors)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment