diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i
index 95870e265c067b9897b2b9584edcfa2e29588b74..81274c3a8bc999a179ae3021cc50318ae07ec177 100644
--- a/src/bindings/swig/hammer.i
+++ b/src/bindings/swig/hammer.i
@@ -2,3 +2,4 @@
 
 %import "hammer/allocator.h"
 %import "hammer/hammer.h"
+
diff --git a/src/hammer.h b/src/hammer.h
index 02e4085a130fd5d1a3593a60c3ffa1179a247b94..c8a2bf380a91df3ba1bde041151e1f68dcde24a8 100644
--- a/src/hammer.h
+++ b/src/hammer.h
@@ -70,8 +70,21 @@ typedef struct HBytes_ {
   size_t len;
 } HBytes;
 
+#ifdef SWIG
+typedef union {
+  HBytes bytes;
+  int64_t sint;
+  uint64_t uint;
+  double dbl;
+  float flt;
+  HCountedArray *seq;
+  void *user;
+} HTokenData;
+#endif
+
 typedef struct HParsedToken_ {
   HTokenType token_type;
+#ifndef SWIG
   union {
     HBytes bytes;
     int64_t sint;
@@ -81,6 +94,9 @@ typedef struct HParsedToken_ {
     HCountedArray *seq; // a sequence of HParsedToken's
     void *user;
   };
+#else
+  HTokenData token_data;
+#endif
   size_t index;
   char bit_offset;
 } HParsedToken;
@@ -144,12 +160,23 @@ typedef struct HParserTestcase_ {
   char* output_unambiguous;
 } HParserTestcase;
 
+#ifdef SWIG
+typedef union {
+  const char* actual_results;
+  size_t parse_time;
+} HResultTiming;
+#endif
+
 typedef struct HCaseResult_ {
   bool success;
+#ifndef SWIG
   union {
     const char* actual_results; // on failure, filled in with the results of h_write_result_unamb
     size_t parse_time; // on success, filled in with time for a single parse, in nsec
   };
+#else
+  HResultTiming timestamp;
+#endif
 } HCaseResult;
 
 typedef struct HBackendResults_ {