diff options
| author | Hannes Schulze <haschu0103@outlook.de> | 2026-04-06 08:02:39 +0200 |
|---|---|---|
| committer | Hannes Schulze <haschu0103@outlook.de> | 2026-04-06 08:02:39 +0200 |
| commit | 78907b4340b06c58ec7a31da68e96f398b65e940 (patch) | |
| tree | e27861951746ca087a574a7441e3bd7b61646ddb /tools/Scanner | |
| parent | 92da08078a5459ca1089743eb58385e752bdb5fa (diff) | |
(de-)marshal enums and bitfields
Diffstat (limited to 'tools/Scanner')
| -rw-r--r-- | tools/Scanner/Generator.lean | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/tools/Scanner/Generator.lean b/tools/Scanner/Generator.lean index 76542e7..f2514f4 100644 --- a/tools/Scanner/Generator.lean +++ b/tools/Scanner/Generator.lean @@ -85,6 +85,16 @@ private def typeToLean : ArgumentType → Generator String | .newID .none => do return s!"AnyObject" | .newID (.some iface) => resolveInterface iface +private def marshalType : ArgumentType → String + | .int _ => ".int" + | .uint _ => ".uint" + | .fixed => ".fixed" + | .string _ => ".string" + | .object _ _ => ".object" + | .newID _ => ".object" + | .array => ".array" + | .fd => ".fd" + section Header private def emitNameDefinitions (protocol : ProtocolDesc) : Generator Unit := do @@ -113,9 +123,38 @@ private def emitEnumMarshallable (protocol : ProtocolDesc) : Generator Unit := d for enum in iface.enums do emitLine s!"" emitLine s!"instance : Marshallable {iface.name.pascalCase}.{enum.name.pascalCase} where" - emitLine s!" marshal := sorry" - emitLine s!" demarshal := sorry" - -- TODO + if enum.bitfield then + emitLine s!" marshal" + emitLine s!" | .uint, μ => ArgumentMarshaller.marshalUInt <|" + emitLine s!" 0" + for entry in enum.entries do + emitLine s!" ||| (if μ.{entry.name.camelCase} then {entry.value} else 0)" + emitLine s!" | _, _ => throw \"Marshalling unexpected type, expected uint.\"" + emitLine s!" demarshal" + emitLine s!" | .uint => do" + emitLine s!" let μ ← ArgumentDemarshaller.demarshalUInt" + emitLine " return {" + for entry in enum.entries do + emitLine s!" {entry.name.camelCase} := (μ &&& {entry.value}) == {entry.value}" + emitLine " }" + emitLine s!" | _ => throw \"Demarshalling unexpected type, expected uint.\"" + else + emitLine s!" marshal" + for entry in enum.entries do + emitLine s!" | .int, .{entry.name.camelCase} => ArgumentMarshaller.marshalInt {entry.value}" + emitLine s!" | .uint, .{entry.name.camelCase} => ArgumentMarshaller.marshalUInt {entry.value}" + emitLine s!" | _, _ => throw \"Marshalling unexpected type, expected int or uint.\"" + emitLine s!" demarshal" + let emitMatch (demarshal : String) : Generator Unit := do + emitLine s!" match (← ArgumentDemarshaller.{demarshal}) with" + for entry in enum.entries do + emitLine s!" | {entry.value} => pure .{entry.name.camelCase}" + emitLine s!" | _ => throw \"Invalid enum value.\"" + emitLine s!" | .int => do" + emitMatch "demarshalInt" + emitLine s!" | .uint => do" + emitMatch "demarshalUInt" + emitLine s!" | _ => throw \"Demarshalling unexpected type, expected int or uint.\"" def generateHeader (rootModule : String) (protocol : ProtocolDesc) : String := Generator.runProtocol rootModule protocol ".Header" do @@ -186,8 +225,8 @@ private def emitInterfaceInstances (protocol : ProtocolDesc) : Generator Unit := for ev in iface.events do emitLine s!" | {ev.opcode} => do" emitLine s!" return .{ev.name.camelCase}" - for _ in ev.arguments do - emitLine s!" (← Marshallable.demarshal)" + for arg in ev.arguments do + emitLine s!" (← Marshallable.demarshal {marshalType arg.type})" emitLine " | _ => throw s!\"Received invalid opcode\"" def generateInterface (rootModule : String) (protocol : ProtocolDesc) : String := @@ -252,7 +291,7 @@ private def emitRequests (protocol : ProtocolDesc) : Generator Unit := do emitLine s!" ArgumentMarshaller.marshalUInt (inferInstanceAs (Interface ι)).version" emitLine s!" ArgumentMarshaller.marshalAnyObject .none" | _ => - emitLine s!" Marshallable.marshal {arg.name.camelCase}" + emitLine s!" Marshallable.marshal {marshalType arg.type} {arg.name.camelCase}" emitLine s!" return {req.opcode}" -- Special case wl_callback handling if req.returnType.isWlCallback then |
