From 1f50f07c246ab14d3a1dd52ee5131658d09e1f7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carl-Henrik=20Sk=C3=A5rstedt?= <cskarstedt@gmail.com>
Date: Mon, 4 Jan 2016 20:55:32 -0800
Subject: [PATCH] STRUCT Directive fix

- Structs can contain empty lines
- Structs can be empty
- All structs have a size member named bytes, the number of bytes used
by a struct is <struct>.bytes
---
 x65.cpp | 13 +++++++++++++
 x65.txt | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/x65.cpp b/x65.cpp
index b48f23a..79bfdab 100644
--- a/x65.cpp
+++ b/x65.cpp
@@ -3017,6 +3017,8 @@ StatusCode Asm::BuildStruct(strref name, strref declaration)
 	while (strref line = declaration.line()) {
 		line.trim_whitespace();
 		strref type = line.split_label();
+		if (!type)
+			continue;
 		line.skip_whitespace();
 		unsigned int type_hash = type.fnv1a();
 		unsigned short type_size = 0;
@@ -3055,6 +3057,17 @@ StatusCode Asm::BuildStruct(strref name, strref declaration)
 		member_count++;
 	}
 
+	// add a trailing member of 0 bytes to access the size of the structure
+	{
+		struct MemberOffset bytes_member;
+		bytes_member.offset = size;
+		bytes_member.name = "bytes";
+		bytes_member.name_hash = bytes_member.name.fnv1a();
+		bytes_member.sub_struct = strref();
+		structMembers.push_back(bytes_member);
+		member_count++;
+	}
+
 	pStruct->numMembers = member_count;
 	pStruct->size = size;
 
diff --git a/x65.txt b/x65.txt
index f65a72c..0bcb22f 100644
--- a/x65.txt
+++ b/x65.txt
@@ -662,6 +662,48 @@ Directives for String Symbols
 Structs and Enums
 -----------------
 
+Hierarchical data structures (dot separated sub structures)
+
+Structs helps define complex data types, there are two basic types to
+define struct members, and as long as a struct is declared it can be
+used as a member type of another struct.
+
+The result of a struct is that each member is an offset from the start
+of the data block in memory. Each substruct is referenced by separating
+the struct names with dots.
+
+To get the size of a struct simply use the automatic 'bytes' member as
+in <struct>.bytes
+
+Example:
+
+struct MyStruct {
+    byte    count
+    word    pointer
+}
+
+struct TwoThings {
+    MyStruct thing_one
+    MyStruct thing_two
+}
+
+struct Mixed {
+    word banana
+    TwoThings things
+}
+
+Eval Mixed.bytes
+Eval Mixed.things
+Eval Mixed.things.thing_two
+Eval Mixed.things.thing_two.pointer
+Eval Mixed.things.thing_one.count
+results in the output:
+
+EVAL(15): "Mixed.bytes" = $3
+EVAL(16): "Mixed.things" = $2
+EVAL(27): "Mixed.things.thing_two" = $5
+EVAL(28): "Mixed.things.thing_two.pointer" = $6
+EVAL(29): "Mixed.things.thing_one.count" = $2
 
 * ENUM - structs and enums, declare enumerations like C
 * STRUCT - structs and enums, declare a C-like structure of symbols