summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorHannes Schulze <haschu0103@outlook.de>2026-04-06 08:02:39 +0200
committerHannes Schulze <haschu0103@outlook.de>2026-04-06 08:02:39 +0200
commit78907b4340b06c58ec7a31da68e96f398b65e940 (patch)
treee27861951746ca087a574a7441e3bd7b61646ddb /tools
parent92da08078a5459ca1089743eb58385e752bdb5fa (diff)
(de-)marshal enums and bitfields
Diffstat (limited to 'tools')
-rw-r--r--tools/Scanner/Generator.lean51
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