Created
August 11, 2015 06:13
-
-
Save red75prime/ce6260c918a17019a02f to your computer and use it in GitHub Desktop.
This file contains 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
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